From b1fccf2aa9908fb4a03aadfc5af63322150e757c Mon Sep 17 00:00:00 2001 From: Rainer Klute Date: Wed, 17 Jul 2002 16:23:22 +0000 Subject: [PATCH] Broken HPSF usage of POI's general little-endian classes fixed. git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352778 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/contrib/poibrowser/Codec.java | 45 ++++ .../poi/contrib/poibrowser/POIBrowser.java | 2 +- .../PropertySetDescriptorRenderer.java | 14 +- src/java/org/apache/poi/hpsf/ClassID.java | 114 +++++----- src/java/org/apache/poi/hpsf/PropertySet.java | 2 +- src/java/org/apache/poi/hpsf/Section.java | 202 +++++++++--------- 6 files changed, 208 insertions(+), 171 deletions(-) diff --git a/src/contrib/src/org/apache/poi/contrib/poibrowser/Codec.java b/src/contrib/src/org/apache/poi/contrib/poibrowser/Codec.java index 637eed256..9b7d21ca0 100644 --- a/src/contrib/src/org/apache/poi/contrib/poibrowser/Codec.java +++ b/src/contrib/src/org/apache/poi/contrib/poibrowser/Codec.java @@ -60,6 +60,7 @@ package org.apache.poi.contrib.poibrowser; import java.io.*; import java.util.*; +import org.apache.poi.hpsf.ClassID; @@ -141,6 +142,50 @@ public class Codec + /** + *

Converts an int value (32-bit) into its hexadecimal + * notation.

+ */ + public static String hexEncode(final int i) + { + StringBuffer sb = new StringBuffer(8); + sb.append((char) hexval[(i & 0xF0000000) >> 28]); + sb.append((char) hexval[(i & 0x0F000000) >> 24]); + sb.append((char) hexval[(i & 0x00F00000) >> 20]); + sb.append((char) hexval[(i & 0x000F0000) >> 16]); + sb.append((char) hexval[(i & 0x0000F000) >> 12]); + sb.append((char) hexval[(i & 0x00000F00) >> 8]); + sb.append((char) hexval[(i & 0x000000F0) >> 4]); + sb.append((char) hexval[(i & 0x0000000F) >> 0]); + return sb.toString(); + } + + + + /** + *

Converts a long value (64-bit) into its hexadecimal + * notation.

+ */ + public static String hexEncode(final long l) + { + StringBuffer sb = new StringBuffer(16); + sb.append((l & 0xFFFFFFFF00000000L) >> 32); + sb.append((l & 0x00000000FFFFFFFFL) >> 0); + return sb.toString(); + } + + + + /** + *

Converts a class ID into its hexadecimal notation.

+ */ + public static String hexEncode(final ClassID classID) + { + return hexEncode(classID.getBytes()); + } + + + /** *

Decodes the hexadecimal representation of a sequence of * bytes into a byte array. Each character in the string diff --git a/src/contrib/src/org/apache/poi/contrib/poibrowser/POIBrowser.java b/src/contrib/src/org/apache/poi/contrib/poibrowser/POIBrowser.java index 90ccf3c69..5e1cb1394 100644 --- a/src/contrib/src/org/apache/poi/contrib/poibrowser/POIBrowser.java +++ b/src/contrib/src/org/apache/poi/contrib/poibrowser/POIBrowser.java @@ -159,7 +159,7 @@ public class POIBrowser extends JFrame new PropertySetDescriptorRenderer()); treeUI.setCellRenderer(etcr); setSize(600, 450); - setTitle("POI Browser 0.06"); + setTitle("POI Browser 0.07"); setVisible(true); } diff --git a/src/contrib/src/org/apache/poi/contrib/poibrowser/PropertySetDescriptorRenderer.java b/src/contrib/src/org/apache/poi/contrib/poibrowser/PropertySetDescriptorRenderer.java index 522fa061a..bb2750ab2 100644 --- a/src/contrib/src/org/apache/poi/contrib/poibrowser/PropertySetDescriptorRenderer.java +++ b/src/contrib/src/org/apache/poi/contrib/poibrowser/PropertySetDescriptorRenderer.java @@ -85,9 +85,6 @@ public class PropertySetDescriptorRenderer extends DocumentDescriptorRenderer final int row, final boolean hasFocus) { - - throw new RuntimeException("THIS FUNCTION BROKEN -- FIX IT"); -/* final PropertySetDescriptor d = (PropertySetDescriptor) ((DefaultMutableTreeNode) value).getUserObject(); final PropertySet ps = d.getPropertySet(); @@ -110,9 +107,8 @@ public class PropertySetDescriptorRenderer extends DocumentDescriptorRenderer if (ps instanceof SummaryInformation) { -*/ /* Use the convenience methods. */ -/* final SummaryInformation si = (SummaryInformation) ps; + final SummaryInformation si = (SummaryInformation) ps; text.append("\n"); text.append("\nTitle: " + si.getTitle()); text.append("\nSubject: " + si.getSubject()); @@ -136,7 +132,7 @@ public class PropertySetDescriptorRenderer extends DocumentDescriptorRenderer if (selected) Util.invert(text); - return p;*/ + return p; } @@ -164,12 +160,9 @@ public class PropertySetDescriptorRenderer extends DocumentDescriptorRenderer */ protected String toString(final Section s, final String name) { - - throw new RuntimeException("THIS FUNCTION BROKEN -- FIX IT"); -/* final StringBuffer b = new StringBuffer(); b.append("\n" + name + " Format ID: "); - b.append(Integer.toHexString(s.getFormatID())); + b.append(Codec.hexEncode(s.getFormatID())); b.append("\n" + name + " Offset: " + s.getOffset()); b.append("\n" + name + " Section size: " + s.getSize()); b.append("\n" + name + " Property count: " + s.getPropertyCount()); @@ -195,7 +188,6 @@ public class PropertySetDescriptorRenderer extends DocumentDescriptorRenderer b.append(value.toString()); } return b.toString(); -*/ } } diff --git a/src/java/org/apache/poi/hpsf/ClassID.java b/src/java/org/apache/poi/hpsf/ClassID.java index b87d775bf..37cc49058 100644 --- a/src/java/org/apache/poi/hpsf/ClassID.java +++ b/src/java/org/apache/poi/hpsf/ClassID.java @@ -59,83 +59,93 @@ import java.io.*; import org.apache.poi.util.LittleEndian; /** - * REWRITE ME - *

- * Represents a class ID (16 bytes). Unlike other little-endian type the {@link - * ClassID} is not just 16 bytes stored in the wrong order. Instead, it is a - * double word (4 bytes) followed by two words (2 bytes each) followed by 8 - * bytes.

+ *

Represents a class ID (16 bytes). Unlike other little-endian + * type the {@link ClassID} is not just 16 bytes stored in the wrong + * order. Instead, it is a double word (4 bytes) followed by two + * words (2 bytes each) followed by 8 bytes.

* - *@author Rainer Klute (klute@rainer-klute.de) - *@created May 10, 2002 - *@see LittleEndian - *@version $Id$ - *@since 2002-02-09 + * @author Rainer Klute (klute@rainer-klute.de) + * @version $Id$ + * @since 2002-02-09 */ -public class ClassID { +public class ClassID +{ /** - *

- * - * Creates a {@link ClassID} and reads its value from a byte array.

- * - *@param src The byte array to read from. - *@param offset The offset of the first byte to read. + *

The bytes making out the class ID in correct order, + * i.e. big-endian.

*/ - public ClassID(final byte[] src, final int offset) { - // super(src, offset); + protected byte[] bytes; + + + + /** + *

Creates a {@link ClassID} and reads its value from a byte + * array.

+ * + * @param src The byte array to read from. + * @param offset The offset of the first byte to read. + */ + public ClassID(final byte[] src, final int offset) + { + read(src, offset); } public final static int LENGTH = 16; - public int length() { + public int length() + { return LENGTH; } - public byte[] getBytes() { - - throw new RuntimeException("This fucntion must be rewritten"); - } /** - * Description of the Method - REWRITE ME REWRITE ME REWRITE ME - * ISNT += offset a bug? -- doesn't the order of operations evaluate that - * last? - * - *@param src Description of the Parameter - *@param offset Description of the Parameter - *@return Description of the Return Value + *

Gets the bytes making out the class ID. They are returned in + * correct order, i.e. big-endian.

*/ - public byte[] read(byte[] src, int offset) { - byte[] retval = new byte[24]; + public byte[] getBytes() + { + return bytes; + } - //throw new RuntimeException("This fucntion must be rewritten"); - //Number[] b = new Number[11]; - //b[0] = new Integer(LittleEndian.getInt(src, offset)); - //transfer the first Int from little to big endian - retval[0] = src[3]; - retval[1] = src[2]; - retval[2] = src[1]; - retval[3] = src[0]; + /** + *

Reads a class ID from a byte array by turning little-endian + * into big-endian.

+ * + * @param src The byte array to read from + * + * @param offset The offset within the src byte array + * + * @return A byte array containing the class ID. + */ + public byte[] read(final byte[] src, final int offset) + { + bytes = new byte[16]; - //b[1] = new Short(LittleEndian.getInt(src, offset += LittleEndian.INT_SIZE)); - //transfer the second short from little to big endian - retval[4] = src[5]; - retval[5] = src[4]; + /* Read double word. */ + bytes[0] = src[3 + offset]; + bytes[1] = src[2 + offset]; + bytes[2] = src[1 + offset]; + bytes[3] = src[0 + offset]; - //b[2] = new Short(LittleEndian.getInt(src, offset += LittleEndian.SHORT_SIZE)); - //transfer the third short from little to big endian - retval[6] = src[7]; - retval[7] = src[6]; + /* Read first word. */ + bytes[4] = src[5 + offset]; + bytes[5] = src[4 + offset]; - System.arraycopy(src, 8, retval, 8, retval.length - 8); + /* Read second word. */ + bytes[6] = src[7 + offset]; + bytes[7] = src[6 + offset]; - return retval; + /* Read 8 bytes. */ + for (int i = 8; i < 16; i++) + bytes[i] = src[i + offset]; + + return bytes; } } diff --git a/src/java/org/apache/poi/hpsf/PropertySet.java b/src/java/org/apache/poi/hpsf/PropertySet.java index f4f856b48..103374cc3 100644 --- a/src/java/org/apache/poi/hpsf/PropertySet.java +++ b/src/java/org/apache/poi/hpsf/PropertySet.java @@ -95,7 +95,7 @@ import org.apache.poi.poifs.filesystem.*; */ public class PropertySet { final static byte[] BYTE_ORDER_ASSERTION = - new byte[]{(byte) 0xFF, (byte) 0xFE}; + new byte[]{(byte) 0xFE, (byte) 0xFF}; final static byte[] FORMAT_ASSERTION = new byte[]{(byte) 0x00, (byte) 0x00}; diff --git a/src/java/org/apache/poi/hpsf/Section.java b/src/java/org/apache/poi/hpsf/Section.java index 9137b034b..a640fd9bd 100644 --- a/src/java/org/apache/poi/hpsf/Section.java +++ b/src/java/org/apache/poi/hpsf/Section.java @@ -59,23 +59,19 @@ import org.apache.poi.util.LittleEndian; import org.apache.poi.hpsf.wellknown.*; /** - *

+ *

Represents a section in a {@link PropertySet}.

* - * Represents a section in a {@link PropertySet}.

- * - *@author Rainer Klute (klute@rainer-klute.de) - *@author Drew Varner (Drew.Varner allUpIn sc.edu) - *@created May 10, 2002 - *@version $Id$ - *@since 2002-02-09 + * @author Rainer Klute (klute@rainer-klute.de) + * @author Drew Varner (Drew.Varner allUpIn sc.edu) + * @version $Id$ + * @since 2002-02-09 */ -public class Section { +public class Section +{ /** - *

- * - * Maps property IDs to section-private PID strings. These strings can be - * found in the property with ID 0.

+ *

Maps property IDs to section-private PID strings. These + * strings can be found in the property with ID 0.

*/ protected Map dictionary; @@ -83,13 +79,13 @@ public class Section { /** - *

+ *

Returns the format ID. The format ID is the "type" of the + * section.

* - * Returns the format ID. The format ID is the "type" of the section.

- * - *@return The formatID value + * @return The format ID */ - public ClassID getFormatID() { + public ClassID getFormatID() + { return formatID; } @@ -99,13 +95,12 @@ public class Section { /** - *

+ *

Returns the offset of the section in the stream.

* - * Returns the offset of the section in the stream.

- * - *@return The offset value + * @return The offset of the section in the stream. */ - public long getOffset() { + public long getOffset() + { return offset; } @@ -115,13 +110,12 @@ public class Section { /** - *

+ *

Returns the section's size in bytes.

* - * Returns the section's size in bytes.

- * - *@return The size value + * @return The section's size in bytes. */ - public int getSize() { + public int getSize() + { return size; } @@ -131,13 +125,12 @@ public class Section { /** - *

+ *

Returns the number of properties in this section.

* - * Returns the number of properties in this section.

- * - *@return The propertyCount value + * @return The number of properties in this section. */ - public int getPropertyCount() { + public int getPropertyCount() + { return propertyCount; } @@ -147,28 +140,26 @@ public class Section { /** - *

+ *

Returns this section's properties.

* - * Returns this section's properties.

- * - *@return The properties value + * @return This section's properties. */ - public Property[] getProperties() { + public Property[] getProperties() + { return properties; } /** - *

+ *

Creates a {@link Section} instance from a byte array.

* - * Creates a {@link Section} instance from a byte array.

- * - *@param src Contains the complete property set stream. - *@param offset The position in the stream that points to the section's - * format ID. + * @param src Contains the complete property set stream. + * @param offset The position in the stream that points to the + * section's format ID. */ - public Section(final byte[] src, int offset) { + public Section(final byte[] src, int offset) + { /* * Read the format ID. */ @@ -217,7 +208,8 @@ public class Section { length = (int)(src.length - this.offset - sOffset); } else { length = (int) - LittleEndian.getUInt(src, offset + LittleEndian.INT_SIZE) - sOffset; + LittleEndian.getUInt(src, offset + LittleEndian.INT_SIZE) - + sOffset; } /* @@ -236,22 +228,21 @@ public class Section { /** - *

+ *

Returns the value of the property with the specified ID. If + * the property is not available, null is returned + * and a subsequent call to {@link #wasNull} will return + * true.

* - * Returns the value of the property with the specified ID. If the property - * is not available, null is returned and a subsequent call to - * {@link #wasNull} will return true.

+ * @param id The property's ID * - *@param id Description of the Parameter - *@return The property value + * @return The property's value */ - protected Object getProperty(final int id) { + protected Object getProperty(final int id) + { wasNull = false; - for (int i = 0; i < properties.length; i++) { - if (id == properties[i].getID()) { + for (int i = 0; i < properties.length; i++) + if (id == properties[i].getID()) return properties[i].getValue(); - } - } wasNull = true; return null; } @@ -259,47 +250,48 @@ public class Section { /** - *

+ *

Returns the value of the numeric property with the specified + * ID. If the property is not available, 0 is returned. A + * subsequent call to {@link #wasNull} will return + * true to let the caller distinguish that case from + * a real property value of 0.

* - * Returns the value of the numeric property with the specified ID. If the - * property is not available, 0 is returned. A subsequent call to {@link - * #wasNull} will return true to let the caller distinguish - * that case from a real property value of 0.

+ * @param id The property's ID * - *@param id Description of the Parameter - *@return The propertyIntValue value + * @return The property's value */ - protected int getPropertyIntValue(final int id) { - final Integer i = (Integer) getProperty(id); - if (i != null) { + protected int getPropertyIntValue(final int id) + { + /* FIXME: Find out why the following is a Long instead of an + * Integer! */ + final Long i = (Long) getProperty(id); + if (i != null) return i.intValue(); - } else { + else return 0; - } } /** - *

+ *

Returns the value of the boolean property with the specified + * ID. If the property is not available, false is + * returned. A subsequent call to {@link #wasNull} will return + * true to let the caller distinguish that case from + * a real property value of false.

* - * Returns the value of the boolean property with the specified ID. If the - * property is not available, false is returned. A subsequent - * call to {@link #wasNull} will return true to let the caller - * distinguish that case from a real property value of false. - *

+ * @param id The property's ID * - *@param id Description of the Parameter - *@return The propertyBooleanValue value + * @return The property's value */ - protected boolean getPropertyBooleanValue(final int id) { + protected boolean getPropertyBooleanValue(final int id) + { final Boolean b = (Boolean) getProperty(id); - if (b != null) { + if (b != null) return b.booleanValue(); - } else { + else return false; } - } @@ -307,46 +299,44 @@ public class Section { /** - *

+ *

Checks whether the property which the last call to {@link + * #getPropertyIntValue} or {@link #getProperty} tried to access + * was available or not. This information might be important for + * callers of {@link #getPropertyIntValue} since the latter + * returns 0 if the property does not exist. Using {@link + * #wasNull} the caller can distiguish this case from a property's + * real value of 0.

* - * Checks whether the property which the last call to {@link - * #getPropertyIntValue} or {@link #getProperty} tried to access was - * available or not. This information might be important for callers of - * {@link #getPropertyIntValue} since the latter returns 0 if the property - * does not exist. Using {@link #wasNull} the caller can distiguish this - * case from a property's real value of 0.

- * - *@return true if the last call to {@link - * #getPropertyIntValue} or {@link #getProperty} tried to access a - * property that was not available, else false. + * @return true if the last call to {@link + * #getPropertyIntValue} or {@link #getProperty} tried to access a + * property that was not available, else false. */ - public boolean wasNull() { + public boolean wasNull() + { return wasNull; } /** - *

+ *

Returns the PID string associated with a property ID. The ID + * is first looked up in the {@link Section}'s private + * dictionary. If it is not found there, the method calls {@link + * SectionIDMap#getPIDString}.

* - * Returns the PID string associated with a property ID. The ID is first - * looked up in the {@link Section}'s private dictionary. If it is not - * found there, the method calls {@link SectionIDMap#getPIDString}.

+ * @param pid The property ID * - *@param pid Description of the Parameter - *@return The pIDString value + * @return The property ID's string value */ - public String getPIDString(final int pid) { + public String getPIDString(final int pid) + { String s = null; - if (dictionary != null) { + if (dictionary != null) s = (String) dictionary.get(new Integer(pid)); - } - if (s == null) { + if (s == null) s = SectionIDMap.getPIDString(getFormatID().getBytes(), pid); - } - if (s == null) { + if (s == null) s = SectionIDMap.UNDEFINED; - } return s; }