diff options
author | Josh Micich <josh@apache.org> | 2008-10-30 22:06:10 +0000 |
---|---|---|
committer | Josh Micich <josh@apache.org> | 2008-10-30 22:06:10 +0000 |
commit | 0f60f5eba5bfff80c34df7db0a42d9a457dbbc35 (patch) | |
tree | 07a92110d7ff8a321d777fb133c16df981da0fe1 /src/java/org/apache/poi/ss | |
parent | 2b9938194aeb72c5ec3e4f0c98488f99b713a39a (diff) | |
download | poi-0f60f5eba5bfff80c34df7db0a42d9a457dbbc35.tar.gz poi-0f60f5eba5bfff80c34df7db0a42d9a457dbbc35.zip |
Merged revisions 708385,708996,709054,709217,709221,709235 via svnmerge from
https://svn.apache.org/repos/asf/poi/trunk
........
r708385 | josh | 2008-10-27 16:44:44 -0700 (Mon, 27 Oct 2008) | 1 line
Small fix for bug in RecordInputStream.readAllContinuedRemainder() introduced in r707778. It seems like only BiffViewer was affected.
........
r708996 | josh | 2008-10-29 13:13:58 -0700 (Wed, 29 Oct 2008) | 1 line
Allowed for quad-byte padding alignment on ObjRecord
........
r709054 | josh | 2008-10-29 17:21:24 -0700 (Wed, 29 Oct 2008) | 1 line
removed obsolete methods
........
r709217 | josh | 2008-10-30 10:56:34 -0700 (Thu, 30 Oct 2008) | 1 line
Fixed compiler warnings / simplified code
........
r709221 | josh | 2008-10-30 11:33:35 -0700 (Thu, 30 Oct 2008) | 1 line
Optimised slow test case (after reviewing original purpose)
........
r709235 | josh | 2008-10-30 13:17:04 -0700 (Thu, 30 Oct 2008) | 1 line
Fix for bug 15716 - - converted Ptg arrays into Formula objects to optimise memory usage
........
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@709262 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/poi/ss')
-rw-r--r-- | src/java/org/apache/poi/ss/formula/Formula.java | 133 | ||||
-rw-r--r-- | src/java/org/apache/poi/ss/util/CellRangeAddress.java | 18 | ||||
-rw-r--r-- | src/java/org/apache/poi/ss/util/CellRangeAddressList.java | 16 |
3 files changed, 156 insertions, 11 deletions
diff --git a/src/java/org/apache/poi/ss/formula/Formula.java b/src/java/org/apache/poi/ss/formula/Formula.java new file mode 100644 index 0000000000..55314452a2 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/Formula.java @@ -0,0 +1,133 @@ +package org.apache.poi.ss.formula;
+
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.util.LittleEndianByteArrayInputStream;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+public class Formula {
+
+ private static final byte[] EMPTY_BYTE_ARRAY = { };
+ private final byte[] _byteEncoding;
+ private final int _encodedTokenLen;
+
+ private Formula(byte[] byteEncoding, int encodedTokenLen) {
+ _byteEncoding = byteEncoding;
+ _encodedTokenLen = encodedTokenLen;
+ if (false) { // set to true to eagerly check Ptg decoding
+ LittleEndianByteArrayInputStream in = new LittleEndianByteArrayInputStream(byteEncoding);
+ Ptg.readTokens(encodedTokenLen, in);
+ int nUnusedBytes = _byteEncoding.length - in.getReadIndex();
+ if (nUnusedBytes > 0) {
+ // TODO - this seems to occur when IntersectionPtg is present
+ // This example file "IntersectionPtg.xls"
+ // used by test: TestIntersectionPtg.testReading()
+ // has 10 bytes unused at the end of the formula
+ // 10 extra bytes are just 0x01 and 0x00
+ System.out.println(nUnusedBytes + " unused bytes at end of formula");
+ }
+ }
+ }
+ /**
+ * Convenience method for {@link #read(int, LittleEndianInput, int)}
+ */
+ public static Formula read(int encodedTokenLen, LittleEndianInput in) {
+ return read(encodedTokenLen, in, encodedTokenLen);
+ }
+ /**
+ * When there are no array constants present, <tt>encodedTokenLen</tt>==<tt>totalEncodedLen</tt>
+ * @param encodedTokenLen number of bytes in the stream taken by the plain formula tokens
+ * @param totalEncodedLen the total number of bytes in the formula (includes trailing encoding
+ * for array constants, but does not include 2 bytes for initial <tt>ushort encodedTokenLen</tt> field.
+ * @return A new formula object as read from the stream. Possibly empty, never <code>null</code>.
+ */
+ public static Formula read(int encodedTokenLen, LittleEndianInput in, int totalEncodedLen) {
+ byte[] byteEncoding = new byte[totalEncodedLen];
+ in.readFully(byteEncoding);
+ return new Formula(byteEncoding, encodedTokenLen);
+ }
+
+ public Ptg[] getTokens() {
+ LittleEndianInput in = new LittleEndianByteArrayInputStream(_byteEncoding);
+ return Ptg.readTokens(_encodedTokenLen, in);
+ }
+ /**
+ * Writes The formula encoding is includes:
+ * <ul>
+ * <li>ushort tokenDataLen</li>
+ * <li>tokenData</li>
+ * <li>arrayConstantData (if present)</li>
+ * </ul>
+ */
+ public void serialize(LittleEndianOutput out) {
+ out.writeShort(_encodedTokenLen);
+ out.write(_byteEncoding);
+ }
+
+ public void serializeTokens(LittleEndianOutput out) {
+ out.write(_byteEncoding, 0, _encodedTokenLen);
+ }
+ public void serializeArrayConstantData(LittleEndianOutput out) {
+ int len = _byteEncoding.length-_encodedTokenLen;
+ out.write(_byteEncoding, _encodedTokenLen, len);
+ }
+
+
+ /**
+ * @return total formula encoding length. The formula encoding includes:
+ * <ul>
+ * <li>ushort tokenDataLen</li>
+ * <li>tokenData</li>
+ * <li>arrayConstantData (optional)</li>
+ * </ul>
+ * Note - this value is different to <tt>tokenDataLength</tt>
+ */
+ public int getEncodedSize() {
+ return 2 + _byteEncoding.length;
+ }
+ /**
+ * This method is often used when the formula length does not appear immediately before
+ * the encoded token data.
+ *
+ * @return the encoded length of the plain formula tokens. This does <em>not</em> include
+ * the leading ushort field, nor any trailing array constant data.
+ */
+ public int getEncodedTokenSize() {
+ return _encodedTokenLen;
+ }
+
+ /**
+ * Creates a {@link Formula} object from a supplied {@link Ptg} array.
+ * Handles <code>null</code>s OK.
+ * @param ptgs may be <code>null</code>
+ * @return Never <code>null</code> (Possibly empty if the supplied <tt>ptgs</tt> is <code>null</code>)
+ */
+ public static Formula create(Ptg[] ptgs) {
+ if (ptgs == null) {
+ return new Formula(EMPTY_BYTE_ARRAY, 0);
+ }
+ int totalSize = Ptg.getEncodedSize(ptgs);
+ byte[] encodedData = new byte[totalSize];
+ Ptg.serializePtgs(ptgs, encodedData, 0);
+ int encodedTokenLen = Ptg.getEncodedSizeWithoutArrayData(ptgs);
+ return new Formula(encodedData, encodedTokenLen);
+ }
+ /**
+ * Gets the {@link Ptg} array from the supplied {@link Formula}.
+ * Handles <code>null</code>s OK.
+ *
+ * @param formula may be <code>null</code>
+ * @return possibly <code>null</code> (if the supplied <tt>formula</tt> is <code>null</code>)
+ */
+ public static Ptg[] getTokens(Formula formula) {
+ if (formula == null) {
+ return null;
+ }
+ return formula.getTokens();
+ }
+
+ public Formula copy() {
+ // OK to return this for the moment because currently immutable
+ return this;
+ }
+}
diff --git a/src/java/org/apache/poi/ss/util/CellRangeAddress.java b/src/java/org/apache/poi/ss/util/CellRangeAddress.java index 3cc70cf483..fe3c922979 100644 --- a/src/java/org/apache/poi/ss/util/CellRangeAddress.java +++ b/src/java/org/apache/poi/ss/util/CellRangeAddress.java @@ -18,7 +18,8 @@ package org.apache.poi.ss.util; import org.apache.poi.hssf.record.RecordInputStream; import org.apache.poi.hssf.record.SelectionRecord; -import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.LittleEndianByteArrayOutputStream; +import org.apache.poi.util.LittleEndianOutput; /** * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/> @@ -36,13 +37,20 @@ public class CellRangeAddress extends CellRangeAddressBase { super(firstRow, lastRow, firstCol, lastCol); } + /** + * @deprecated use {@link #serialize(LittleEndianOutput)} + */ public int serialize(int offset, byte[] data) { - LittleEndian.putUShort(data, offset + 0, getFirstRow()); - LittleEndian.putUShort(data, offset + 2, getLastRow()); - LittleEndian.putUShort(data, offset + 4, getFirstColumn()); - LittleEndian.putUShort(data, offset + 6, getLastColumn()); + serialize(new LittleEndianByteArrayOutputStream(data, offset, ENCODED_SIZE)); return ENCODED_SIZE; } + public void serialize(LittleEndianOutput out) { + out.writeShort(getFirstRow()); + out.writeShort(getLastRow()); + out.writeShort(getFirstColumn()); + out.writeShort(getLastColumn()); + } + public CellRangeAddress(RecordInputStream in) { super(readUShortAndCheck(in), in.readUShort(), in.readUShort(), in.readUShort()); } diff --git a/src/java/org/apache/poi/ss/util/CellRangeAddressList.java b/src/java/org/apache/poi/ss/util/CellRangeAddressList.java index 65474ef980..f5dd8ab7ce 100644 --- a/src/java/org/apache/poi/ss/util/CellRangeAddressList.java +++ b/src/java/org/apache/poi/ss/util/CellRangeAddressList.java @@ -20,7 +20,8 @@ import java.util.ArrayList; import java.util.List; import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.LittleEndianByteArrayOutputStream; +import org.apache.poi.util.LittleEndianOutput; /** * Implementation of the cell range address lists,like is described @@ -122,16 +123,19 @@ public class CellRangeAddressList { } public int serialize(int offset, byte[] data) { - int pos = 2; - + int totalSize = getSize(); + serialize(new LittleEndianByteArrayOutputStream(data, offset, totalSize)); + return totalSize; + } + public void serialize(LittleEndianOutput out) { int nItems = _list.size(); - LittleEndian.putUShort(data, offset, nItems); + out.writeShort(nItems); for (int k = 0; k < nItems; k++) { CellRangeAddress region = (CellRangeAddress) _list.get(k); - pos += region.serialize(offset + pos, data); + region.serialize(out); } - return getSize(); } + public CellRangeAddressList copy() { CellRangeAddressList result = new CellRangeAddressList(); |