You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by jo...@apache.org on 2008/10/26 08:18:19 UTC
svn commit: r707945 [1/4] - in /poi/branches/ooxml: ./
src/contrib/src/org/apache/poi/contrib/poibrowser/
src/java/org/apache/poi/hssf/model/ src/java/org/apache/poi/hssf/record/
src/java/org/apache/poi/hssf/record/constant/ src/java/org/apache/poi/hss...
Author: josh
Date: Sun Oct 26 00:18:17 2008
New Revision: 707945
URL: http://svn.apache.org/viewvc?rev=707945&view=rev
Log:
Merged revisions 707486,707519,707525,707534,707541-707542,707551,707585,707729,707778,707780,707802 via svnmerge from
https://svn.apache.org/repos/asf/poi/trunk
........
r707486 | josh | 2008-10-23 15:28:05 -0700 (Thu, 23 Oct 2008) | 1 line
Converted Ptgs to use LittleEndianOutput
........
r707519 | josh | 2008-10-23 17:58:49 -0700 (Thu, 23 Oct 2008) | 1 line
Fix for unicode string bug in StyleRecord. Improvements to WriteAccessRecord.
........
r707525 | josh | 2008-10-23 19:08:47 -0700 (Thu, 23 Oct 2008) | 1 line
Further conversion of Ptg classes to use LittleEndian input/output interfaces
........
r707534 | josh | 2008-10-23 20:47:42 -0700 (Thu, 23 Oct 2008) | 1 line
added LittleEndianByteArrayInputStream
........
r707541 | josh | 2008-10-23 21:30:38 -0700 (Thu, 23 Oct 2008) | 1 line
Removed String methods from LittleEndianInput
........
r707542 | josh | 2008-10-23 21:40:37 -0700 (Thu, 23 Oct 2008) | 1 line
removing unused code
........
r707551 | josh | 2008-10-23 22:46:29 -0700 (Thu, 23 Oct 2008) | 1 line
Simplification and code clean-up
........
r707585 | josh | 2008-10-24 01:58:00 -0700 (Fri, 24 Oct 2008) | 1 line
General clean-up in LittleEndian util class. (Some optimization, some obsolete code removal)
........
r707729 | josh | 2008-10-24 12:25:11 -0700 (Fri, 24 Oct 2008) | 1 line
Fixed test suite name
........
r707778 | josh | 2008-10-24 16:13:44 -0700 (Fri, 24 Oct 2008) | 1 line
Optimisation of RecordInputStream - removed intermediate 8K byte buffer. Expected performance gain was not realised immediately, so LittleEndianInput stuff has been pushed down into DocumentInputStream to help.
........
r707780 | josh | 2008-10-24 16:19:26 -0700 (Fri, 24 Oct 2008) | 1 line
should have been submitted with c707778
........
r707802 | josh | 2008-10-24 18:02:37 -0700 (Fri, 24 Oct 2008) | 1 line
Further simplification to RecordInputStream. Mostly regarding Strings, ContinueRecords and LittleEndianInput
........
Added:
poi/branches/ooxml/src/java/org/apache/poi/poifs/storage/DataInputBlock.java
- copied unchanged from r707802, poi/trunk/src/java/org/apache/poi/poifs/storage/DataInputBlock.java
poi/branches/ooxml/src/java/org/apache/poi/util/LittleEndianByteArrayInputStream.java
- copied unchanged from r707802, poi/trunk/src/java/org/apache/poi/util/LittleEndianByteArrayInputStream.java
poi/branches/ooxml/src/java/org/apache/poi/util/LittleEndianByteArrayOutputStream.java
- copied unchanged from r707802, poi/trunk/src/java/org/apache/poi/util/LittleEndianByteArrayOutputStream.java
poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestStyleRecord.java
- copied unchanged from r707802, poi/trunk/src/testcases/org/apache/poi/hssf/record/TestStyleRecord.java
Removed:
poi/branches/ooxml/src/java/org/apache/poi/util/DoubleList.java
poi/branches/ooxml/src/java/org/apache/poi/util/DoubleList2d.java
poi/branches/ooxml/src/testcases/org/apache/poi/util/TestDoubleList2d.java
Modified:
poi/branches/ooxml/ (props changed)
poi/branches/ooxml/src/contrib/src/org/apache/poi/contrib/poibrowser/TreeReaderListener.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/model/Workbook.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/CRNRecord.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/RecordInputStream.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/StyleRecord.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/SubRecord.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/SupBookRecord.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/TextObjectRecord.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/UnicodeString.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/WriteAccessRecord.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaNPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AttrPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/BoolPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/DeletedArea3DPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/DeletedRef3DPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/ErrPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/ExpPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/FuncPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/FuncVarPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/IntPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/IntersectionPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/MemAreaPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/MemErrPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/MemFuncPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/MissingArgPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/NamePtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/NameXPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/NumberPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/ParenthesisPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Ptg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/RangePtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Ref2DPtgBase.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/RefErrorPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/RefNPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/RefPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/RefPtgBase.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/StringPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/TblPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/UnionPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/UnknownPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/ValueOperatorPtg.java
poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
poi/branches/ooxml/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java
poi/branches/ooxml/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java
poi/branches/ooxml/src/java/org/apache/poi/poifs/storage/DocumentBlock.java
poi/branches/ooxml/src/java/org/apache/poi/poifs/storage/SmallDocumentBlock.java
poi/branches/ooxml/src/java/org/apache/poi/ss/formula/SheetRefEvaluator.java (props changed)
poi/branches/ooxml/src/java/org/apache/poi/util/LittleEndian.java
poi/branches/ooxml/src/java/org/apache/poi/util/LittleEndianInput.java
poi/branches/ooxml/src/java/org/apache/poi/util/LittleEndianInputStream.java
poi/branches/ooxml/src/java/org/apache/poi/util/StringUtil.java
poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java
poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestCommonObjectDataSubRecord.java
poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java
poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java
poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestHyperlinkRecord.java
poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java
poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestTextObjectBaseRecord.java
poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestTextObjectRecord.java
poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestcaseRecordInputStream.java
poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/constant/TestConstantValueParser.java
poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java
poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/TestAttrPtg.java
poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/TestFuncPtg.java
poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/TestReferencePtg.java
poi/branches/ooxml/src/testcases/org/apache/poi/poifs/filesystem/TestDocumentInputStream.java
poi/branches/ooxml/src/testcases/org/apache/poi/poifs/storage/AllPOIFSStorageTests.java
poi/branches/ooxml/src/testcases/org/apache/poi/poifs/storage/TestDocumentBlock.java
poi/branches/ooxml/src/testcases/org/apache/poi/poifs/storage/TestSmallDocumentBlock.java
poi/branches/ooxml/src/testcases/org/apache/poi/util/AllPOIUtilTests.java
poi/branches/ooxml/src/testcases/org/apache/poi/util/TestLittleEndian.java
poi/branches/ooxml/src/testcases/org/apache/poi/util/TestStringUtil.java
Propchange: poi/branches/ooxml/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sun Oct 26 00:18:17 2008
@@ -1 +1 @@
-/poi/trunk:693591-694881,695264-695420,695621,695649-707481
+/poi/trunk:693591-694881,695264-695420,695621,695649-707802
Propchange: poi/branches/ooxml/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Sun Oct 26 00:18:17 2008
@@ -1 +1 @@
-/poi/trunk:1-638784,638786-639486,639488-639601,639603-640056,640058-642562,642564-642566,642568-642574,642576-642736,642739-650914,650916-707481
+/poi/trunk:1-638784,638786-639486,639488-639601,639603-640056,640058-642562,642564-642566,642568-642574,642576-642736,642739-650914,650916-707802
Modified: poi/branches/ooxml/src/contrib/src/org/apache/poi/contrib/poibrowser/TreeReaderListener.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/contrib/src/org/apache/poi/contrib/poibrowser/TreeReaderListener.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/contrib/src/org/apache/poi/contrib/poibrowser/TreeReaderListener.java (original)
+++ poi/branches/ooxml/src/contrib/src/org/apache/poi/contrib/poibrowser/TreeReaderListener.java Sun Oct 26 00:18:17 2008
@@ -1,4 +1,3 @@
-
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@@ -15,11 +14,9 @@
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
-
package org.apache.poi.contrib.poibrowser;
-import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@@ -160,17 +157,7 @@
throw new RuntimeException(t.getMessage());
}
- try
- {
- is.close();
- }
- catch (IOException ex)
- {
- System.err.println
- ("Unexpected exception while closing " +
- event.getName() + " in " + event.getPath().toString());
- ex.printStackTrace(System.err);
- }
+ is.close();
final MutableTreeNode parentNode = getNode(d.path, filename, rootNode);
final MutableTreeNode nameNode = new DefaultMutableTreeNode(d.name);
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/model/Workbook.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/model/Workbook.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/model/Workbook.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/model/Workbook.java Sun Oct 26 00:18:17 2008
@@ -788,7 +788,7 @@
if(r instanceof ExtendedFormatRecord) {
} else if(r instanceof StyleRecord) {
StyleRecord sr = (StyleRecord)r;
- if(sr.getIndex() == xfIndex) {
+ if(sr.getXFIndex() == xfIndex) {
return sr;
}
} else {
@@ -806,7 +806,7 @@
// Style records always follow after
// the ExtendedFormat records
StyleRecord newSR = new StyleRecord();
- newSR.setIndex((short)xfIndex);
+ newSR.setXFIndex(xfIndex);
// Find the spot
int addAt = -1;
@@ -1782,45 +1782,44 @@
* @see org.apache.poi.hssf.record.StyleRecord
* @see org.apache.poi.hssf.record.Record
*/
-
protected Record createStyle(int id) { // we'll need multiple editions
StyleRecord retval = new StyleRecord();
switch (id) {
case 0 :
- retval.setIndex(( short ) 0xffff8010);
- retval.setBuiltin(( byte ) 3);
+ retval.setXFIndex(0x010);
+ retval.setBuiltinStyle(3);
retval.setOutlineStyleLevel(( byte ) 0xffffffff);
break;
case 1 :
- retval.setIndex(( short ) 0xffff8011);
- retval.setBuiltin(( byte ) 6);
+ retval.setXFIndex(0x011);
+ retval.setBuiltinStyle(6);
retval.setOutlineStyleLevel(( byte ) 0xffffffff);
break;
case 2 :
- retval.setIndex(( short ) 0xffff8012);
- retval.setBuiltin(( byte ) 4);
+ retval.setXFIndex(0x012);
+ retval.setBuiltinStyle(4);
retval.setOutlineStyleLevel(( byte ) 0xffffffff);
break;
case 3 :
- retval.setIndex(( short ) 0xffff8013);
- retval.setBuiltin(( byte ) 7);
+ retval.setXFIndex(0x013);
+ retval.setBuiltinStyle(7);
retval.setOutlineStyleLevel(( byte ) 0xffffffff);
break;
case 4 :
- retval.setIndex(( short ) 0xffff8000);
- retval.setBuiltin(( byte ) 0);
+ retval.setXFIndex(0x000);
+ retval.setBuiltinStyle(0);
retval.setOutlineStyleLevel(( byte ) 0xffffffff);
break;
case 5 :
- retval.setIndex(( short ) 0xffff8014);
- retval.setBuiltin(( byte ) 5);
+ retval.setXFIndex(0x014);
+ retval.setBuiltinStyle(5);
retval.setOutlineStyleLevel(( byte ) 0xffffffff);
break;
}
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/CRNRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/CRNRecord.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/CRNRecord.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/CRNRecord.java Sun Oct 26 00:18:17 2008
@@ -18,17 +18,18 @@
package org.apache.poi.hssf.record;
import org.apache.poi.hssf.record.constant.ConstantValueParser;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianByteArrayOutputStream;
+import org.apache.poi.util.LittleEndianOutput;
/**
- * Title: CRN <P>
- * Description: This record stores the contents of an external cell or cell range <P>
- * REFERENCE: 5.23<P>
+ * Title: CRN(0x005A) <p/>
+ * Description: This record stores the contents of an external cell or cell range <p/>
+ * REFERENCE: OOO 5.23<p/>
*
* @author josh micich
*/
public final class CRNRecord extends Record {
- public final static short sid = 0x5A;
+ public final static short sid = 0x005A;
private int field_1_last_column_index;
private int field_2_first_column_index;
@@ -45,8 +46,8 @@
public CRNRecord(RecordInputStream in) {
- field_1_last_column_index = in.readByte() & 0x00FF;
- field_2_first_column_index = in.readByte() & 0x00FF;
+ field_1_last_column_index = in.readUByte();
+ field_2_first_column_index = in.readUByte();
field_3_row_index = in.readShort();
int nValues = field_1_last_column_index - field_2_first_column_index + 1;
field_4_constant_values = ConstantValueParser.parse(in, nValues);
@@ -68,13 +69,15 @@
public int serialize(int offset, byte [] data) {
int dataSize = getDataSize();
- LittleEndian.putShort(data, 0 + offset, sid);
- LittleEndian.putShort(data, 2 + offset, (short) dataSize);
- LittleEndian.putByte(data, 4 + offset, field_1_last_column_index);
- LittleEndian.putByte(data, 5 + offset, field_2_first_column_index);
- LittleEndian.putShort(data, 6 + offset, (short) field_3_row_index);
- ConstantValueParser.encode(data, 8 + offset, field_4_constant_values);
- return getRecordSize();
+ int recSize = 4 + dataSize;
+ LittleEndianOutput out = new LittleEndianByteArrayOutputStream(data, offset, recSize);
+ out.writeShort(sid);
+ out.writeShort(dataSize);
+ out.writeByte(field_1_last_column_index);
+ out.writeByte(field_2_first_column_index);
+ out.writeShort(field_3_row_index);
+ ConstantValueParser.encode(out, field_4_constant_values);
+ return recSize;
}
public int getRecordSize() {
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java Sun Oct 26 00:18:17 2008
@@ -27,6 +27,7 @@
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianInputStream;
import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.StringUtil;
@@ -111,10 +112,10 @@
field_3_unicode_flag = ( in.readByte() & 0x01 ) != 0;
remaining -= LittleEndian.BYTE_SIZE;
if (field_3_unicode_flag) {
- field_4_ole_classname = in.readUnicodeLEString(nChars);
+ field_4_ole_classname = StringUtil.readUnicodeLE(in, nChars);
stringByteCount = nChars * 2;
} else {
- field_4_ole_classname = in.readCompressedUnicode(nChars);
+ field_4_ole_classname = StringUtil.readCompressedUnicode(in, nChars);
stringByteCount = nChars;
}
} else {
@@ -156,12 +157,7 @@
}
private static Ptg readRefPtg(byte[] formulaRawBytes) {
- byte[] data = new byte[formulaRawBytes.length + 4];
- LittleEndian.putUShort(data, 0, -5555);
- LittleEndian.putUShort(data, 2, formulaRawBytes.length);
- System.arraycopy(formulaRawBytes, 0, data, 4, formulaRawBytes.length);
- RecordInputStream in = new RecordInputStream(new ByteArrayInputStream(data));
- in.nextRecord();
+ LittleEndianInput in = new LittleEndianInputStream(new ByteArrayInputStream(formulaRawBytes));
byte ptgSid = in.readByte();
switch(ptgSid) {
case AreaPtg.sid: return new AreaPtg(in);
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java Sun Oct 26 00:18:17 2008
@@ -51,7 +51,7 @@
.append( "=" )
.append(ptg.toString() )
.append( "\n" )
- .append(ptg.toDebugString() )
+ .append(ptg.toString())
.append( "\n" );
}
}
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/RecordInputStream.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/RecordInputStream.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/RecordInputStream.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/RecordInputStream.java Sun Oct 26 00:18:17 2008
@@ -17,12 +17,12 @@
package org.apache.poi.hssf.record;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianInput;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ByteArrayOutputStream;
+import org.apache.poi.util.LittleEndianInputStream;
/**
* Title: Record Input Stream<P>
@@ -34,115 +34,147 @@
/** Maximum size of a single record (minus the 4 byte header) without a continue*/
public final static short MAX_RECORD_DATA_SIZE = 8224;
private static final int INVALID_SID_VALUE = -1;
+ /**
+ * When {@link #_currentDataLength} has this value, it means that the previous BIFF record is
+ * finished, the next sid has been properly read, but the data size field has not been read yet.
+ */
+ private static final int DATA_LEN_NEEDS_TO_BE_READ = -1;
+ private static final byte[] EMPTY_BYTE_ARRAY = { };
- private InputStream in;
- private short currentSid;
- private short currentLength = -1;
- private short nextSid;
-
- private final byte[] data = new byte[MAX_RECORD_DATA_SIZE];
- private short recordOffset;
- private long pos;
-
- private boolean autoContinue = true;
-
- public RecordInputStream(InputStream in) throws RecordFormatException {
- this.in = in;
- try {
- nextSid = LittleEndian.readShort(in);
- //Don't increment the pos just yet (technically we are at the start of
- //the record stream until nextRecord is called).
- } catch (IOException ex) {
- throw new RecordFormatException("Error reading bytes", ex);
- }
- }
+ /** {@link LittleEndianInput} facet of the wrapped {@link InputStream} */
+ private final LittleEndianInput _le;
+ /** the record identifier of the BIFF record currently being read */
+ private int _currentSid;
+ /**
+ * Length of the data section of the current BIFF record (always 4 less than the total record size).
+ * When uninitialised, this field is set to {@link #DATA_LEN_NEEDS_TO_BE_READ}.
+ */
+ private int _currentDataLength;
+ /**
+ * The BIFF record identifier for the next record is read when just as the current record
+ * is finished.
+ * This field is only really valid during the time that ({@link #_currentDataLength} ==
+ * {@link #DATA_LEN_NEEDS_TO_BE_READ}). At most other times its value is not really the
+ * 'sid of the next record'. Wwhile mid-record, this field coincidentally holds the sid
+ * of the current record.
+ */
+ private int _nextSid;
+ /**
+ * index within the data section of the current BIFF record
+ */
+ private int _currentDataOffset;
+
+ public RecordInputStream(InputStream in) throws RecordFormatException {
+ if (in instanceof LittleEndianInput) {
+ // accessing directly is an optimisation
+ _le = (LittleEndianInput) in;
+ } else {
+ // less optimal, but should work OK just the same. Often occurs in junit tests.
+ _le = new LittleEndianInputStream(in);
+ }
+ _nextSid = readNextSid();
+ }
+
+ /**
+ * @returns the number of bytes available in the current BIFF record
+ * @see #remaining()
+ */
+ public int available() {
+ return remaining();
+ }
- /** This method will read a byte from the current record*/
public int read() {
checkRecordPosition(LittleEndian.BYTE_SIZE);
-
- byte result = data[recordOffset];
- recordOffset += LittleEndian.BYTE_SIZE;
- pos += LittleEndian.BYTE_SIZE;
- return result;
+ _currentDataOffset += LittleEndian.BYTE_SIZE;
+ return _le.readUByte();
+ }
+ public int read(byte[] b, int off, int len) {
+ int limit = Math.min(len, remaining());
+ if (limit == 0) {
+ return 0;
+ }
+ readFully(b, off,limit);
+ return limit;
}
- public short getSid() {
- return currentSid;
- }
-
- public short getLength() {
- return currentLength;
- }
-
- public short getRecordOffset() {
- return recordOffset;
- }
-
- public long getPos() {
- return pos;
- }
-
- public boolean hasNextRecord() {
- return nextSid != INVALID_SID_VALUE;
- }
+ public short getSid() {
+ return (short) _currentSid;
+ }
- /** Moves to the next record in the stream.
- *
- * <i>Note: The auto continue flag is reset to true</i>
- */
- public void nextRecord() throws RecordFormatException {
- if ((currentLength != -1) && (currentLength != recordOffset)) {
- System.out.println("WARN. Unread "+remaining()+" bytes of record 0x"+Integer.toHexString(currentSid));
- }
- currentSid = nextSid;
- pos += LittleEndian.SHORT_SIZE;
- autoContinue = true;
- try {
- recordOffset = 0;
- currentLength = LittleEndian.readShort(in);
- if (currentLength > MAX_RECORD_DATA_SIZE)
- throw new RecordFormatException("The content of an excel record cannot exceed "+MAX_RECORD_DATA_SIZE+" bytes");
- pos += LittleEndian.SHORT_SIZE;
- in.read(data, 0, currentLength);
-
- //Read the Sid of the next record
- if (in.available() < EOFRecord.ENCODED_SIZE) {
- if (in.available() > 0) {
- // some scrap left over?
- // ex45582-22397.xls has one extra byte after the last record
- // Excel reads that file OK
- }
- nextSid = INVALID_SID_VALUE;
- } else {
- nextSid = LittleEndian.readShort(in);
- if (nextSid == INVALID_SID_VALUE) {
- throw new RecordFormatException("Found sid " + nextSid + " after record with sid 0x"
- + Integer.toHexString(currentSid).toUpperCase());
- }
- }
- } catch (IOException ex) {
- throw new RecordFormatException("Error reading bytes", ex);
- }
- }
+ /**
+ * Note - this method is expected to be called only when completed reading the current BIFF record.
+ * Calling this before reaching the end of the current record will cause all remaining data to be
+ * discarded
+ */
+ public boolean hasNextRecord() {
+ if (_currentDataLength != -1 && _currentDataLength != _currentDataOffset) {
+ System.out.println("WARN. Unread "+remaining()+" bytes of record 0x"+Integer.toHexString(_currentSid));
+ // discard unread data
+ while (_currentDataOffset < _currentDataLength) {
+ readByte();
+ }
+ }
+ if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ) {
+ _nextSid = readNextSid();
+ }
+ return _nextSid != INVALID_SID_VALUE;
+ }
- public void setAutoContinue(boolean enable) {
- this.autoContinue = enable;
- }
+ /**
+ *
+ * @return the sid of the next record or {@link #INVALID_SID_VALUE} if at end of stream
+ */
+ private int readNextSid() {
+ int nAvailable = _le.available();
+ if (nAvailable < EOFRecord.ENCODED_SIZE) {
+ if (nAvailable > 0) {
+ // some scrap left over?
+ // ex45582-22397.xls has one extra byte after the last record
+ // Excel reads that file OK
+ }
+ return INVALID_SID_VALUE;
+ }
+ int result = _le.readUShort();
+ if (result == INVALID_SID_VALUE) {
+ throw new RecordFormatException("Found invalid sid (" + result + ")");
+ }
+ _currentDataLength = DATA_LEN_NEEDS_TO_BE_READ;
+ return result;
+ }
- public boolean getAutoContinue() {
- return autoContinue;
- }
+ /** Moves to the next record in the stream.
+ *
+ * <i>Note: The auto continue flag is reset to true</i>
+ */
+ public void nextRecord() throws RecordFormatException {
+ if (_nextSid == INVALID_SID_VALUE) {
+ throw new IllegalStateException("EOF - next record not available");
+ }
+ if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ) {
+ throw new IllegalStateException("Cannot call nextRecord() without checking hasNextRecord() first");
+ }
+ _currentSid = _nextSid;
+ _currentDataOffset = 0;
+ _currentDataLength = _le.readUShort();
+ if (_currentDataLength > MAX_RECORD_DATA_SIZE) {
+ throw new RecordFormatException("The content of an excel record cannot exceed "
+ + MAX_RECORD_DATA_SIZE + " bytes");
+ }
+ }
private void checkRecordPosition(int requiredByteCount) {
- if (remaining() < requiredByteCount) {
- if (isContinueNext() && autoContinue) {
- nextRecord();
- } else {
- throw new ArrayIndexOutOfBoundsException();
- }
+ int nAvailable = remaining();
+ if (nAvailable >= requiredByteCount) {
+ // all OK
+ return;
}
+ if (nAvailable == 0 && isContinueNext()) {
+ nextRecord();
+ return;
+ }
+ throw new RecordFormatException("Not enough data (" + nAvailable
+ + ") to read requested (" + requiredByteCount +") bytes");
}
/**
@@ -150,11 +182,8 @@
*/
public byte readByte() {
checkRecordPosition(LittleEndian.BYTE_SIZE);
-
- byte result = data[recordOffset];
- recordOffset += LittleEndian.BYTE_SIZE;
- pos += LittleEndian.BYTE_SIZE;
- return result;
+ _currentDataOffset += LittleEndian.BYTE_SIZE;
+ return _le.readByte();
}
/**
@@ -162,29 +191,20 @@
*/
public short readShort() {
checkRecordPosition(LittleEndian.SHORT_SIZE);
-
- short result = LittleEndian.getShort(data, recordOffset);
- recordOffset += LittleEndian.SHORT_SIZE;
- pos += LittleEndian.SHORT_SIZE;
- return result;
+ _currentDataOffset += LittleEndian.SHORT_SIZE;
+ return _le.readShort();
}
public int readInt() {
checkRecordPosition(LittleEndian.INT_SIZE);
-
- int result = LittleEndian.getInt(data, recordOffset);
- recordOffset += LittleEndian.INT_SIZE;
- pos += LittleEndian.INT_SIZE;
- return result;
+ _currentDataOffset += LittleEndian.INT_SIZE;
+ return _le.readInt();
}
public long readLong() {
checkRecordPosition(LittleEndian.LONG_SIZE);
-
- long result = LittleEndian.getLong(data, recordOffset);
- recordOffset += LittleEndian.LONG_SIZE;
- pos += LittleEndian.LONG_SIZE;
- return result;
+ _currentDataOffset += LittleEndian.LONG_SIZE;
+ return _le.readLong();
}
/**
@@ -200,22 +220,18 @@
*/
public int readUShort() {
checkRecordPosition(LittleEndian.SHORT_SIZE);
-
- int result = LittleEndian.getUShort(data, recordOffset);
- recordOffset += LittleEndian.SHORT_SIZE;
- pos += LittleEndian.SHORT_SIZE;
- return result;
+ _currentDataOffset += LittleEndian.SHORT_SIZE;
+ return _le.readUShort();
}
public double readDouble() {
checkRecordPosition(LittleEndian.DOUBLE_SIZE);
- long valueLongBits = LittleEndian.getLong(data, recordOffset);
+ _currentDataOffset += LittleEndian.DOUBLE_SIZE;
+ long valueLongBits = _le.readLong();
double result = Double.longBitsToDouble(valueLongBits);
if (Double.isNaN(result)) {
throw new RuntimeException("Did not expect to read NaN"); // (Because Excel typically doesn't write NaN
}
- recordOffset += LittleEndian.DOUBLE_SIZE;
- pos += LittleEndian.DOUBLE_SIZE;
return result;
}
public void readFully(byte[] buf) {
@@ -224,9 +240,8 @@
public void readFully(byte[] buf, int off, int len) {
checkRecordPosition(len);
- System.arraycopy(data, recordOffset, buf, off, len);
- recordOffset+=len;
- pos+=len;
+ _le.readFully(buf, off, len);
+ _currentDataOffset+=len;
}
public String readString() {
@@ -315,18 +330,19 @@
return new UnicodeString(this);
}
- /** Returns the remaining bytes for the current record.
- *
- * @return The remaining bytes of the current record.
- */
- public byte[] readRemainder() {
- int size = remaining();
- byte[] result = new byte[size];
- System.arraycopy(data, recordOffset, result, 0, size);
- recordOffset += size;
- pos += size;
- return result;
- }
+ /** Returns the remaining bytes for the current record.
+ *
+ * @return The remaining bytes of the current record.
+ */
+ public byte[] readRemainder() {
+ int size = remaining();
+ if (size ==0) {
+ return EMPTY_BYTE_ARRAY;
+ }
+ byte[] result = new byte[size];
+ readFully(result);
+ return result;
+ }
/** Reads all byte data for the current record, including any
* that overlaps into any following continue records.
@@ -350,19 +366,34 @@
return out.toByteArray();
}
- /** The remaining number of bytes in the <i>current</i> record.
- *
- * @return The number of bytes remaining in the current record
- */
- public int remaining() {
- return (currentLength - recordOffset);
- }
+ /** The remaining number of bytes in the <i>current</i> record.
+ *
+ * @return The number of bytes remaining in the current record
+ */
+ public int remaining() {
+ if (_currentDataLength == DATA_LEN_NEEDS_TO_BE_READ) {
+ // already read sid of next record. so current one is finished
+ return 0;
+ }
+ return _currentDataLength - _currentDataOffset;
+ }
- /** Returns true iif a Continue record is next in the excel stream
- *
- * @return True when a ContinueRecord is next.
- */
- public boolean isContinueNext() {
- return (nextSid == ContinueRecord.sid);
- }
+ /**
+ *
+ * @return <code>true</code> when a {@link ContinueRecord} is next.
+ */
+ private boolean isContinueNext() {
+ if (_currentDataLength != DATA_LEN_NEEDS_TO_BE_READ && _currentDataOffset != _currentDataLength) {
+ throw new IllegalStateException("Should never be called before end of current record");
+ }
+ if (!hasNextRecord()) {
+ return false;
+ }
+ // At what point are records continued?
+ // - Often from within the char data of long strings (caller is within readStringCommon()).
+ // - From UnicodeString construction (many different points - call via checkRecordPosition)
+ // - During TextObjectRecord construction (just before the text, perhaps within the text,
+ // and before the formatting run data)
+ return _nextSid == ContinueRecord.sid;
+ }
}
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/StyleRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/StyleRecord.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/StyleRecord.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/StyleRecord.java Sun Oct 26 00:18:17 2008
@@ -19,332 +19,181 @@
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.StringUtil;
/**
- * Title: Style Record<P>
+ * Title: Style Record (0x0293)<p/>
* Description: Describes a builtin to the gui or user defined style<P>
* REFERENCE: PG 390 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author aviks : string fixes for UserDefined Style
- * @version 2.0-pre
*/
public final class StyleRecord extends Record {
- public final static short sid = 0x0293;
+ public final static short sid = 0x0293;
- private static final BitField fHighByte = BitFieldFactory.getInstance(0x01);
+ private static final BitField is16BitUnicodeFlag = BitFieldFactory.getInstance(0x01);
- public final static short STYLE_USER_DEFINED = 0;
- public final static short STYLE_BUILT_IN = 1;
+ private static final BitField styleIndexMask = BitFieldFactory.getInstance(0x0FFF);
+ private static final BitField isBuiltinFlag = BitFieldFactory.getInstance(0x8000);
- // shared by both user defined and builtin styles
- private short field_1_xf_index; // TODO: bitfield candidate
-
- // only for built in styles
- private byte field_2_builtin_style;
- private byte field_3_outline_style_level;
-
- // only for user defined styles
- private short field_2_name_length; //OO doc says 16 bit length, so we believe
- private byte field_3_string_options;
- private String field_4_name;
-
- public StyleRecord()
- {
- }
-
- public StyleRecord(RecordInputStream in)
- {
- field_1_xf_index = in.readShort();
- if (getType() == STYLE_BUILT_IN)
- {
- field_2_builtin_style = in.readByte();
- field_3_outline_style_level = in.readByte();
- }
- else if (getType() == STYLE_USER_DEFINED)
- {
- field_2_name_length = in.readShort();
-
- // Some files from Crystal Reports lack
- // the remaining fields, which is naughty
- if(in.remaining() > 0) {
- field_3_string_options = in.readByte();
-
- byte[] string = in.readRemainder();
- if (fHighByte.isSet(field_3_string_options)) {
- field_4_name= StringUtil.getFromUnicodeBE(string, 0, field_2_name_length);
- } else {
- field_4_name=StringUtil.getFromCompressedUnicode(string, 0, field_2_name_length);
- }
- }
- }
-
- // todo sanity check exception to make sure we're one or the other
- }
-
- /**
- * set the entire index field (including the type) (see bit setters that reference this method)
- * @param index bitmask
- */
-
- public void setIndex(short index)
- {
- field_1_xf_index = index;
- }
-
- // bitfields for field 1
-
- /**
- * set the type of the style (builtin or user-defined)
- * @see #STYLE_USER_DEFINED
- * @see #STYLE_BUILT_IN
- * @param type of style (userdefined/builtin)
- * @see #setIndex(short)
- */
-
- public void setType(short type)
- {
- field_1_xf_index = setField(field_1_xf_index, type, 0x8000, 15);
- }
-
- /**
- * set the actual index of the style extended format record
- * @see #setIndex(short)
- * @param index of the xf record
- */
-
- public void setXFIndex(short index)
- {
- field_1_xf_index = setField(field_1_xf_index, index, 0x1FFF, 0);
- }
-
- // end bitfields
- // only for user defined records
-
- /**
- * if this is a user defined record set the length of the style name
- * @param length of the style's name
- * @see #setName(String)
- */
-
- public void setNameLength(byte length)
- {
- field_2_name_length = length;
- }
-
- /**
- * set the style's name
- * @param name of the style
- * @see #setNameLength(byte)
- */
-
- public void setName(String name)
- {
- field_4_name = name;
-
- // Fix up the length
- field_2_name_length = (short)name.length();
- //TODO set name string options
- }
-
- // end user defined
- // only for buildin records
-
- /**
- * if this is a builtin style set teh number of the built in style
- * @param builtin style number (0-7)
- *
- */
-
- public void setBuiltin(byte builtin)
- {
- field_2_builtin_style = builtin;
- }
-
- /**
- * set the row or column level of the style (if builtin 1||2)
- */
-
- public void setOutlineStyleLevel(byte level)
- {
- field_3_outline_style_level = level;
- }
-
- // end builtin records
- // field 1
-
- /**
- * get the entire index field (including the type) (see bit getters that reference this method)
- * @return bitmask
- */
-
- public short getIndex()
- {
- return field_1_xf_index;
- }
-
- // bitfields for field 1
-
- /**
- * get the type of the style (builtin or user-defined)
- * @see #STYLE_USER_DEFINED
- * @see #STYLE_BUILT_IN
- * @return type of style (userdefined/builtin)
- * @see #getIndex()
- */
-
- public short getType()
- {
- return ( short ) ((field_1_xf_index & 0x8000) >> 15);
- }
-
- /**
- * get the actual index of the style extended format record
- * @see #getIndex()
- * @return index of the xf record
- */
-
- public short getXFIndex()
- {
- return ( short ) (field_1_xf_index & 0x1FFF);
- }
-
- // end bitfields
- // only for user defined records
-
- /**
- * if this is a user defined record get the length of the style name
- * @return length of the style's name
- * @see #getName()
- */
-
- public short getNameLength()
- {
- return field_2_name_length;
- }
-
- /**
- * get the style's name
- * @return name of the style
- * @see #getNameLength()
- */
-
- public String getName()
- {
- return field_4_name;
- }
-
- // end user defined
- // only for buildin records
-
- /**
- * if this is a builtin style get the number of the built in style
- * @return builtin style number (0-7)
- *
- */
-
- public byte getBuiltin()
- {
- return field_2_builtin_style;
- }
-
- /**
- * get the row or column level of the style (if builtin 1||2)
- */
-
- public byte getOutlineStyleLevel()
- {
- return field_3_outline_style_level;
- }
-
- // end builtin records
- public String toString()
- {
- StringBuffer buffer = new StringBuffer();
-
- buffer.append("[STYLE]\n");
- buffer.append(" .xf_index_raw = ")
- .append(Integer.toHexString(getIndex())).append("\n");
- buffer.append(" .type = ")
- .append(Integer.toHexString(getType())).append("\n");
- buffer.append(" .xf_index = ")
- .append(Integer.toHexString(getXFIndex())).append("\n");
- if (getType() == STYLE_BUILT_IN)
- {
- buffer.append(" .builtin_style = ")
- .append(Integer.toHexString(getBuiltin())).append("\n");
- buffer.append(" .outline_level = ")
- .append(Integer.toHexString(getOutlineStyleLevel()))
- .append("\n");
- }
- else if (getType() == STYLE_USER_DEFINED)
- {
- buffer.append(" .name_length = ")
- .append(Integer.toHexString(getNameLength())).append("\n");
- buffer.append(" .name = ").append(getName())
- .append("\n");
- }
- buffer.append("[/STYLE]\n");
- return buffer.toString();
- }
-
- private short setField(int fieldValue, int new_value, int mask,
- int shiftLeft)
- {
- return ( short ) ((fieldValue & ~mask)
- | ((new_value << shiftLeft) & mask));
- }
-
- public int serialize(int offset, byte [] data)
- {
- LittleEndian.putShort(data, 0 + offset, sid);
- if (getType() == STYLE_BUILT_IN)
- {
- LittleEndian.putShort(data, 2 + offset,
- (( short ) 0x04)); // 4 bytes (8 total)
- }
- else
- {
- LittleEndian.putShort(data, 2 + offset,
- (( short ) (getRecordSize()-4)));
- }
- LittleEndian.putShort(data, 4 + offset, getIndex());
- if (getType() == STYLE_BUILT_IN)
- {
- data[ 6 + offset ] = getBuiltin();
- data[ 7 + offset ] = getOutlineStyleLevel();
- }
- else
- {
- LittleEndian.putShort(data, 6 + offset , getNameLength());
- data[8+offset]=this.field_3_string_options;
- StringUtil.putCompressedUnicode(getName(), data, 9 + offset);
- }
- return getRecordSize();
- }
-
- public int getRecordSize()
- {
- int retval;
-
- if (getType() == STYLE_BUILT_IN)
- {
- retval = 8;
- }
- else
- {
- if (fHighByte.isSet(field_3_string_options)) {
- retval= 9+2*getNameLength();
- }else {
- retval = 9 + getNameLength();
- }
- }
- return retval;
- }
-
- public short getSid()
- {
- return sid;
- }
+ /** shared by both user defined and built-in styles */
+ private int field_1_xf_index;
+
+ // only for built in styles
+ private int field_2_builtin_style;
+ private int field_3_outline_style_level;
+
+ // only for user defined styles
+ private int field_3_string_options;
+ private String field_4_name;
+
+ /**
+ * creates a new style record, initially set to 'built-in'
+ */
+ public StyleRecord() {
+ field_1_xf_index = isBuiltinFlag.set(field_1_xf_index);
+ }
+
+ public StyleRecord(RecordInputStream in) {
+ field_1_xf_index = in.readShort();
+ if (isBuiltin()) {
+ field_2_builtin_style = in.readByte();
+ field_3_outline_style_level = in.readByte();
+ } else {
+ int field_2_name_length = in.readShort();
+
+ if(in.remaining() < 1) {
+ // Some files from Crystal Reports lack the is16BitUnicode byte
+ // the remaining fields, which is naughty
+ if (field_2_name_length != 0) {
+ throw new RecordFormatException("Ran out of data reading style record");
+ }
+ // guess this is OK if the string length is zero
+ field_4_name = "";
+ } else {
+
+ int is16BitUnicode = in.readByte();
+ if (is16BitUnicodeFlag.isSet(is16BitUnicode)) {
+ field_4_name = StringUtil.readUnicodeLE(in, field_2_name_length);
+ } else {
+ field_4_name = StringUtil.readCompressedUnicode(in, field_2_name_length);
+ }
+ }
+ }
+ }
+
+ /**
+ * set the actual index of the style extended format record
+ * @param xfIndex of the xf record
+ */
+ public void setXFIndex(int xfIndex) {
+ field_1_xf_index = styleIndexMask.setValue(field_1_xf_index, xfIndex);
+ }
+
+ /**
+ * get the actual index of the style extended format record
+ * @see #getIndex()
+ * @return index of the xf record
+ */
+ public int getXFIndex() {
+ return styleIndexMask.getValue(field_1_xf_index);
+ }
+
+ /**
+ * set the style's name
+ * @param name of the style
+ */
+ public void setName(String name) {
+ field_4_name = name;
+ field_3_string_options = StringUtil.hasMultibyte(name) ? 0x01 : 0x00;
+ field_1_xf_index = isBuiltinFlag.clear(field_1_xf_index);
+ }
+
+ /**
+ * if this is a builtin style set the number of the built in style
+ * @param builtinStyleId style number (0-7)
+ *
+ */
+ public void setBuiltinStyle(int builtinStyleId) {
+ field_1_xf_index = isBuiltinFlag.set(field_1_xf_index);
+ field_2_builtin_style = builtinStyleId;
+ }
+
+ /**
+ * set the row or column level of the style (if builtin 1||2)
+ */
+ public void setOutlineStyleLevel(int level) {
+ field_3_outline_style_level = level & 0x00FF;
+ }
+
+ public boolean isBuiltin(){
+ return isBuiltinFlag.isSet(field_1_xf_index);
+ }
+
+ /**
+ * get the style's name
+ * @return name of the style
+ */
+ public String getName() {
+ return field_4_name;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("[STYLE]\n");
+ sb.append(" .xf_index_raw =").append(HexDump.shortToHex(field_1_xf_index)).append("\n");
+ sb.append(" .type =").append(isBuiltin() ? "built-in" : "user-defined").append("\n");
+ sb.append(" .xf_index =").append(HexDump.shortToHex(getXFIndex())).append("\n");
+ if (isBuiltin()){
+ sb.append(" .builtin_style=").append(HexDump.byteToHex(field_2_builtin_style)).append("\n");
+ sb.append(" .outline_level=").append(HexDump.byteToHex(field_3_outline_style_level)).append("\n");
+ } else {
+ sb.append(" .name =").append(getName()).append("\n");
+ }
+ sb.append("[/STYLE]\n");
+ return sb.toString();
+ }
+
+
+ private int getDataSize() {
+ if (isBuiltin()) {
+ return 4; // short, byte, byte
+ }
+ int size = 2 + 3; // short
+ if (is16BitUnicodeFlag.isSet(field_3_string_options)) {
+ size += 2 * field_4_name.length();
+ } else {
+ size += field_4_name.length();
+ }
+ return size;
+ }
+
+ public int serialize(int offset, byte [] data) {
+ int dataSize = getDataSize();
+ LittleEndian.putShort(data, 0 + offset, sid);
+ LittleEndian.putUShort(data, 2 + offset, dataSize);
+
+ LittleEndian.putUShort(data, 4 + offset, field_1_xf_index);
+ if (isBuiltin()) {
+ LittleEndian.putByte(data, 6 + offset, field_2_builtin_style);
+ LittleEndian.putByte(data, 7 + offset, field_3_outline_style_level);
+ } else {
+ LittleEndian.putUShort(data, 6 + offset, field_4_name.length());
+ LittleEndian.putByte(data, 8 + offset, field_3_string_options);
+ StringUtil.putCompressedUnicode(getName(), data, 9 + offset);
+ }
+ return 4+dataSize;
+ }
+
+ public int getRecordSize() {
+ return 4 + getDataSize();
+ }
+
+ public short getSid()
+ {
+ return sid;
+ }
}
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/SubRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/SubRecord.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/SubRecord.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/SubRecord.java Sun Oct 26 00:18:17 2008
@@ -27,6 +27,7 @@
import org.apache.poi.hssf.record.formula.RefPtg;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianByteArrayInputStream;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.LittleEndianOutputStream;
@@ -209,17 +210,12 @@
out.writeShort(_unknownShort13);
}
private static Ptg readRefPtg(byte[] formulaRawBytes) {
- byte[] data = new byte[formulaRawBytes.length + 4];
- LittleEndian.putUShort(data, 0, -5555);
- LittleEndian.putUShort(data, 2, formulaRawBytes.length);
- System.arraycopy(formulaRawBytes, 0, data, 4, formulaRawBytes.length);
- RecordInputStream in = new RecordInputStream(new ByteArrayInputStream(data));
- in.nextRecord();
- byte ptgSid = in.readByte();
+ LittleEndianInput in = new LittleEndianByteArrayInputStream(formulaRawBytes);
+ byte ptgSid = in.readByte();
switch(ptgSid) {
case AreaPtg.sid: return new AreaPtg(in);
case Area3DPtg.sid: return new Area3DPtg(in);
- case RefPtg.sid: return new RefPtg(in);
+ case RefPtg.sid: return new RefPtg(in);
case Ref3DPtg.sid: return new Ref3DPtg(in);
}
return null;
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/SupBookRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/SupBookRecord.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/SupBookRecord.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/SupBookRecord.java Sun Oct 26 00:18:17 2008
@@ -84,9 +84,11 @@
* @param offset of the record's data (provided a big array of the file)
*/
public SupBookRecord(RecordInputStream in) {
+ int recLen = in.remaining();
+
field_1_number_of_sheets = in.readShort();
- if(in.getLength() > SMALL_RECORD_SIZE) {
+ if(recLen > SMALL_RECORD_SIZE) {
// 5.38.1 External References
_isAddInFunctions = false;
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/TextObjectRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/TextObjectRecord.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/TextObjectRecord.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/TextObjectRecord.java Sun Oct 26 00:18:17 2008
@@ -25,6 +25,8 @@
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianByteArrayOutputStream;
+import org.apache.poi.util.LittleEndianOutput;
/**
* The TXO record (0x01B6) is used to define the properties of a text box. It is
@@ -129,13 +131,7 @@
_text = new HSSFRichTextString(text);
if (field_7_formattingDataLength > 0) {
- if (in.isContinueNext() && in.remaining() == 0) {
- in.nextRecord();
- processFontRuns(in, _text, field_7_formattingDataLength);
- } else {
- throw new RecordFormatException(
- "Expected Continue Record to hold font runs for TextObjectRecord");
- }
+ processFontRuns(in, _text, field_7_formattingDataLength);
}
}
@@ -154,10 +150,6 @@
throw new RecordFormatException("Bad format run data length " + formattingRunDataLength
+ ")");
}
- if (in.remaining() != formattingRunDataLength) {
- throw new RecordFormatException("Expected " + formattingRunDataLength
- + " bytes but got " + in.remaining());
- }
int nRuns = formattingRunDataLength / FORMAT_RUN_ENCODED_SIZE;
for (int i = 0; i < nRuns; i++) {
short index = in.readShort();
@@ -190,36 +182,31 @@
private int serializeTXORecord(int offset, byte[] data) {
int dataSize = getDataSize();
+ int recSize = dataSize+4;
+ LittleEndianOutput out = new LittleEndianByteArrayOutputStream(data, offset, recSize);
- LittleEndian.putUShort(data, 0 + offset, TextObjectRecord.sid);
- LittleEndian.putUShort(data, 2 + offset, dataSize);
-
+ out.writeShort(TextObjectRecord.sid);
+ out.writeShort(dataSize);
- LittleEndian.putUShort(data, 4 + offset, field_1_options);
- LittleEndian.putUShort(data, 6 + offset, field_2_textOrientation);
- LittleEndian.putUShort(data, 8 + offset, field_3_reserved4);
- LittleEndian.putUShort(data, 10 + offset, field_4_reserved5);
- LittleEndian.putUShort(data, 12 + offset, field_5_reserved6);
- LittleEndian.putUShort(data, 14 + offset, _text.length());
- LittleEndian.putUShort(data, 16 + offset, getFormattingDataLength());
- LittleEndian.putInt(data, 18 + offset, field_8_reserved7);
+ out.writeShort(field_1_options);
+ out.writeShort(field_2_textOrientation);
+ out.writeShort(field_3_reserved4);
+ out.writeShort(field_4_reserved5);
+ out.writeShort(field_5_reserved6);
+ out.writeShort(_text.length());
+ out.writeShort(getFormattingDataLength());
+ out.writeInt(field_8_reserved7);
if (_linkRefPtg != null) {
- int pos = offset+22;
int formulaSize = _linkRefPtg.getSize();
- LittleEndian.putUShort(data, pos, formulaSize);
- pos += LittleEndian.SHORT_SIZE;
- LittleEndian.putInt(data, pos, _unknownPreFormulaInt);
- pos += LittleEndian.INT_SIZE;
- _linkRefPtg.writeBytes(data, pos);
- pos += formulaSize;
+ out.writeShort(formulaSize);
+ out.writeInt(_unknownPreFormulaInt);
+ _linkRefPtg.write(out);
if (_unknownPostFormulaByte != null) {
- LittleEndian.putByte(data, pos, _unknownPostFormulaByte.byteValue());
- pos += LittleEndian.BYTE_SIZE;
+ out.writeByte(_unknownPostFormulaByte.byteValue());
}
}
-
- return 4 + dataSize;
+ return recSize;
}
private int serializeTrailingRecords(int offset, byte[] data) {
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/UnicodeString.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/UnicodeString.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/UnicodeString.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/UnicodeString.java Sun Oct 26 00:18:17 2008
@@ -36,13 +36,8 @@
* @author Andrew C. Oliver
* @author Marc Johnson (mjohnson at apache dot org)
* @author Glen Stampoultzis (glens at apache.org)
- * @version 2.0-pre
*/
-
-public class UnicodeString
- implements Comparable
-{
- public final static short sid = 0xFFF;
+public final class UnicodeString implements Comparable {
private short field_1_charCount; // = 0;
private byte field_2_optionflags; // = 0;
private String field_3_string; // = null;
@@ -53,8 +48,8 @@
private static final BitField richText = BitFieldFactory.getInstance(0x8);
public static class FormatRun implements Comparable {
- private short character;
- private short fontIndex;
+ short character;
+ short fontIndex;
public FormatRun(short character, short fontIndex) {
this.character = character;
@@ -102,15 +97,6 @@
setString(str);
}
- /**
- * construct a unicode string record and fill its fields, ID is ignored
- * @param in the RecordInputstream to read the record from
- */
-
- public UnicodeString(RecordInputStream in)
- {
- fillFields(in); // TODO - inline
- }
public int hashCode()
@@ -142,9 +128,9 @@
&& field_3_string.equals(other.field_3_string));
if (!eq) return false;
- //Ok string appears to be equal but now lets compare formatting runs
+ //OK string appears to be equal but now lets compare formatting runs
if ((field_4_format_runs == null) && (other.field_4_format_runs == null))
- //Strings are equal, and there are not formtting runs.
+ //Strings are equal, and there are not formatting runs.
return true;
if (((field_4_format_runs == null) && (other.field_4_format_runs != null)) ||
(field_4_format_runs != null) && (other.field_4_format_runs == null))
@@ -186,10 +172,10 @@
}
/**
+ * construct a unicode string record and fill its fields, ID is ignored
* @param in the RecordInputstream to read the record from
*/
- protected void fillFields(RecordInputStream in)
- {
+ public UnicodeString(RecordInputStream in) {
field_1_charCount = in.readShort();
field_2_optionflags = in.readByte();
@@ -206,35 +192,13 @@
extensionLength = in.readInt();
}
- //Now need to get the string data.
- //Turn off autocontinuation so that we can catch the continue boundary
- in.setAutoContinue(false);
- StringBuffer tmpString = new StringBuffer(field_1_charCount);
- int stringCharCount = field_1_charCount;
boolean isCompressed = ((field_2_optionflags & 1) == 0);
- while (stringCharCount != 0) {
- if (in.remaining() == 0) {
- if (in.isContinueNext()) {
- in.nextRecord();
- //Check if we are now reading, compressed or uncompressed unicode.
- byte optionflags = in.readByte();
- isCompressed = ((optionflags & 1) == 0);
- } else
- throw new RecordFormatException("Expected continue record.");
- }
- if (isCompressed) {
- char ch = (char)in.readUByte(); // avoid sex
- tmpString.append(ch);
- } else {
- char ch = (char) in.readShort();
- tmpString.append(ch);
- }
- stringCharCount --;
+ if (isCompressed) {
+ field_3_string = in.readCompressedUnicode(field_1_charCount);
+ } else {
+ field_3_string = in.readUnicodeLEString(field_1_charCount);
}
- field_3_string = tmpString.toString();
- //Turn back on autocontinuation
- in.setAutoContinue(true);
-
+
if (isRichText() && (runCount > 0)) {
field_4_format_runs = new ArrayList(runCount);
@@ -305,13 +269,8 @@
}
/**
- * get the actual string this contains as a java String object
- *
- *
- * @return String
- *
+ * @return the actual string this contains as a java String object
*/
-
public String getString()
{
return field_3_string;
@@ -341,7 +300,7 @@
}
}
if (useUTF16)
- //Set the uncomressed bit
+ //Set the uncompressed bit
field_2_optionflags = highByte.setByte(field_2_optionflags);
else field_2_optionflags = highByte.clearByte(field_2_optionflags);
}
@@ -392,7 +351,7 @@
//Make sure that we now say that we are a rich string
field_2_optionflags = richText.setByte(field_2_optionflags);
- }
+ }
public Iterator formatIterator() {
if (field_4_format_runs != null)
@@ -497,8 +456,8 @@
LittleEndian.putShort(data, offset, ContinueRecord.sid);
offset+=2;
- //Record the location of the last continue legnth position, but dont write
- //anything there yet (since we dont know what it will be!)
+ //Record the location of the last continue length position, but don't write
+ //anything there yet (since we don't know what it will be!)
stats.lastLengthPos = offset;
offset += 2;
@@ -506,7 +465,7 @@
stats.remainingSize = SSTRecord.MAX_RECORD_SIZE-4;
}
return offset;
- }
+ }
public int serialize(UnicodeRecordStats stats, final int offset, byte [] data)
{
@@ -514,7 +473,6 @@
//Basic string overhead
pos = writeContinueIfRequired(stats, 3, pos, data);
- // byte[] retval = new byte[ 3 + (getString().length() * charsize)];
LittleEndian.putShort(data, pos, getCharCount());
pos += 2;
data[ pos ] = getOptionFlags();
@@ -568,39 +526,39 @@
//Check to see if the offset occurs mid string, if so then we need to add
//the byte to start with that represents the first byte of the continue record.
if (strSize > stats.remainingSize) {
- //Ok the offset occurs half way through the string, that means that
+ //OK the offset occurs half way through the string, that means that
//we need an extra byte after the continue record ie we didnt finish
//writing out the string the 1st time through
//But hang on, how many continue records did we span? What if this is
//a REALLY long string. We need to work this all out.
- int ammountThatCantFit = strSize;
+ int amountThatCantFit = strSize;
int strPos = 0;
- while (ammountThatCantFit > 0) {
- int ammountWritten = Math.min(stats.remainingSize, ammountThatCantFit);
- //Make sure that the ammount that cant fit takes into account
+ while (amountThatCantFit > 0) {
+ int amountWritten = Math.min(stats.remainingSize, amountThatCantFit);
+ //Make sure that the amount that can't fit takes into account
//whether we are writing double byte unicode
if (isUncompressedUnicode()) {
//We have the '-1' here because whether this is the first record or
//subsequent continue records, there is always the case that the
- //number of bytes in a string on doube byte boundaries is actually odd.
- if ( ( (ammountWritten ) % 2) == 1)
- ammountWritten--;
- }
- System.arraycopy(strBytes, strPos, data, pos, ammountWritten);
- pos += ammountWritten;
- strPos += ammountWritten;
- stats.recordSize += ammountWritten;
- stats.remainingSize -= ammountWritten;
+ //number of bytes in a string on double byte boundaries is actually odd.
+ if ( ( (amountWritten ) % 2) == 1)
+ amountWritten--;
+ }
+ System.arraycopy(strBytes, strPos, data, pos, amountWritten);
+ pos += amountWritten;
+ strPos += amountWritten;
+ stats.recordSize += amountWritten;
+ stats.remainingSize -= amountWritten;
//Ok lets subtract what we can write
- ammountThatCantFit -= ammountWritten;
+ amountThatCantFit -= amountWritten;
//Each iteration of this while loop is another continue record, unless
//everything now fits.
- if (ammountThatCantFit > 0) {
+ if (amountThatCantFit > 0) {
//We know that a continue WILL be requied, but use this common method
- pos = writeContinueIfRequired(stats, ammountThatCantFit, pos, data);
+ pos = writeContinueIfRequired(stats, amountThatCantFit, pos, data);
//The first byte after a continue mid string is the extra byte to
//indicate if this run is compressed or not.
@@ -686,7 +644,7 @@
return highByte.isSet(getOptionFlags());
}
- /** Returns the size of this record, given the ammount of record space
+ /** Returns the size of this record, given the amount of record space
* remaining, it will also include the size of writing a continue record.
*/
@@ -833,13 +791,6 @@
}
}
-
-
- public short getSid()
- {
- return sid;
- }
-
public int compareTo(Object obj)
{
UnicodeString str = ( UnicodeString ) obj;
@@ -877,7 +828,7 @@
}
//Well the format runs are equal as well!, better check the ExtRst data
- //Which by the way we dont know how to decode!
+ //Which by the way we don't know how to decode!
if ((field_5_ext_rst == null) && (str.field_5_ext_rst == null))
return 0;
if ((field_5_ext_rst == null) && (str.field_5_ext_rst != null))
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/WriteAccessRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/WriteAccessRecord.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/WriteAccessRecord.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/WriteAccessRecord.java Sun Oct 26 00:18:17 2008
@@ -1,4 +1,3 @@
-
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@@ -15,111 +14,130 @@
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.StringUtil;
/**
- * Title: Write Access Record<P>
- * Description: Stores the username of that who owns the spreadsheet generator
- * (on unix the user's login, on Windoze its the name you typed when
- * you installed the thing)<P>
- * REFERENCE: PG 424 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
+ * Title: Write Access Record (0x005C)<p/>
+ *
+ * Description: Stores the username of that who owns the spreadsheet generator (on unix the user's
+ * login, on Windoze its the name you typed when you installed the thing)
+ * <p/>
+ * REFERENCE: PG 424 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
+ * <p/>
+ *
* @author Andrew C. Oliver (acoliver at apache dot org)
- * @version 2.0-pre
*/
-
-public class WriteAccessRecord
- extends Record
-{
- public final static short sid = 0x5c;
- private String field_1_username;
-
- public WriteAccessRecord()
- {
- }
-
- public WriteAccessRecord(RecordInputStream in)
- {
- byte[] data = in.readRemainder();
- //The string is always 112 characters (padded with spaces), therefore
- //this record can not be continued.
-
- //What a wierd record, it is not really a unicode string because the
- //header doesnt provide a correct size indication.???
- //But the header is present, so we need to skip over it.
- //Odd, Odd, Odd ;-)
- field_1_username = StringUtil.getFromCompressedUnicode(data, 3, data.length - 3);
- }
-
- /**
- * set the username for the user that created the report. HSSF uses the logged in user.
- * @param username of the user who is logged in (probably "tomcat" or "apache")
- */
-
- public void setUsername(String username)
- {
- field_1_username = username;
- }
-
- /**
- * get the username for the user that created the report. HSSF uses the logged in user. On
- * natively created M$ Excel sheet this would be the name you typed in when you installed it
- * in most cases.
- * @return username of the user who is logged in (probably "tomcat" or "apache")
- */
-
- public String getUsername()
- {
- return field_1_username;
- }
-
- public String toString()
- {
- StringBuffer buffer = new StringBuffer();
-
- buffer.append("[WRITEACCESS]\n");
- buffer.append(" .name = ")
- .append(field_1_username.toString()).append("\n");
- buffer.append("[/WRITEACCESS]\n");
- return buffer.toString();
- }
-
- public int serialize(int offset, byte [] data)
- {
- String username = getUsername();
- StringBuffer temp = new StringBuffer(0x70 - (0x3));
-
- temp.append(username);
- while (temp.length() < 0x70 - 0x3)
- {
- temp.append(
- " "); // (70 = fixed lenght -3 = the overhead bits of unicode string)
- }
- username = temp.toString();
- UnicodeString str = new UnicodeString(username);
- str.setOptionFlags(( byte ) 0x0);
-
- LittleEndian.putShort(data, 0 + offset, sid);
- LittleEndian.putShort(data, 2 + offset, (short)112); // 112 bytes (115 total)
- UnicodeString.UnicodeRecordStats stats = new UnicodeString.UnicodeRecordStats();
- stats.recordSize += 4;
- stats.remainingSize-= 4;
- str.serialize(stats, 4 + offset, data);
-
- return getRecordSize();
- }
-
- public int getRecordSize()
- {
- return 116;
- }
-
- public short getSid()
- {
- return sid;
- }
+public final class WriteAccessRecord extends Record {
+ private static final byte PAD_CHAR = (byte) ' ';
+ public final static short sid = 0x005C;
+ private static final int DATA_SIZE = 112;
+ private String field_1_username;
+ /** this record is always padded to a constant length */
+ private byte[] padding;
+
+ public WriteAccessRecord() {
+ setUsername("");
+ padding = new byte[DATA_SIZE - 3];
+ }
+
+ public WriteAccessRecord(RecordInputStream in) {
+ if (in.remaining() > DATA_SIZE) {
+ throw new RecordFormatException("Expected data size (" + DATA_SIZE + ") but got ("
+ + in.remaining() + ")");
+ }
+ // The string is always 112 characters (padded with spaces), therefore
+ // this record can not be continued.
+
+ int nChars = in.readUShort();
+ int is16BitFlag = in.readUByte();
+ int expectedPadSize = DATA_SIZE - 3;
+ if ((is16BitFlag & 0x01) == 0x00) {
+ field_1_username = StringUtil.readCompressedUnicode(in, nChars);
+ expectedPadSize -= nChars;
+ } else {
+ field_1_username = StringUtil.readUnicodeLE(in, nChars);
+ expectedPadSize -= nChars * 2;
+ }
+ padding = new byte[expectedPadSize];
+ int padSize = in.remaining();
+ in.readFully(padding, 0, padSize);
+ if (padSize < expectedPadSize) {
+ // this occurs in a couple of test examples: "42564.xls",
+ // "bug_42794.xls"
+ Arrays.fill(padding, padSize, expectedPadSize, PAD_CHAR);
+ }
+ }
+
+ /**
+ * set the username for the user that created the report. HSSF uses the
+ * logged in user.
+ *
+ * @param username of the user who is logged in (probably "tomcat" or "apache")
+ */
+ public void setUsername(String username) {
+ boolean is16bit = StringUtil.hasMultibyte(username);
+ int encodedByteCount = 3 + username.length() * (is16bit ? 2 : 1);
+ int paddingSize = DATA_SIZE - encodedByteCount;
+ if (paddingSize < 0) {
+ throw new IllegalArgumentException("Name is too long: " + username);
+ }
+ padding = new byte[paddingSize];
+ Arrays.fill(padding, PAD_CHAR);
+
+ field_1_username = username;
+ }
+
+ /**
+ * get the username for the user that created the report. HSSF uses the
+ * logged in user. On natively created M$ Excel sheet this would be the name
+ * you typed in when you installed it in most cases.
+ *
+ * @return username of the user who is logged in (probably "tomcat" or "apache")
+ */
+ public String getUsername() {
+ return field_1_username;
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append("[WRITEACCESS]\n");
+ buffer.append(" .name = ").append(field_1_username.toString()).append("\n");
+ buffer.append("[/WRITEACCESS]\n");
+ return buffer.toString();
+ }
+
+ public int serialize(int offset, byte[] data) {
+ String username = getUsername();
+ boolean is16bit = StringUtil.hasMultibyte(username);
+
+ LittleEndian.putUShort(data, 0 + offset, sid);
+ LittleEndian.putUShort(data, 2 + offset, DATA_SIZE);
+ LittleEndian.putUShort(data, 4 + offset, username.length());
+ LittleEndian.putByte(data, 6 + offset, is16bit ? 0x01 : 0x00);
+ int pos = offset + 7;
+ if (is16bit) {
+ StringUtil.putUnicodeLE(username, data, pos);
+ pos += username.length() * 2;
+ } else {
+ StringUtil.putCompressedUnicode(username, data, pos);
+ pos += username.length();
+ }
+ System.arraycopy(padding, 0, data, pos, padding.length);
+ return 4 + DATA_SIZE;
+ }
+
+ public int getRecordSize() {
+ return 4 + DATA_SIZE;
+ }
+
+ public short getSid() {
+ return sid;
+ }
}
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java Sun Oct 26 00:18:17 2008
@@ -17,10 +17,11 @@
package org.apache.poi.hssf.record.constant;
-import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.record.UnicodeString;
import org.apache.poi.hssf.record.UnicodeString.UnicodeRecordStats;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
/**
* To support Constant Values (2.5.7) as required by the CRN record.
@@ -47,7 +48,7 @@
// no instances of this class
}
- public static Object[] parse(RecordInputStream in, int nValues) {
+ public static Object[] parse(LittleEndianInput in, int nValues) {
Object[] result = new Object[nValues];
for (int i = 0; i < result.length; i++) {
result[i] = readAConstantValue(in);
@@ -55,7 +56,7 @@
return result;
}
- private static Object readAConstantValue(RecordInputStream in) {
+ private static Object readAConstantValue(LittleEndianInput in) {
byte grbit = in.readByte();
switch(grbit) {
case TYPE_EMPTY:
@@ -64,7 +65,7 @@
case TYPE_NUMBER:
return new Double(in.readDouble());
case TYPE_STRING:
- return in.readUnicodeString();
+ return new UnicodeString(StringUtil.readUnicodeString(in));
case TYPE_BOOLEAN:
return readBoolean(in);
case TYPE_ERROR_CODE:
@@ -77,7 +78,7 @@
throw new RuntimeException("Unknown grbit value (" + grbit + ")");
}
- private static Object readBoolean(RecordInputStream in) {
+ private static Object readBoolean(LittleEndianInput in) {
byte val = (byte)in.readLong(); // 7 bytes 'not used'
switch(val) {
case FALSE_ENCODING:
@@ -116,46 +117,43 @@
return urs.recordSize;
}
- public static void encode(byte[] data, int offset, Object[] values) {
- int currentOffset = offset;
+ public static void encode(LittleEndianOutput out, Object[] values) {
for (int i = 0; i < values.length; i++) {
- currentOffset += encodeSingleValue(data, currentOffset, values[i]);
+ encodeSingleValue(out, values[i]);
}
}
- private static int encodeSingleValue(byte[] data, int offset, Object value) {
+ private static void encodeSingleValue(LittleEndianOutput out, Object value) {
if (value == EMPTY_REPRESENTATION) {
- LittleEndian.putByte(data, offset, TYPE_EMPTY);
- LittleEndian.putLong(data, offset+1, 0L);
- return 9;
+ out.writeByte(TYPE_EMPTY);
+ out.writeLong(0L);
+ return;
}
if (value instanceof Boolean) {
Boolean bVal = ((Boolean)value);
- LittleEndian.putByte(data, offset, TYPE_BOOLEAN);
+ out.writeByte(TYPE_BOOLEAN);
long longVal = bVal.booleanValue() ? 1L : 0L;
- LittleEndian.putLong(data, offset+1, longVal);
- return 9;
+ out.writeLong(longVal);
+ return;
}
if (value instanceof Double) {
Double dVal = (Double) value;
- LittleEndian.putByte(data, offset, TYPE_NUMBER);
- LittleEndian.putDouble(data, offset+1, dVal.doubleValue());
- return 9;
+ out.writeByte(TYPE_NUMBER);
+ out.writeDouble(dVal.doubleValue());
+ return;
}
if (value instanceof UnicodeString) {
UnicodeString usVal = (UnicodeString) value;
- LittleEndian.putByte(data, offset, TYPE_STRING);
- UnicodeRecordStats urs = new UnicodeRecordStats();
- usVal.serialize(urs, offset +1, data);
- return 1 + urs.recordSize;
+ out.writeByte(TYPE_STRING);
+ StringUtil.writeUnicodeString(out, usVal.getString());
+ return;
}
if (value instanceof ErrorConstant) {
ErrorConstant ecVal = (ErrorConstant) value;
- LittleEndian.putByte(data, offset, TYPE_ERROR_CODE);
- LittleEndian.putUShort(data, offset+1, ecVal.getErrorCode());
- LittleEndian.putUShort(data, offset+3, 0);
- LittleEndian.putInt(data, offset+5, 0);
- return 9;
+ out.writeByte(TYPE_ERROR_CODE);
+ long longVal = ecVal.getErrorCode();
+ out.writeLong(longVal);
+ return;
}
throw new IllegalStateException("Unexpected value type (" + value.getClass().getName() + "'");
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java Sun Oct 26 00:18:17 2008
@@ -98,7 +98,6 @@
buf.append(")");
}
- public abstract void writeBytes(byte[] array, int offset);
public abstract int getSize();
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java Sun Oct 26 00:18:17 2008
@@ -17,42 +17,48 @@
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
/**
- * Common superclass of 2-D area refs
+ * Common superclass of 2-D area refs
*/
public abstract class Area2DPtgBase extends AreaPtgBase {
- private final static int SIZE = 9;
+ private final static int SIZE = 9;
protected Area2DPtgBase(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
}
- protected Area2DPtgBase(RecordInputStream in) {
+
+ protected Area2DPtgBase(LittleEndianInput in) {
readCoordinates(in);
}
+
protected abstract byte getSid();
- public final void writeBytes(byte [] array, int offset) {
- LittleEndian.putByte(array, offset+0, getSid() + getPtgClass());
- writeCoordinates(array, offset+1);
+ public final void write(LittleEndianOutput out) {
+ out.writeByte(getSid() + getPtgClass());
+ writeCoordinates(out);
}
+
public Area2DPtgBase(String arearef) {
- super(arearef);
+ super(arearef);
}
+
public final int getSize() {
return SIZE;
}
+
public final String toFormulaString() {
- return formatReferenceAsString();
+ return formatReferenceAsString();
+ }
+
+ public final String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append(" [");
+ sb.append(formatReferenceAsString());
+ sb.append("]");
+ return sb.toString();
}
- public final String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append(getClass().getName());
- sb.append(" [");
- sb.append(formatReferenceAsString());
- sb.append("]");
- return sb.toString();
- }
}
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java Sun Oct 26 00:18:17 2008
@@ -17,11 +17,11 @@
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.ss.formula.ExternSheetReferenceToken;
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
import org.apache.poi.ss.formula.WorkbookDependentFormula;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
/**
* Title: Area 3D Ptg - 3D reference (Sheet + Area)<P>
@@ -44,7 +44,7 @@
setExternSheetIndex( externIdx );
}
- public Area3DPtg(RecordInputStream in) {
+ public Area3DPtg(LittleEndianInput in) {
field_1_index_extern_sheet = in.readShort();
readCoordinates(in);
}
@@ -67,10 +67,10 @@
return sb.toString();
}
- public void writeBytes(byte[] array, int offset) {
- LittleEndian.putByte(array, offset + 0, sid + getPtgClass());
- LittleEndian.putUShort(array, 1 + offset, field_1_index_extern_sheet);
- writeCoordinates(array, offset+3);
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeShort(field_1_index_extern_sheet);
+ writeCoordinates(out);
}
public int getSize() {
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java Sun Oct 26 00:18:17 2008
@@ -17,9 +17,9 @@
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
-import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
/**
* AreaErr - handles deleted cell area references.
@@ -36,16 +36,16 @@
unused2 = 0;
}
- public AreaErrPtg(RecordInputStream in) {
+ public AreaErrPtg(LittleEndianInput in) {
// 8 bytes unused:
unused1 = in.readInt();
unused2 = in.readInt();
}
- public void writeBytes(byte[] array, int offset) {
- LittleEndian.putByte(array, offset + 0, sid + getPtgClass());
- LittleEndian.putInt(array, offset + 1, unused1);
- LittleEndian.putInt(array, offset + 5, unused2);
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeInt(unused1);
+ out.writeInt(unused2);
}
public String toFormulaString() {
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaNPtg.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaNPtg.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaNPtg.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaNPtg.java Sun Oct 26 00:18:17 2008
@@ -17,7 +17,7 @@
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.LittleEndianInput;
/**
* Specifies a rectangular area of cells A1:A4 for instance.
@@ -26,7 +26,7 @@
public final class AreaNPtg extends Area2DPtgBase {
public final static short sid = 0x2D;
- public AreaNPtg(RecordInputStream in) {
+ public AreaNPtg(LittleEndianInput in) {
super(in);
}
Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java?rev=707945&r1=707944&r2=707945&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java Sun Oct 26 00:18:17 2008
@@ -17,7 +17,7 @@
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.LittleEndianInput;
/**
* Specifies a rectangular area of cells A1:A4 for instance.
@@ -29,7 +29,7 @@
public AreaPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
}
- public AreaPtg(RecordInputStream in) {
+ public AreaPtg(LittleEndianInput in) {
super(in);
}
public AreaPtg(String arearef) {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org