]> source.dussan.org Git - poi.git/commitdiff
- A section's size is a multiple of 4 now. The Windows explorer seems to be constrain...
authorRainer Klute <klute@apache.org>
Tue, 31 Aug 2004 20:47:09 +0000 (20:47 +0000)
committerRainer Klute <klute@apache.org>
Tue, 31 Aug 2004 20:47:09 +0000 (20:47 +0000)
- Custom properties may be written in character encodings different from Unicode.

git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353596 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hpsf/MutablePropertySet.java
src/java/org/apache/poi/hpsf/MutableSection.java

index 05e96e6680186d3d633dc9eadfbeacd513b6df1b..d1dccf29495d095fed71cb2bc1ab9c2acf42895e 100644 (file)
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Copyright 2002-2004   Apache Software Foundation
 
@@ -22,6 +21,7 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.ListIterator;
@@ -223,7 +223,18 @@ public class MutablePropertySet extends PropertySet
                 throw new NoFormatIDException();
             length += TypeWriter.writeToStream(out, s.getFormatID());
             length += TypeWriter.writeUIntToStream(out, offset);
-            offset += s.getSize();
+            try
+            {
+                offset += s.getSize();
+            }
+            catch (HPSFRuntimeException ex)
+            {
+                final Throwable cause = ex.getReason();
+                if (cause instanceof UnsupportedEncodingException)
+                    throw new IllegalPropertySetDataException(cause);
+                else
+                    throw ex;
+            }
         }
 
         /* Write the sections themselves. */
index f457631a14f23e743b97275cf6c4b50eaf4b0e99..7fe040e78e3616846174f0c712952d3aa15e6012 100644 (file)
@@ -302,7 +302,9 @@ public class MutableSection extends Section
         final ByteArrayOutputStream out = new ByteArrayOutputStream();
         write(out);
         out.close();
-        sectionBytes = out.toByteArray();
+        /* Pad to multiple of 4 bytes so that even the Windows shell (explorer)
+         * shows custom properties. */
+        sectionBytes = Util.pad4(out.toByteArray());
         return sectionBytes.length;
     }
 
@@ -356,6 +358,7 @@ public class MutableSection extends Section
         /* Writing the section's dictionary it tricky. If there is a dictionary
          * (property 0) the codepage property (property 1) has to be set, too.
          * Since HPSF supports Unicode only, the codepage must be 1200. */
+        int codepage = -1;
         if (getProperty(PropertyIDMap.PID_DICTIONARY) != null)
         {
             final Object p1 = getProperty(PropertyIDMap.PID_CODEPAGE);
@@ -365,14 +368,12 @@ public class MutableSection extends Section
                     throw new IllegalPropertySetDataException
                         ("The codepage property (ID = 1) must be an " +
                          "Integer object.");
-                else if (((Integer) p1).intValue() != Constants.CP_UNICODE)
-                    throw new IllegalPropertySetDataException
-                        ("The codepage property (ID = 1) must be " +
-                         "1200 (Unicode).");
             }
             else
                 throw new IllegalPropertySetDataException
-                    ("The codepage property (ID = 1) must be set.");
+                    ("The codepage property (ID = 1) must be set if the " +
+                     "section contains a dictionary.");
+            codepage = getCodepage();
         }
 
         /* Sort the property list by their property IDs: */
@@ -412,11 +413,11 @@ public class MutableSection extends Section
                 position += p.write(propertyStream, getCodepage());
             else
             {
-                final int codepage = getCodepage();
                 if (codepage == -1)
                     throw new IllegalPropertySetDataException
                         ("Codepage (property 1) is undefined.");
-                position += writeDictionary(propertyStream, dictionary);
+                position += writeDictionary(propertyStream, dictionary,
+                                            codepage);
             }
         }
         propertyStream.close();
@@ -450,40 +451,61 @@ public class MutableSection extends Section
      *
      * @param out The output stream to write to.
      * @param dictionary The dictionary.
+     * @param codepage The codepage to be used to write the dictionary items.
      * @return The number of bytes written
      * @exception IOException if an I/O exception occurs.
      */
     private static int writeDictionary(final OutputStream out,
-                                       final Map dictionary)
+                                       final Map dictionary, final int codepage)
         throws IOException
     {
-        int length = 0;
-        length += TypeWriter.writeUIntToStream(out, dictionary.size());
+        int length = TypeWriter.writeUIntToStream(out, dictionary.size());
         for (final Iterator i = dictionary.keySet().iterator(); i.hasNext();)
         {
             final Long key = (Long) i.next();
             final String value = (String) dictionary.get(key);
-            int sLength = value.length() + 1;
-            if (sLength % 2 == 1)
-                sLength++;
-            length += TypeWriter.writeUIntToStream(out, key.longValue());
-            length += TypeWriter.writeUIntToStream(out, sLength);
-            final char[] ca = value.toCharArray();
-            for (int j = 0; j < ca.length; j++)
+
+            if (codepage == Constants.CP_UNICODE)
             {
-                int high = (ca[j] & 0x0ff00) >> 8;
-                int low  = (ca[j] & 0x000ff);
-                out.write(low);
-                out.write(high);
-                length += 2;
-                sLength--;
+                /* Write the dictionary item in Unicode. */
+                int sLength = value.length() + 1;
+                if (sLength % 2 == 1)
+                    sLength++;
+                length += TypeWriter.writeUIntToStream(out, key.longValue());
+                length += TypeWriter.writeUIntToStream(out, sLength);
+                final char[] ca = value.toCharArray();
+                for (int j = 0; j < ca.length; j++)
+                {
+                    int high = (ca[j] & 0x0ff00) >> 8;
+                    int low  = (ca[j] & 0x000ff);
+                    out.write(low);
+                    out.write(high);
+                    length += 2;
+                    sLength--;
+                }
+                while (sLength > 0)
+                {
+                    out.write(0x00);
+                    out.write(0x00);
+                    length += 2;
+                    sLength--;
+                }
             }
-            while (sLength > 0)
+            else
             {
+                /* Write the dictionary item in another codepage than
+                 * Unicode. */
+                length += TypeWriter.writeUIntToStream(out, key.longValue());
+                length += TypeWriter.writeUIntToStream(out, value.length() + 1);
+                final byte[] ba =
+                    value.getBytes(VariantSupport.codepageToEncoding(codepage));
+                for (int j = 0; j < ba.length; j++)
+                {
+                    out.write(ba[j]);
+                    length++;
+                }
                 out.write(0x00);
-                out.write(0x00);
-                length += 2;
-                sLength--;
+                length++;
             }
         }
         return length;