poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ye...@apache.org
Subject svn commit: r1241380 - in /poi/trunk/src: documentation/content/xdocs/ java/org/apache/poi/hssf/dev/ java/org/apache/poi/hssf/record/ testcases/org/apache/poi/hssf/record/
Date Tue, 07 Feb 2012 09:00:50 GMT
Author: yegor
Date: Tue Feb  7 09:00:47 2012
New Revision: 1241380

URL: http://svn.apache.org/viewvc?rev=1241380&view=rev
Log:
Bugzilla 52569:  Support DConRefRecord in HSSF

Added:
    poi/trunk/src/java/org/apache/poi/hssf/record/DConRefRecord.java   (with props)
    poi/trunk/src/testcases/org/apache/poi/hssf/record/TestDConRefRecord.java
Modified:
    poi/trunk/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java
    poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java
    poi/trunk/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=1241380&r1=1241379&r2=1241380&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Tue Feb  7 09:00:47 2012
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.8-beta6" date="2012-??-??">
+           <action dev="poi-developers" type="add">52569 - Support DConRefRecord in
HSSF</action>
            <action dev="poi-developers" type="add">52575 - added an option to ignore
missing workbook references in formula evaluator</action>
            <action dev="poi-developers" type="add">Validate address of hyperlinks in
XSSF</action>
            <action dev="poi-developers" type="fix">52540 - Relax the M4.1 constraint
on reading OOXML files, as some Office produced ones do have 2 Core Properties, despite the
specification explicitly forbidding this</action>

Modified: poi/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java?rev=1241380&r1=1241379&r2=1241380&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java Tue Feb  7 09:00:47 2012
@@ -148,6 +148,7 @@ public final class BiffViewer {
 			case DatRecord.sid:            return new DatRecord(in);
 			case DataFormatRecord.sid:     return new DataFormatRecord(in);
 			case DateWindow1904Record.sid: return new DateWindow1904Record(in);
+		case DConRefRecord.sid: return new DConRefRecord(in);
 			case DefaultColWidthRecord.sid:return new DefaultColWidthRecord(in);
 			case DefaultDataLabelTextPropertiesRecord.sid: return new DefaultDataLabelTextPropertiesRecord(in);
 			case DefaultRowHeightRecord.sid: return new DefaultRowHeightRecord(in);

Added: poi/trunk/src/java/org/apache/poi/hssf/record/DConRefRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/DConRefRecord.java?rev=1241380&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/DConRefRecord.java (added)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/DConRefRecord.java Tue Feb  7 09:00:47 2012
@@ -0,0 +1,313 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+package org.apache.poi.hssf.record;
+
+import java.util.Arrays;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * DConRef records specify a range in a workbook (internal or external) that serves as a
data source
+ * for pivot tables or data consolidation.
+ *
+ * Represents a <code>DConRef</code> Structure
+ * <a href="http://msdn.microsoft.com/en-us/library/dd923854(office.12).aspx">[MS-XLS
s.
+ * 2.4.86]</a>, and the contained <code>DConFile</code> structure
+ * <a href="http://msdn.microsoft.com/en-us/library/dd950157(office.12).aspx">
+ * [MS-XLS s. 2.5.69]</a>. This in turn contains a <code>XLUnicodeStringNoCch</code>
+ * <a href="http://msdn.microsoft.com/en-us/library/dd910585(office.12).aspx">
+ * [MS-XLS s. 2.5.296]</a>.
+ *
+ * <pre>
+ *         _______________________________
+ *        |          DConRef              |
+ *(bytes) +-+-+-+-+-+-+-+-+-+-+...+-+-+-+-+
+ *        |    ref    |cch|  stFile   | un|
+ *        +-+-+-+-+-+-+-+-+-+-+...+-+-+-+-+
+ *                              |
+ *                     _________|_____________________
+ *                    |DConFile / XLUnicodeStringNoCch|
+ *                    +-+-+-+-+-+-+-+-+-+-+-+...+-+-+-+
+ *             (bits) |h|   reserved  |      rgb      |
+ *                    +-+-+-+-+-+-+-+-+-+-+-+...+-+-+-+
+ * </pre>
+ * Where
+ * <ul>
+ * <li><code>DConFile.h = 0x00</code> if the characters in<code>rgb</code>
are single byte, and
+ * <code>DConFile.h = 0x01</code> if they are double byte. <br/>
+ * If they are double byte, then<br/>
+ * <ul>
+ * <li> If it exists, the length of <code>DConRef.un = 2</code>. Otherwise
it is 1.
+ * <li> The length of <code>DConFile.rgb = (2 * DConRef.cch)</code>. Otherwise
it is equal to
+ * <code>DConRef.cch</code>.
+ * </ul>
+ * <li><code>DConRef.rgb</code> starts with <code>0x01</code>
if it is an external reference,
+ * and with <code>0x02</code> if it is a self-reference.
+ * </ul>
+ *
+ * At the moment this class is read-only.
+ *
+ * @author Niklas Rehfeld
+ */
+public class DConRefRecord extends StandardRecord
+{
+
+    /**
+     * The id of the record type,
+     * <code>sid = {@value}</code>
+     */
+    public static final short sid = 0x0051;
+    /**
+     * A RefU structure specifying the range of cells if this record is part of an SXTBL.
+     * <a href="http://msdn.microsoft.com/en-us/library/dd920420(office.12).aspx">
+     * [MS XLS s.2.5.211]</a>
+     */
+    private int firstRow, lastRow, firstCol, lastCol;
+    /**
+     * the number of chars in the link
+     */
+    private int charCount;
+    /**
+     * the type of characters (single or double byte)
+     */
+    private int charType;
+    /**
+     * The link's path string. This is the <code>rgb</code> field of a
+     * <code>XLUnicodeStringNoCch</code>. Therefore it will contain at least
one leading special
+     * character (0x01 or 0x02) and probably other ones.<p/>
+     * @see <A href="http://msdn.microsoft.com/en-us/library/dd923491(office.12).aspx">
+     * DConFile [MS-XLS s. 2.5.77]</A> and
+     * <A href="http://msdn.microsoft.com/en-us/library/dd950157(office.12).aspx">
+     * VirtualPath [MS-XLS s. 2.5.69]</a>
+     * <p/>
+     */
+    private byte[] path;
+    /**
+     * unused bits at the end, must be set to 0.
+     */
+    private byte[] _unused;
+
+    /**
+     * Read constructor.
+     *
+     * @param data byte array containing a DConRef Record, including the header.
+     */
+    public DConRefRecord(byte[] data)
+    {
+        int offset = 0;
+        if (!(LittleEndian.getShort(data, offset) == DConRefRecord.sid))
+            throw new RecordFormatException("incompatible sid.");
+        offset += LittleEndian.SHORT_SIZE;
+
+        //length = LittleEndian.getShort(data, offset);
+        offset += LittleEndian.SHORT_SIZE;
+
+        firstRow = LittleEndian.getUShort(data, offset);
+        offset += LittleEndian.SHORT_SIZE;
+        lastRow = LittleEndian.getUShort(data, offset);
+        offset += LittleEndian.SHORT_SIZE;
+        firstCol = LittleEndian.getUByte(data, offset);
+        offset += LittleEndian.BYTE_SIZE;
+        lastCol = LittleEndian.getUByte(data, offset);
+        offset += LittleEndian.BYTE_SIZE;
+        charCount = LittleEndian.getUShort(data, offset);
+        offset += LittleEndian.SHORT_SIZE;
+        if (charCount < 2)
+            throw new org.apache.poi.hssf.record.RecordFormatException(
+                    "Character count must be >= 2");
+
+        charType = LittleEndian.getUByte(data, offset);
+        offset += LittleEndian.BYTE_SIZE; //7 bits reserved + 1 bit type
+
+        /*
+         * bytelength is the length of the string in bytes, which depends on whether the
string is
+         * made of single- or double-byte chars. This is given by charType, which equals
0 if
+         * single-byte, 1 if double-byte.
+         */
+        int byteLength = charCount * ((charType & 1) + 1);
+
+        path = LittleEndian.getByteArray(data, offset, byteLength);
+        offset += byteLength;
+
+        /*
+         * If it's a self reference, the last one or two bytes (depending on char type) are
the
+         * unused field. Not sure If i need to bother with this...
+         */
+        if (path[0] == 0x02)
+            _unused = LittleEndian.getByteArray(data, offset, (charType + 1));
+
+    }
+
+    /**
+     * Read Constructor.
+     *
+     * @param inStream RecordInputStream containing a DConRefRecord structure.
+     */
+    public DConRefRecord(RecordInputStream inStream)
+    {
+        if (inStream.getSid() != sid)
+            throw new RecordFormatException("Wrong sid: " + inStream.getSid());
+
+        firstRow = inStream.readUShort();
+        lastRow = inStream.readUShort();
+        firstCol = inStream.readUByte();
+        lastCol = inStream.readUByte();
+
+        charCount = inStream.readUShort();
+        charType = inStream.readUByte() & 0x01; //first bit only.
+
+        // byteLength depends on whether we are using single- or double-byte chars.
+        int byteLength = charCount * (charType + 1);
+
+        path = new byte[byteLength];
+        inStream.readFully(path);
+
+        if (path[0] == 0x02)
+            _unused = inStream.readRemainder();
+
+    }
+
+    /*
+     * assuming this wants the number of bytes returned by {@link serialize(LittleEndianOutput)},
+     * that is, (length - 4).
+     */
+    @Override
+    protected int getDataSize()
+    {
+        int sz = 9 + path.length;
+        if (path[0] == 0x02)
+            sz += _unused.length;
+        return sz;
+    }
+
+    @Override
+    protected void serialize(LittleEndianOutput out)
+    {
+        out.writeShort(firstRow);
+        out.writeShort(lastRow);
+        out.writeByte(firstCol);
+        out.writeByte(lastCol);
+        out.writeShort(charCount);
+        out.writeByte(charType);
+        out.write(path);
+        if (path[0] == 0x02)
+            out.write(_unused);
+    }
+
+    @Override
+    public short getSid()
+    {
+        return sid;
+    }
+
+    /**
+     * @return The first column of the range.
+     */
+    public int getFirstColumn()
+    {
+        return firstCol;
+    }
+
+    /**
+     * @return The first row of the range.
+     */
+    public int getFirstRow()
+    {
+        return firstRow;
+    }
+
+    /**
+     * @return The last column of the range.
+     */
+    public int getLastColumn()
+    {
+        return lastCol;
+    }
+
+    /**
+     * @return The last row of the range.
+     */
+    public int getLastRow()
+    {
+        return lastRow;
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuilder b = new StringBuilder();
+	b.append("[DCONREF]\n");
+        b.append("    .ref\n");
+        b.append("        .firstrow   = ").append(firstRow).append("\n");
+        b.append("        .lastrow    = ").append(lastRow).append("\n");
+        b.append("        .firstcol   = ").append(firstCol).append("\n");
+        b.append("        .lastcol    = ").append(lastCol).append("\n");
+        b.append("    .cch            = ").append(charCount).append("\n");
+	b.append("    .stFile\n");
+	b.append("        .h          = ").append(charType).append("\n");
+	b.append("        .rgb        = ").append(getReadablePath()).append("\n");
+	b.append("[/DCONREF]\n");
+
+        return b.toString();
+    }
+
+    /**
+     *
+     * @return raw path byte array.
+     */
+    public byte[] getPath()
+    {
+        return Arrays.copyOf(path, path.length);
+    }
+
+    /**
+     * @return the link's path, with the special characters stripped/replaced. May be null.
+     * @see MS-XLS 2.5.277 (VirtualPath)
+     */
+    public String getReadablePath()
+    {
+        if (path != null)
+        {
+            //all of the path strings start with either 0x02 or 0x01 followed by zero or
+            //more of 0x01..0x08
+            int offset = 1;
+            while (path[offset] < 0x20 && offset < path.length)
+            {
+                offset++;
+            }
+            String out = new String(Arrays.copyOfRange(path, offset, path.length));
+            //UNC paths have \u0003 chars as path separators.
+            out = out.replaceAll("\u0003", "/");
+            return out;
+        }
+        return null;
+    }
+
+    /**
+     * Checks if the data source in this reference record is external to this sheet or internal.
+     *
+     * @return true iff this is an external reference.
+     */
+    public boolean isExternalRef()
+    {
+        if (path[0] == 0x01)
+            return true;
+        return false;
+    }
+}

Propchange: poi/trunk/src/java/org/apache/poi/hssf/record/DConRefRecord.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java?rev=1241380&r1=1241379&r2=1241380&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java Tue Feb  7 09:00:47 2012
@@ -129,6 +129,7 @@ public final class RecordFactory {
 		CRNRecord.class,
 		DateWindow1904Record.class,
 		DBCellRecord.class,
+                DConRefRecord.class,
 		DefaultColWidthRecord.class,
 		DefaultRowHeightRecord.class,
 		DeltaRecord.class,

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java?rev=1241380&r1=1241379&r2=1241380&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java Tue Feb  7 09:00:47
2012
@@ -96,6 +96,7 @@ public final class AllRecordTests {
 		result.addTestSuite(TestUnicodeNameRecord.class);
 		result.addTestSuite(TestUnicodeString.class);
 		result.addTestSuite(TestWriteAccessRecord.class);
+                result.addTestSuite(TestDConRefRecord.class);
 		return result;
 	}
 }

Added: poi/trunk/src/testcases/org/apache/poi/hssf/record/TestDConRefRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/TestDConRefRecord.java?rev=1241380&view=auto
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/TestDConRefRecord.java (added)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/TestDConRefRecord.java Tue Feb  7 09:00:47
2012
@@ -0,0 +1,310 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.hssf.record;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import junit.framework.TestCase;
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.hssf.record.TestcaseRecordInputStream;
+import org.apache.poi.util.LittleEndianOutputStream;
+//import static org.junit.Assert.assertArrayEquals;
+//import org.junit.Test;
+import junit.framework.Assert;
+
+/**
+ * Unit tests for DConRefRecord class.
+ *
+ * @author Niklas Rehfeld
+ */
+public class TestDConRefRecord extends TestCase
+{
+    /**
+     * record of a proper single-byte external 'volume'-style path with multiple parts and
a sheet
+     * name.
+     */
+    final byte[] volumeString = new byte[]
+    {
+        0, 0, 0, 0, 0, 0, //ref (6 bytes) not used...
+        17, 0,//cchFile (2 bytes)
+        0, //char type
+        1, 1, 'c', '[', 'f', 'o', 'o', 0x3,
+        'b', 'a', 'r', ']', 's', 'h', 'e', 'e',
+        't'
+    };
+    /**
+     * record of a proper single-byte external 'unc-volume'-style path with multiple parts
and a
+     * sheet name.
+     */
+    final byte[] uncVolumeString = new byte[]
+    {
+        0, 0, 0, 0, 0, 0, //ref (6 bytes) not used...
+        34, 0,//cchFile (2 bytes)
+        0, //char type
+        1, 1, '@', '[', 'c', 'o', 'm', 'p',
+        0x3, 's', 'h', 'a', 'r', 'e', 'd', 0x3,
+        'r', 'e', 'l', 'a', 't', 'i', 'v', 'e',
+        0x3, 'f', 'o', 'o', ']', 's', 'h', 'e',
+        'e', 't'
+    };
+    /**
+     * record of a proper single-byte external 'simple-file-path-dcon' style path with a
sheet name.
+     */
+    final byte[] simpleFilePathDconString = new byte[]
+    {
+        0, 0, 0, 0, 0, 0, //ref (6 bytes) not used...
+        16, 0,//cchFile (2 bytes)
+        0, //char type
+        1, 'c', '[', 'f', 'o', 'o', 0x3, 'b',
+        'a', 'r', ']', 's', 'h', 'e', 'e', 't'
+    };
+    /**
+     * record of a proper 'transfer-protocol'-style path. This one has a sheet name at the
end, and
+     * another one inside the file path. The spec doesn't seem to care about what they are.
+     */
+    final byte[] transferProtocolString = new byte[]
+    {
+        0, 0, 0, 0, 0, 0, //ref (6 bytes) not used...
+        33, 0,//cchFile (2 bytes)
+        0, //char type
+        0x1, 0x5, 30, //count = 30
+        '[', 'h', 't', 't', 'p', ':', '/', '/',
+        '[', 'f', 'o', 'o', 0x3, 'b', 'a', 'r',
+        ']', 's', 'h', 'e', 'e', 't', '1', ']',
+        's', 'h', 'e', 'e', 't', 'x'
+    };
+    /**
+     * startup-type path.
+     */
+    final byte[] relVolumeString = new byte[]
+    {
+        0, 0, 0, 0, 0, 0, //ref (6 bytes) not used...
+        16, 0,//cchFile (2 bytes)
+        0, //char type
+        0x1, 0x2, '[', 'f', 'o', 'o', 0x3, 'b',
+        'a', 'r', ']', 's', 'h', 'e', 'e', 't'
+    };
+    /**
+     * startup-type path.
+     */
+    final byte[] startupString = new byte[]
+    {
+        0, 0, 0, 0, 0, 0, //ref (6 bytes) not used...
+        16, 0,//cchFile (2 bytes)
+        0, //char type
+        0x1, 0x6, '[', 'f', 'o', 'o', 0x3, 'b',
+        'a', 'r', ']', 's', 'h', 'e', 'e', 't'
+    };
+    /**
+     * alt-startup-type path.
+     */
+    final byte[] altStartupString = new byte[]
+    {
+        0, 0, 0, 0, 0, 0, //ref (6 bytes) not used...
+        16, 0,//cchFile (2 bytes)
+        0, //char type
+        0x1, 0x7, '[', 'f', 'o', 'o', 0x3, 'b',
+        'a', 'r', ']', 's', 'h', 'e', 'e', 't'
+    };
+    /**
+     * library-style path.
+     */
+    final byte[] libraryString = new byte[]
+    {
+        0, 0, 0, 0, 0, 0, //ref (6 bytes) not used...
+        16, 0,//cchFile (2 bytes)
+        0, //char type
+        0x1, 0x8, '[', 'f', 'o', 'o', 0x3, 'b',
+        'a', 'r', ']', 's', 'h', 'e', 'e', 't'
+    };
+    /**
+     * record of single-byte string, external, volume path.
+     */
+    final byte[] data1 = new byte[]
+    {
+        0, 0, 0, 0, 0, 0, //ref (6 bytes) not used...
+        10, 0,//cchFile (2 bytes)
+        0, //char type
+        1, 1, (byte) 'b', (byte) 'l', (byte) 'a', (byte) ' ', (byte) 't',
+        (byte) 'e', (byte) 's', (byte) 't'
+    //unused doesn't exist as stFile[1] != 2
+    };
+    /**
+     * record of double-byte string, self-reference.
+     */
+    final byte[] data2 = new byte[]
+    {
+        0, 0, 0, 0, 0, 0, //ref (6 bytes) not used...
+        9, 0,//cchFile (2 bytes)
+        1, //char type = unicode
+        2, 0, (byte) 'b', 0, (byte) 'l', 0, (byte) 'a', 0, (byte) ' ', 0, (byte) 't', 0,
+        (byte) 'e', 0, (byte) 's', (byte) 't', 0,//stFile
+        0, 0 //unused (2 bytes as we're using double-byte chars)
+    };
+    /**
+     * record of single-byte string, self-reference.
+     */
+    final byte[] data3 = new byte[]
+    {
+        0, 0, 0, 0, 0, 0, //ref (6 bytes) not used...
+        9, 0,//cchFile (2 bytes)
+        0, //char type = ansi
+        2, (byte) 'b', (byte) 'l', (byte) 'a', (byte) ' ', (byte) 't', (byte) 'e', (byte)
's',
+        (byte) 't',//stFile
+        0 //unused (1 byte as we're using single byes)
+    };
+    /**
+     * double-byte string, external reference, unc-volume.
+     */
+    final byte[] data4 = new byte[]
+    {
+        0, 0, 0, 0, 0, 0, //ref (6 bytes) not used...
+        16, 0,//cchFile (2 bytes)
+        //stFile starts here:
+        1, //char type = unicode
+        1, 0, 1, 0, 0x40, 0, (byte) 'c', 0, (byte) 'o', 0, (byte) 'm', 0, (byte) 'p', 0,
0x03, 0,
+        (byte) 'b', 0, (byte) 'l', 0, (byte) 'a', 0, 0x03, 0, (byte) 't', 0, (byte) 'e',
0,
+        (byte) 's', 0, (byte) 't', 0,
+    //unused doesn't exist as stFile[1] != 2
+    };
+
+    /**
+     * test read-constructor-then-serialize for a single-byte external reference strings
of
+     * various flavours. This uses the RecordInputStream constructor.
+     * @throws IOException
+     */
+    public void testReadWriteSBExtRef() throws IOException
+    {
+        testReadWrite(data1, "read-write single-byte external reference, volume type path");
+        testReadWrite(volumeString,
+                "read-write properly formed single-byte external reference, volume type path");
+        testReadWrite(uncVolumeString,
+                "read-write properly formed single-byte external reference, UNC volume type
path");
+        testReadWrite(relVolumeString,
+                "read-write properly formed single-byte external reference, rel-volume type
path");
+        testReadWrite(simpleFilePathDconString,
+                "read-write properly formed single-byte external reference, simple-file-path-dcon
type path");
+        testReadWrite(transferProtocolString,
+                "read-write properly formed single-byte external reference, transfer-protocol
type path");
+        testReadWrite(startupString,
+                "read-write properly formed single-byte external reference, startup type
path");
+        testReadWrite(altStartupString,
+                "read-write properly formed single-byte external reference, alt-startup type
path");
+        testReadWrite(libraryString,
+                "read-write properly formed single-byte external reference, library type
path");
+    }
+
+    /**
+     * test read-constructor-then-serialize for a double-byte external reference 'UNC-Volume'
style
+     * string
+     * <p/>
+     * @throws IOException
+     */
+    public void testReadWriteDBExtRefUncVol() throws IOException
+    {
+        testReadWrite(data4, "read-write double-byte external reference, UNC volume type
path");
+    }
+
+    private void testReadWrite(byte[] data, String message) throws IOException
+    {
+        RecordInputStream is = TestcaseRecordInputStream.create(81, data);
+        DConRefRecord d = new DConRefRecord(is);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);
+        LittleEndianOutputStream o = new LittleEndianOutputStream(bos);
+        d.serialize(o);
+        o.flush();
+
+        assertTrue(message, Arrays.equals(data,
+                bos.toByteArray()));
+    }
+
+    /**
+     * test read-constructor-then-serialize for a double-byte self-reference style string
+     * <p/>
+     * @throws IOException
+     */
+    public void testReadWriteDBSelfRef() throws IOException
+    {
+        testReadWrite(data2, "read-write double-byte self reference");
+    }
+
+    /**
+     * test read-constructor-then-serialize for a single-byte self-reference style string
+     * <p/>
+     * @throws IOException
+     */
+    public void testReadWriteSBSelfRef() throws IOException
+    {
+        testReadWrite(data3, "read-write single byte self reference");
+    }
+
+    /**
+     * Test of getDataSize method, of class DConRefRecord.
+     */
+    public void testGetDataSize()
+    {
+        DConRefRecord instance = new DConRefRecord(TestcaseRecordInputStream.create(81, data1));
+        int expResult = data1.length;
+        int result = instance.getDataSize();
+        assertEquals("single byte external reference, volume type path data size", expResult,
result);
+        instance = new DConRefRecord(TestcaseRecordInputStream.create(81, data2));
+        assertEquals("double byte self reference data size", data2.length, instance.getDataSize());
+        instance = new DConRefRecord(TestcaseRecordInputStream.create(81, data3));
+        assertEquals("single byte self reference data size", data3.length, instance.getDataSize());
+        instance = new DConRefRecord(TestcaseRecordInputStream.create(81, data4));
+        assertEquals("double byte external reference, UNC volume type path data size", data4.length,
+                instance.getDataSize());
+    }
+
+    /**
+     * Test of getSid method, of class DConRefRecord.
+     */
+    public void testGetSid()
+    {
+        DConRefRecord instance = new DConRefRecord(TestcaseRecordInputStream.create(81, data1));
+        short expResult = 81;
+        short result = instance.getSid();
+        assertEquals("SID", expResult, result);
+    }
+
+    /**
+     * Test of getPath method, of class DConRefRecord.
+     * @todo different types of paths.
+     */
+    public void testGetPath()
+    {
+        DConRefRecord instance = new DConRefRecord(TestcaseRecordInputStream.create(81, data1));
+        byte[] expResult = Arrays.copyOfRange(data1, 9, data1.length);
+        byte[] result = instance.getPath();
+        assertTrue("get path", Arrays.equals(expResult, result));
+    }
+
+    /**
+     * Test of isExternalRef method, of class DConRefRecord.
+     */
+    public void testIsExternalRef()
+    {
+        DConRefRecord instance = new DConRefRecord(TestcaseRecordInputStream.create(81, data1));
+        assertTrue("external reference", instance.isExternalRef());
+        instance = new DConRefRecord(TestcaseRecordInputStream.create(81, data2));
+        assertFalse("internal reference", instance.isExternalRef());
+    }
+}



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


Mime
View raw message