SonarCube fixes - visibility of member attributes
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1771583 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
12009f09d6
commit
8968b6d6b6
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
package org.apache.poi.hpsf;
|
package org.apache.poi.hpsf;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.apache.poi.util.HexDump;
|
import org.apache.poi.util.HexDump;
|
||||||
import org.apache.poi.util.StringUtil;
|
import org.apache.poi.util.StringUtil;
|
||||||
|
|
||||||
@ -40,12 +42,15 @@ public class ClassID
|
|||||||
public static final ClassID POWERPOINT95 = new ClassID("{EA7BAE70-FB3B-11CD-A903-00AA00510EA3}");
|
public static final ClassID POWERPOINT95 = new ClassID("{EA7BAE70-FB3B-11CD-A903-00AA00510EA3}");
|
||||||
public static final ClassID EQUATION30 = new ClassID("{0002CE02-0000-0000-C000-000000000046}");
|
public static final ClassID EQUATION30 = new ClassID("{0002CE02-0000-0000-C000-000000000046}");
|
||||||
|
|
||||||
|
/** <p>The number of bytes occupied by this object in the byte
|
||||||
|
* stream.</p> */
|
||||||
|
public static final int LENGTH = 16;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>The bytes making out the class ID in correct order,
|
* <p>The bytes making out the class ID in correct order,
|
||||||
* i.e. big-endian.</p>
|
* i.e. big-endian.</p>
|
||||||
*/
|
*/
|
||||||
protected byte[] bytes;
|
private final byte[] bytes = new byte[LENGTH];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -56,8 +61,7 @@ public class ClassID
|
|||||||
* @param src The byte array to read from.
|
* @param src The byte array to read from.
|
||||||
* @param offset The offset of the first byte to read.
|
* @param offset The offset of the first byte to read.
|
||||||
*/
|
*/
|
||||||
public ClassID(final byte[] src, final int offset)
|
public ClassID(final byte[] src, final int offset) {
|
||||||
{
|
|
||||||
read(src, offset);
|
read(src, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,11 +70,8 @@ public class ClassID
|
|||||||
* <p>Creates a {@link ClassID} and initializes its value with
|
* <p>Creates a {@link ClassID} and initializes its value with
|
||||||
* 0x00 bytes.</p>
|
* 0x00 bytes.</p>
|
||||||
*/
|
*/
|
||||||
public ClassID()
|
public ClassID() {
|
||||||
{
|
Arrays.fill(bytes, (byte)0);
|
||||||
bytes = new byte[LENGTH];
|
|
||||||
for (int i = 0; i < LENGTH; i++)
|
|
||||||
bytes[i] = 0x00;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -81,7 +82,6 @@ public class ClassID
|
|||||||
* @param externalForm representation of the Class ID represented by this object.
|
* @param externalForm representation of the Class ID represented by this object.
|
||||||
*/
|
*/
|
||||||
public ClassID(String externalForm) {
|
public ClassID(String externalForm) {
|
||||||
bytes = new byte[LENGTH];
|
|
||||||
String clsStr = externalForm.replaceAll("[{}-]", "");
|
String clsStr = externalForm.replaceAll("[{}-]", "");
|
||||||
for (int i=0; i<clsStr.length(); i+=2) {
|
for (int i=0; i<clsStr.length(); i+=2) {
|
||||||
bytes[i/2] = (byte)Integer.parseInt(clsStr.substring(i, i+2), 16);
|
bytes[i/2] = (byte)Integer.parseInt(clsStr.substring(i, i+2), 16);
|
||||||
@ -89,16 +89,11 @@ public class ClassID
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** <p>The number of bytes occupied by this object in the byte
|
|
||||||
* stream.</p> */
|
|
||||||
public static final int LENGTH = 16;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The number of bytes occupied by this object in the byte
|
* @return The number of bytes occupied by this object in the byte
|
||||||
* stream.
|
* stream.
|
||||||
*/
|
*/
|
||||||
public int length()
|
public int length() {
|
||||||
{
|
|
||||||
return LENGTH;
|
return LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,8 +105,7 @@ public class ClassID
|
|||||||
*
|
*
|
||||||
* @return the bytes making out the class ID.
|
* @return the bytes making out the class ID.
|
||||||
*/
|
*/
|
||||||
public byte[] getBytes()
|
public byte[] getBytes() {
|
||||||
{
|
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,10 +117,8 @@ public class ClassID
|
|||||||
* @param bytes The bytes making out the class ID in big-endian format. They
|
* @param bytes The bytes making out the class ID in big-endian format. They
|
||||||
* are copied without their order being changed.
|
* are copied without their order being changed.
|
||||||
*/
|
*/
|
||||||
public void setBytes(final byte[] bytes)
|
public void setBytes(final byte[] bytes) {
|
||||||
{
|
System.arraycopy(bytes, 0, this.bytes, 0, LENGTH);
|
||||||
for (int i = 0; i < this.bytes.length; i++)
|
|
||||||
this.bytes[i] = bytes[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -141,10 +133,7 @@ public class ClassID
|
|||||||
*
|
*
|
||||||
* @return A byte array containing the class ID.
|
* @return A byte array containing the class ID.
|
||||||
*/
|
*/
|
||||||
public byte[] read(final byte[] src, final int offset)
|
public byte[] read(final byte[] src, final int offset) {
|
||||||
{
|
|
||||||
bytes = new byte[16];
|
|
||||||
|
|
||||||
/* Read double word. */
|
/* Read double word. */
|
||||||
bytes[0] = src[3 + offset];
|
bytes[0] = src[3 + offset];
|
||||||
bytes[1] = src[2 + offset];
|
bytes[1] = src[2 + offset];
|
||||||
@ -160,8 +149,7 @@ public class ClassID
|
|||||||
bytes[7] = src[6 + offset];
|
bytes[7] = src[6 + offset];
|
||||||
|
|
||||||
/* Read 8 bytes. */
|
/* Read 8 bytes. */
|
||||||
for (int i = 8; i < 16; i++)
|
System.arraycopy(src, 8 + offset, bytes, 8, 8);
|
||||||
bytes[i] = src[i + offset];
|
|
||||||
|
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
@ -180,13 +168,14 @@ public class ClassID
|
|||||||
* ID 16 bytes in the byte array after the <var>offset</var> position.
|
* ID 16 bytes in the byte array after the <var>offset</var> position.
|
||||||
*/
|
*/
|
||||||
public void write(final byte[] dst, final int offset)
|
public void write(final byte[] dst, final int offset)
|
||||||
throws ArrayStoreException
|
throws ArrayStoreException {
|
||||||
{
|
|
||||||
/* Check array size: */
|
/* Check array size: */
|
||||||
if (dst.length < 16)
|
if (dst.length < LENGTH) {
|
||||||
throw new ArrayStoreException
|
throw new ArrayStoreException
|
||||||
("Destination byte[] must have room for at least 16 bytes, " +
|
("Destination byte[] must have room for at least 16 bytes, " +
|
||||||
"but has a length of only " + dst.length + ".");
|
"but has a length of only " + dst.length + ".");
|
||||||
|
}
|
||||||
|
|
||||||
/* Write double word. */
|
/* Write double word. */
|
||||||
dst[0 + offset] = bytes[3];
|
dst[0 + offset] = bytes[3];
|
||||||
dst[1 + offset] = bytes[2];
|
dst[1 + offset] = bytes[2];
|
||||||
@ -202,8 +191,7 @@ public class ClassID
|
|||||||
dst[7 + offset] = bytes[6];
|
dst[7 + offset] = bytes[6];
|
||||||
|
|
||||||
/* Write 8 bytes. */
|
/* Write 8 bytes. */
|
||||||
for (int i = 8; i < 16; i++)
|
System.arraycopy(bytes, 8, dst, 8 + offset, 8);
|
||||||
dst[i + offset] = bytes[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -217,16 +205,19 @@ public class ClassID
|
|||||||
* <code>false</code>.
|
* <code>false</code>.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object o)
|
public boolean equals(final Object o) {
|
||||||
{
|
if (o == null || !(o instanceof ClassID)) {
|
||||||
if (o == null || !(o instanceof ClassID))
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
final ClassID cid = (ClassID) o;
|
final ClassID cid = (ClassID) o;
|
||||||
if (bytes.length != cid.bytes.length)
|
if (bytes.length != cid.bytes.length) {
|
||||||
return false;
|
return false;
|
||||||
for (int i = 0; i < bytes.length; i++)
|
}
|
||||||
if (bytes[i] != cid.bytes[i])
|
for (int i = 0; i < bytes.length; i++) {
|
||||||
|
if (bytes[i] != cid.bytes[i]) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,8 +227,7 @@ public class ClassID
|
|||||||
* @see Object#hashCode()
|
* @see Object#hashCode()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode() {
|
||||||
{
|
|
||||||
return new String(bytes, StringUtil.UTF8).hashCode();
|
return new String(bytes, StringUtil.UTF8).hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,18 +238,16 @@ public class ClassID
|
|||||||
* @return String representation of the Class ID represented by this object.
|
* @return String representation of the Class ID represented by this object.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString() {
|
||||||
{
|
StringBuilder sbClassId = new StringBuilder(38);
|
||||||
StringBuffer sbClassId = new StringBuffer(38);
|
|
||||||
sbClassId.append('{');
|
sbClassId.append('{');
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < LENGTH; i++) {
|
||||||
{
|
|
||||||
sbClassId.append(HexDump.toHex(bytes[i]));
|
sbClassId.append(HexDump.toHex(bytes[i]));
|
||||||
if (i == 3 || i == 5 || i == 7 || i == 9)
|
if (i == 3 || i == 5 || i == 7 || i == 9) {
|
||||||
sbClassId.append('-');
|
sbClassId.append('-');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sbClassId.append('}');
|
sbClassId.append('}');
|
||||||
return sbClassId.toString();
|
return sbClassId.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,35 +30,35 @@ import java.io.OutputStream;
|
|||||||
* TODO Fix this, as it starts to go wrong on
|
* TODO Fix this, as it starts to go wrong on
|
||||||
* large streams
|
* large streams
|
||||||
*/
|
*/
|
||||||
final class HDGFLZWCompressor {
|
/* package */ final class HDGFLZWCompressor {
|
||||||
// We use 12 bit codes:
|
// We use 12 bit codes:
|
||||||
// * 0-255 are real bytes
|
// * 0-255 are real bytes
|
||||||
// * 256-4095 are the substring codes
|
// * 256-4095 are the substring codes
|
||||||
// Java handily initialises our buffer / dictionary
|
// Java handily initialises our buffer / dictionary
|
||||||
// to all zeros
|
// to all zeros
|
||||||
byte[] dict = new byte[4096];
|
private byte[] dict = new byte[4096];
|
||||||
|
|
||||||
// The next block of data to be written out, minus
|
// The next block of data to be written out, minus
|
||||||
// its mask byte
|
// its mask byte
|
||||||
byte[] buffer = new byte[16];
|
private byte[] buffer = new byte[16];
|
||||||
// And how long it is
|
// And how long it is
|
||||||
// (Un-compressed codes are 1 byte each, compressed codes
|
// (Un-compressed codes are 1 byte each, compressed codes
|
||||||
// are two)
|
// are two)
|
||||||
int bufferLen = 0;
|
private int bufferLen = 0;
|
||||||
|
|
||||||
// The raw length of a code is limited to 4 bits + 2
|
// The raw length of a code is limited to 4 bits + 2
|
||||||
byte[] rawCode = new byte[18];
|
private byte[] rawCode = new byte[18];
|
||||||
// And how much we're using
|
// And how much we're using
|
||||||
int rawCodeLen = 0;
|
private int rawCodeLen = 0;
|
||||||
|
|
||||||
// How far through the input and output streams we are
|
// How far through the input and output streams we are
|
||||||
int posInp = 0;
|
private int posInp = 0;
|
||||||
int posOut = 0;
|
private int posOut = 0;
|
||||||
|
|
||||||
// What the next mask byte to output will be
|
// What the next mask byte to output will be
|
||||||
int nextMask = 0;
|
private int nextMask = 0;
|
||||||
// And how many bits we've already set
|
// And how many bits we've already set
|
||||||
int maskBitsSet = 0;
|
private int maskBitsSet = 0;
|
||||||
|
|
||||||
public HDGFLZWCompressor() {}
|
public HDGFLZWCompressor() {}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ public final class Chunk {
|
|||||||
public int getOnDiskSize() {
|
public int getOnDiskSize() {
|
||||||
int size = header.getSizeInBytes() + contents.length;
|
int size = header.getSizeInBytes() + contents.length;
|
||||||
if(trailer != null) {
|
if(trailer != null) {
|
||||||
size += trailer.trailerData.length;
|
size += trailer.getTrailerData().length;
|
||||||
}
|
}
|
||||||
if(separator != null) {
|
if(separator != null) {
|
||||||
size += separator.separatorData.length;
|
size += separator.separatorData.length;
|
||||||
|
@ -130,7 +130,7 @@ public final class ChunkFactory {
|
|||||||
ChunkHeader header =
|
ChunkHeader header =
|
||||||
ChunkHeader.createChunkHeader(version, data, offset);
|
ChunkHeader.createChunkHeader(version, data, offset);
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if(header.length < 0) {
|
if(header.getLength() < 0) {
|
||||||
throw new IllegalArgumentException("Found a chunk with a negative length, which isn't allowed");
|
throw new IllegalArgumentException("Found a chunk with a negative length, which isn't allowed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,14 +144,14 @@ public final class ChunkFactory {
|
|||||||
"Header called for " + header.getLength() +" bytes, but that would take us past the end of the data!");
|
"Header called for " + header.getLength() +" bytes, but that would take us past the end of the data!");
|
||||||
|
|
||||||
endOfDataPos = data.length;
|
endOfDataPos = data.length;
|
||||||
header.length = data.length - offset - header.getSizeInBytes();
|
header.setLength(data.length - offset - header.getSizeInBytes());
|
||||||
|
|
||||||
if(header.hasTrailer()) {
|
if(header.hasTrailer()) {
|
||||||
header.length -= 8;
|
header.setLength(header.getLength() - 8);
|
||||||
endOfDataPos -= 8;
|
endOfDataPos -= 8;
|
||||||
}
|
}
|
||||||
if(header.hasSeparator()) {
|
if(header.hasSeparator()) {
|
||||||
header.length -= 4;
|
header.setLength(header.getLength() - 4);
|
||||||
endOfDataPos -= 4;
|
endOfDataPos -= 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,10 +25,10 @@ import java.nio.charset.Charset;
|
|||||||
* A chunk header
|
* A chunk header
|
||||||
*/
|
*/
|
||||||
public abstract class ChunkHeader {
|
public abstract class ChunkHeader {
|
||||||
protected int type;
|
private int type;
|
||||||
protected int id;
|
private int id;
|
||||||
protected int length;
|
private int length;
|
||||||
protected int unknown1;
|
private int unknown1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the appropriate ChunkHeader for the Chunk Header at
|
* Creates the appropriate ChunkHeader for the Chunk Header at
|
||||||
@ -42,23 +42,23 @@ public abstract class ChunkHeader {
|
|||||||
} else {
|
} else {
|
||||||
ch = new ChunkHeaderV6();
|
ch = new ChunkHeaderV6();
|
||||||
}
|
}
|
||||||
ch.type = (int)LittleEndian.getUInt(data, offset + 0);
|
ch.setType((int)LittleEndian.getUInt(data, offset + 0));
|
||||||
ch.id = (int)LittleEndian.getUInt(data, offset + 4);
|
ch.setId((int)LittleEndian.getUInt(data, offset + 4));
|
||||||
ch.unknown1 = (int)LittleEndian.getUInt(data, offset + 8);
|
ch.setUnknown1((int)LittleEndian.getUInt(data, offset + 8));
|
||||||
ch.length = (int)LittleEndian.getUInt(data, offset + 12);
|
ch.setLength((int)LittleEndian.getUInt(data, offset + 12));
|
||||||
ch.unknown2 = LittleEndian.getShort(data, offset + 16);
|
ch.setUnknown2(LittleEndian.getShort(data, offset + 16));
|
||||||
ch.unknown3 = LittleEndian.getUByte(data, offset + 18);
|
ch.setUnknown3(LittleEndian.getUByte(data, offset + 18));
|
||||||
|
|
||||||
return ch;
|
return ch;
|
||||||
} else if(documentVersion == 5 || documentVersion == 4) {
|
} else if(documentVersion == 5 || documentVersion == 4) {
|
||||||
ChunkHeaderV4V5 ch = new ChunkHeaderV4V5();
|
ChunkHeaderV4V5 ch = new ChunkHeaderV4V5();
|
||||||
|
|
||||||
ch.type = LittleEndian.getShort(data, offset + 0);
|
ch.setType(LittleEndian.getShort(data, offset + 0));
|
||||||
ch.id = LittleEndian.getShort(data, offset + 2);
|
ch.setId(LittleEndian.getShort(data, offset + 2));
|
||||||
ch.unknown2 = LittleEndian.getUByte(data, offset + 4);
|
ch.setUnknown2(LittleEndian.getUByte(data, offset + 4));
|
||||||
ch.unknown3 = LittleEndian.getUByte(data, offset + 5);
|
ch.setUnknown3(LittleEndian.getUByte(data, offset + 5));
|
||||||
ch.unknown1 = LittleEndian.getShort(data, offset + 6);
|
ch.setUnknown1(LittleEndian.getShort(data, offset + 6));
|
||||||
ch.length = (int)LittleEndian.getUInt(data, offset + 8);
|
ch.setLength((int)LittleEndian.getUInt(data, offset + 8));
|
||||||
|
|
||||||
return ch;
|
return ch;
|
||||||
} else {
|
} else {
|
||||||
@ -90,6 +90,7 @@ public abstract class ChunkHeader {
|
|||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the length of the trunk, excluding the length
|
* Returns the length of the trunk, excluding the length
|
||||||
* of the header, trailer or separator.
|
* of the header, trailer or separator.
|
||||||
@ -97,6 +98,7 @@ public abstract class ChunkHeader {
|
|||||||
public int getLength() {
|
public int getLength() {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the type of the chunk, which affects the
|
* Returns the type of the chunk, which affects the
|
||||||
* mandatory information
|
* mandatory information
|
||||||
@ -104,7 +106,24 @@ public abstract class ChunkHeader {
|
|||||||
public int getType() {
|
public int getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getUnknown1() {
|
public int getUnknown1() {
|
||||||
return unknown1;
|
return unknown1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setType(int type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLength(int length) {
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUnknown1(int unknown1) {
|
||||||
|
this.unknown1 = unknown1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,30 +23,45 @@ import java.nio.charset.Charset;
|
|||||||
* A chunk header from v11+
|
* A chunk header from v11+
|
||||||
*/
|
*/
|
||||||
public final class ChunkHeaderV11 extends ChunkHeaderV6 {
|
public final class ChunkHeaderV11 extends ChunkHeaderV6 {
|
||||||
/**
|
/**
|
||||||
* Does the chunk have a separator?
|
* Does the chunk have a separator?
|
||||||
*/
|
*/
|
||||||
public boolean hasSeparator() {
|
public boolean hasSeparator() {
|
||||||
// For some reason, there are two types that don't have a
|
short unknown2 = getUnknown2();
|
||||||
// separator despite the flags that indicate they do
|
short unknown3 = getUnknown3();
|
||||||
if(type == 0x1f || type == 0xc9) { return false; }
|
|
||||||
|
switch (getType()) {
|
||||||
|
case 0x1f: case 0xc9:
|
||||||
|
// For some reason, there are two types that don't have a
|
||||||
|
// separator despite the flags that indicate they do
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case 0x69:
|
||||||
|
return true;
|
||||||
|
|
||||||
// If there's a trailer, there's a separator
|
case 0xa9: case 0xaa: case 0xb4: case 0xb6:
|
||||||
if(hasTrailer()) { return true; }
|
if (unknown2 == 2 && unknown3 == 0x54) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if(unknown2 == 2 && unknown3 == 0x55) { return true; }
|
if (
|
||||||
if(unknown2 == 2 && unknown3 == 0x54 && type == 0xa9) { return true; }
|
(unknown2 == 2 && unknown3 == 0x55) ||
|
||||||
if(unknown2 == 2 && unknown3 == 0x54 && type == 0xaa) { return true; }
|
(unknown2 == 3 && unknown3 != 0x50)
|
||||||
if(unknown2 == 2 && unknown3 == 0x54 && type == 0xb4) { return true; }
|
) {
|
||||||
if(unknown2 == 2 && unknown3 == 0x54 && type == 0xb6) { return true; }
|
return true;
|
||||||
if(unknown2 == 3 && unknown3 != 0x50) { return true; }
|
}
|
||||||
if(type == 0x69) { return true; }
|
|
||||||
|
// If there's a trailer, there's a separator
|
||||||
|
return hasTrailer();
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
@Override
|
||||||
}
|
public Charset getChunkCharset() {
|
||||||
|
return Charset.forName("UTF-16LE");
|
||||||
@Override
|
}
|
||||||
public Charset getChunkCharset() {
|
|
||||||
return Charset.forName("UTF-16LE");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,8 @@ import java.nio.charset.Charset;
|
|||||||
* A chunk header from v4 or v5
|
* A chunk header from v4 or v5
|
||||||
*/
|
*/
|
||||||
public final class ChunkHeaderV4V5 extends ChunkHeader {
|
public final class ChunkHeaderV4V5 extends ChunkHeader {
|
||||||
protected short unknown2;
|
private short unknown2;
|
||||||
protected short unknown3;
|
private short unknown3;
|
||||||
|
|
||||||
public short getUnknown2() {
|
public short getUnknown2() {
|
||||||
return unknown2;
|
return unknown2;
|
||||||
@ -61,4 +61,12 @@ public final class ChunkHeaderV4V5 extends ChunkHeader {
|
|||||||
public Charset getChunkCharset() {
|
public Charset getChunkCharset() {
|
||||||
return Charset.forName("ASCII");
|
return Charset.forName("ASCII");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setUnknown2(short unknown2) {
|
||||||
|
this.unknown2 = unknown2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUnknown3(short unknown3) {
|
||||||
|
this.unknown3 = unknown3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,8 @@ import java.nio.charset.Charset;
|
|||||||
* A chunk header from v6
|
* A chunk header from v6
|
||||||
*/
|
*/
|
||||||
public class ChunkHeaderV6 extends ChunkHeader {
|
public class ChunkHeaderV6 extends ChunkHeader {
|
||||||
protected short unknown2;
|
private short unknown2;
|
||||||
protected short unknown3;
|
private short unknown3;
|
||||||
|
|
||||||
public short getUnknown2() {
|
public short getUnknown2() {
|
||||||
return unknown2;
|
return unknown2;
|
||||||
@ -45,15 +45,15 @@ public class ChunkHeaderV6 extends ChunkHeader {
|
|||||||
* Does the chunk have a trailer?
|
* Does the chunk have a trailer?
|
||||||
*/
|
*/
|
||||||
public boolean hasTrailer() {
|
public boolean hasTrailer() {
|
||||||
if(unknown1 != 0 || type == 0x71 || type == 0x70) {
|
switch (getType()) {
|
||||||
return true;
|
case 0x2c: case 0x65: case 0x66: case 0x69:
|
||||||
}
|
case 0x6a: case 0x6b: case 0x70: case 0x71:
|
||||||
if(type == 0x6b || type == 0x6a || type == 0x69 || type == 0x66
|
return true;
|
||||||
|| type == 0x65 || type == 0x2c) {
|
default:
|
||||||
return true;
|
return (getUnknown1() != 0);
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does the chunk have a separator?
|
* Does the chunk have a separator?
|
||||||
*/
|
*/
|
||||||
@ -66,4 +66,12 @@ public class ChunkHeaderV6 extends ChunkHeader {
|
|||||||
public Charset getChunkCharset() {
|
public Charset getChunkCharset() {
|
||||||
return Charset.forName("ASCII");
|
return Charset.forName("ASCII");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setUnknown2(short unknown2) {
|
||||||
|
this.unknown2 = unknown2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUnknown3(short unknown3) {
|
||||||
|
this.unknown3 = unknown3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ package org.apache.poi.hdgf.chunks;
|
|||||||
* A trailer that follows a chunk
|
* A trailer that follows a chunk
|
||||||
*/
|
*/
|
||||||
public final class ChunkTrailer {
|
public final class ChunkTrailer {
|
||||||
protected byte[] trailerData;
|
private byte[] trailerData;
|
||||||
|
|
||||||
public ChunkTrailer(byte[] data, int offset) {
|
public ChunkTrailer(byte[] data, int offset) {
|
||||||
trailerData = new byte[8];
|
trailerData = new byte[8];
|
||||||
@ -31,4 +31,8 @@ public final class ChunkTrailer {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "<ChunkTrailer of length " + trailerData.length + ">";
|
return "<ChunkTrailer of length " + trailerData.length + ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] getTrailerData() {
|
||||||
|
return trailerData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,8 @@ import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
|
|||||||
public final class VSDDumper {
|
public final class VSDDumper {
|
||||||
final static String tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
|
final static String tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
|
||||||
|
|
||||||
final PrintStream ps;
|
private final PrintStream ps;
|
||||||
final HDGFDiagram hdgf;
|
private final HDGFDiagram hdgf;
|
||||||
VSDDumper(PrintStream ps, HDGFDiagram hdgf) {
|
VSDDumper(PrintStream ps, HDGFDiagram hdgf) {
|
||||||
this.ps = ps;
|
this.ps = ps;
|
||||||
this.hdgf = hdgf;
|
this.hdgf = hdgf;
|
||||||
|
@ -22,11 +22,11 @@ package org.apache.poi.hdgf.pointers;
|
|||||||
* blocks elsewhere in the file
|
* blocks elsewhere in the file
|
||||||
*/
|
*/
|
||||||
public abstract class Pointer {
|
public abstract class Pointer {
|
||||||
protected int type;
|
private int type;
|
||||||
protected int address;
|
private int address;
|
||||||
protected int offset;
|
private int offset;
|
||||||
protected int length;
|
private int length;
|
||||||
protected short format;
|
private short format;
|
||||||
|
|
||||||
public int getAddress() {
|
public int getAddress() {
|
||||||
return address;
|
return address;
|
||||||
@ -53,4 +53,25 @@ public abstract class Pointer {
|
|||||||
public abstract boolean destinationHasPointers();
|
public abstract boolean destinationHasPointers();
|
||||||
public abstract boolean destinationHasChunks();
|
public abstract boolean destinationHasChunks();
|
||||||
public abstract boolean destinationCompressed();
|
public abstract boolean destinationCompressed();
|
||||||
|
|
||||||
|
protected void setType(int type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
protected void setAddress(int address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
protected void setOffset(int offset) {
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
protected void setLength(int length) {
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
protected void setFormat(short format) {
|
||||||
|
this.format = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isFormatBetween(int min, int max) {
|
||||||
|
return (min <= format && format < max);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,20 +38,20 @@ public final class PointerFactory {
|
|||||||
Pointer p;
|
Pointer p;
|
||||||
if(version >= 6) {
|
if(version >= 6) {
|
||||||
p = new PointerV6();
|
p = new PointerV6();
|
||||||
p.type = LittleEndian.getInt(data, offset+0);
|
p.setType(LittleEndian.getInt(data, offset+0));
|
||||||
p.address = (int)LittleEndian.getUInt(data, offset+4);
|
p.setAddress((int)LittleEndian.getUInt(data, offset+4));
|
||||||
p.offset = (int)LittleEndian.getUInt(data, offset+8);
|
p.setOffset((int)LittleEndian.getUInt(data, offset+8));
|
||||||
p.length = (int)LittleEndian.getUInt(data, offset+12);
|
p.setLength((int)LittleEndian.getUInt(data, offset+12));
|
||||||
p.format = LittleEndian.getShort(data, offset+16);
|
p.setFormat(LittleEndian.getShort(data, offset+16));
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
} else if(version == 5) {
|
} else if(version == 5) {
|
||||||
p = new PointerV5();
|
p = new PointerV5();
|
||||||
p.type = LittleEndian.getShort(data, offset+0);
|
p.setType(LittleEndian.getShort(data, offset+0));
|
||||||
p.format = LittleEndian.getShort(data, offset+2);
|
p.setFormat(LittleEndian.getShort(data, offset+2));
|
||||||
p.address = (int)LittleEndian.getUInt(data, offset+4);
|
p.setAddress((int)LittleEndian.getUInt(data, offset+4));
|
||||||
p.offset = (int)LittleEndian.getUInt(data, offset+8);
|
p.setOffset((int)LittleEndian.getUInt(data, offset+8));
|
||||||
p.length = (int)LittleEndian.getUInt(data, offset+12);
|
p.setLength((int)LittleEndian.getUInt(data, offset+12));
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
} else {
|
} else {
|
||||||
|
@ -25,33 +25,34 @@ import org.apache.poi.util.LittleEndian;
|
|||||||
public final class PointerV5 extends Pointer {
|
public final class PointerV5 extends Pointer {
|
||||||
// TODO Are these getters correct?
|
// TODO Are these getters correct?
|
||||||
public boolean destinationHasStrings() {
|
public boolean destinationHasStrings() {
|
||||||
return (0x40 <= format && format < 0x50);
|
return isFormatBetween(0x40, 0x50);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean destinationHasPointers() {
|
public boolean destinationHasPointers() {
|
||||||
if(type == 20) {
|
switch (getType()) {
|
||||||
return true;
|
case 20:
|
||||||
|
return true;
|
||||||
|
case 22:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return isFormatBetween(0x1d, 0x1f) || isFormatBetween(0x50, 0x60);
|
||||||
}
|
}
|
||||||
if(type == 22) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(format == 0x1d || format == 0x1e) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return (0x50 <= format && format < 0x60);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean destinationHasChunks() {
|
public boolean destinationHasChunks() {
|
||||||
if (type == 21) {
|
switch (getType()) {
|
||||||
return true;
|
case 21:
|
||||||
|
return true;
|
||||||
|
case 24:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return isFormatBetween(0xd0, 0xdf);
|
||||||
}
|
}
|
||||||
if (type == 24) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return (0xd0 <= format && format < 0xdf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean destinationCompressed() {
|
public boolean destinationCompressed() {
|
||||||
// Apparently, it's the second least significant bit
|
// Apparently, it's the second least significant bit
|
||||||
return (format & 2) > 0;
|
return (getFormat() & 2) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,7 +64,7 @@ public final class PointerV5 extends Pointer {
|
|||||||
* Depends on the type only, not stored
|
* Depends on the type only, not stored
|
||||||
*/
|
*/
|
||||||
public int getNumPointersOffset(byte[] data) {
|
public int getNumPointersOffset(byte[] data) {
|
||||||
switch (type) {
|
switch (getType()) {
|
||||||
case 0x1d:
|
case 0x1d:
|
||||||
case 0x4e:
|
case 0x4e:
|
||||||
return 30;
|
return 30;
|
||||||
|
@ -24,20 +24,19 @@ import org.apache.poi.util.LittleEndian;
|
|||||||
*/
|
*/
|
||||||
public final class PointerV6 extends Pointer {
|
public final class PointerV6 extends Pointer {
|
||||||
public boolean destinationHasStrings() {
|
public boolean destinationHasStrings() {
|
||||||
return (0x40 <= format && format < 0x50);
|
return isFormatBetween(0x40, 0x50);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean destinationHasPointers() {
|
public boolean destinationHasPointers() {
|
||||||
if(type == 20) return true;
|
return (getType() == 20) || isFormatBetween(0x1d, 0x1f) || isFormatBetween(0x50, 0x60);
|
||||||
if(format == 0x1d || format == 0x1e) return true;
|
|
||||||
return (0x50 <= format && format < 0x60);
|
|
||||||
}
|
}
|
||||||
public boolean destinationHasChunks() {
|
public boolean destinationHasChunks() {
|
||||||
return (0xd0 <= format && format < 0xdf);
|
return isFormatBetween(0xd0, 0xdf);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean destinationCompressed() {
|
public boolean destinationCompressed() {
|
||||||
// Apparently, it's the second least significant bit
|
// Apparently, it's the second least significant bit
|
||||||
return (format & 2) > 0;
|
return (getFormat() & 2) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,6 +42,7 @@ public abstract class EscherPart extends HPBFPart {
|
|||||||
new DefaultEscherRecordFactory();
|
new DefaultEscherRecordFactory();
|
||||||
|
|
||||||
ArrayList<EscherRecord> ec = new ArrayList<EscherRecord>();
|
ArrayList<EscherRecord> ec = new ArrayList<EscherRecord>();
|
||||||
|
byte data[] = getData();
|
||||||
int left = data.length;
|
int left = data.length;
|
||||||
while(left > 0) {
|
while(left > 0) {
|
||||||
EscherRecord er = erf.createRecord(data, 0);
|
EscherRecord er = erf.createRecord(data, 0);
|
||||||
@ -68,12 +69,14 @@ public abstract class EscherPart extends HPBFPart {
|
|||||||
size += records[i].getRecordSize();
|
size += records[i].getRecordSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
data = new byte[size];
|
byte data[] = new byte[size];
|
||||||
size = 0;
|
size = 0;
|
||||||
for(int i=0; i<records.length; i++) {
|
for(int i=0; i<records.length; i++) {
|
||||||
int thisSize =
|
int thisSize =
|
||||||
records[i].serialize(size, data);
|
records[i].serialize(size, data);
|
||||||
size += thisSize;
|
size += thisSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setData(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ import org.apache.poi.util.IOUtils;
|
|||||||
* for all of them.
|
* for all of them.
|
||||||
*/
|
*/
|
||||||
public abstract class HPBFPart {
|
public abstract class HPBFPart {
|
||||||
protected byte[] data;
|
private byte[] data;
|
||||||
/**
|
/**
|
||||||
* @param path the path to the part, eg Contents or Quill, QuillSub, CONTENTS
|
* @param path the path to the part, eg Contents or Quill, QuillSub, CONTENTS
|
||||||
*/
|
*/
|
||||||
@ -94,7 +94,11 @@ public abstract class HPBFPart {
|
|||||||
* Returns the raw data that makes up
|
* Returns the raw data that makes up
|
||||||
* this document part.
|
* this document part.
|
||||||
*/
|
*/
|
||||||
public byte[] getData() { return data; }
|
public final byte[] getData() { return data; }
|
||||||
|
|
||||||
|
protected final void setData(byte data[]) {
|
||||||
|
this.data = data.clone();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns
|
* Returns
|
||||||
|
@ -39,6 +39,7 @@ public final class QuillContents extends HPBFPart {
|
|||||||
|
|
||||||
// Now parse the first 512 bytes, and produce
|
// Now parse the first 512 bytes, and produce
|
||||||
// all our bits
|
// all our bits
|
||||||
|
byte data[] = getData();
|
||||||
|
|
||||||
// Check first 8 bytes
|
// Check first 8 bytes
|
||||||
String f8 = new String(data, 0, 8, LocaleUtil.CHARSET_1252);
|
String f8 = new String(data, 0, 8, LocaleUtil.CHARSET_1252);
|
||||||
|
@ -21,15 +21,15 @@ package org.apache.poi.hpbf.model.qcbits;
|
|||||||
* Parent of all Quill CONTENTS bits
|
* Parent of all Quill CONTENTS bits
|
||||||
*/
|
*/
|
||||||
public abstract class QCBit {
|
public abstract class QCBit {
|
||||||
protected String thingType;
|
private String thingType;
|
||||||
protected String bitType;
|
private String bitType;
|
||||||
protected byte[] data;
|
private byte[] data;
|
||||||
|
|
||||||
protected int optA;
|
private int optA;
|
||||||
protected int optB;
|
private int optB;
|
||||||
protected int optC;
|
private int optC;
|
||||||
|
|
||||||
protected int dataOffset;
|
private int dataOffset;
|
||||||
|
|
||||||
public QCBit(String thingType, String bitType, byte[] data) {
|
public QCBit(String thingType, String bitType, byte[] data) {
|
||||||
this.thingType = thingType;
|
this.thingType = thingType;
|
||||||
@ -47,7 +47,10 @@ public abstract class QCBit {
|
|||||||
* or PLC
|
* or PLC
|
||||||
*/
|
*/
|
||||||
public String getBitType() { return bitType; }
|
public String getBitType() { return bitType; }
|
||||||
public byte[] getData() { return data; }
|
public final byte[] getData() { return data; }
|
||||||
|
protected final void setData(byte data[]) {
|
||||||
|
this.data = data.clone();
|
||||||
|
}
|
||||||
|
|
||||||
public int getOptA() {
|
public int getOptA() {
|
||||||
return optA;
|
return optA;
|
||||||
|
@ -26,18 +26,18 @@ import org.apache.poi.util.StringUtil;
|
|||||||
* format is determined by the type of the PLCs.
|
* format is determined by the type of the PLCs.
|
||||||
*/
|
*/
|
||||||
public abstract class QCPLCBit extends QCBit {
|
public abstract class QCPLCBit extends QCBit {
|
||||||
protected int numberOfPLCs;
|
private int numberOfPLCs;
|
||||||
protected int typeOfPLCS;
|
private int typeOfPLCS;
|
||||||
/**
|
/**
|
||||||
* The data which goes before the main PLC entries.
|
* The data which goes before the main PLC entries.
|
||||||
* This is apparently always made up of 2 byte
|
* This is apparently always made up of 2 byte
|
||||||
* un-signed ints..
|
* un-signed ints..
|
||||||
*/
|
*/
|
||||||
protected int[] preData;
|
private int[] preData;
|
||||||
/** The first value of each PLC, normally 4 bytes */
|
/** The first value of each PLC, normally 4 bytes */
|
||||||
protected long[] plcValA;
|
private long[] plcValA;
|
||||||
/** The second value of each PLC, normally 4 bytes */
|
/** The second value of each PLC, normally 4 bytes */
|
||||||
protected long[] plcValB;
|
private long[] plcValB;
|
||||||
|
|
||||||
|
|
||||||
private QCPLCBit(String thingType, String bitType, byte[] data) {
|
private QCPLCBit(String thingType, String bitType, byte[] data) {
|
||||||
@ -74,7 +74,19 @@ public abstract class QCPLCBit extends QCBit {
|
|||||||
return plcValB;
|
return plcValB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final void setPreData(int preData[]) {
|
||||||
|
this.preData = preData.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
final void setPlcValA(long[] plcValA) {
|
||||||
|
this.plcValA = plcValA.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
final void setPlcValB(long[] plcValB) {
|
||||||
|
this.plcValB = plcValB.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static QCPLCBit createQCPLCBit(String thingType, String bitType, byte[] data) {
|
public static QCPLCBit createQCPLCBit(String thingType, String bitType, byte[] data) {
|
||||||
// Grab the type
|
// Grab the type
|
||||||
@ -103,17 +115,23 @@ public abstract class QCPLCBit extends QCBit {
|
|||||||
super(thingType, bitType, data);
|
super(thingType, bitType, data);
|
||||||
|
|
||||||
// Grab our 4x pre-data
|
// Grab our 4x pre-data
|
||||||
preData = new int[4];
|
int preData[] = {
|
||||||
preData[0] = LittleEndian.getUShort(data, 8+0);
|
LittleEndian.getUShort(data, 8+0),
|
||||||
preData[1] = LittleEndian.getUShort(data, 8+2);
|
LittleEndian.getUShort(data, 8+2),
|
||||||
preData[2] = LittleEndian.getUShort(data, 8+4);
|
LittleEndian.getUShort(data, 8+4),
|
||||||
preData[3] = LittleEndian.getUShort(data, 8+6);
|
LittleEndian.getUShort(data, 8+6)
|
||||||
|
};
|
||||||
|
setPreData(preData);
|
||||||
|
|
||||||
// And grab the 2 byte values
|
// And grab the 2 byte values
|
||||||
for(int i=0; i<numberOfPLCs; i++) {
|
int cntPlcs = getNumberOfPLCs();
|
||||||
|
long plcValA[] = new long[cntPlcs], plcValB[] = new long[cntPlcs];
|
||||||
|
for(int i=0; i<cntPlcs; i++) {
|
||||||
plcValA[i] = LittleEndian.getUShort(data, 16+(4*i));
|
plcValA[i] = LittleEndian.getUShort(data, 16+(4*i));
|
||||||
plcValB[i] = LittleEndian.getUShort(data, 16+(4*i)+2);
|
plcValB[i] = LittleEndian.getUShort(data, 16+(4*i)+2);
|
||||||
}
|
}
|
||||||
|
setPlcValA(plcValA);
|
||||||
|
setPlcValB(plcValB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,17 +144,23 @@ public abstract class QCPLCBit extends QCBit {
|
|||||||
super(thingType, bitType, data);
|
super(thingType, bitType, data);
|
||||||
|
|
||||||
// Grab our 4x pre-data
|
// Grab our 4x pre-data
|
||||||
preData = new int[4];
|
int preData[] = {
|
||||||
preData[0] = LittleEndian.getUShort(data, 8+0);
|
LittleEndian.getUShort(data, 8+0),
|
||||||
preData[1] = LittleEndian.getUShort(data, 8+2);
|
LittleEndian.getUShort(data, 8+2),
|
||||||
preData[2] = LittleEndian.getUShort(data, 8+4);
|
LittleEndian.getUShort(data, 8+4),
|
||||||
preData[3] = LittleEndian.getUShort(data, 8+6);
|
LittleEndian.getUShort(data, 8+6)
|
||||||
|
};
|
||||||
|
setPreData(preData);
|
||||||
|
|
||||||
// And grab the 4 byte values
|
// And grab the 4 byte values
|
||||||
for(int i=0; i<numberOfPLCs; i++) {
|
int cntPlcs = getNumberOfPLCs();
|
||||||
|
long plcValA[] = new long[cntPlcs], plcValB[] = new long[cntPlcs];
|
||||||
|
for(int i=0; i<cntPlcs; i++) {
|
||||||
plcValA[i] = LittleEndian.getUInt(data, 16+(8*i));
|
plcValA[i] = LittleEndian.getUInt(data, 16+(8*i));
|
||||||
plcValB[i] = LittleEndian.getUInt(data, 16+(8*i)+4);
|
plcValB[i] = LittleEndian.getUInt(data, 16+(8*i)+4);
|
||||||
}
|
}
|
||||||
|
setPlcValA(plcValA);
|
||||||
|
setPlcValB(plcValB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,20 +173,26 @@ public abstract class QCPLCBit extends QCBit {
|
|||||||
super(thingType, bitType, data);
|
super(thingType, bitType, data);
|
||||||
|
|
||||||
// Grab our 7x pre-data
|
// Grab our 7x pre-data
|
||||||
preData = new int[7];
|
int preData[] = {
|
||||||
preData[0] = LittleEndian.getUShort(data, 8+0);
|
LittleEndian.getUShort(data, 8+0),
|
||||||
preData[1] = LittleEndian.getUShort(data, 8+2);
|
LittleEndian.getUShort(data, 8+2),
|
||||||
preData[2] = LittleEndian.getUShort(data, 8+4);
|
LittleEndian.getUShort(data, 8+4),
|
||||||
preData[3] = LittleEndian.getUShort(data, 8+6);
|
LittleEndian.getUShort(data, 8+6),
|
||||||
preData[4] = LittleEndian.getUShort(data, 8+8);
|
LittleEndian.getUShort(data, 8+8),
|
||||||
preData[5] = LittleEndian.getUShort(data, 8+10);
|
LittleEndian.getUShort(data, 8+10),
|
||||||
preData[6] = LittleEndian.getUShort(data, 8+12);
|
LittleEndian.getUShort(data, 8+12)
|
||||||
|
};
|
||||||
|
setPreData(preData);
|
||||||
|
|
||||||
// And grab the 4 byte values
|
// And grab the 4 byte values
|
||||||
for(int i=0; i<numberOfPLCs; i++) {
|
int cntPlcs = getNumberOfPLCs();
|
||||||
|
long plcValA[] = new long[cntPlcs], plcValB[] = new long[cntPlcs];
|
||||||
|
for(int i=0; i<cntPlcs; i++) {
|
||||||
plcValA[i] = LittleEndian.getUInt(data, 22+(8*i));
|
plcValA[i] = LittleEndian.getUInt(data, 22+(8*i));
|
||||||
plcValB[i] = LittleEndian.getUInt(data, 22+(8*i)+4);
|
plcValB[i] = LittleEndian.getUInt(data, 22+(8*i)+4);
|
||||||
}
|
}
|
||||||
|
setPlcValA(plcValA);
|
||||||
|
setPlcValB(plcValB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,37 +213,38 @@ public abstract class QCPLCBit extends QCBit {
|
|||||||
private Type12(String thingType, String bitType, byte[] data) {
|
private Type12(String thingType, String bitType, byte[] data) {
|
||||||
super(thingType, bitType, data);
|
super(thingType, bitType, data);
|
||||||
|
|
||||||
|
int cntPlcs = getNumberOfPLCs();
|
||||||
|
|
||||||
// How many hyperlinks do we really have?
|
// How many hyperlinks do we really have?
|
||||||
// (zero hyperlinks gets numberOfPLCs=1)
|
// (zero hyperlinks gets numberOfPLCs=1)
|
||||||
if(data.length == 0x34) {
|
hyperlinks = new String[data.length == 0x34 ? 0 : cntPlcs];
|
||||||
hyperlinks = new String[0];
|
|
||||||
} else {
|
|
||||||
hyperlinks = new String[numberOfPLCs];
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have 4 bytes, then the start point of each
|
// We have 4 bytes, then the start point of each
|
||||||
// hyperlink, then the end point of the text.
|
// hyperlink, then the end point of the text.
|
||||||
preData = new int[1+numberOfPLCs+1];
|
int preData[] = new int[1+cntPlcs+1];
|
||||||
for(int i=0; i<preData.length; i++) {
|
for(int i=0; i<preData.length; i++) {
|
||||||
preData[i] = (int)LittleEndian.getUInt(data, 8+(i*4));
|
preData[i] = (int)LittleEndian.getUInt(data, 8+(i*4));
|
||||||
}
|
}
|
||||||
|
setPreData(preData);
|
||||||
|
|
||||||
// Then we have a whole bunch of stuff, which grows
|
// Then we have a whole bunch of stuff, which grows
|
||||||
// with the number of hyperlinks
|
// with the number of hyperlinks
|
||||||
// For now, we think these are shorts
|
// For now, we think these are shorts
|
||||||
int at = 8+4+(numberOfPLCs*4)+4;
|
int at = 8+4+(cntPlcs*4)+4;
|
||||||
int until = 0x34;
|
int until = 0x34;
|
||||||
if(numberOfPLCs == 1 && hyperlinks.length == 1) {
|
if(cntPlcs == 1 && hyperlinks.length == 1) {
|
||||||
until = oneStartsAt;
|
until = oneStartsAt;
|
||||||
} else if(numberOfPLCs >= 2) {
|
} else if(cntPlcs >= 2) {
|
||||||
until = twoStartsAt + (numberOfPLCs-2)*threePlusIncrement;
|
until = twoStartsAt + (cntPlcs-2)*threePlusIncrement;
|
||||||
}
|
}
|
||||||
|
|
||||||
plcValA = new long[(until-at)/2];
|
long plcValA[] = new long[(until-at)/2];
|
||||||
plcValB = new long[0];
|
long plcValB[] = new long[0];
|
||||||
for(int i=0; i<plcValA.length; i++) {
|
for(int i=0; i<plcValA.length; i++) {
|
||||||
plcValA[i] = LittleEndian.getUShort(data, at+(i*2));
|
plcValA[i] = LittleEndian.getUShort(data, at+(i*2));
|
||||||
}
|
}
|
||||||
|
setPlcValA(plcValA);
|
||||||
|
setPlcValB(plcValB);
|
||||||
|
|
||||||
// Finally, we have a series of lengths + hyperlinks
|
// Finally, we have a series of lengths + hyperlinks
|
||||||
at = until;
|
at = until;
|
||||||
@ -259,7 +290,7 @@ public abstract class QCPLCBit extends QCBit {
|
|||||||
* @param number The hyperlink number, zero based
|
* @param number The hyperlink number, zero based
|
||||||
*/
|
*/
|
||||||
public int getTextStartAt(int number) {
|
public int getTextStartAt(int number) {
|
||||||
return preData[1+number];
|
return getPreData()[1+number];
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Returns where in the text that this block
|
* Returns where in the text that this block
|
||||||
@ -269,7 +300,7 @@ public abstract class QCPLCBit extends QCBit {
|
|||||||
* PLCBit applies to.
|
* PLCBit applies to.
|
||||||
*/
|
*/
|
||||||
public int getAllTextEndAt() {
|
public int getAllTextEndAt() {
|
||||||
return preData[numberOfPLCs+1];
|
return getPreData()[getNumberOfPLCs()+1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,13 +32,12 @@ public final class QCTextBit extends QCBit {
|
|||||||
* are \r and not \n
|
* are \r and not \n
|
||||||
*/
|
*/
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return StringUtil.getFromUnicodeLE(
|
return StringUtil.getFromUnicodeLE(getData());
|
||||||
data, 0, data.length/2
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setText(String text) {
|
public void setText(String text) {
|
||||||
data = new byte[text.length()*2];
|
byte data[] = new byte[text.length()*2];
|
||||||
StringUtil.putUnicodeLE(text, data, 0);
|
StringUtil.putUnicodeLE(text, data, 0);
|
||||||
|
setData(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,10 @@ public abstract class StreamTest extends TestCase {
|
|||||||
protected boolean hasPointers = false;
|
protected boolean hasPointers = false;
|
||||||
public TestPointer(boolean compressed, int offset, int length, int type, short format) {
|
public TestPointer(boolean compressed, int offset, int length, int type, short format) {
|
||||||
this.compressed = compressed;
|
this.compressed = compressed;
|
||||||
this.offset = offset;
|
setOffset(offset);
|
||||||
this.length = length;
|
setLength(length);
|
||||||
this.type = type;
|
setType(type);
|
||||||
this.format = format;
|
setFormat(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user