You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@poi.apache.org by kl...@apache.org on 2003/08/30 11:13:53 UTC
cvs commit: jakarta-poi/src/java/org/apache/poi/hpsf/wellknown PropertyIDMap.java
klute 2003/08/30 02:13:53
Modified: src/java/org/apache/poi/hpsf ClassID.java
DocumentSummaryInformation.java HPSFException.java
HPSFRuntimeException.java
MarkUnsupportedException.java
NoPropertySetStreamException.java
NoSingleSectionException.java Property.java
PropertySet.java PropertySetFactory.java
ReadingNotSupportedException.java Section.java
SpecialPropertySet.java SummaryInformation.java
TypeWriter.java
UnexpectedPropertySetTypeException.java
UnsupportedVariantTypeException.java Util.java
Variant.java VariantSupport.java
WritingNotSupportedException.java
src/java/org/apache/poi/hpsf/wellknown PropertyIDMap.java
Added: src/java/org/apache/poi/hpsf MutableProperty.java
MutablePropertySet.java MutableSection.java
Log:
HPSF writing capability added.
Revision Changes Path
1.8 +15 -4 jakarta-poi/src/java/org/apache/poi/hpsf/ClassID.java
Index: ClassID.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/ClassID.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- ClassID.java 3 Aug 2003 20:16:46 -0000 1.7
+++ ClassID.java 30 Aug 2003 09:13:52 -0000 1.8
@@ -61,7 +61,8 @@
* order. Instead, it is a 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 <a
+ * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @version $Id$
* @since 2002-02-09
*/
@@ -120,7 +121,7 @@
/**
* <p>Gets the bytes making out the class ID. They are returned in
* correct order, i.e. big-endian.</p>
- *
+ *
* @return the bytes making out the class ID.
*/
public byte[] getBytes()
@@ -175,7 +176,7 @@
*
* @param offset The offset within the <var>dst</var> byte array.
*
- * @exception ArrayStoreException if there is not enough room for the class
+ * @exception ArrayStoreException if there is not enough room for the class
* ID 16 bytes in the byte array after the <var>offset</var> position.
*/
public void write(final byte[] dst, final int offset)
@@ -226,6 +227,16 @@
if (bytes[i] != cid.bytes[i])
return false;
return true;
+ }
+
+
+
+ /**
+ * @see Object#hashCode()
+ */
+ public int hashCode()
+ {
+ throw new UnsupportedOperationException("FIXME: Not yet implemented.");
}
}
1.11 +4 -3 jakarta-poi/src/java/org/apache/poi/hpsf/DocumentSummaryInformation.java
Index: DocumentSummaryInformation.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/DocumentSummaryInformation.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- DocumentSummaryInformation.java 2 Aug 2003 19:02:28 -0000 1.10
+++ DocumentSummaryInformation.java 30 Aug 2003 09:13:52 -0000 1.11
@@ -60,7 +60,8 @@
* <p>Convenience class representing a DocumentSummary Information stream in a
* Microsoft Office document.</p>
*
- * @author Rainer Klute (klute@rainer-klute.de)
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @author Drew Varner (Drew.Varner closeTo sc.edu)
* @see SummaryInformation
* @version $Id$
@@ -289,7 +290,7 @@
* <p>Returns <code>true</code> if the custom links are hampered
* by excessive noise, for all applications.</p> <p>
*
- * <strong>FIXME:</strong> Explain this some more! I (Rainer)
+ * <strong>FIXME (3):</strong> Explain this some more! I (Rainer)
* don't understand it.</p>
*
* @return The linksDirty value
1.8 +3 -2 jakarta-poi/src/java/org/apache/poi/hpsf/HPSFException.java
Index: HPSFException.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/HPSFException.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- HPSFException.java 2 Aug 2003 19:02:28 -0000 1.7
+++ HPSFException.java 30 Aug 2003 09:13:52 -0000 1.8
@@ -59,7 +59,8 @@
* thrown in this package. It supports a nested "reason" throwable,
* i.e. an exception that caused this one to be thrown.</p>
*
- * @author Rainer Klute (klute@rainer-klute.de)
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @version $Id$
* @since 2002-02-09
*/
1.8 +48 -2 jakarta-poi/src/java/org/apache/poi/hpsf/HPSFRuntimeException.java
Index: HPSFRuntimeException.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/HPSFRuntimeException.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- HPSFRuntimeException.java 2 Aug 2003 19:02:28 -0000 1.7
+++ HPSFRuntimeException.java 30 Aug 2003 09:13:52 -0000 1.8
@@ -54,12 +54,16 @@
*/
package org.apache.poi.hpsf;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
/**
* <p>This exception is the superclass of all other unchecked
* exceptions thrown in this package. It supports a nested "reason"
* throwable, i.e. an exception that caused this one to be thrown.</p>
*
- * @author Rainer Klute (klute@rainer-klute.de)
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @version $Id$
* @since 2002-02-09
*/
@@ -136,6 +140,48 @@
public Throwable getReason()
{
return reason;
+ }
+
+
+
+ /**
+ * @see Throwable#printStackTrace()
+ */
+ public void printStackTrace()
+ {
+ printStackTrace(System.err);
+ }
+
+
+
+ /**
+ * @see Throwable#printStackTrace(java.io.PrintStream)
+ */
+ public void printStackTrace(final PrintStream p)
+ {
+ final Throwable reason = getReason();
+ super.printStackTrace(p);
+ if (reason != null)
+ {
+ p.println("Caused by:");
+ reason.printStackTrace(p);
+ }
+ }
+
+
+
+ /**
+ * @see Throwable#printStackTrace(java.io.PrintWriter)
+ */
+ public void printStackTrace(final PrintWriter p)
+ {
+ final Throwable reason = getReason();
+ super.printStackTrace(p);
+ if (reason != null)
+ {
+ p.println("Caused by:");
+ reason.printStackTrace(p);
+ }
}
}
1.8 +7 -6 jakarta-poi/src/java/org/apache/poi/hpsf/MarkUnsupportedException.java
Index: MarkUnsupportedException.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/MarkUnsupportedException.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- MarkUnsupportedException.java 2 Aug 2003 19:02:28 -0000 1.7
+++ MarkUnsupportedException.java 30 Aug 2003 09:13:52 -0000 1.8
@@ -58,7 +58,8 @@
* <p>This exception is thrown if an {@link java.io.InputStream} does
* not support the {@link java.io.InputStream#mark} operation.</p>
*
- * @author Rainer Klute (klute@rainer-klute.de)
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @version $Id$
* @since 2002-02-09
*/
@@ -76,7 +77,7 @@
/**
* <p>Constructor</p>
- *
+ *
* @param msg The exception's message string
*/
public MarkUnsupportedException(final String msg)
@@ -87,7 +88,7 @@
/**
* <p>Constructor</p>
- *
+ *
* @param reason This exception's underlying reason
*/
public MarkUnsupportedException(final Throwable reason)
@@ -98,7 +99,7 @@
/**
* <p>Constructor</p>
- *
+ *
* @param msg The exception's message string
* @param reason This exception's underlying reason
*/
@@ -107,4 +108,4 @@
super(msg, reason);
}
-}
\ No newline at end of file
+}
1.8 +12 -11 jakarta-poi/src/java/org/apache/poi/hpsf/NoPropertySetStreamException.java
Index: NoPropertySetStreamException.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/NoPropertySetStreamException.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- NoPropertySetStreamException.java 2 Aug 2003 19:02:28 -0000 1.7
+++ NoPropertySetStreamException.java 30 Aug 2003 09:13:52 -0000 1.8
@@ -55,18 +55,16 @@
package org.apache.poi.hpsf;
/**
- * <p>
+ * <p>This exception is thrown if a format error in a property set stream is
+ * detected or when the input data do not constitute a property set stream.</p>
+ *
+ * <p>The constructors of this class are analogous to those of its superclass
+ * and are documented there.</p>
*
- * This exception is thrown if a format error in a property set stream is
- * detected or when the input data do not constitute a property set stream.</p>
- * <p>
- *
- * The constructors of this class are analogous to those of its superclass and
- * documented there.</p>
- *
- *@author Rainer Klute (klute@rainer-klute.de)
- *@version $Id$
- *@since 2002-02-09
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
+ * @version $Id$
+ * @since 2002-02-09
*/
public class NoPropertySetStreamException extends HPSFException
{
@@ -80,6 +78,7 @@
}
+
/**
* <p>Constructor</p>
*
@@ -91,6 +90,7 @@
}
+
/**
* <p>Constructor</p>
*
@@ -100,6 +100,7 @@
{
super(reason);
}
+
/**
1.8 +3 -2 jakarta-poi/src/java/org/apache/poi/hpsf/NoSingleSectionException.java
Index: NoSingleSectionException.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/NoSingleSectionException.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- NoSingleSectionException.java 2 Aug 2003 19:02:28 -0000 1.7
+++ NoSingleSectionException.java 30 Aug 2003 09:13:52 -0000 1.8
@@ -63,7 +63,8 @@
* <p>The constructors of this class are analogous to those of its
* superclass and documented there.</p>
*
- * @author Rainer Klute (klute@rainer-klute.de)
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @version $Id$
* @since 2002-02-09
*/
1.14 +75 -33 jakarta-poi/src/java/org/apache/poi/hpsf/Property.java
Index: Property.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/Property.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- Property.java 23 Aug 2003 15:12:22 -0000 1.13
+++ Property.java 30 Aug 2003 09:13:52 -0000 1.14
@@ -63,8 +63,6 @@
package org.apache.poi.hpsf;
import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
import java.util.Map;
import org.apache.poi.util.LittleEndian;
@@ -85,11 +83,13 @@
* value, {@link Variant#VT_FILETIME} some date and time (of a
* file).</p>
*
- * <p><strong>FIXME:</strong> Reading is not implemented for all
- * {@link Variant} types yet. Feel free to submit error reports or
- * patches for the types you need.</p>
+ * <p>Please note that not all {@link Variant} types yet. This might change
+ * over time but largely depends on your feedback so that the POI team knows
+ * which variant types are really needed. So please feel free to submit error
+ * reports or patches for the types you need.</p>
*
- * @author Rainer Klute (klute@rainer-klute.de)
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @author Drew Varner (Drew.Varner InAndAround sc.edu)
* @see Section
* @see Variant
@@ -103,7 +103,7 @@
private static final int CP_UNICODE = 1200;
/** <p>The property's ID.</p> */
- protected int id;
+ protected long id;
/**
@@ -111,7 +111,7 @@
*
* @return The ID value
*/
- public int getID()
+ public long getID()
{
return id;
}
@@ -162,7 +162,7 @@
* @param codepage The section's and thus the property's
* codepage. It is needed only when reading string values.
*/
- public Property(final int id, final byte[] src, final long offset,
+ public Property(final long id, final byte[] src, final long offset,
final int length, final int codepage)
{
this.id = id;
@@ -187,7 +187,7 @@
}
catch (UnsupportedVariantTypeException ex)
{
- logUnsupported(ex);
+ VariantSupport.writeUnsupportedTypeMessage(ex);
value = ex.getValue();
}
}
@@ -281,15 +281,21 @@
* 4.</p>
*
* @return the property's size in bytes
+ *
+ * @exception WritingNotSupportedException if HPSF does not yet support the
+ * property's variant type.
*/
- protected int getSize()
+ protected int getSize() throws WritingNotSupportedException
{
- int length = LittleEndian.INT_SIZE;
+ int length = VariantSupport.getVariantLength(type);
+ if (length >= 0)
+ return length; /* Fixed length */
+ if (length == -2)
+ /* Unknown length */
+ throw new WritingNotSupportedException(type, null);
+
+ /* Variable length: */
final int PADDING = 4; /* Pad to multiples of 4. */
- if (type > Integer.MAX_VALUE)
- throw new HPSFRuntimeException
- ("Variant type " + type + " is greater than " +
- Integer.MAX_VALUE + ".");
switch ((int) type)
{
case Variant.VT_LPSTR:
@@ -304,9 +310,7 @@
case Variant.VT_EMPTY:
break;
default:
- throw new HPSFRuntimeException
- ("Writing is not yet implemented for variant type " +
- type + ". Please report this problem to the POI team!");
+ throw new WritingNotSupportedException(type, value);
}
return length;
}
@@ -318,27 +322,65 @@
*/
public boolean equals(final Object o)
{
- throw new UnsupportedOperationException("FIXME: Not yet implemented.");
+ if (!(o instanceof Property))
+ return false;
+ final Property p = (Property) o;
+ final Object pValue = p.getValue();
+ if (id != p.getID() || type != p.getType())
+ return false;
+ if (value == null && pValue == null)
+ return true;
+ if (value == null || pValue == null)
+ return false;
+
+ /* It's clear now that both values are non-null. */
+ final Class valueClass = value.getClass();
+ final Class pValueClass = pValue.getClass();
+ if (!(valueClass.isAssignableFrom(pValueClass)) &&
+ !(pValueClass.isAssignableFrom(valueClass)))
+ return false;
+
+ if (value instanceof byte[])
+ return Util.equal((byte[]) value, (byte[]) pValue);
+
+ return value.equals(pValue);
}
/**
- * <p>Keeps a list of those variant types for those an "unsupported" message
- * has already been issued.</p>
+ * @see Object#hashCode()
*/
- protected static List unsupportedMessage;
+ public int hashCode()
+ {
+ long hashCode = 0;
+ hashCode += id;
+ hashCode += type;
+ if (value != null)
+ hashCode += value.hashCode();
+ final int returnHashCode = (int) (hashCode & 0x0ffffffffL );
+ return returnHashCode;
+
+ }
- private static void logUnsupported(final UnsupportedVariantTypeException ex)
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
{
- if (unsupportedMessage == null)
- unsupportedMessage = new LinkedList();
- Long vt = new Long(ex.getVariantType());
- if (!unsupportedMessage.contains(vt))
- {
- System.err.println(ex.getMessage());
- unsupportedMessage.add(vt);
- }
+ final StringBuffer b = new StringBuffer();
+ b.append(getClass().getName());
+ b.append('[');
+ b.append("id: ");
+ b.append(getID());
+ b.append(", type: ");
+ b.append(getType());
+ b.append(", value: ");
+ b.append(getValue());
+ b.append(']');
+ return b.toString();
}
}
1.12 +47 -5 jakarta-poi/src/java/org/apache/poi/hpsf/PropertySet.java
Index: PropertySet.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/PropertySet.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- PropertySet.java 3 Aug 2003 20:16:46 -0000 1.11
+++ PropertySet.java 30 Aug 2003 09:13:52 -0000 1.12
@@ -57,7 +57,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.LinkedList;
import java.util.List;
import org.apache.poi.hpsf.wellknown.SectionIDMap;
@@ -91,7 +90,8 @@
* NoSingleSectionException} if the {@link PropertySet} contains more
* (or less) than exactly one {@link Section}).</p>
*
- * @author Rainer Klute (klute@rainer-klute.de)
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @author Drew Varner (Drew.Varner hanginIn sc.edu)
* @version $Id$
* @since 2002-02-09
@@ -397,7 +397,7 @@
final int offset,
final int length)
{
- /* FIXME: Ensure that at most "length" bytes are read. */
+ /* FIXME (3): Ensure that at most "length" bytes are read. */
/*
* Read the header fields of the stream. They must always be
@@ -442,7 +442,7 @@
*/
private void init(final byte[] src, final int offset, final int length)
{
- /* FIXME: Ensure that at most "length" bytes are read. */
+ /* FIXME (3): Ensure that at most "length" bytes are read. */
/*
* Read the stream's header fields.
@@ -645,6 +645,9 @@
* to the specified parameter, else <code>false</code>.</p>
*
* @param o the object to compare this <code>PropertySet</code> with
+ *
+ * @return <code>true</code> if the objects are equal, <code>false</code>
+ * if not
*/
public boolean equals(final Object o)
{
@@ -672,4 +675,43 @@
return Util.equals(getSections(), ps.getSections());
}
+
+
+ /**
+ * @see Object#hashCode()
+ */
+ public int hashCode()
+ {
+ throw new UnsupportedOperationException("FIXME: Not yet implemented.");
+ }
+
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ final StringBuffer b = new StringBuffer();
+ final int sectionCount = getSectionCount();
+ b.append(getClass().getName());
+ b.append('[');
+ b.append("byteOrder: ");
+ b.append(getByteOrder());
+ b.append(", classID: ");
+ b.append(getClassID());
+ b.append(", format: ");
+ b.append(getFormat());
+ b.append(", OSVersion: ");
+ b.append(getOSVersion());
+ b.append(", sectionCount: ");
+ b.append(sectionCount);
+ b.append(", sections: [");
+ final List sections = getSections();
+ for (int i = 0; i < sectionCount; i++)
+ b.append(((Section) sections.get(0)).toString());
+ b.append(']');
+ b.append(']');
+ return b.toString();
+ }
}
1.8 +3 -2 jakarta-poi/src/java/org/apache/poi/hpsf/PropertySetFactory.java
Index: PropertySetFactory.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/PropertySetFactory.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- PropertySetFactory.java 2 Aug 2003 19:02:28 -0000 1.7
+++ PropertySetFactory.java 30 Aug 2003 09:13:52 -0000 1.8
@@ -61,7 +61,8 @@
* <p>Factory class to create instances of {@link SummaryInformation},
* {@link DocumentSummaryInformation} and {@link PropertySet}.</p>
*
- * @author Rainer Klute (klute@rainer-klute.de)
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @version $Id$
* @since 2002-02-09
*/
1.3 +10 -6 jakarta-poi/src/java/org/apache/poi/hpsf/ReadingNotSupportedException.java
Index: ReadingNotSupportedException.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/ReadingNotSupportedException.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ReadingNotSupportedException.java 25 Aug 2003 19:46:00 -0000 1.2
+++ ReadingNotSupportedException.java 30 Aug 2003 09:13:52 -0000 1.3
@@ -63,8 +63,11 @@
package org.apache.poi.hpsf;
/**
- * <p>This exception is thrown when trying to read a (yet) unsupported variant
- * type.</p>
+ * <p>This exception is thrown when HPSF tries to read a (yet) unsupported
+ * variant type.</p>
+ *
+ * @see WritingNotSupportedException
+ * @see UnsupportedVariantTypeException
*
* @author Rainer Klute <a
* href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
@@ -78,10 +81,11 @@
/**
* <p>Constructor</p>
*
- * @param variantType
- * @param value
+ * @param variantType The unsupported variant type.
+ * @param value The value.
*/
- public ReadingNotSupportedException(long variantType, Object value)
+ public ReadingNotSupportedException(final long variantType,
+ final Object value)
{
super(variantType, value);
}
1.14 +50 -3 jakarta-poi/src/java/org/apache/poi/hpsf/Section.java
Index: Section.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/Section.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- Section.java 23 Aug 2003 15:12:22 -0000 1.13
+++ Section.java 30 Aug 2003 09:13:52 -0000 1.14
@@ -67,7 +67,8 @@
/**
* <p>Represents a section in a {@link PropertySet}.</p>
*
- * @author Rainer Klute (klute@rainer-klute.de)
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @author Drew Varner (Drew.Varner allUpIn sc.edu)
* @version $Id$
* @since 2002-02-09
@@ -493,7 +494,7 @@
/**
* <p>Checks whether this section is equal to another object.</p>
*
- * @param o The object to cpmpare this section with
+ * @param o The object to compare this section with
* @return <code>true</code> if the objects are equal, <code>false</code> if
* not
*/
@@ -507,6 +508,52 @@
if (s.getPropertyCount() != getPropertyCount())
return false;
return Util.equals(s.getProperties(), getProperties());
+ }
+
+
+
+ /**
+ * @see Object#hashCode()
+ */
+ public int hashCode()
+ {
+ long hashCode = 0;
+ hashCode += getFormatID().hashCode();
+ final Property[] pa = getProperties();
+ for (int i = 0; i < pa.length; i++)
+ hashCode += pa[i].hashCode();
+ final int returnHashCode = (int) (hashCode & 0x0ffffffffL);
+ return returnHashCode;
+ }
+
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ final StringBuffer b = new StringBuffer();
+ final Property[] pa = getProperties();
+ b.append(getClass().getName());
+ b.append('[');
+ b.append("formatID: ");
+ b.append(getFormatID());
+ b.append(", offset: ");
+ b.append(getOffset());
+ b.append(", propertyCount: ");
+ b.append(getPropertyCount());
+ b.append(", size: ");
+ b.append(getSize());
+ b.append(", properties: [\n");
+ for (int i = 0; i < pa.length; i++)
+ {
+ b.append(pa[i].toString());
+ b.append(",\n");
+ }
+ b.append(']');
+ b.append(']');
+ return b.toString();
}
}
1.10 +3 -2 jakarta-poi/src/java/org/apache/poi/hpsf/SpecialPropertySet.java
Index: SpecialPropertySet.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/SpecialPropertySet.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- SpecialPropertySet.java 2 Aug 2003 19:02:28 -0000 1.9
+++ SpecialPropertySet.java 30 Aug 2003 09:13:52 -0000 1.10
@@ -82,7 +82,8 @@
* went the other way round historically: the convenience classes came
* only late to my mind.</p>
*
- * @author Rainer Klute (klute@rainer-klute.de)
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @version $Id$
* @since 2002-02-09
*/
1.12 +4 -3 jakarta-poi/src/java/org/apache/poi/hpsf/SummaryInformation.java
Index: SummaryInformation.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/SummaryInformation.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- SummaryInformation.java 2 Aug 2003 19:02:28 -0000 1.11
+++ SummaryInformation.java 30 Aug 2003 09:13:52 -0000 1.12
@@ -69,7 +69,8 @@
* href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/stgu_8910.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/stgu_8910.asp</a>
* for documentation from That Redmond Company.</p>
*
- * @author Rainer Klute (klute@rainer-klute.de)
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @see DocumentSummaryInformation
* @version $Id$
* @since 2002-02-09
@@ -297,7 +298,7 @@
* <strong>when this method is implemented. Please note that the
* return type is likely to change!</strong></p>
*
- * <p><strong>FIXME / Hint to developers:</strong> Drew Varner
+ * <p><strong>FIXME (3) / Hint to developers:</strong> Drew Varner
* <Drew.Varner -at- sc.edu> said that this is an image in
* WMF or Clipboard (BMP?) format. He also provided two links that
* might be helpful: <a
1.2 +7 -6 jakarta-poi/src/java/org/apache/poi/hpsf/TypeWriter.java
Index: TypeWriter.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/TypeWriter.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TypeWriter.java 23 Aug 2003 15:12:22 -0000 1.1
+++ TypeWriter.java 30 Aug 2003 09:13:52 -0000 1.2
@@ -66,12 +66,12 @@
import java.io.OutputStream;
import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.LittleEndianConsts;
/**
* <p>Class for writing little-endian data and more.</p>
*
- * @author Rainer Klute (klute@rainer-klute.de)
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @version $Id$
* @since 2003-02-20
*/
@@ -81,8 +81,9 @@
/**
* <p>Writes a two-byte value (short) to an output stream.</p>
*
- * @param out The stream to write to
- * @param n The value to write
+ * @param out The stream to write to.
+ * @param n The value to write.
+ * @return The number of bytes that have been written.
* @exception IOException if an I/O error occurs
*/
public static int writeToStream(final OutputStream out, final short n)
@@ -149,7 +150,7 @@
throws IOException
{
long high = n & 0xFFFFFFFF00000000L;
- if (high != 0)
+ if (high != 0 && high != 0xFFFFFFFF00000000L)
throw new IllegalPropertySetDataException
("Value " + n + " cannot be represented by 4 bytes.");
return writeToStream(out, (int) n);
1.8 +3 -2 jakarta-poi/src/java/org/apache/poi/hpsf/UnexpectedPropertySetTypeException.java
Index: UnexpectedPropertySetTypeException.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/UnexpectedPropertySetTypeException.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- UnexpectedPropertySetTypeException.java 2 Aug 2003 19:02:28 -0000 1.7
+++ UnexpectedPropertySetTypeException.java 30 Aug 2003 09:13:52 -0000 1.8
@@ -62,7 +62,8 @@
* <p>The constructors of this class are analogous to those of its
* superclass and documented there.</p>
*
- * @author Rainer Klute (klute@rainer-klute.de)
+ * @author Rainer Klute <a
+ * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @version $Id$
* @since 2002-02-09
*/
1.2 +2 -2 jakarta-poi/src/java/org/apache/poi/hpsf/UnsupportedVariantTypeException.java
Index: UnsupportedVariantTypeException.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/UnsupportedVariantTypeException.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- UnsupportedVariantTypeException.java 23 Aug 2003 15:12:22 -0000 1.1
+++ UnsupportedVariantTypeException.java 30 Aug 2003 09:13:52 -0000 1.2
@@ -88,7 +88,7 @@
{
super("HPSF does not yet support the variant type " + variantType +
" (" + Variant.getVariantName(variantType) + ", " +
- HexDump.toHex((int) variantType) + "). If you want support for " +
+ HexDump.toHex(variantType) + "). If you want support for " +
"this variant type in one of the next POI releases please " +
"submit a request for enhancement (RFE) to " +
"<http://nagoya.apache.org/bugzilla/>! Thank you!");
1.11 +87 -2 jakarta-poi/src/java/org/apache/poi/hpsf/Util.java
Index: Util.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/Util.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- Util.java 23 Aug 2003 15:12:22 -0000 1.10
+++ Util.java 30 Aug 2003 09:13:52 -0000 1.11
@@ -78,7 +78,7 @@
* <li><p>if for each <var>i</var> with
* <var>i</var> >= 0 and
* <var>i</var> < <var>a.length</var> holds
- * <var>a</var>[<var>i</var>] == <var>b</var>[<var>i</var>].</p></li>
+ * <var>a</var>[<var>i</var>] == <var>b</var>[<var>i</var>].</p></li>
*
* </ul>
*
@@ -191,6 +191,16 @@
return new Date(ms_since_19700101);
}
+
+
+ /**
+ * <p>Converts a {@link Date} into a filetime.</p>
+ *
+ * @param date The date to be converted
+ * @return The filetime
+ *
+ * @see #filetimeToDate
+ */
public static long dateToFileTime(final Date date)
{
long ms_since_19700101 = date.getTime();
@@ -228,6 +238,17 @@
return internalEquals(o1, o2);
}
+
+
+ /**
+ * <p>Compares to object arrays with regarding the objects' order. For
+ * example, [1, 2, 3] and [2, 1, 3] are equal.</p>
+ *
+ * @param c1 The first object array.
+ * @param c2 The second object array.
+ * @return <code>true</code> if the object arrays are equal,
+ * <code>false</code> if they are not.
+ */
public static boolean equals(final Object[] c1, final Object[] c2)
{
final Object[] o1 = (Object[]) c1.clone();
@@ -250,6 +271,70 @@
return false;
}
return true;
+ }
+
+
+
+ /**
+ * <p>Pads a byte array with 0x00 bytes so that its length is a multiple of
+ * 4.</p>
+ *
+ * @param ba The byte array to pad.
+ * @return The padded byte array.
+ */
+ public static byte[] pad4(final byte[] ba)
+ {
+ final int PAD = 4;
+ final byte[] result;
+ int l = ba.length % PAD;
+ if (l == 0)
+ result = ba;
+ else
+ {
+ l = PAD - l;
+ result = new byte[ba.length + l];
+ System.arraycopy(ba, 0, result, 0, ba.length);
+ }
+ return result;
+ }
+
+
+
+ /**
+ * <p>Pads a character array with 0x0000 characters so that its length is a
+ * multiple of 4.</p>
+ *
+ * @param ca The character array to pad.
+ * @return The padded character array.
+ */
+ public static char[] pad4(final char[] ca)
+ {
+ final int PAD = 4;
+ final char[] result;
+ int l = ca.length % PAD;
+ if (l == 0)
+ result = ca;
+ else
+ {
+ l = PAD - l;
+ result = new char[ca.length + l];
+ System.arraycopy(ca, 0, result, 0, ca.length);
+ }
+ return result;
+ }
+
+
+
+ /**
+ * <p>Pads a string with 0x0000 characters so that its length is a
+ * multiple of 4.</p>
+ *
+ * @param s The string to pad.
+ * @return The padded string as a character array.
+ */
+ public static char[] pad4(final String s)
+ {
+ return pad4(s.toCharArray());
}
}
1.9 +163 -48 jakarta-poi/src/java/org/apache/poi/hpsf/Variant.java
Index: Variant.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/Variant.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- Variant.java 23 Aug 2003 15:12:22 -0000 1.8
+++ Variant.java 30 Aug 2003 09:13:52 -0000 1.9
@@ -54,6 +54,7 @@
*/
package org.apache.poi.hpsf;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -357,79 +358,193 @@
public static final int VT_BYREF = 0x4000;
/**
- * <p>FIXME: Document this!</p>
+ * <p>FIXME (3): Document this!</p>
*/
public static final int VT_RESERVED = 0x8000;
/**
- * <p>FIXME: Document this!</p>
+ * <p>FIXME (3): Document this!</p>
*/
public static final int VT_ILLEGAL = 0xFFFF;
/**
- * <p>FIXME: Document this!</p>
+ * <p>FIXME (3): Document this!</p>
*/
public static final int VT_ILLEGALMASKED = 0xFFF;
/**
- * <p>FIXME: Document this!</p>
+ * <p>FIXME (3): Document this!</p>
*/
public static final int VT_TYPEMASK = 0xFFF;
- public static final Map m = new HashMap();
+ /**
+ * <p>Maps the numbers denoting the variant types to their corresponding
+ * variant type names.</p>
+ */
+ private static Map numberToName;
+
+ private static Map numberToLength;
+
+ /**
+ * <p>Denotes a variant type with a length that is unknown to HPSF yet.</p>
+ */
+ public static final Integer LENGTH_UNKNOWN = new Integer(-2);
+
+ /**
+ * <p>Denotes a variant type with a variable length.</p>
+ */
+ public static final Integer LENGTH_VARIABLE = new Integer(-1);
+
+ /**
+ * <p>Denotes a variant type with a length of 0 bytes.</p>
+ */
+ public static final Integer LENGTH_0 = new Integer(0);
+
+ /**
+ * <p>Denotes a variant type with a length of 2 bytes.</p>
+ */
+ public static final Integer LENGTH_2 = new Integer(2);
+
+ /**
+ * <p>Denotes a variant type with a length of 4 bytes.</p>
+ */
+ public static final Integer LENGTH_4 = new Integer(4);
+
+ /**
+ * <p>Denotes a variant type with a length of 8 bytes.</p>
+ */
+ public static final Integer LENGTH_8 = new Integer(8);
+
+
static
{
- m.put(new Integer(0), "VT_EMPTY");
- m.put(new Integer(1), "VT_NULL");
- m.put(new Integer(2), "VT_I2");
- m.put(new Integer(3), "VT_I4");
- m.put(new Integer(4), "VT_R4");
- m.put(new Integer(5), "VT_R8");
- m.put(new Integer(6), "VT_CY");
- m.put(new Integer(7), "VT_DATE");
- m.put(new Integer(8), "VT_BSTR");
- m.put(new Integer(9), "VT_DISPATCH");
- m.put(new Integer(10), "VT_ERROR");
- m.put(new Integer(11), "VT_BOOL");
- m.put(new Integer(12), "VT_VARIANT");
- m.put(new Integer(13), "VT_UNKNOWN");
- m.put(new Integer(14), "VT_DECIMAL");
- m.put(new Integer(16), "VT_I1");
- m.put(new Integer(17), "VT_UI1");
- m.put(new Integer(18), "VT_UI2");
- m.put(new Integer(19), "VT_UI4");
- m.put(new Integer(20), "VT_I8");
- m.put(new Integer(21), "VT_UI8");
- m.put(new Integer(22), "VT_INT");
- m.put(new Integer(23), "VT_UINT");
- m.put(new Integer(24), "VT_VOID");
- m.put(new Integer(25), "VT_HRESULT");
- m.put(new Integer(26), "VT_PTR");
- m.put(new Integer(27), "VT_SAFEARRAY");
- m.put(new Integer(28), "VT_CARRAY");
- m.put(new Integer(29), "VT_USERDEFINED");
- m.put(new Integer(30), "VT_LPSTR");
- m.put(new Integer(31), "VT_LPWSTR");
- m.put(new Integer(64), "VT_FILETIME");
- m.put(new Integer(65), "VT_BLOB");
- m.put(new Integer(66), "VT_STREAM");
- m.put(new Integer(67), "VT_STORAGE");
- m.put(new Integer(68), "VT_STREAMED_OBJECT");
- m.put(new Integer(69), "VT_STORED_OBJECT");
- m.put(new Integer(70), "VT_BLOB_OBJECT");
- m.put(new Integer(71), "VT_CF");
- m.put(new Integer(72), "VT_CLSID");
+ /* Initialize the number-to-name map: */
+ Map tm1 = new HashMap();
+ tm1.put(new Long(0), "VT_EMPTY");
+ tm1.put(new Long(1), "VT_NULL");
+ tm1.put(new Long(2), "VT_I2");
+ tm1.put(new Long(3), "VT_I4");
+ tm1.put(new Long(4), "VT_R4");
+ tm1.put(new Long(5), "VT_R8");
+ tm1.put(new Long(6), "VT_CY");
+ tm1.put(new Long(7), "VT_DATE");
+ tm1.put(new Long(8), "VT_BSTR");
+ tm1.put(new Long(9), "VT_DISPATCH");
+ tm1.put(new Long(10), "VT_ERROR");
+ tm1.put(new Long(11), "VT_BOOL");
+ tm1.put(new Long(12), "VT_VARIANT");
+ tm1.put(new Long(13), "VT_UNKNOWN");
+ tm1.put(new Long(14), "VT_DECIMAL");
+ tm1.put(new Long(16), "VT_I1");
+ tm1.put(new Long(17), "VT_UI1");
+ tm1.put(new Long(18), "VT_UI2");
+ tm1.put(new Long(19), "VT_UI4");
+ tm1.put(new Long(20), "VT_I8");
+ tm1.put(new Long(21), "VT_UI8");
+ tm1.put(new Long(22), "VT_INT");
+ tm1.put(new Long(23), "VT_UINT");
+ tm1.put(new Long(24), "VT_VOID");
+ tm1.put(new Long(25), "VT_HRESULT");
+ tm1.put(new Long(26), "VT_PTR");
+ tm1.put(new Long(27), "VT_SAFEARRAY");
+ tm1.put(new Long(28), "VT_CARRAY");
+ tm1.put(new Long(29), "VT_USERDEFINED");
+ tm1.put(new Long(30), "VT_LPSTR");
+ tm1.put(new Long(31), "VT_LPWSTR");
+ tm1.put(new Long(64), "VT_FILETIME");
+ tm1.put(new Long(65), "VT_BLOB");
+ tm1.put(new Long(66), "VT_STREAM");
+ tm1.put(new Long(67), "VT_STORAGE");
+ tm1.put(new Long(68), "VT_STREAMED_OBJECT");
+ tm1.put(new Long(69), "VT_STORED_OBJECT");
+ tm1.put(new Long(70), "VT_BLOB_OBJECT");
+ tm1.put(new Long(71), "VT_CF");
+ tm1.put(new Long(72), "VT_CLSID");
+ Map tm2 = new HashMap(tm1.size(), 1.0F);
+ tm2.putAll(tm1);
+ numberToName = Collections.unmodifiableMap(tm2);
+
+ /* Initialize the number-to-length map: */
+ tm1.clear();
+ tm1.put(new Long(0), LENGTH_0);
+ tm1.put(new Long(1), LENGTH_UNKNOWN);
+ tm1.put(new Long(2), LENGTH_2);
+ tm1.put(new Long(3), LENGTH_4);
+ tm1.put(new Long(4), LENGTH_4);
+ tm1.put(new Long(5), LENGTH_8);
+ tm1.put(new Long(6), LENGTH_UNKNOWN);
+ tm1.put(new Long(7), LENGTH_UNKNOWN);
+ tm1.put(new Long(8), LENGTH_UNKNOWN);
+ tm1.put(new Long(9), LENGTH_UNKNOWN);
+ tm1.put(new Long(10), LENGTH_UNKNOWN);
+ tm1.put(new Long(11), LENGTH_UNKNOWN);
+ tm1.put(new Long(12), LENGTH_UNKNOWN);
+ tm1.put(new Long(13), LENGTH_UNKNOWN);
+ tm1.put(new Long(14), LENGTH_UNKNOWN);
+ tm1.put(new Long(16), LENGTH_UNKNOWN);
+ tm1.put(new Long(17), LENGTH_UNKNOWN);
+ tm1.put(new Long(18), LENGTH_UNKNOWN);
+ tm1.put(new Long(19), LENGTH_UNKNOWN);
+ tm1.put(new Long(20), LENGTH_UNKNOWN);
+ tm1.put(new Long(21), LENGTH_UNKNOWN);
+ tm1.put(new Long(22), LENGTH_UNKNOWN);
+ tm1.put(new Long(23), LENGTH_UNKNOWN);
+ tm1.put(new Long(24), LENGTH_UNKNOWN);
+ tm1.put(new Long(25), LENGTH_UNKNOWN);
+ tm1.put(new Long(26), LENGTH_UNKNOWN);
+ tm1.put(new Long(27), LENGTH_UNKNOWN);
+ tm1.put(new Long(28), LENGTH_UNKNOWN);
+ tm1.put(new Long(29), LENGTH_UNKNOWN);
+ tm1.put(new Long(30), LENGTH_VARIABLE);
+ tm1.put(new Long(31), LENGTH_UNKNOWN);
+ tm1.put(new Long(64), LENGTH_8);
+ tm1.put(new Long(65), LENGTH_UNKNOWN);
+ tm1.put(new Long(66), LENGTH_UNKNOWN);
+ tm1.put(new Long(67), LENGTH_UNKNOWN);
+ tm1.put(new Long(68), LENGTH_UNKNOWN);
+ tm1.put(new Long(69), LENGTH_UNKNOWN);
+ tm1.put(new Long(70), LENGTH_UNKNOWN);
+ tm1.put(new Long(71), LENGTH_UNKNOWN);
+ tm1.put(new Long(72), LENGTH_UNKNOWN);
+ tm2 = new HashMap(tm1.size(), 1.0F);
+ tm2.putAll(tm1);
+ numberToLength = Collections.unmodifiableMap(tm2);
}
+ /**
+ * <p>Returns the variant type name associated with a variant type
+ * number.</p>
+ *
+ * @param variantType The variant type number
+ * @return The variant type name or the string "unknown variant type"
+ */
public static String getVariantName(final long variantType)
{
- String name = (String) m.get(new Integer((int) variantType));
+ final String name = (String) numberToName.get(new Long(variantType));
return name != null ? name : "unknown variant type";
}
-}
\ No newline at end of file
+ /**
+ * <p>Returns a variant type's length.</p>
+ *
+ * @param variantType The variant type number
+ * @return The length of the variant type's data in bytes. If the length is
+ * variable, i.e. the length of a string, -1 is returned. If HPSF does not
+ * know the length, -2 is returned. The latter usually indicates an
+ * unsupported variant type.
+ */
+ public static int getVariantLength(final long variantType)
+ {
+ final Long key = new Long((int) variantType);
+ final Long length = (Long) numberToLength.get(key);
+ if (length == null)
+ return -2;
+ return length.intValue();
+ }
+
+}
1.2 +126 -65 jakarta-poi/src/java/org/apache/poi/hpsf/VariantSupport.java
Index: VariantSupport.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/VariantSupport.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- VariantSupport.java 23 Aug 2003 15:12:22 -0000 1.1
+++ VariantSupport.java 30 Aug 2003 09:13:52 -0000 1.2
@@ -65,6 +65,8 @@
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;
@@ -72,8 +74,8 @@
/**
* <p>Supports reading and writing of variant data.</p>
*
- * <p><strong>FIXME:</strong> Reading and writing must be made more uniform than
- * it is now. The following items should be resolved:
+ * <p><strong>FIXME (3):</strong> Reading and writing should be made more
+ * uniform than it is now. The following items should be resolved:
*
* <ul>
*
@@ -87,14 +89,73 @@
*
* @author Rainer Klute <a
* href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
- * @since 08.08.2003
+ * @since 2003-08-08
* @version $Id$
*/
public class VariantSupport extends Variant
{
+ private static boolean logUnsupportedTypes = false;
+
+ /**
+ * <p>Specifies whether warnings about unsupported variant types are to be
+ * written to <code>System.err</code> or not.</p>
+ *
+ * @param logUnsupportedTypes If <code>true</code> warnings will be written,
+ * if <code>false</code> they won't.
+ */
+ public static void setLogUnsupportedTypes(final boolean logUnsupportedTypes)
+ {
+ VariantSupport.logUnsupportedTypes = logUnsupportedTypes;
+ }
+
/**
- * <p>Reads a variant data type from a byte array.</p>
+ * <p>Checks whether logging of unsupported variant types warning is turned
+ * on or off.</p>
+ *
+ * @return <code>true</code> if logging is turned on, else
+ * <code>false</code>.
+ */
+ public static boolean isLogUnsupportedTypes()
+ {
+ return logUnsupportedTypes;
+ }
+
+
+
+ /**
+ * <p>Keeps a list of the variant types an "unsupported" message has already
+ * been issued for.</p>
+ */
+ protected static List unsupportedMessage;
+
+ /**
+ * <p>Writes a warning to <code>System.err</code> that a variant type is
+ * unsupported by HPSF. Such a warning is written only once for each variant
+ * type. Log messages can be turned on or off by </p>
+ *
+ * @param ex The exception to log
+ */
+ protected static void writeUnsupportedTypeMessage
+ (final UnsupportedVariantTypeException ex)
+ {
+ if (isLogUnsupportedTypes())
+ {
+ if (unsupportedMessage == null)
+ unsupportedMessage = new LinkedList();
+ Long vt = new Long(ex.getVariantType());
+ if (!unsupportedMessage.contains(vt))
+ {
+ System.err.println(ex.getMessage());
+ unsupportedMessage.add(vt);
+ }
+ }
+ }
+
+
+
+ /**
+ * <p>Reads a variant type from a byte array.</p>
*
* @param src The byte array
* @param offset The offset in the byte array where the variant
@@ -105,8 +166,8 @@
* @return A Java object that corresponds best to the variant
* field. For example, a VT_I4 is returned as a {@link Long}, a
* VT_LPSTR as a {@link String}.
- * @exception UnsupportedVariantTypeException if HPSF does not (yet)
- * support the variant type which is to be read
+ * @exception ReadingNotSupportedException if a property is to be written
+ * who's variant type HPSF does not yet support
*
* @see Variant
*/
@@ -161,7 +222,7 @@
* String object. The 0x00 bytes at the end must be
* stripped.
*
- * FIXME: Reading an 8-bit string should pay attention
+ * FIXME (2): Reading an 8-bit string should pay attention
* to the codepage. Currently the byte making out the
* property's value are interpreted according to the
* platform's default character set.
@@ -238,51 +299,57 @@
/**
- * <p>Writes a variant value to an output stream.</p>
+ * <p>Writes a variant value to an output stream. This method ensures that
+ * always a multiple of 4 bytes is written.</p>
*
* @param out The stream to write the value to.
* @param type The variant's type.
* @param value The variant's value.
* @return The number of entities that have been written. In many cases an
* "entity" is a byte but this is not always the case.
+ * @exception IOException if an I/O exceptions occurs
+ * @exception WritingNotSupportedException if a property is to be written
+ * who's variant type HPSF does not yet support
*/
public static int write(final OutputStream out, final long type,
- final Object value)
+ final Object value)
throws IOException, WritingNotSupportedException
{
+ int length = 0;
switch ((int) type)
{
case Variant.VT_BOOL:
{
int trueOrFalse;
- int length = 0;
if (((Boolean) value).booleanValue())
trueOrFalse = 1;
else
trueOrFalse = 0;
- length += TypeWriter.writeUIntToStream(out, trueOrFalse);
- return length;
+ length = TypeWriter.writeUIntToStream(out, trueOrFalse);
+ break;
}
case Variant.VT_LPSTR:
{
- TypeWriter.writeUIntToStream
+ length = TypeWriter.writeUIntToStream
(out, ((String) value).length() + 1);
- char[] s = toPaddedCharArray((String) value);
- /* FIXME: The following line forces characters to bytes. This
- * is generally wrong and should only be done according to a
- * codepage. Alternatively Unicode could be written (see
+ char[] s = Util.pad4((String) value);
+ /* FIXME (2): The following line forces characters to bytes.
+ * This is generally wrong and should only be done according to
+ * a codepage. Alternatively Unicode could be written (see
* Variant.VT_LPWSTR). */
- byte[] b = new byte[s.length];
+ byte[] b = new byte[s.length + 1];
for (int i = 0; i < s.length; i++)
b[i] = (byte) s[i];
+ b[b.length - 1] = 0x00;
out.write(b);
- return b.length;
+ length += b.length;
+ break;
}
case Variant.VT_LPWSTR:
{
final int nrOfChars = ((String) value).length() + 1;
TypeWriter.writeUIntToStream(out, nrOfChars);
- char[] s = toPaddedCharArray((String) value);
+ char[] s = Util.pad4((String) value);
for (int i = 0; i < s.length; i++)
{
final int high = (int) ((s[i] & 0xff00) >> 8);
@@ -292,79 +359,73 @@
out.write(lowb);
out.write(highb);
}
- return nrOfChars * 2;
+ length = nrOfChars * 2;
+ out.write(0x00);
+ out.write(0x00);
+ length += 2;
+ break;
}
case Variant.VT_CF:
{
final byte[] b = (byte[]) value;
out.write(b);
- return b.length;
+ length = b.length;
+ break;
}
case Variant.VT_EMPTY:
{
TypeWriter.writeUIntToStream(out, Variant.VT_EMPTY);
- return LittleEndianConsts.INT_SIZE;
+ length = LittleEndianConsts.INT_SIZE;
+ break;
}
case Variant.VT_I2:
{
TypeWriter.writeToStream(out, ((Integer) value).shortValue());
- return LittleEndianConsts.SHORT_SIZE;
+ length = LittleEndianConsts.SHORT_SIZE;
+ break;
}
case Variant.VT_I4:
{
TypeWriter.writeToStream(out, ((Long) value).intValue());
- return LittleEndianConsts.INT_SIZE;
+ length = LittleEndianConsts.INT_SIZE;
+ break;
}
case Variant.VT_FILETIME:
{
- int length = 0;
long filetime = Util.dateToFileTime((Date) value);
int high = (int) ((filetime >> 32) & 0xFFFFFFFFL);
int low = (int) (filetime & 0x00000000FFFFFFFFL);
- length += TypeWriter.writeUIntToStream(out, 0x0000000FFFFFFFFL & low);
- length += TypeWriter.writeUIntToStream(out, 0x0000000FFFFFFFFL & high);
- return length;
+ length += TypeWriter.writeUIntToStream
+ (out, 0x0000000FFFFFFFFL & low);
+ length += TypeWriter.writeUIntToStream
+ (out, 0x0000000FFFFFFFFL & high);
+ break;
}
default:
{
- throw new WritingNotSupportedException(type, value);
- }
+ /* The variant type is not supported yet. However, if the value
+ * is a byte array we can write it nevertheless. */
+ if (value instanceof byte[])
+ {
+ final byte[] b = (byte[]) value;
+ out.write(b);
+ length = b.length;
+ writeUnsupportedTypeMessage
+ (new WritingNotSupportedException(type, value));
+ }
+ else
+ throw new WritingNotSupportedException(type, value);
+ break;
+ }
}
- }
-
-
-
- /**
- * <p>Converts a string into a 0x00-terminated character sequence padded
- * with 0x00 bytes to a multiple of 4.</p>
- *
- * @param value The string to convert
- * @return The padded character array
- */
- private static char[] toPaddedCharArray(final String s)
- {
- final int PADDING = 4;
- int dl = s.length() + 1;
- final int r = dl % 4;
- if (r > 0)
- dl += PADDING - r;
- char[] buffer = new char[dl];
- s.getChars(0, s.length(), buffer, 0);
- for (int i = s.length(); i < dl; i++)
- buffer[i] = (char) 0;
- return buffer;
- }
-
-
- public static int getLength(final long variantType, final int lengthInBytes)
- {
- switch ((int) variantType)
+ /* Add 0x00 character to write a multiple of four bytes: */
+ while (length % 4 != 0)
{
- case VT_LPWSTR:
- return lengthInBytes / 2;
- default:
- return lengthInBytes;
+ out.write(0);
+ length++;
}
+ return length;
}
+
}
1.3 +8 -4 jakarta-poi/src/java/org/apache/poi/hpsf/WritingNotSupportedException.java
Index: WritingNotSupportedException.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/WritingNotSupportedException.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- WritingNotSupportedException.java 25 Aug 2003 19:46:00 -0000 1.2
+++ WritingNotSupportedException.java 30 Aug 2003 09:13:52 -0000 1.3
@@ -65,6 +65,9 @@
/**
* <p>This exception is thrown when trying to write a (yet) unsupported variant
* type.</p>
+ *
+ * @see ReadingNotSupportedException
+ * @see UnsupportedVariantTypeException
*
* @author Rainer Klute <a
* href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
@@ -78,10 +81,11 @@
/**
* <p>Constructor</p>
*
- * @param variantType
- * @param value
+ * @param variantType The unsupported varian type.
+ * @param value The value.
*/
- public WritingNotSupportedException(long variantType, Object value)
+ public WritingNotSupportedException(final long variantType,
+ final Object value)
{
super(variantType, value);
}
1.1 jakarta-poi/src/java/org/apache/poi/hpsf/MutableProperty.java
Index: MutableProperty.java
===================================================================
package org.apache.poi.hpsf;
import java.io.IOException;
import java.io.OutputStream;
/**
* <p>Adds writing capability to the {@link Property} class.</p>
*
* <p>Please be aware that this class' functionality will be merged into the
* {@link Property} class at a later time, so the API will change.</p>
*
* @author Rainer Klute <a
* href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @since 2003-08-03
* @version $Id: MutableProperty.java,v 1.1 2003/08/30 09:13:52 klute Exp $
*/
public class MutableProperty extends Property
{
/**
* <p>Creates an empty property. It must be filled using the set method to
* be usable.</p>
*/
public MutableProperty()
{ }
/**
* <p>Sets the property's ID.</p>
*
* @param id the ID
*/
public void setID(final long id)
{
this.id = id;
}
/**
* <p>Sets the property's type.</p>
*
* @param type the property's type
*/
public void setType(final long type)
{
this.type = type;
}
/**
* <p>Sets the property's value.</p>
*
* @param value the property's value
*/
public void setValue(final Object value)
{
this.value = value;
}
/**
* <p>Writes the property to an output stream.</p>
*
* @param out The output stream to write to.
* @return the number of bytes written to the stream
*
* @exception IOException if an I/O error occurs
* @exception WritingNotSupportedException if a variant type is to be
* written that is not yet supported
*/
public int write(final OutputStream out)
throws IOException, WritingNotSupportedException
{
int length = 0;
long variantType = getType();
length += TypeWriter.writeUIntToStream(out, variantType);
length += VariantSupport.write(out, variantType, getValue());
return length;
}
}
1.1 jakarta-poi/src/java/org/apache/poi/hpsf/MutablePropertySet.java
Index: MutablePropertySet.java
===================================================================
/*
* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.poi.hpsf;
import java.io.IOException;
import java.io.OutputStream;
import java.util.LinkedList;
import java.util.ListIterator;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;
/**
* <p>Adds writing support to the {@link PropertySet} class.</p>
*
* <p>Please be aware that this class' functionality will be merged into the
* {@link PropertySet} class at a later time, so the API will change.</p>
*
* @author Rainer Klute <a
* href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @version $Id: MutablePropertySet.java,v 1.1 2003/08/30 09:13:52 klute Exp $
* @since 2003-02-19
*/
public class MutablePropertySet extends PropertySet
{
/**
* <p>Constructs a <code>MutablePropertySet</code> instance. Its
* primary task is to initialize the immutable field with their proper
* values. It also sets fields that might change to reasonable defaults.</p>
*/
public MutablePropertySet()
{
/* Initialize the "byteOrder" field. */
byteOrder = LittleEndian.getUShort(BYTE_ORDER_ASSERTION);
/* Initialize the "format" field. */
format = LittleEndian.getUShort(FORMAT_ASSERTION);
/* Initialize "osVersion" field as if the property has been created on
* a Win32 platform, whether this is the case or not. */
osVersion = (OS_WIN32 << 16) | 0x0A04;
/* Initailize the "classID" field. */
classID = new ClassID();
/* Initialize the sections. Since property set must have at least
* one section it is added right here. */
sections = new LinkedList();
sections.add(new MutableSection());
}
/**
* <p>The length of the property set stream header.</p>
*/
private final int OFFSET_HEADER =
BYTE_ORDER_ASSERTION.length + /* Byte order */
FORMAT_ASSERTION.length + /* Format */
LittleEndianConsts.INT_SIZE + /* OS version */
ClassID.LENGTH + /* Class ID */
LittleEndianConsts.INT_SIZE; /* Section count */
/**
* <p>Sets the "byteOrder" property.</p>
*
* @param byteOrder the byteOrder value to set
*/
public void setByteOrder(final int byteOrder)
{
this.byteOrder = byteOrder;
}
/**
* <p>Sets the "format" property.</p>
*
* @param format the format value to set
*/
public void setFormat(final int format)
{
this.format = format;
}
/**
* <p>Sets the "osVersion" property.</p>
*
* @param osVersion the osVersion value to set
*/
public void setOSVersion(final int osVersion)
{
this.osVersion = osVersion;
}
/**
* <p>Sets the property set stream's low-level "class ID"
* field.</p>
*
* @param classID The property set stream's low-level "class ID" field.
*
* @see #getClassID
*/
public void setClassID(final ClassID classID)
{
this.classID = classID;
}
/**
* <p>Removes all sections from this property set.</p>
*/
public void clearSections()
{
sections = null;
}
/**
* <p>Adds a section to this property set.</p>
*
* @param section The {@link Section} to add. It will be appended
* after any sections that are already present in the property set
* and thus become the last section.
*/
public void addSection(final Section section)
{
if (sections == null)
sections = new LinkedList();
sections.add(section);
}
/**
* <p>Writes the property set to an output stream.</p>
*
* @param out the output stream to write the section to
* @exception IOException if an error when writing to the output stream
* occurs
* @exception WritingNotSupportedException if HPSF does not yet support
* writing a property's variant type.
*/
public void write(final OutputStream out)
throws WritingNotSupportedException, IOException
{
/* Write the number of sections in this property set stream. */
final int nrSections = sections.size();
int length = 0;
/* Write the property set's header. */
length += TypeWriter.writeToStream(out, (short) getByteOrder());
length += TypeWriter.writeToStream(out, (short) getFormat());
length += TypeWriter.writeToStream(out, (int) getOSVersion());
length += TypeWriter.writeToStream(out, getClassID());
length += TypeWriter.writeToStream(out, (int) nrSections);
int offset = OFFSET_HEADER;
/* Write the section list, i.e. the references to the sections. Each
* entry in the section list consist of a class ID and the offset to the
* section's begin. */
offset += nrSections * (ClassID.LENGTH + LittleEndian.INT_SIZE);
final int sectionsBegin = offset;
for (final ListIterator i = sections.listIterator(); i.hasNext();)
{
final MutableSection s = (MutableSection) i.next();
length += TypeWriter.writeToStream(out, s.getFormatID());
length += TypeWriter.writeUIntToStream(out, offset);
offset += s.getSize();
}
/* Write the sections themselves. */
offset = sectionsBegin;
for (final ListIterator i = sections.listIterator(); i.hasNext();)
{
final MutableSection s = (MutableSection) i.next();
offset = s.write(out, offset);
}
}
}
1.1 jakarta-poi/src/java/org/apache/poi/hpsf/MutableSection.java
Index: MutableSection.java
===================================================================
/*
* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.poi.hpsf;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;
/**
* <p>Adds writing capability to the {@link Section} class.</p>
*
* <p>Please be aware that this class' functionality will be merged into the
* {@link Section} class at a later time, so the API will change.</p>
*
* @author Rainer Klute <a
* href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
* @version $Id: MutableSection.java,v 1.1 2003/08/30 09:13:52 klute Exp $
* @since 2002-02-20
*/
public class MutableSection extends Section
{
/**
* <p>If the "dirty" flag is true, the section's size must be
* (re-)calculated before the section is written.</p>
*/
private boolean dirty = true;
/**
* <p>List to assemble the properties. Unfortunately a wrong
* decision has been taken when specifying the "properties" field
* as an Property[]. It should have been a {@link java.util.List}.</p>
*/
private List preprops;
/**
* <p>Creates an empty mutable section.</p>
*/
public MutableSection()
{
dirty = true;
formatID = null;
offset = -1;
preprops = new LinkedList();
}
/**
* <p>Sets the section's format ID.</p>
*
* @param formatID The section's format ID
*
* @see #setFormatID(byte[])
* @see #getFormatID
*/
public void setFormatID(final ClassID formatID)
{
this.formatID = formatID;
}
/**
* <p>Sets the section's format ID.</p>
*
* @param formatID The section's format ID as a byte array. It components
* are in big-endian format.
*
* @see #setFormatID(ClassID)
* @see #getFormatID
*/
public void setFormatID(final byte[] formatID)
{
setFormatID(new ClassID(formatID, 0));
}
/**
* <p>Sets this section's properties. Any former values are overwritten.</p>
*
* @param properties This section's new properties.
*/
public void setProperties(final Property[] properties)
{
preprops = new LinkedList();
for (int i = 0; i < properties.length; i++)
preprops.add(properties[i]);
dirty = true;
}
/**
* <p>Sets the value of the property with the specified ID. If a
* property with this ID is not yet present in the section, it
* will be added. An already present property with the specified
* ID will be overwritten.</p>
*
* @param id The property's ID
* @param value The property's value. It will be written as a Unicode
* string.
*
* @see #setProperty(int, int, Object)
* @see #getProperty
*/
public void setProperty(final int id, final String value)
{
setProperty(id, Variant.VT_LPWSTR, value);
dirty = true;
}
/**
* <p>Sets the value and the variant type of the property with the
* specified ID. If a property with this ID is not yet present in
* the section, it will be added. An already present property with
* the specified ID will be overwritten. A default mapping will be
* used to choose the property's type.</p>
*
* @param id The property's ID.
* @param variantType The property's variant type.
* @param value The property's value.
*
* @see #setProperty(int, Object)
* @see #getProperty
* @see Variant
*/
public void setProperty(final int id, final long variantType,
final Object value)
{
final MutableProperty p = new MutableProperty();
p.setID(id);
p.setType(variantType);
p.setValue(value);
setProperty(p);
dirty = true;
}
/**
* <p>Sets a property. If a property with the same ID is not yet present in
* the section, the property will be added to the section. If there is
* already a property with the same ID present in the section, it will be
* overwritten.</p>
*
* @param p The property to be added to the section
*
* @see #setProperty(int, int, Object)
* @see #setProperty(int, String)
* @see #getProperty
* @see Variant
*/
public void setProperty(final Property p)
{
final long id = p.getID();
for (final Iterator i = preprops.iterator(); i.hasNext();)
if (((Property) i.next()).getID() == id)
{
i.remove();
break;
}
preprops.add(p);
dirty = true;
}
/**
* <p>Sets the value of the boolean property with the specified
* ID.</p>
*
* @param id The property's ID
* @param value The property's value
*
* @see #setProperty(int, int, Object)
* @see #getProperty
* @see Variant
*/
protected void setPropertyBooleanValue(final int id, final boolean value)
{
setProperty(id, (long) Variant.VT_BOOL, new Boolean(value));
}
/**
* <p>Returns the section's size.</p>
*
* @return the section's size.
*/
public int getSize()
{
if (dirty)
{
size = calcSize();
dirty = false;
}
return size;
}
/**
* <p>Calculates the section's size. It is the sum of the lengths of the
* section's header (8), the properties list (16 times the number of
* properties) and the properties themselves.</p>
*
* @return the section's length in bytes.
*/
private int calcSize()
{
int length = 0;
/* The section header. */
length += LittleEndianConsts.INT_SIZE * 2;
/* The length of the property list. */
Property[] psa = getProperties();
if (psa == null)
psa = new MutableProperty[0];
length += psa.length * LittleEndianConsts.INT_SIZE * 3;
/* The sum of the lengths of the properties - it is calculated by simply
* writing the properties to a temporary byte array output stream: */
final ByteArrayOutputStream b = new ByteArrayOutputStream();
for (int i = 0; i < psa.length; i++)
{
final MutableProperty mp = new MutableProperty();
mp.setID(psa[i].getID());
mp.setType(psa[i].getType());
mp.setValue(psa[i].getValue());
try
{
length += mp.write(b);
}
catch (WritingNotSupportedException ex)
{
/* It was not possible to write the property, not even as a
* byte array. We cannot do anything about that. Instead of the
* property we insert an empty one into the stream. */
mp.setType(Variant.VT_EMPTY);
mp.setValue(null);
try
{
length += mp.write(b);
}
catch (Exception ex2)
{
/* Even writing an empty property went awfully wrong.
* Let's give up. */
throw new HPSFRuntimeException(ex2);
}
}
catch (IOException ex)
{
/* Should never occur. */
throw new HPSFRuntimeException(ex);
}
}
return length;
}
/**
* <p>Writes this section into an output stream.</p>
*
* <p>Internally this is done by writing into three byte array output
* streams: one for the properties, one for the property list and one for
* the section as such. The two former are appended to the latter when they
* have received all their data.</p>
*
* @param out The stream to write into
* @param offset The offset from the beginning of the property set
* stream this section begins at
*
* @return The offset of the first byte following this section in
* the property set stream.
* @exception IOException if an I/O error occurs
* @exception WritingNotSupportedException if HPSF does not yet support
* writing a property's variant type.
*/
public int write(final OutputStream out, final int offset)
throws WritingNotSupportedException, IOException
{
/* The properties are written to this stream. */
final ByteArrayOutputStream propertyStream =
new ByteArrayOutputStream();
/* The property list is established here. After each property that has
* been written to "propertyStream", a property list entry is written to
* "propertyListStream". */
final ByteArrayOutputStream propertyListStream =
new ByteArrayOutputStream();
/* Maintain the current position in the list. */
int position = 0;
/* Increase the position variable by the size of the property list so
* that it points to the beginning of the properties themselves. */
position += 2 * LittleEndian.INT_SIZE +
getPropertyCount() * 2 * LittleEndian.INT_SIZE;
/* Write the properties and the property list into their respective
* streams: */
for (final Iterator i = preprops.iterator(); i.hasNext();)
{
final MutableProperty p = (MutableProperty) i.next();
/* Write the property list entry. */
TypeWriter.writeUIntToStream(propertyListStream, p.getID());
TypeWriter.writeUIntToStream(propertyListStream, position);
/* Write the property and update the position to the next
* property. */
position += p.write(propertyStream);
}
propertyStream.close();
propertyListStream.close();
/* Write the section: */
byte[] pb1 = propertyListStream.toByteArray();
byte[] pb2 = propertyStream.toByteArray();
TypeWriter.writeToStream(out, LittleEndian.INT_SIZE * 2 + pb1.length +
pb2.length);
TypeWriter.writeToStream(out, getPropertyCount());
out.write(pb1);
out.write(pb2);
return offset + position;
}
/**
* <p>Overwrites the super class' method to cope with a redundancy:
* the property count is maintained in a separate member variable, but
* shouldn't.</p>
*
* @return The number of properties in this section
*/
public int getPropertyCount()
{
return preprops.size();
}
/**
* <p>Returns this section's properties.</p>
*
* @return this section's properties.
*/
public Property[] getProperties()
{
return (Property[]) preprops.toArray(new Property[0]);
}
}
1.9 +4 -4 jakarta-poi/src/java/org/apache/poi/hpsf/wellknown/PropertyIDMap.java
Index: PropertyIDMap.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hpsf/wellknown/PropertyIDMap.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- PropertyIDMap.java 2 Aug 2003 19:02:28 -0000 1.8
+++ PropertyIDMap.java 30 Aug 2003 09:13:53 -0000 1.9
@@ -66,9 +66,9 @@
* should treat them as unmodifiable, copy them and modifiy the
* copies.</p>
*
- * <p><strong>FIXME:</strong> Make the singletons unmodifiable. However,
+ * <p><strong>FIXME (3):</strong> Make the singletons unmodifiable. However,
* since this requires to use a {@link HashMap} delegate instead of
- * extending {@link HashMap} and thus requires a lot of stupid typing. I won't
+ * extending {@link HashMap} and thus requires a lot of stupid typing, I won't
* do that for the time being.</p>
*
* @author Rainer Klute (klute@rainer-klute.de)
@@ -141,7 +141,7 @@
* document</p> */
public static final int PID_APPNAME = 18;
- /** <p>ID of the property that denotes... FIXME</p> */
+ /** <p>ID of the property that denotes... FIXME (2)</p> */
public static final int PID_SECURITY = 19;
---------------------------------------------------------------------
To unsubscribe, e-mail: poi-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: poi-dev-help@jakarta.apache.org