convert tabs to spaces

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1869962 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2019-11-18 08:56:06 +00:00
parent 63bb22887d
commit 948b0e8f08
3 changed files with 1569 additions and 1571 deletions

View File

@ -42,52 +42,52 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
static final class GUID {
/*
* this class is currently only used here, but could be moved to a
* common package if needed
*/
private static final int TEXT_FORMAT_LENGTH = 36;
/*
* this class is currently only used here, but could be moved to a
* common package if needed
*/
private static final int TEXT_FORMAT_LENGTH = 36;
public static final int ENCODED_SIZE = 16;
public static final int ENCODED_SIZE = 16;
/** 4 bytes - little endian */
private final int _d1;
/** 2 bytes - little endian */
private final int _d2;
/** 2 bytes - little endian */
private final int _d3;
/**
* 8 bytes - serialized as big endian, stored with inverted endianness here
*/
private final long _d4;
/** 4 bytes - little endian */
private final int _d1;
/** 2 bytes - little endian */
private final int _d2;
/** 2 bytes - little endian */
private final int _d3;
/**
* 8 bytes - serialized as big endian, stored with inverted endianness here
*/
private final long _d4;
public GUID(LittleEndianInput in) {
this(in.readInt(), in.readUShort(), in.readUShort(), in.readLong());
}
public GUID(LittleEndianInput in) {
this(in.readInt(), in.readUShort(), in.readUShort(), in.readLong());
}
public GUID(int d1, int d2, int d3, long d4) {
_d1 = d1;
_d2 = d2;
_d3 = d3;
_d4 = d4;
}
public GUID(int d1, int d2, int d3, long d4) {
_d1 = d1;
_d2 = d2;
_d3 = d3;
_d4 = d4;
}
public void serialize(LittleEndianOutput out) {
out.writeInt(_d1);
out.writeShort(_d2);
out.writeShort(_d3);
out.writeLong(_d4);
}
public void serialize(LittleEndianOutput out) {
out.writeInt(_d1);
out.writeShort(_d2);
out.writeShort(_d3);
out.writeLong(_d4);
}
@Override
public boolean equals(Object obj) {
@Override
public boolean equals(Object obj) {
if (!(obj instanceof GUID)) {
return false;
}
GUID other = (GUID) obj;
return _d1 == other._d1 && _d2 == other._d2
&& _d3 == other._d3 && _d4 == other._d4;
}
GUID other = (GUID) obj;
return _d1 == other._d1 && _d2 == other._d2
&& _d3 == other._d3 && _d4 == other._d4;
}
@Override
public int hashCode() {
@ -96,108 +96,108 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
}
public int getD1() {
return _d1;
}
return _d1;
}
public int getD2() {
return _d2;
}
public int getD2() {
return _d2;
}
public int getD3() {
return _d3;
}
public int getD3() {
return _d3;
}
public long getD4() {
byte[] result = new byte[Long.SIZE/Byte.SIZE];
long l = _d4;
for (int i = result.length-1; i >= 0; i--) {
result[i] = (byte)(l & 0xFF);
l >>= 8;
}
return LittleEndian.getLong(result, 0);
}
public long getD4() {
byte[] result = new byte[Long.SIZE/Byte.SIZE];
long l = _d4;
for (int i = result.length-1; i >= 0; i--) {
result[i] = (byte)(l & 0xFF);
l >>= 8;
}
public String formatAsString() {
return LittleEndian.getLong(result, 0);
}
StringBuilder sb = new StringBuilder(36);
public String formatAsString() {
int PREFIX_LEN = "0x".length();
sb.append(HexDump.intToHex(_d1).substring(PREFIX_LEN));
sb.append("-");
sb.append(HexDump.shortToHex(_d2).substring(PREFIX_LEN));
sb.append("-");
sb.append(HexDump.shortToHex(_d3).substring(PREFIX_LEN));
sb.append("-");
String d4Chars = HexDump.longToHex(getD4());
sb.append(d4Chars, PREFIX_LEN, PREFIX_LEN+4);
sb.append("-");
sb.append(d4Chars.substring(PREFIX_LEN+4));
return sb.toString();
}
StringBuilder sb = new StringBuilder(36);
@Override
public String toString() {
StringBuilder sb = new StringBuilder(64);
sb.append(getClass().getName()).append(" [");
sb.append(formatAsString());
sb.append("]");
return sb.toString();
}
int PREFIX_LEN = "0x".length();
sb.append(HexDump.intToHex(_d1).substring(PREFIX_LEN));
sb.append("-");
sb.append(HexDump.shortToHex(_d2).substring(PREFIX_LEN));
sb.append("-");
sb.append(HexDump.shortToHex(_d3).substring(PREFIX_LEN));
sb.append("-");
String d4Chars = HexDump.longToHex(getD4());
sb.append(d4Chars, PREFIX_LEN, PREFIX_LEN+4);
sb.append("-");
sb.append(d4Chars.substring(PREFIX_LEN+4));
return sb.toString();
}
/**
* Read a GUID in standard text form e.g.<br>
* 13579BDF-0246-8ACE-0123-456789ABCDEF
* <br> -&gt; <br>
* 0x13579BDF, 0x0246, 0x8ACE 0x0123456789ABCDEF
*/
public static GUID parse(String rep) {
char[] cc = rep.toCharArray();
if (cc.length != TEXT_FORMAT_LENGTH) {
throw new RecordFormatException("supplied text is the wrong length for a GUID");
}
int d0 = (parseShort(cc, 0) << 16) + (parseShort(cc, 4) << 0);
int d1 = parseShort(cc, 9);
int d2 = parseShort(cc, 14);
@Override
public String toString() {
StringBuilder sb = new StringBuilder(64);
sb.append(getClass().getName()).append(" [");
sb.append(formatAsString());
sb.append("]");
return sb.toString();
}
/**
* Read a GUID in standard text form e.g.<br>
* 13579BDF-0246-8ACE-0123-456789ABCDEF
* <br> -&gt; <br>
* 0x13579BDF, 0x0246, 0x8ACE 0x0123456789ABCDEF
*/
public static GUID parse(String rep) {
char[] cc = rep.toCharArray();
if (cc.length != TEXT_FORMAT_LENGTH) {
throw new RecordFormatException("supplied text is the wrong length for a GUID");
}
int d0 = (parseShort(cc, 0) << 16) + (parseShort(cc, 4) << 0);
int d1 = parseShort(cc, 9);
int d2 = parseShort(cc, 14);
System.arraycopy(cc, 19, cc, 20, 4);
long d3 = parseLELong(cc, 20);
long d3 = parseLELong(cc, 20);
return new GUID(d0, d1, d2, d3);
}
return new GUID(d0, d1, d2, d3);
}
private static long parseLELong(char[] cc, int startIndex) {
long acc = 0;
for (int i = startIndex + 14; i >= startIndex; i -= 2) {
acc <<= 4;
acc += parseHexChar(cc[i + 0]);
acc <<= 4;
acc += parseHexChar(cc[i + 1]);
}
return acc;
}
private static long parseLELong(char[] cc, int startIndex) {
long acc = 0;
for (int i = startIndex + 14; i >= startIndex; i -= 2) {
acc <<= 4;
acc += parseHexChar(cc[i + 0]);
acc <<= 4;
acc += parseHexChar(cc[i + 1]);
}
return acc;
}
private static int parseShort(char[] cc, int startIndex) {
int acc = 0;
for (int i = 0; i < 4; i++) {
acc <<= 4;
acc += parseHexChar(cc[startIndex + i]);
}
return acc;
}
private static int parseShort(char[] cc, int startIndex) {
int acc = 0;
for (int i = 0; i < 4; i++) {
acc <<= 4;
acc += parseHexChar(cc[startIndex + i]);
}
return acc;
}
private static int parseHexChar(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
if (c >= 'A' && c <= 'F') {
return c - 'A' + 10;
}
if (c >= 'a' && c <= 'f') {
return c - 'a' + 10;
}
throw new RecordFormatException("Bad hex char '" + c + "'");
}
}
private static int parseHexChar(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
if (c >= 'A' && c <= 'F') {
return c - 'A' + 10;
}
if (c >= 'a' && c <= 'f') {
return c - 'a' + 10;
}
throw new RecordFormatException("Bad hex char '" + c + "'");
}
}
/**
* Link flags
@ -628,7 +628,7 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
size += 4; //address length
size += _address.length()*2;
if (_uninterpretedTail != null) {
size += TAIL_SIZE;
size += TAIL_SIZE;
}
} else if (FILE_MONIKER.equals(_moniker)){
size += 2; //file_opts
@ -652,8 +652,8 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
private static byte[] readTail(byte[] expectedTail, LittleEndianInput in) {
byte[] result = new byte[TAIL_SIZE];
in.readFully(result);
byte[] result = new byte[TAIL_SIZE];
in.readFully(result);
// if (false) { // Quite a few examples in the unit tests which don't have the exact expected tail
// for (int i = 0; i < expectedTail.length; i++) {
// if (expectedTail[i] != result[i]) {

File diff suppressed because it is too large Load Diff

View File

@ -28,283 +28,281 @@ import org.apache.poi.util.POILogger;
* Base of all chunks, which hold data, flags etc
*/
public final class Chunk {
/**
* The contents of the chunk, excluding the header,
* trailer and separator
*/
private byte[] contents;
private ChunkHeader header;
/** May be null */
private ChunkTrailer trailer;
/** May be null */
private ChunkSeparator separator;
/** The possible different commands we can hold */
protected CommandDefinition[] commandDefinitions;
/** The command+value pairs we hold */
private Command[] commands;
/* The blocks (if any) we hold */
//private Block[] blocks
/** The name of the chunk, as found from the commandDefinitions */
private String name;
/**
* The contents of the chunk, excluding the header,
* trailer and separator
*/
private byte[] contents;
private ChunkHeader header;
/** May be null */
private ChunkTrailer trailer;
/** May be null */
private ChunkSeparator separator;
/** The possible different commands we can hold */
protected CommandDefinition[] commandDefinitions;
/** The command+value pairs we hold */
private Command[] commands;
/* The blocks (if any) we hold */
//private Block[] blocks
/** The name of the chunk, as found from the commandDefinitions */
private String name;
/** For logging warnings about the structure of the file */
private POILogger logger = POILogFactory.getLogger(Chunk.class);
/** For logging warnings about the structure of the file */
private POILogger logger = POILogFactory.getLogger(Chunk.class);
public Chunk(ChunkHeader header, ChunkTrailer trailer, ChunkSeparator separator, byte[] contents) {
this.header = header;
this.trailer = trailer;
this.separator = separator;
this.contents = contents.clone();
}
public Chunk(ChunkHeader header, ChunkTrailer trailer, ChunkSeparator separator, byte[] contents) {
this.header = header;
this.trailer = trailer;
this.separator = separator;
this.contents = contents.clone();
}
public byte[] _getContents() {
return contents;
}
public byte[] _getContents() {
return contents;
}
public ChunkHeader getHeader() {
return header;
}
public ChunkHeader getHeader() {
return header;
}
/**
* Gets the separator between this chunk and the next, if it exists
*
* @return the separator
*/
public ChunkSeparator getSeparator() {
return separator;
}
/**
* Gets the separator between this chunk and the next, if it exists
*
* @return the separator
*/
public ChunkSeparator getSeparator() {
return separator;
}
/**
* Gets the trailer for this chunk, if it exists
*
* @return the trailer
*/
public ChunkTrailer getTrailer() {
return trailer;
}
/**
* Gets the trailer for this chunk, if it exists
*
* @return the trailer
*/
public ChunkTrailer getTrailer() {
return trailer;
}
/**
* Gets the command definitions, which define and describe much
* of the data held by the chunk.
*
* @return the command definitions
*/
public CommandDefinition[] getCommandDefinitions() {
return commandDefinitions;
}
/**
* Gets the command definitions, which define and describe much
* of the data held by the chunk.
*
* @return the command definitions
*/
public CommandDefinition[] getCommandDefinitions() {
return commandDefinitions;
}
public Command[] getCommands() {
return commands;
}
public Command[] getCommands() {
return commands;
}
/**
* Get the name of the chunk, as found from the CommandDefinitions
*
* @return the name of the chunk
*/
public String getName() {
return name;
}
/**
* Get the name of the chunk, as found from the CommandDefinitions
*
* @return the name of the chunk
*/
public String getName() {
return name;
}
/**
* Returns the size of the chunk, including any
* headers, trailers and separators.
*
* @return the size of the chunk
*/
public int getOnDiskSize() {
int size = header.getSizeInBytes() + contents.length;
if(trailer != null) {
size += trailer.getTrailerData().length;
}
if(separator != null) {
size += separator.separatorData.length;
}
return size;
}
/**
* Returns the size of the chunk, including any
* headers, trailers and separators.
*
* @return the size of the chunk
*/
public int getOnDiskSize() {
int size = header.getSizeInBytes() + contents.length;
if(trailer != null) {
size += trailer.getTrailerData().length;
}
if(separator != null) {
size += separator.separatorData.length;
}
return size;
}
/**
* Uses our CommandDefinitions to process the commands
* our chunk type has, and figure out the
* values for them.
*/
protected void processCommands() {
if(commandDefinitions == null) {
throw new IllegalStateException("You must supply the command definitions before calling processCommands!");
}
/**
* Uses our CommandDefinitions to process the commands
* our chunk type has, and figure out the
* values for them.
*/
protected void processCommands() {
if(commandDefinitions == null) {
throw new IllegalStateException("You must supply the command definitions before calling processCommands!");
}
// Loop over the definitions, building the commands
// and getting their values
ArrayList<Command> commandList = new ArrayList<>();
for(CommandDefinition cdef : commandDefinitions) {
int type = cdef.getType();
int offset = cdef.getOffset();
// Loop over the definitions, building the commands
// and getting their values
ArrayList<Command> commandList = new ArrayList<>();
for(CommandDefinition cdef : commandDefinitions) {
int type = cdef.getType();
int offset = cdef.getOffset();
// Handle virtual commands
if(type == 10) {
name = cdef.getName();
continue;
} else if(type == 18) {
continue;
}
// Handle virtual commands
if(type == 10) {
name = cdef.getName();
continue;
} else if(type == 18) {
continue;
}
// Build the appropriate command for the type
Command command;
if(type == 11 || type == 21) {
command = new BlockOffsetCommand(cdef);
} else {
command = new Command(cdef);
}
// Build the appropriate command for the type
Command command;
if(type == 11 || type == 21) {
command = new BlockOffsetCommand(cdef);
} else {
command = new Command(cdef);
}
// Bizarrely, many of the offsets are from the start of the
// header, not from the start of the chunk body
switch(type) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
case 11: case 21:
case 12: case 16: case 17: case 18: case 28: case 29:
// Offset is from start of chunk
break;
default:
// Offset is from start of header!
if(offset >= 19) {
offset -= 19;
}
}
// Bizarrely, many of the offsets are from the start of the
// header, not from the start of the chunk body
switch(type) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
case 11: case 21:
case 12: case 16: case 17: case 18: case 28: case 29:
// Offset is from start of chunk
break;
default:
// Offset is from start of header!
if(offset >= 19) {
offset -= 19;
}
}
// Check we seem to have enough data
if(offset >= contents.length) {
logger.log(POILogger.WARN,
"Command offset " + offset + " past end of data at " + contents.length
);
continue;
}
// Check we seem to have enough data
if(offset >= contents.length) {
logger.log(POILogger.WARN,
"Command offset " + offset + " past end of data at " + contents.length
);
continue;
}
try {
// Process
switch(type) {
// Types 0->7 = a flat at bit 0->7
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
int val = contents[offset] & (1<<type);
command.value = Boolean.valueOf(val > 0);
break;
case 8:
command.value = Byte.valueOf(contents[offset]);
break;
case 9:
command.value = Double.valueOf(
LittleEndian.getDouble(contents, offset)
);
break;
case 12:
// A Little Endian String
// Starts 8 bytes into the data segment
// Ends at end of data, or 00 00
try {
// Process
switch(type) {
// Types 0->7 = a flat at bit 0->7
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
int val = contents[offset] & (1<<type);
command.value = Boolean.valueOf(val > 0);
break;
case 8:
command.value = Byte.valueOf(contents[offset]);
break;
case 9:
command.value = Double.valueOf(LittleEndian.getDouble(contents, offset));
break;
case 12:
// A Little Endian String
// Starts 8 bytes into the data segment
// Ends at end of data, or 00 00
// Ensure we have enough data
if(contents.length < 8) {
command.value = "";
break;
}
// Ensure we have enough data
if(contents.length < 8) {
command.value = "";
break;
}
// Find the end point
int startsAt = 8;
int endsAt = startsAt;
for(int j=startsAt; j<contents.length-1 && endsAt == startsAt; j++) {
if(contents[j] == 0 && contents[j+1] == 0) {
endsAt = j;
}
}
if(endsAt == startsAt) {
endsAt = contents.length;
}
// Find the end point
int startsAt = 8;
int endsAt = startsAt;
for(int j=startsAt; j<contents.length-1 && endsAt == startsAt; j++) {
if(contents[j] == 0 && contents[j+1] == 0) {
endsAt = j;
}
}
if(endsAt == startsAt) {
endsAt = contents.length;
}
int strLen = endsAt - startsAt;
command.value = new String(contents, startsAt, strLen, header.getChunkCharset().name());
break;
case 25:
command.value = Short.valueOf(
LittleEndian.getShort(contents, offset)
);
break;
case 26:
command.value = Integer.valueOf(
LittleEndian.getInt(contents, offset)
);
break;
int strLen = endsAt - startsAt;
command.value = new String(contents, startsAt, strLen, header.getChunkCharset().name());
break;
case 25:
command.value = Short.valueOf(
LittleEndian.getShort(contents, offset)
);
break;
case 26:
command.value = Integer.valueOf(
LittleEndian.getInt(contents, offset)
);
break;
// Types 11 and 21 hold the offset to the blocks
case 11: case 21:
if(offset < contents.length - 3) {
int bOffset = (int)LittleEndian.getUInt(contents, offset);
BlockOffsetCommand bcmd = (BlockOffsetCommand)command;
bcmd.setOffset(bOffset);
}
break;
// Types 11 and 21 hold the offset to the blocks
case 11: case 21:
if(offset < contents.length - 3) {
int bOffset = (int)LittleEndian.getUInt(contents, offset);
BlockOffsetCommand bcmd = (BlockOffsetCommand)command;
bcmd.setOffset(bOffset);
}
break;
default:
logger.log(POILogger.INFO,
"Command of type " + type + " not processed!");
}
}
catch (Exception e) {
logger.log(POILogger.ERROR, "Unexpected error processing command, ignoring and continuing. Command: " +
command, e);
}
default:
logger.log(POILogger.INFO,
"Command of type " + type + " not processed!");
}
}
catch (Exception e) {
logger.log(POILogger.ERROR, "Unexpected error processing command, ignoring and continuing. Command: " +
command, e);
}
// Add to the array
commandList.add(command);
}
// Add to the array
commandList.add(command);
}
// Save the commands we liked the look of
this.commands = commandList.toArray(
// Save the commands we liked the look of
this.commands = commandList.toArray(
new Command[0]);
// Now build up the blocks, if we had a command that tells
// us where a block is
}
// Now build up the blocks, if we had a command that tells
// us where a block is
}
/**
* A command in the visio file. In order to make things fun,
* all the chunk actually stores is the value of the command.
* You have to have your own lookup table to figure out what
* the commands are based on the chunk type.
*/
public static class Command {
protected Object value;
private CommandDefinition definition;
/**
* A command in the visio file. In order to make things fun,
* all the chunk actually stores is the value of the command.
* You have to have your own lookup table to figure out what
* the commands are based on the chunk type.
*/
public static class Command {
protected Object value;
private CommandDefinition definition;
private Command(CommandDefinition definition, Object value) {
this.definition = definition;
this.value = value;
}
private Command(CommandDefinition definition) {
this(definition, null);
}
private Command(CommandDefinition definition, Object value) {
this.definition = definition;
this.value = value;
}
private Command(CommandDefinition definition) {
this(definition, null);
}
public CommandDefinition getDefinition() { return definition; }
public Object getValue() { return value; }
}
/*
* A special kind of command that is an artificat of how we
* process CommandDefinitions, and so doesn't actually exist
* in the chunk
*/
public CommandDefinition getDefinition() { return definition; }
public Object getValue() { return value; }
}
/*
* A special kind of command that is an artificat of how we
* process CommandDefinitions, and so doesn't actually exist
* in the chunk
*/
// public static class VirtualCommand extends Command {
// private VirtualCommand(CommandDefinition definition) {
// super(definition);
// }
// }
/**
* A special kind of command that holds the offset to
* a block
*/
private static class BlockOffsetCommand extends Command {
private BlockOffsetCommand(CommandDefinition definition) {
super(definition, null);
}
private void setOffset(int offset) {
value = Integer.valueOf(offset);
}
}
/**
* A special kind of command that holds the offset to
* a block
*/
private static class BlockOffsetCommand extends Command {
private BlockOffsetCommand(CommandDefinition definition) {
super(definition, null);
}
private void setOffset(int offset) {
value = Integer.valueOf(offset);
}
}
}