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
This commit is contained in:
Rainer Klute 2002-07-17 16:23:22 +00:00
parent 9102bc3f39
commit b1fccf2aa9
6 changed files with 208 additions and 171 deletions

View File

@ -60,6 +60,7 @@ package org.apache.poi.contrib.poibrowser;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import org.apache.poi.hpsf.ClassID;
@ -141,6 +142,50 @@ public class Codec
/**
* <p>Converts an int value (32-bit) into its hexadecimal
* notation.</p>
*/
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();
}
/**
* <p>Converts a long value (64-bit) into its hexadecimal
* notation.</p>
*/
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();
}
/**
* <p>Converts a class ID into its hexadecimal notation.</p>
*/
public static String hexEncode(final ClassID classID)
{
return hexEncode(classID.getBytes());
}
/** /**
* <p>Decodes the hexadecimal representation of a sequence of * <p>Decodes the hexadecimal representation of a sequence of
* bytes into a byte array. Each character in the string * bytes into a byte array. Each character in the string

View File

@ -159,7 +159,7 @@ public class POIBrowser extends JFrame
new PropertySetDescriptorRenderer()); new PropertySetDescriptorRenderer());
treeUI.setCellRenderer(etcr); treeUI.setCellRenderer(etcr);
setSize(600, 450); setSize(600, 450);
setTitle("POI Browser 0.06"); setTitle("POI Browser 0.07");
setVisible(true); setVisible(true);
} }

View File

@ -85,9 +85,6 @@ public class PropertySetDescriptorRenderer extends DocumentDescriptorRenderer
final int row, final int row,
final boolean hasFocus) final boolean hasFocus)
{ {
throw new RuntimeException("THIS FUNCTION BROKEN -- FIX IT");
/*
final PropertySetDescriptor d = (PropertySetDescriptor) final PropertySetDescriptor d = (PropertySetDescriptor)
((DefaultMutableTreeNode) value).getUserObject(); ((DefaultMutableTreeNode) value).getUserObject();
final PropertySet ps = d.getPropertySet(); final PropertySet ps = d.getPropertySet();
@ -110,9 +107,8 @@ public class PropertySetDescriptorRenderer extends DocumentDescriptorRenderer
if (ps instanceof SummaryInformation) if (ps instanceof SummaryInformation)
{ {
*/
/* Use the convenience methods. */ /* Use the convenience methods. */
/* final SummaryInformation si = (SummaryInformation) ps; final SummaryInformation si = (SummaryInformation) ps;
text.append("\n"); text.append("\n");
text.append("\nTitle: " + si.getTitle()); text.append("\nTitle: " + si.getTitle());
text.append("\nSubject: " + si.getSubject()); text.append("\nSubject: " + si.getSubject());
@ -136,7 +132,7 @@ public class PropertySetDescriptorRenderer extends DocumentDescriptorRenderer
if (selected) if (selected)
Util.invert(text); 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) protected String toString(final Section s, final String name)
{ {
throw new RuntimeException("THIS FUNCTION BROKEN -- FIX IT");
/*
final StringBuffer b = new StringBuffer(); final StringBuffer b = new StringBuffer();
b.append("\n" + name + " Format ID: "); 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 + " Offset: " + s.getOffset());
b.append("\n" + name + " Section size: " + s.getSize()); b.append("\n" + name + " Section size: " + s.getSize());
b.append("\n" + name + " Property count: " + s.getPropertyCount()); b.append("\n" + name + " Property count: " + s.getPropertyCount());
@ -195,7 +188,6 @@ public class PropertySetDescriptorRenderer extends DocumentDescriptorRenderer
b.append(value.toString()); b.append(value.toString());
} }
return b.toString(); return b.toString();
*/
} }
} }

View File

@ -59,83 +59,93 @@ import java.io.*;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
/** /**
* REWRITE ME * <p>Represents a class ID (16 bytes). Unlike other little-endian
* <p> * type the {@link ClassID} is not just 16 bytes stored in the wrong
* Represents a class ID (16 bytes). Unlike other little-endian type the {@link * order. Instead, it is a double word (4 bytes) followed by two
* ClassID} is not just 16 bytes stored in the wrong order. Instead, it is a * words (2 bytes each) followed by 8 bytes.</p>
* double word (4 bytes) followed by two words (2 bytes each) followed by 8
* bytes.</p>
* *
*@author Rainer Klute (klute@rainer-klute.de) * @author Rainer Klute (klute@rainer-klute.de)
*@created May 10, 2002 * @version $Id$
*@see LittleEndian * @since 2002-02-09
*@version $Id$
*@since 2002-02-09
*/ */
public class ClassID { public class ClassID
{
/** /**
* <p> * <p>The bytes making out the class ID in correct order,
* * i.e. big-endian.</p>
* Creates a {@link ClassID} and reads its value from a byte array.</p>
*
*@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) { protected byte[] bytes;
// super(src, offset);
/**
* <p>Creates a {@link ClassID} and reads its value from a byte
* array.</p>
*
* @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 final static int LENGTH = 16;
public int length() { public int length()
{
return LENGTH; return LENGTH;
} }
public byte[] getBytes() {
throw new RuntimeException("This fucntion must be rewritten");
}
/** /**
* Description of the Method - REWRITE ME REWRITE ME REWRITE ME * <p>Gets the bytes making out the class ID. They are returned in
* ISNT += offset a bug? -- doesn't the order of operations evaluate that * correct order, i.e. big-endian.</p>
* last?
*
*@param src Description of the Parameter
*@param offset Description of the Parameter
*@return Description of the Return Value
*/ */
public byte[] read(byte[] src, int offset) { public byte[] getBytes()
byte[] retval = new byte[24]; {
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 * <p>Reads a class ID from a byte array by turning little-endian
retval[0] = src[3]; * into big-endian.</p>
retval[1] = src[2]; *
retval[2] = src[1]; * @param src The byte array to read from
retval[3] = src[0]; *
* @param offset The offset within the <var>src</var> 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)); /* Read double word. */
//transfer the second short from little to big endian bytes[0] = src[3 + offset];
retval[4] = src[5]; bytes[1] = src[2 + offset];
retval[5] = src[4]; bytes[2] = src[1 + offset];
bytes[3] = src[0 + offset];
//b[2] = new Short(LittleEndian.getInt(src, offset += LittleEndian.SHORT_SIZE)); /* Read first word. */
//transfer the third short from little to big endian bytes[4] = src[5 + offset];
retval[6] = src[7]; bytes[5] = src[4 + offset];
retval[7] = src[6];
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;
} }
} }

View File

@ -95,7 +95,7 @@ import org.apache.poi.poifs.filesystem.*;
*/ */
public class PropertySet { public class PropertySet {
final static byte[] BYTE_ORDER_ASSERTION = final static byte[] BYTE_ORDER_ASSERTION =
new byte[]{(byte) 0xFF, (byte) 0xFE}; new byte[]{(byte) 0xFE, (byte) 0xFF};
final static byte[] FORMAT_ASSERTION = final static byte[] FORMAT_ASSERTION =
new byte[]{(byte) 0x00, (byte) 0x00}; new byte[]{(byte) 0x00, (byte) 0x00};

View File

@ -59,23 +59,19 @@ import org.apache.poi.util.LittleEndian;
import org.apache.poi.hpsf.wellknown.*; import org.apache.poi.hpsf.wellknown.*;
/** /**
* <p> * <p>Represents a section in a {@link PropertySet}.</p>
* *
* Represents a section in a {@link PropertySet}.</p> * @author Rainer Klute (klute@rainer-klute.de)
* * @author Drew Varner (Drew.Varner allUpIn sc.edu)
*@author Rainer Klute (klute@rainer-klute.de) * @version $Id$
*@author Drew Varner (Drew.Varner allUpIn sc.edu) * @since 2002-02-09
*@created May 10, 2002
*@version $Id$
*@since 2002-02-09
*/ */
public class Section { public class Section
{
/** /**
* <p> * <p>Maps property IDs to section-private PID strings. These
* * strings can be found in the property with ID 0.</p>
* Maps property IDs to section-private PID strings. These strings can be
* found in the property with ID 0.</p>
*/ */
protected Map dictionary; protected Map dictionary;
@ -83,13 +79,13 @@ public class Section {
/** /**
* <p> * <p>Returns the format ID. The format ID is the "type" of the
* section.</p>
* *
* Returns the format ID. The format ID is the "type" of the section.</p> * @return The format ID
*
*@return The formatID value
*/ */
public ClassID getFormatID() { public ClassID getFormatID()
{
return formatID; return formatID;
} }
@ -99,13 +95,12 @@ public class Section {
/** /**
* <p> * <p>Returns the offset of the section in the stream.</p>
* *
* Returns the offset of the section in the stream.</p> * @return The offset of the section in the stream.
*
*@return The offset value
*/ */
public long getOffset() { public long getOffset()
{
return offset; return offset;
} }
@ -115,13 +110,12 @@ public class Section {
/** /**
* <p> * <p>Returns the section's size in bytes.</p>
* *
* Returns the section's size in bytes.</p> * @return The section's size in bytes.
*
*@return The size value
*/ */
public int getSize() { public int getSize()
{
return size; return size;
} }
@ -131,13 +125,12 @@ public class Section {
/** /**
* <p> * <p>Returns the number of properties in this section.</p>
* *
* Returns the number of properties in this section.</p> * @return The number of properties in this section.
*
*@return The propertyCount value
*/ */
public int getPropertyCount() { public int getPropertyCount()
{
return propertyCount; return propertyCount;
} }
@ -147,28 +140,26 @@ public class Section {
/** /**
* <p> * <p>Returns this section's properties.</p>
* *
* Returns this section's properties.</p> * @return This section's properties.
*
*@return The properties value
*/ */
public Property[] getProperties() { public Property[] getProperties()
{
return properties; return properties;
} }
/** /**
* <p> * <p>Creates a {@link Section} instance from a byte array.</p>
* *
* Creates a {@link Section} instance from a byte array.</p> * @param src Contains the complete property set stream.
* * @param offset The position in the stream that points to the
*@param src Contains the complete property set stream. * section's format ID.
*@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. * Read the format ID.
*/ */
@ -217,7 +208,8 @@ public class Section {
length = (int)(src.length - this.offset - sOffset); length = (int)(src.length - this.offset - sOffset);
} else { } else {
length = (int) 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 {
/** /**
* <p> * <p>Returns the value of the property with the specified ID. If
* the property is not available, <code>null</code> is returned
* and a subsequent call to {@link #wasNull} will return
* <code>true</code>.</p>
* *
* Returns the value of the property with the specified ID. If the property * @param id The property's ID
* is not available, <code>null</code> is returned and a subsequent call to
* {@link #wasNull} will return <code>true</code>.</p>
* *
*@param id Description of the Parameter * @return The property's value
*@return The property value
*/ */
protected Object getProperty(final int id) { protected Object getProperty(final int id)
{
wasNull = false; wasNull = false;
for (int i = 0; i < properties.length; i++) { for (int i = 0; i < properties.length; i++)
if (id == properties[i].getID()) { if (id == properties[i].getID())
return properties[i].getValue(); return properties[i].getValue();
}
}
wasNull = true; wasNull = true;
return null; return null;
} }
@ -259,47 +250,48 @@ public class Section {
/** /**
* <p> * <p>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
* <code>true</code> to let the caller distinguish that case from
* a real property value of 0.</p>
* *
* Returns the value of the numeric property with the specified ID. If the * @param id The property's ID
* property is not available, 0 is returned. A subsequent call to {@link
* #wasNull} will return <code>true</code> to let the caller distinguish
* that case from a real property value of 0.</p>
* *
*@param id Description of the Parameter * @return The property's value
*@return The propertyIntValue value
*/ */
protected int getPropertyIntValue(final int id) { protected int getPropertyIntValue(final int id)
final Integer i = (Integer) getProperty(id); {
if (i != null) { /* 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(); return i.intValue();
} else { else
return 0; return 0;
}
} }
/** /**
* <p> * <p>Returns the value of the boolean property with the specified
* ID. If the property is not available, <code>false</code> is
* returned. A subsequent call to {@link #wasNull} will return
* <code>true</code> to let the caller distinguish that case from
* a real property value of <code>false</code>.</p>
* *
* Returns the value of the boolean property with the specified ID. If the * @param id The property's ID
* property is not available, <code>false</code> is returned. A subsequent
* call to {@link #wasNull} will return <code>true</code> to let the caller
* distinguish that case from a real property value of <code>false</code>.
* </p>
* *
*@param id Description of the Parameter * @return The property's value
*@return The propertyBooleanValue value
*/ */
protected boolean getPropertyBooleanValue(final int id) { protected boolean getPropertyBooleanValue(final int id)
{
final Boolean b = (Boolean) getProperty(id); final Boolean b = (Boolean) getProperty(id);
if (b != null) { if (b != null)
return b.booleanValue(); return b.booleanValue();
} else { else
return false; return false;
} }
}
@ -307,46 +299,44 @@ public class Section {
/** /**
* <p> * <p>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.</p>
* *
* Checks whether the property which the last call to {@link * @return <code>true</code> if the last call to {@link
* #getPropertyIntValue} or {@link #getProperty} tried to access was * #getPropertyIntValue} or {@link #getProperty} tried to access a
* available or not. This information might be important for callers of * property that was not available, else <code>false</code>.
* {@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.</p>
*
*@return <code>true</code> if the last call to {@link
* #getPropertyIntValue} or {@link #getProperty} tried to access a
* property that was not available, else <code>false</code>.
*/ */
public boolean wasNull() { public boolean wasNull()
{
return wasNull; return wasNull;
} }
/** /**
* <p> * <p>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}.</p>
* *
* Returns the PID string associated with a property ID. The ID is first * @param pid The property ID
* looked up in the {@link Section}'s private dictionary. If it is not
* found there, the method calls {@link SectionIDMap#getPIDString}.</p>
* *
*@param pid Description of the Parameter * @return The property ID's string value
*@return The pIDString value
*/ */
public String getPIDString(final int pid) { public String getPIDString(final int pid)
{
String s = null; String s = null;
if (dictionary != null) { if (dictionary != null)
s = (String) dictionary.get(new Integer(pid)); s = (String) dictionary.get(new Integer(pid));
} if (s == null)
if (s == null) {
s = SectionIDMap.getPIDString(getFormatID().getBytes(), pid); s = SectionIDMap.getPIDString(getFormatID().getBytes(), pid);
} if (s == null)
if (s == null) {
s = SectionIDMap.UNDEFINED; s = SectionIDMap.UNDEFINED;
}
return s; return s;
} }