poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From max...@apache.org
Subject svn commit: r995415 - in /poi/trunk: src/java/org/apache/poi/poifs/filesystem/ src/testcases/org/apache/poi/poifs/filesystem/ test-data/poifs/
Date Thu, 09 Sep 2010 13:18:48 GMT
Author: maxcom
Date: Thu Sep  9 13:18:48 2010
New Revision: 995415

URL: http://svn.apache.org/viewvc?rev=995415&view=rev
Log:
Add code for reading Ole10Native data

Added:
    poi/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10Native.java
    poi/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10NativeException.java
    poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestOle10Native.java
    poi/trunk/test-data/poifs/oleObject1.bin   (with props)
Modified:
    poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/AllPOIFSFileSystemTests.java

Added: poi/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10Native.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10Native.java?rev=995415&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10Native.java (added)
+++ poi/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10Native.java Thu Sep  9 13:18:48
2010
@@ -0,0 +1,259 @@
+package org.apache.poi.poifs.filesystem;
+
+import org.apache.poi.util.*;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * Represents an Ole10Native record which is wrapped around certain binary
+ * files being embedded in OLE2 documents.
+ *
+ * @author Rainer Schwarze
+ */
+public class Ole10Native {
+  // (the fields as they appear in the raw record:)
+  private final int totalSize;                // 4 bytes, total size of record not including
this field
+  private short flags1;                // 2 bytes, unknown, mostly [02 00]
+  private final String label;                // ASCIIZ, stored in this field without the
terminating zero
+  private final String fileName;        // ASCIIZ, stored in this field without the terminating
zero
+  private short flags2;                // 2 bytes, unknown, mostly [00 00]
+  // private byte unknown1Length;	// 1 byte, specifying the length of the following byte
array (unknown1)
+  private byte[] unknown1;        // see below
+  private byte[] unknown2;        // 3 bytes, unknown, mostly [00 00 00]
+  private final String command;                // ASCIIZ, stored in this field without the
terminating zero
+  private final int dataSize;                // 4 bytes (if space), size of following buffer
+  private final byte[] dataBuffer;        // varying size, the actual native data
+  private short flags3;                // some final flags? or zero terminators?, sometimes
not there
+  public static final String OLE10_NATIVE = "\u0001Ole10Native";
+
+  /**
+   * Creates an instance of this class from an embedded OLE Object. The OLE Object is expected
+   * to include a stream "{01}Ole10Native" which contains the actual
+   * data relevant for this class.
+   *
+   * @param poifs POI Filesystem object
+   * @return Returns an instance of this class
+   * @throws IOException on IO error
+   * @throws Ole10NativeException on invalid or unexcepted data format
+   */
+  public static Ole10Native createFromEmbeddedOleObject(POIFSFileSystem poifs) throws IOException,
Ole10NativeException {
+    boolean plain = false;
+
+    try {
+      poifs.getRoot().getEntry("\u0001Ole10ItemName");
+      plain = true;
+    } catch (FileNotFoundException ex) {
+      plain = false;
+    }
+
+    DocumentInputStream dis = poifs.createDocumentInputStream(OLE10_NATIVE);
+    ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    IOUtils.copy(dis, bos);
+    byte[] data = bos.toByteArray();
+
+    return new Ole10Native(data, 0, plain);
+  }
+
+  /**
+   * Creates an instance and fills the fields based on the data in the given buffer.
+   *
+   * @param data   The buffer containing the Ole10Native record
+   * @param offset The start offset of the record in the buffer
+   * @throws Ole10NativeException on invalid or unexcepted data format
+   */
+  public Ole10Native(byte[] data, int offset) throws Ole10NativeException {
+    this(data, offset, false);
+  }
+  /**
+   * Creates an instance and fills the fields based on the data in the given buffer.
+   *
+   * @param data   The buffer containing the Ole10Native record
+   * @param offset The start offset of the record in the buffer
+   * @param plain Specified 'plain' format without filename
+   * @throws Ole10NativeException on invalid or unexcepted data format
+   */
+  public Ole10Native(byte[] data, int offset, boolean plain) throws Ole10NativeException
{
+    int ofs = offset;        // current offset, initialized to start
+
+    if (data.length<offset+2) {
+      throw new Ole10NativeException("data is too small");
+    }
+
+    totalSize = LittleEndian.getInt(data, ofs);
+    ofs += LittleEndianConsts.INT_SIZE;
+
+    if (plain) {
+      dataBuffer = new byte[totalSize-4];
+      System.arraycopy(data, 4, dataBuffer, 0, dataBuffer.length);
+      dataSize = totalSize - 4;
+      label = "ole-"+ HexDump.toHex(Arrays.copyOf(dataBuffer, 8));
+      fileName = label;
+      command = label;
+    } else {
+      flags1 = LittleEndian.getShort(data, ofs);
+      ofs += LittleEndianConsts.SHORT_SIZE;
+      int len = getStringLength(data, ofs);
+      label = StringUtil.getFromCompressedUnicode(data, ofs, len - 1);
+      ofs += len;
+      len = getStringLength(data, ofs);
+      fileName = StringUtil.getFromCompressedUnicode(data, ofs, len - 1);
+      ofs += len;
+      flags2 = LittleEndian.getShort(data, ofs);
+      ofs += LittleEndianConsts.SHORT_SIZE;
+      len = LittleEndian.getUnsignedByte(data, ofs);
+      unknown1 = new byte[len];
+      ofs += len;
+      len = 3;
+      unknown2 = new byte[len];
+      ofs += len;
+      len = getStringLength(data, ofs);
+      command = StringUtil.getFromCompressedUnicode(data, ofs, len - 1);
+      ofs += len;
+
+      if (totalSize + LittleEndianConsts.INT_SIZE - ofs > LittleEndianConsts.INT_SIZE)
{
+        dataSize = LittleEndian.getInt(data, ofs);
+        ofs += LittleEndianConsts.INT_SIZE;
+
+        if (dataSize > totalSize || dataSize<0) {
+          throw new Ole10NativeException("Invalid Ole10Native");
+        }
+
+        dataBuffer = new byte[dataSize];
+        System.arraycopy(data, ofs, dataBuffer, 0, dataSize);
+        ofs += dataSize;
+
+        if (unknown1.length > 0) {
+          flags3 = LittleEndian.getShort(data, ofs);
+          ofs += LittleEndianConsts.SHORT_SIZE;
+        } else {
+          flags3 = 0;
+        }
+      } else {
+        throw new Ole10NativeException("Invalid Ole10Native");
+      }
+    }
+  }
+
+  /*
+   * Helper - determine length of zero terminated string (ASCIIZ).
+   */
+  private static int getStringLength(byte[] data, int ofs) {
+    int len = 0;
+    while (len+ofs<data.length && data[ofs + len] != 0) {
+      len++;
+    }
+    len++;
+    return len;
+  }
+
+  /**
+   * Returns the value of the totalSize field - the total length of the structure
+   * is totalSize + 4 (value of this field + size of this field).
+   *
+   * @return the totalSize
+   */
+  public int getTotalSize() {
+    return totalSize;
+  }
+
+  /**
+   * Returns flags1 - currently unknown - usually 0x0002.
+   *
+   * @return the flags1
+   */
+  public short getFlags1() {
+    return flags1;
+  }
+
+  /**
+   * Returns the label field - usually the name of the file (without directory) but
+   * probably may be any name specified during packaging/embedding the data.
+   *
+   * @return the label
+   */
+  public String getLabel() {
+    return label;
+  }
+
+  /**
+   * Returns the fileName field - usually the name of the file being embedded
+   * including the full path.
+   *
+   * @return the fileName
+   */
+  public String getFileName() {
+    return fileName;
+  }
+
+  /**
+   * Returns flags2 - currently unknown - mostly 0x0000.
+   *
+   * @return the flags2
+   */
+  public short getFlags2() {
+    return flags2;
+  }
+
+  /**
+   * Returns unknown1 field - currently unknown.
+   *
+   * @return the unknown1
+   */
+  public byte[] getUnknown1() {
+    return unknown1;
+  }
+
+  /**
+   * Returns the unknown2 field - currently being a byte[3] - mostly {0, 0, 0}.
+   *
+   * @return the unknown2
+   */
+  public byte[] getUnknown2() {
+    return unknown2;
+  }
+
+  /**
+   * Returns the command field - usually the name of the file being embedded
+   * including the full path, may be a command specified during embedding the file.
+   *
+   * @return the command
+   */
+  public String getCommand() {
+    return command;
+  }
+
+  /**
+   * Returns the size of the embedded file. If the size is 0 (zero), no data has been
+   * embedded. To be sure, that no data has been embedded, check whether
+   * {@link #getDataBuffer()} returns <code>null</code>.
+   *
+   * @return the dataSize
+   */
+  public int getDataSize() {
+    return dataSize;
+  }
+
+  /**
+   * Returns the buffer containing the embedded file's data, or <code>null</code>
+   * if no data was embedded. Note that an embedding may provide information about
+   * the data, but the actual data is not included. (So label, filename etc. are
+   * available, but this method returns <code>null</code>.)
+   *
+   * @return the dataBuffer
+   */
+  public byte[] getDataBuffer() {
+    return dataBuffer;
+  }
+
+  /**
+   * Returns the flags3 - currently unknown.
+   *
+   * @return the flags3
+   */
+  public short getFlags3() {
+    return flags3;
+  }
+}

Added: poi/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10NativeException.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10NativeException.java?rev=995415&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10NativeException.java (added)
+++ poi/trunk/src/java/org/apache/poi/poifs/filesystem/Ole10NativeException.java Thu Sep 
9 13:18:48 2010
@@ -0,0 +1,7 @@
+package org.apache.poi.poifs.filesystem;
+
+public class Ole10NativeException extends Exception {
+    public Ole10NativeException(String message) {
+        super(message);
+    }
+}

Modified: poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/AllPOIFSFileSystemTests.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/AllPOIFSFileSystemTests.java?rev=995415&r1=995414&r2=995415&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/AllPOIFSFileSystemTests.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/AllPOIFSFileSystemTests.java Thu
Sep  9 13:18:48 2010
@@ -40,6 +40,7 @@ public final class AllPOIFSFileSystemTes
         result.addTestSuite(TestPOIFSDocumentPath.class);
         result.addTestSuite(TestPOIFSFileSystem.class);
         result.addTestSuite(TestPropertySorter.class);
+        result.addTestSuite(TestOle10Native.class);
         return result;
     }
 }

Added: poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestOle10Native.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestOle10Native.java?rev=995415&view=auto
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestOle10Native.java (added)
+++ poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestOle10Native.java Thu Sep 
9 13:18:48 2010
@@ -0,0 +1,19 @@
+package org.apache.poi.poifs.filesystem;
+
+import junit.framework.TestCase;
+import org.apache.poi.POIDataSamples;
+
+import java.io.IOException;
+
+public class TestOle10Native extends TestCase {
+    private static final POIDataSamples dataSamples = POIDataSamples.getPOIFSInstance();
+
+    public void testOleNative() throws IOException, Ole10NativeException {
+        POIFSFileSystem fs = new POIFSFileSystem(dataSamples.openResourceAsStream("oleObject1.bin"));
+
+        Ole10Native ole = Ole10Native.createFromEmbeddedOleObject(fs);
+
+        assertEquals("File1.svg", ole.getLabel());
+        assertEquals("D:\\Documents and Settings\\rsc\\My Documents\\file1.svg", ole.getCommand());
+    }
+}

Added: poi/trunk/test-data/poifs/oleObject1.bin
URL: http://svn.apache.org/viewvc/poi/trunk/test-data/poifs/oleObject1.bin?rev=995415&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/test-data/poifs/oleObject1.bin
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org


Mime
View raw message