aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/poi/ss
diff options
context:
space:
mode:
authorJosh Micich <josh@apache.org>2008-10-30 22:06:10 +0000
committerJosh Micich <josh@apache.org>2008-10-30 22:06:10 +0000
commit0f60f5eba5bfff80c34df7db0a42d9a457dbbc35 (patch)
tree07a92110d7ff8a321d777fb133c16df981da0fe1 /src/java/org/apache/poi/ss
parent2b9938194aeb72c5ec3e4f0c98488f99b713a39a (diff)
downloadpoi-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.java133
-rw-r--r--src/java/org/apache/poi/ss/util/CellRangeAddress.java18
-rw-r--r--src/java/org/apache/poi/ss/util/CellRangeAddressList.java16
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();