From 294932abb8717e37f3e23b7928107dd75f063d0d Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Mon, 19 May 2008 06:35:30 +0000 Subject: [PATCH] merged with trunk r657726 git-svn-id: https://svn.apache.org/repos/asf/poi/tags/REL_3_1_BETA2@657731 13f79535-47bb-0310-9956-ffa450edef68 --- .../hssf/usermodel/contrib/HSSFCellUtil.java | 15 +- src/documentation/content/xdocs/changes.xml | 11 + .../content/xdocs/hssf/quick-guide.xml | 14 +- src/documentation/content/xdocs/status.xml | 11 + src/documentation/release-guide.txt | 4 +- .../org/apache/poi/hssf/dev/BiffViewer.java | 545 +++----- .../apache/poi/hssf/model/FormulaParser.java | 5 +- src/java/org/apache/poi/hssf/model/Sheet.java | 1167 +++++------------ .../apache/poi/hssf/record/LabelRecord.java | 52 +- .../apache/poi/hssf/record/PaneRecord.java | 26 +- .../org/apache/poi/hssf/record/RowRecord.java | 65 +- .../poi/hssf/record/WindowOneRecord.java | 75 +- .../poi/hssf/record/WindowTwoRecord.java | 30 +- .../aggregates/RowRecordsAggregate.java | 47 +- .../record/constant/ConstantValueParser.java | 3 +- .../hssf/record/constant/ErrorConstant.java | 27 +- .../poi/hssf/record/formula/ArrayPtg.java | 374 +++--- .../poi/hssf/record/formula/ArrayPtgA.java | 35 +- .../poi/hssf/record/formula/ArrayPtgV.java | 36 +- .../poi/hssf/record/formula/AttrPtg.java | 82 +- .../poi/hssf/record/formula/FuncPtg.java | 20 +- .../poi/hssf/record/formula/StringPtg.java | 151 ++- .../hssf/record/formula/eval/Area2DEval.java | 80 +- .../hssf/record/formula/eval/Area3DEval.java | 86 +- .../record/formula/eval/AreaEvalBase.java | 122 ++ .../function/FunctionMetadataReader.java | 22 +- .../apache/poi/hssf/usermodel/HSSFCell.java | 3 +- .../hssf/usermodel/HSSFFormulaEvaluator.java | 3 +- .../apache/poi/hssf/usermodel/HSSFName.java | 9 + .../apache/poi/hssf/usermodel/HSSFRow.java | 40 +- .../apache/poi/hssf/usermodel/HSSFSheet.java | 96 +- .../poi/hssf/usermodel/HSSFWorkbook.java | 203 ++- .../poi/poifs/storage/BlockListImpl.java | 3 +- .../poi/poifs/storage/RawDataBlock.java | 5 +- src/records/definitions/pane_record.xml | 2 +- .../function/functionMetadata-asGenerated.txt | 46 +- .../formula/function/functionMetadata.txt | 46 +- .../poi/hslf/examples/DataExtraction.java | 23 +- .../apache/poi/hslf/model/ShapeFactory.java | 1 + .../org/apache/poi/hslf/model/TextRun.java | 49 +- .../org/apache/poi/hslf/record/ExControl.java | 95 ++ .../apache/poi/hslf/record/ExControlAtom.java | 96 ++ .../org/apache/poi/hslf/record/ExEmbed.java | 20 +- .../apache/poi/hslf/record/ExOleObjStg.java | 25 +- .../apache/poi/hslf/record/RecordTypes.java | 2 +- .../poi/hslf/record/TextSpecInfoAtom.java | 115 ++ .../apache/poi/hslf/usermodel/ObjectData.java | 10 + .../poi/hslf/usermodel/RichTextRun.java | 12 +- .../org/apache/poi/hwpf/model/ListLevel.java | 68 +- .../poi/hslf/record/TestTextSpecInfoAtom.java | 95 ++ .../org/apache/poi/hssf/HSSFTests.java | 8 +- .../org/apache/poi/hssf/data/24207.xls | Bin 0 -> 13824 bytes .../org/apache/poi/hssf/data/36947.xls | Bin 0 -> 142336 bytes .../org/apache/poi/hssf/data/39634.xls | Bin 0 -> 68608 bytes .../org/apache/poi/hssf/data/44235.xls | Bin 0 -> 78336 bytes .../apache/poi/hssf/data/ex41187-19267.xls | Bin 0 -> 5632 bytes .../apache/poi/hssf/data/ex42570-20305.xls | Bin 0 -> 192512 bytes .../apache/poi/hssf/model/AllModelTests.java | 40 + .../poi/hssf/model/TestFormulaParser.java | 110 +- .../org/apache/poi/hssf/model/TestSheet.java | 184 ++- .../poi/hssf/model/TestSheetAdditional.java | 266 +--- .../poi/hssf/record/AllRecordTests.java | 1 + .../hssf/record/TestExternalNameRecord.java | 2 + .../poi/hssf/record/TestFormulaRecord.java | 51 +- .../poi/hssf/record/TestLabelRecord.java | 41 + .../aggregates/TestRowRecordsAggregate.java | 31 +- .../hssf/record/formula/AllFormulaTests.java | 1 + .../poi/hssf/record/formula/TestArrayPtg.java | 95 ++ .../poi/hssf/record/formula/TestFuncPtg.java | 53 +- .../formula/eval/AllFormulaEvalTests.java | 3 +- .../record/formula/eval/TestAreaEval.java | 62 + .../ExcelFileFormatDocFunctionExtractor.java | 98 +- .../formula/functions/TestCountFuncs.java | 7 +- .../record/formula/functions/TestIndex.java | 6 - .../poi/hssf/usermodel/AllUserModelTests.java | 12 +- .../apache/poi/hssf/usermodel/TestBugs.java | 86 +- .../usermodel/TestFormulaEvaluatorBugs.java | 132 +- .../poi/hssf/usermodel/TestHSSFRow.java | 54 +- .../poi/hssf/usermodel/TestHSSFSheet.java | 100 +- .../poi/hssf/usermodel/TestHSSFWorkbook.java | 240 +++- .../poi/hssf/usermodel/TestNamedRange.java | 24 + .../apache/poi/poifs/data/ShortLastBlock.qwp | Bin 0 -> 1303681 bytes .../apache/poi/poifs/data/ShortLastBlock.wps | Bin 0 -> 140787 bytes .../poifs/filesystem/TestPOIFSFileSystem.java | 37 + .../poi/poifs/storage/TestRawDataBlock.java | 2 +- 85 files changed, 3119 insertions(+), 2799 deletions(-) create mode 100644 src/java/org/apache/poi/hssf/record/formula/eval/AreaEvalBase.java create mode 100755 src/scratchpad/src/org/apache/poi/hslf/record/ExControl.java create mode 100755 src/scratchpad/src/org/apache/poi/hslf/record/ExControlAtom.java create mode 100755 src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextSpecInfoAtom.java create mode 100755 src/testcases/org/apache/poi/hssf/data/24207.xls create mode 100755 src/testcases/org/apache/poi/hssf/data/36947.xls create mode 100755 src/testcases/org/apache/poi/hssf/data/39634.xls create mode 100755 src/testcases/org/apache/poi/hssf/data/44235.xls create mode 100644 src/testcases/org/apache/poi/hssf/data/ex41187-19267.xls create mode 100644 src/testcases/org/apache/poi/hssf/data/ex42570-20305.xls create mode 100755 src/testcases/org/apache/poi/hssf/model/AllModelTests.java create mode 100644 src/testcases/org/apache/poi/hssf/record/TestLabelRecord.java create mode 100644 src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java create mode 100644 src/testcases/org/apache/poi/hssf/record/formula/eval/TestAreaEval.java create mode 100644 src/testcases/org/apache/poi/poifs/data/ShortLastBlock.qwp create mode 100644 src/testcases/org/apache/poi/poifs/data/ShortLastBlock.wps diff --git a/src/contrib/src/org/apache/poi/hssf/usermodel/contrib/HSSFCellUtil.java b/src/contrib/src/org/apache/poi/hssf/usermodel/contrib/HSSFCellUtil.java index 7c17614ec31..5e2cf1e0fe7 100644 --- a/src/contrib/src/org/apache/poi/hssf/usermodel/contrib/HSSFCellUtil.java +++ b/src/contrib/src/org/apache/poi/hssf/usermodel/contrib/HSSFCellUtil.java @@ -55,10 +55,10 @@ public class HSSFCellUtil */ public static HSSFRow getRow( int rowCounter, HSSFSheet sheet ) { - HSSFRow row = sheet.getRow( (short) rowCounter ); + HSSFRow row = sheet.getRow( rowCounter ); if ( row == null ) { - row = sheet.createRow( (short) rowCounter ); + row = sheet.createRow( rowCounter ); } return row; @@ -66,7 +66,8 @@ public static HSSFRow getRow( int rowCounter, HSSFSheet sheet ) /** - * Get a specific cell from a row. If the cell doesn't exist, then create it. + * Get a specific cell from a row. If the cell doesn't exist, + * then create it. * *@param row The row that the cell is part of *@param column The column index that the cell is in. @@ -74,11 +75,11 @@ public static HSSFRow getRow( int rowCounter, HSSFSheet sheet ) */ public static HSSFCell getCell( HSSFRow row, int column ) { - HSSFCell cell = row.getCell( (short) column ); + HSSFCell cell = row.getCell( column ); if ( cell == null ) { - cell = row.createCell( (short) column ); + cell = row.createCell( (short)column ); } return cell; } @@ -98,7 +99,7 @@ public static HSSFCell createCell( HSSFRow row, int column, String value, HSSFCe { HSSFCell cell = getCell( row, column ); - cell.setCellValue( value ); + cell.setCellValue(new HSSFRichTextString(value)); if ( style != null ) { cell.setCellStyle( style ); @@ -222,7 +223,7 @@ public static void setCellStyleProperty( HSSFCell cell, HSSFWorkbook workbook, S public static HSSFCell translateUnicodeValues( HSSFCell cell ) { - String s = cell.getStringCellValue(); + String s = cell.getRichStringCellValue().getString(); boolean foundUnicode = false; for ( Iterator i = unicodeMappings.entrySet().iterator(); i.hasNext(); ) diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index 150b41ff9d4..f6f5f8a6208 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -37,6 +37,17 @@ + 44306 - fixed reading/writing of AttrPtg(type=choose) and method toFormulaString() for CHOOSE formulas + 24207 - added HSSFName.isDeleted() to check if the name points to cell that no longer exists + 40414 - fixed selected/active sheet after removing sheet from workbook + 44523 - fixed workbook sheet selection and focus + 45000 - Fixed NPE in ListLevel when numberText is null + 44985 - Properly update TextSpecInfoAtom when the parent text is changed + 41187 - fixed HSSFSheet to properly read xls files without ROW records + 44950 - fixed HSSFFormulaEvaluator.evaluateInCell() and Area3DEval.getValue() also added validation for number of elements in AreaEvals + 42570 - fixed LabelRecord to use empty string instead of null when the length is zero. + 42564 - fixed ArrayPtg to use ConstantValueParser. Fixed a few other ArrayPtg encoding issues. + Follow-on from 28754 - StringPtg.toFormulaString() should escape double quotes 44929 - Improved error handling in HSSFWorkbook when attempting to read a BIFF5 file 44675 - Parameter operand classes (function metadata) required to encode SUM() etc properly. Added parse validation for number of parameters 44921 - allow Ptg.writeBytes() to be called on relative ref Ptgs (RefN* and AreaN*) diff --git a/src/documentation/content/xdocs/hssf/quick-guide.xml b/src/documentation/content/xdocs/hssf/quick-guide.xml index 66da6048923..28e23743387 100644 --- a/src/documentation/content/xdocs/hssf/quick-guide.xml +++ b/src/documentation/content/xdocs/hssf/quick-guide.xml @@ -1225,7 +1225,19 @@ Examples: // Do something with this corner cell } } - + +

+ Note, when a cell is deleted, Excel does not delete the attached named range. + As result, workbook can contain named ranges that point to cells that no longer exist. + You should check the validity of a reference before constructing AreaReference +

+ + if(hssfName.isDeleted()){ + //named range points to a deleted cell. + } else { + AreaReference ref = new AreaReference(hssfName.getReference()); + } +
Cell Comments diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index e9059493b7d..2b5196f9624 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,17 @@ + 44306 - fixed reading/writing of AttrPtg(type=choose) and method toFormulaString() for CHOOSE formulas + 24207 - added HSSFName.isDeleted() to check if the name points to cell that no longer exists + 40414 - fixed selected/active sheet after removing sheet from workbook + 44523 - fixed workbook sheet selection and focus + 45000 - Fixed NPE in ListLevel when numberText is null + 44985 - Properly update TextSpecInfoAtom when the parent text is changed + 41187 - fixed HSSFSheet to properly read xls files without ROW records + 44950 - fixed HSSFFormulaEvaluator.evaluateInCell() and Area3DEval.getValue() also added validation for number of elements in AreaEvals + 42570 - fixed LabelRecord to use empty string instead of null when the length is zero. + 42564 - fixed ArrayPtg to use ConstantValueParser. Fixed a few other ArrayPtg encoding issues. + Follow-on from 28754 - StringPtg.toFormulaString() should escape double quotes 44929 - Improved error handling in HSSFWorkbook when attempting to read a BIFF5 file 44675 - Parameter operand classes (function metadata) required to encode SUM() etc properly. Added parse validation for number of parameters 44921 - allow Ptg.writeBytes() to be called on relative ref Ptgs (RefN* and AreaN*) diff --git a/src/documentation/release-guide.txt b/src/documentation/release-guide.txt index 56ebf3fa1d3..e1fbc94e6f6 100755 --- a/src/documentation/release-guide.txt +++ b/src/documentation/release-guide.txt @@ -37,14 +37,14 @@ where $TAG is the release tag, for example, REL_3_1_BETA1 3. Checkout the tagged version {code} cd tags -svn checkout https://svn.apache.org/repos/asf/poi/tags/TAG +svn checkout https://svn.apache.org/repos/asf/poi/tags/$TAG {code} 4. Merge (if required) {code} cd $TAG -$ svn merge https://svn.apache.org/repos/asf/poi/tags/TAG \ +$ svn merge https://svn.apache.org/repos/asf/poi/tags/$TAG \ https://svn.apache.org/repos/asf/poi/trunk {code} diff --git a/src/java/org/apache/poi/hssf/dev/BiffViewer.java b/src/java/org/apache/poi/hssf/dev/BiffViewer.java index 8263d1b9b9c..cd436519128 100644 --- a/src/java/org/apache/poi/hssf/dev/BiffViewer.java +++ b/src/java/org/apache/poi/hssf/dev/BiffViewer.java @@ -15,22 +15,20 @@ Licensed to the Apache Software Foundation (ASF) under one or more limitations under the License. ==================================================================== */ -/* - * BiffViewer.java - * - * Created on November 13, 2001, 9:23 AM - */ package org.apache.poi.hssf.dev; -import org.apache.poi.hssf.record.*; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.HexDump; - +import java.io.File; import java.io.FileInputStream; -import java.io.IOException; +import java.io.FileOutputStream; import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; import java.util.ArrayList; +import org.apache.poi.hssf.record.*; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.util.HexDump; + /** * Utillity for reading in BIFF8 records and displaying data from them. * @@ -38,38 +36,26 @@ Licensed to the Apache Software Foundation (ASF) under one or more *@author Glen Stampoultzis (glens at apache.org) *@see #main */ - -public class BiffViewer { - String filename; +public final class BiffViewer { + private final File _inputFile; private boolean dump; + private final PrintStream _ps; - /** - * Creates new BiffViewer - * - *@param args - */ - - public BiffViewer(String[] args) { - if (args.length > 0) { - filename = args[0]; - } else { - System.out.println("BIFFVIEWER REQUIRES A FILENAME***"); - } + public BiffViewer(File inFile, PrintStream ps) { + _inputFile = inFile; + _ps = ps; } /** * Method run starts up BiffViewer... */ - public void run() { try { - POIFSFileSystem fs = - new POIFSFileSystem(new FileInputStream(filename)); - InputStream stream = - fs.createDocumentInputStream("Workbook"); - createRecords(stream, dump); + POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(_inputFile)); + InputStream stream = fs.createDocumentInputStream("Workbook"); + createRecords(stream, dump, _ps); } catch (Exception e) { e.printStackTrace(); } @@ -86,451 +72,306 @@ public void run() { * InputStream *@exception RecordFormatException on error processing the InputStream */ - - public static Record[] createRecords(InputStream in, boolean dump) + public static Record[] createRecords(InputStream in, boolean dump, PrintStream ps) throws RecordFormatException { ArrayList records = new ArrayList(); RecordDetails activeRecord = null; - try { - BiffviewRecordInputStream recStream = new BiffviewRecordInputStream(in); - while (recStream.hasNextRecord()) { + BiffviewRecordInputStream recStream = new BiffviewRecordInputStream(in); + while (recStream.hasNextRecord()) { recStream.nextRecord(); if (recStream.getSid() != 0) { - Record record = createRecord (recStream); + Record record = createRecord (recStream); if (record.getSid() != ContinueRecord.sid) { records.add(record); if (activeRecord != null) - activeRecord.dump(); - activeRecord = new RecordDetails(recStream.getSid(), recStream.getLength(), (int)recStream.getPos(), record); + activeRecord.dump(ps); + activeRecord = new RecordDetails(recStream.getSid(), recStream.getLength(), (int)recStream.getPos(), record); } if (dump) { - recStream.dumpBytes(); - } + recStream.dumpBytes(ps); } - } - activeRecord.dump(); - } catch (IOException e) { - throw new RecordFormatException("Error reading bytes", e); + } + } + if (activeRecord != null) { + activeRecord.dump(ps); } Record[] retval = new Record[records.size()]; - - retval = (Record[]) records.toArray(retval); + records.toArray(retval); return retval; } - private static void dumpNormal(Record record, int startloc, short rectype, short recsize) - { - //System.out.println("Offset 0x" + Integer.toHexString(startloc) + " (" + startloc + ")"); - System.out.println( "recordid = 0x" + Integer.toHexString( rectype ) + ", size = " + recsize ); - System.out.println( record.toString() ); - - } /** - * Essentially a duplicate of RecordFactory. Kept seperate as not to screw + * Essentially a duplicate of RecordFactory. Kept separate as not to screw * up non-debug operations. * */ private static Record createRecord( RecordInputStream in ) { - Record retval = null; - switch ( in.getSid() ) { - case ChartRecord.sid: - retval = new ChartRecord( in ); - break; + return new ChartRecord( in ); case ChartFormatRecord.sid: - retval = new ChartFormatRecord( in ); - break; + return new ChartFormatRecord( in ); case SeriesRecord.sid: - retval = new SeriesRecord( in ); - break; + return new SeriesRecord( in ); case BeginRecord.sid: - retval = new BeginRecord( in ); - break; + return new BeginRecord( in ); case EndRecord.sid: - retval = new EndRecord( in ); - break; + return new EndRecord( in ); case BOFRecord.sid: - retval = new BOFRecord( in ); - break; + return new BOFRecord( in ); case InterfaceHdrRecord.sid: - retval = new InterfaceHdrRecord( in ); - break; + return new InterfaceHdrRecord( in ); case MMSRecord.sid: - retval = new MMSRecord( in ); - break; + return new MMSRecord( in ); case InterfaceEndRecord.sid: - retval = new InterfaceEndRecord( in ); - break; + return new InterfaceEndRecord( in ); case WriteAccessRecord.sid: - retval = new WriteAccessRecord( in ); - break; + return new WriteAccessRecord( in ); case CodepageRecord.sid: - retval = new CodepageRecord( in ); - break; + return new CodepageRecord( in ); case DSFRecord.sid: - retval = new DSFRecord( in ); - break; + return new DSFRecord( in ); case TabIdRecord.sid: - retval = new TabIdRecord( in ); - break; + return new TabIdRecord( in ); case FnGroupCountRecord.sid: - retval = new FnGroupCountRecord( in ); - break; + return new FnGroupCountRecord( in ); case WindowProtectRecord.sid: - retval = new WindowProtectRecord( in ); - break; + return new WindowProtectRecord( in ); case ProtectRecord.sid: - retval = new ProtectRecord( in ); - break; + return new ProtectRecord( in ); case PasswordRecord.sid: - retval = new PasswordRecord( in ); - break; + return new PasswordRecord( in ); case ProtectionRev4Record.sid: - retval = new ProtectionRev4Record( in ); - break; + return new ProtectionRev4Record( in ); case PasswordRev4Record.sid: - retval = new PasswordRev4Record( in ); - break; + return new PasswordRev4Record( in ); case WindowOneRecord.sid: - retval = new WindowOneRecord( in ); - break; + return new WindowOneRecord( in ); case BackupRecord.sid: - retval = new BackupRecord( in ); - break; + return new BackupRecord( in ); case HideObjRecord.sid: - retval = new HideObjRecord( in ); - break; + return new HideObjRecord( in ); case DateWindow1904Record.sid: - retval = new DateWindow1904Record( in ); - break; + return new DateWindow1904Record( in ); case PrecisionRecord.sid: - retval = new PrecisionRecord( in ); - break; + return new PrecisionRecord( in ); case RefreshAllRecord.sid: - retval = new RefreshAllRecord( in ); - break; + return new RefreshAllRecord( in ); case BookBoolRecord.sid: - retval = new BookBoolRecord( in ); - break; + return new BookBoolRecord( in ); case FontRecord.sid: - retval = new FontRecord( in ); - break; + return new FontRecord( in ); case FormatRecord.sid: - retval = new FormatRecord( in ); - break; + return new FormatRecord( in ); case ExtendedFormatRecord.sid: - retval = new ExtendedFormatRecord( in ); - break; + return new ExtendedFormatRecord( in ); case StyleRecord.sid: - retval = new StyleRecord( in ); - break; + return new StyleRecord( in ); case UseSelFSRecord.sid: - retval = new UseSelFSRecord( in ); - break; + return new UseSelFSRecord( in ); case BoundSheetRecord.sid: - retval = new BoundSheetRecord( in ); - break; + return new BoundSheetRecord( in ); case CountryRecord.sid: - retval = new CountryRecord( in ); - break; + return new CountryRecord( in ); case SSTRecord.sid: - retval = new SSTRecord( in ); - break; + return new SSTRecord( in ); case ExtSSTRecord.sid: - retval = new ExtSSTRecord( in ); - break; + return new ExtSSTRecord( in ); case EOFRecord.sid: - retval = new EOFRecord( in ); - break; + return new EOFRecord( in ); case IndexRecord.sid: - retval = new IndexRecord( in ); - break; + return new IndexRecord( in ); case CalcModeRecord.sid: - retval = new CalcModeRecord( in ); - break; + return new CalcModeRecord( in ); case CalcCountRecord.sid: - retval = new CalcCountRecord( in ); - break; + return new CalcCountRecord( in ); case RefModeRecord.sid: - retval = new RefModeRecord( in ); - break; + return new RefModeRecord( in ); case IterationRecord.sid: - retval = new IterationRecord( in ); - break; + return new IterationRecord( in ); case DeltaRecord.sid: - retval = new DeltaRecord( in ); - break; + return new DeltaRecord( in ); case SaveRecalcRecord.sid: - retval = new SaveRecalcRecord( in ); - break; + return new SaveRecalcRecord( in ); case PrintHeadersRecord.sid: - retval = new PrintHeadersRecord( in ); - break; + return new PrintHeadersRecord( in ); case PrintGridlinesRecord.sid: - retval = new PrintGridlinesRecord( in ); - break; + return new PrintGridlinesRecord( in ); case GridsetRecord.sid: - retval = new GridsetRecord( in ); - break; + return new GridsetRecord( in ); case DrawingGroupRecord.sid: - retval = new DrawingGroupRecord( in ); - break; + return new DrawingGroupRecord( in ); case DrawingRecordForBiffViewer.sid: - retval = new DrawingRecordForBiffViewer( in ); - break; + return new DrawingRecordForBiffViewer( in ); case DrawingSelectionRecord.sid: - retval = new DrawingSelectionRecord( in ); - break; + return new DrawingSelectionRecord( in ); case GutsRecord.sid: - retval = new GutsRecord( in ); - break; + return new GutsRecord( in ); case DefaultRowHeightRecord.sid: - retval = new DefaultRowHeightRecord( in ); - break; + return new DefaultRowHeightRecord( in ); case WSBoolRecord.sid: - retval = new WSBoolRecord( in ); - break; + return new WSBoolRecord( in ); case HeaderRecord.sid: - retval = new HeaderRecord( in ); - break; + return new HeaderRecord( in ); case FooterRecord.sid: - retval = new FooterRecord( in ); - break; + return new FooterRecord( in ); case HCenterRecord.sid: - retval = new HCenterRecord( in ); - break; + return new HCenterRecord( in ); case VCenterRecord.sid: - retval = new VCenterRecord( in ); - break; + return new VCenterRecord( in ); case PrintSetupRecord.sid: - retval = new PrintSetupRecord( in ); - break; + return new PrintSetupRecord( in ); case DefaultColWidthRecord.sid: - retval = new DefaultColWidthRecord( in ); - break; + return new DefaultColWidthRecord( in ); case DimensionsRecord.sid: - retval = new DimensionsRecord( in ); - break; + return new DimensionsRecord( in ); case RowRecord.sid: - retval = new RowRecord( in ); - break; + return new RowRecord( in ); case LabelSSTRecord.sid: - retval = new LabelSSTRecord( in ); - break; + return new LabelSSTRecord( in ); case RKRecord.sid: - retval = new RKRecord( in ); - break; + return new RKRecord( in ); case NumberRecord.sid: - retval = new NumberRecord( in ); - break; + return new NumberRecord( in ); case DBCellRecord.sid: - retval = new DBCellRecord( in ); - break; + return new DBCellRecord( in ); case WindowTwoRecord.sid: - retval = new WindowTwoRecord( in ); - break; + return new WindowTwoRecord( in ); case SelectionRecord.sid: - retval = new SelectionRecord( in ); - break; + return new SelectionRecord( in ); case ContinueRecord.sid: - retval = new ContinueRecord( in ); - break; + return new ContinueRecord( in ); case LabelRecord.sid: - retval = new LabelRecord( in ); - break; + return new LabelRecord( in ); case MulRKRecord.sid: - retval = new MulRKRecord( in ); - break; + return new MulRKRecord( in ); case MulBlankRecord.sid: - retval = new MulBlankRecord( in ); - break; + return new MulBlankRecord( in ); case BlankRecord.sid: - retval = new BlankRecord( in ); - break; + return new BlankRecord( in ); case BoolErrRecord.sid: - retval = new BoolErrRecord( in ); - break; + return new BoolErrRecord( in ); case ColumnInfoRecord.sid: - retval = new ColumnInfoRecord( in ); - break; + return new ColumnInfoRecord( in ); case MergeCellsRecord.sid: - retval = new MergeCellsRecord( in ); - break; + return new MergeCellsRecord( in ); case AreaRecord.sid: - retval = new AreaRecord( in ); - break; + return new AreaRecord( in ); case DataFormatRecord.sid: - retval = new DataFormatRecord( in ); - break; + return new DataFormatRecord( in ); case BarRecord.sid: - retval = new BarRecord( in ); - break; + return new BarRecord( in ); case DatRecord.sid: - retval = new DatRecord( in ); - break; + return new DatRecord( in ); case PlotGrowthRecord.sid: - retval = new PlotGrowthRecord( in ); - break; + return new PlotGrowthRecord( in ); case UnitsRecord.sid: - retval = new UnitsRecord( in ); - break; + return new UnitsRecord( in ); case FrameRecord.sid: - retval = new FrameRecord( in ); - break; + return new FrameRecord( in ); case ValueRangeRecord.sid: - retval = new ValueRangeRecord( in ); - break; + return new ValueRangeRecord( in ); case SeriesListRecord.sid: - retval = new SeriesListRecord( in ); - break; + return new SeriesListRecord( in ); case FontBasisRecord.sid: - retval = new FontBasisRecord( in ); - break; + return new FontBasisRecord( in ); case FontIndexRecord.sid: - retval = new FontIndexRecord( in ); - break; + return new FontIndexRecord( in ); case LineFormatRecord.sid: - retval = new LineFormatRecord( in ); - break; + return new LineFormatRecord( in ); case AreaFormatRecord.sid: - retval = new AreaFormatRecord( in ); - break; + return new AreaFormatRecord( in ); case LinkedDataRecord.sid: - retval = new LinkedDataRecord( in ); - break; + return new LinkedDataRecord( in ); case FormulaRecord.sid: - retval = new FormulaRecord( in ); - break; + return new FormulaRecord( in ); case SheetPropertiesRecord.sid: - retval = new SheetPropertiesRecord( in ); - break; + return new SheetPropertiesRecord( in ); case DefaultDataLabelTextPropertiesRecord.sid: - retval = new DefaultDataLabelTextPropertiesRecord( in ); - break; + return new DefaultDataLabelTextPropertiesRecord( in ); case TextRecord.sid: - retval = new TextRecord( in ); - break; + return new TextRecord( in ); case AxisParentRecord.sid: - retval = new AxisParentRecord( in ); - break; + return new AxisParentRecord( in ); case AxisLineFormatRecord.sid: - retval = new AxisLineFormatRecord( in ); - break; + return new AxisLineFormatRecord( in ); case SupBookRecord.sid: - retval = new SupBookRecord( in ); - break; + return new SupBookRecord( in ); case ExternSheetRecord.sid: - retval = new ExternSheetRecord( in ); - break; + return new ExternSheetRecord( in ); case SCLRecord.sid: - retval = new SCLRecord( in ); - break; + return new SCLRecord( in ); case SeriesToChartGroupRecord.sid: - retval = new SeriesToChartGroupRecord( in ); - break; + return new SeriesToChartGroupRecord( in ); case AxisUsedRecord.sid: - retval = new AxisUsedRecord( in ); - break; + return new AxisUsedRecord( in ); case AxisRecord.sid: - retval = new AxisRecord( in ); - break; + return new AxisRecord( in ); case CategorySeriesAxisRecord.sid: - retval = new CategorySeriesAxisRecord( in ); - break; + return new CategorySeriesAxisRecord( in ); case AxisOptionsRecord.sid: - retval = new AxisOptionsRecord( in ); - break; + return new AxisOptionsRecord( in ); case TickRecord.sid: - retval = new TickRecord( in ); - break; + return new TickRecord( in ); case SeriesTextRecord.sid: - retval = new SeriesTextRecord( in ); - break; + return new SeriesTextRecord( in ); case ObjectLinkRecord.sid: - retval = new ObjectLinkRecord( in ); - break; + return new ObjectLinkRecord( in ); case PlotAreaRecord.sid: - retval = new PlotAreaRecord( in ); - break; + return new PlotAreaRecord( in ); case SeriesIndexRecord.sid: - retval = new SeriesIndexRecord( in ); - break; + return new SeriesIndexRecord( in ); case LegendRecord.sid: - retval = new LegendRecord( in ); - break; + return new LegendRecord( in ); case LeftMarginRecord.sid: - retval = new LeftMarginRecord( in ); - break; + return new LeftMarginRecord( in ); case RightMarginRecord.sid: - retval = new RightMarginRecord( in ); - break; + return new RightMarginRecord( in ); case TopMarginRecord.sid: - retval = new TopMarginRecord( in ); - break; + return new TopMarginRecord( in ); case BottomMarginRecord.sid: - retval = new BottomMarginRecord( in ); - break; + return new BottomMarginRecord( in ); case PaletteRecord.sid: - retval = new PaletteRecord( in ); - break; + return new PaletteRecord( in ); case StringRecord.sid: - retval = new StringRecord( in ); - break; + return new StringRecord( in ); case NameRecord.sid: - retval = new NameRecord( in ); - break; + return new NameRecord( in ); case PaneRecord.sid: - retval = new PaneRecord( in ); - break; + return new PaneRecord( in ); case SharedFormulaRecord.sid: - retval = new SharedFormulaRecord( in); - break; + return new SharedFormulaRecord( in); case ObjRecord.sid: - retval = new ObjRecord( in); - break; + return new ObjRecord( in); case TextObjectRecord.sid: - retval = new TextObjectRecord( in); - break; + return new TextObjectRecord( in); case HorizontalPageBreakRecord.sid: - retval = new HorizontalPageBreakRecord( in); - break; + return new HorizontalPageBreakRecord( in); case VerticalPageBreakRecord.sid: - retval = new VerticalPageBreakRecord( in); - break; + return new VerticalPageBreakRecord( in); case WriteProtectRecord.sid: - retval = new WriteProtectRecord( in); - break; + return new WriteProtectRecord( in); case FilePassRecord.sid: - retval = new FilePassRecord(in); - break; + return new FilePassRecord(in); case NoteRecord.sid: - retval = new NoteRecord( in ); - break; + return new NoteRecord( in ); case FileSharingRecord.sid: - retval = new FileSharingRecord( in ); - break; + return new FileSharingRecord( in ); case HyperlinkRecord.sid: - retval = new HyperlinkRecord( in ); - break; - default: - retval = new UnknownRecord( in ); + return new HyperlinkRecord( in ); } - return retval; + return new UnknownRecord( in ); } /** * Method setDump - hex dump out data or not. - * - *@param dump */ - public void setDump(boolean dump) { this.dump = dump; } @@ -552,33 +393,44 @@ public void setDump(boolean dump) { * */ public static void main(String[] args) { + + System.setProperty("poi.deserialize.escher", "true"); + + if (args.length == 0) { + System.out.println( "Biff viewer needs a filename" ); + return; + } + try { - System.setProperty("poi.deserialize.escher", "true"); + String inFileName = args[0]; + File inputFile = new File(inFileName); + if(!inputFile.exists()) { + throw new RuntimeException("specified inputFile '" + inFileName + "' does not exist"); + } + PrintStream ps; + if (false) { // set to true to output to file + OutputStream os = new FileOutputStream(inFileName + ".out"); + ps = new PrintStream(os); + } else { + ps = System.out; + } + BiffViewer viewer = new BiffViewer(inputFile, ps); - if (args.length == 0) - { - System.out.println( "Biff viewer needs a filename" ); + if (args.length > 1 && args[1].equals("on")) { + viewer.setDump(true); } - else - { - BiffViewer viewer = new BiffViewer(args); - if ((args.length > 1) && args[1].equals("on")) { - viewer.setDump(true); - } - if ((args.length > 1) && args[1].equals("bfd")) { - POIFSFileSystem fs = - new POIFSFileSystem(new FileInputStream(args[0])); - InputStream stream = - fs.createDocumentInputStream("Workbook"); - int size = stream.available(); - byte[] data = new byte[size]; - - stream.read(data); - HexDump.dump(data, 0, System.out, 0); - } else { - viewer.run(); - } + if (args.length > 1 && args[1].equals("bfd")) { + POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(inputFile)); + InputStream stream = fs.createDocumentInputStream("Workbook"); + int size = stream.available(); + byte[] data = new byte[size]; + + stream.read(data); + HexDump.dump(data, 0, System.out, 0); + } else { + viewer.run(); } + ps.close(); } catch (Exception e) { e.printStackTrace(); } @@ -587,7 +439,7 @@ public static void main(String[] args) { /** * This record supports dumping of completed continue records. */ - static class RecordDetails + private static final class RecordDetails { short rectype, recsize; int startloc; @@ -616,18 +468,19 @@ public Record getRecord() return record; } - public void dump() throws IOException - { - dumpNormal(record, startloc, rectype, recsize); + public void dump(PrintStream ps) { + ps.println("Offset 0x" + Integer.toHexString(startloc) + " (" + startloc + ")"); + ps.println( "recordid = 0x" + Integer.toHexString( rectype ) + ", size = " + recsize ); + ps.println( record.toString() ); } } - static class BiffviewRecordInputStream extends RecordInputStream { + private static final class BiffviewRecordInputStream extends RecordInputStream { public BiffviewRecordInputStream(InputStream in) { super(in); } - public void dumpBytes() { - HexDump.dump(this.data, 0, this.currentLength); + public void dumpBytes(PrintStream ps) { + ps.println(HexDump.dump(this.data, 0, this.currentLength)); } } diff --git a/src/java/org/apache/poi/hssf/model/FormulaParser.java b/src/java/org/apache/poi/hssf/model/FormulaParser.java index f16ab451294..2819786ef68 100644 --- a/src/java/org/apache/poi/hssf/model/FormulaParser.java +++ b/src/java/org/apache/poi/hssf/model/FormulaParser.java @@ -1000,7 +1000,7 @@ public static String toFormulaString(HSSFWorkbook book, Ptg[] ptgs) { if (ptg instanceof AttrPtg) { AttrPtg attrPtg = ((AttrPtg) ptg); - if (attrPtg.isOptimizedIf()) { + if (attrPtg.isOptimizedIf() || attrPtg.isOptimizedChoose() || attrPtg.isGoto()) { continue; } if (attrPtg.isSpace()) { @@ -1014,6 +1014,9 @@ public static String toFormulaString(HSSFWorkbook book, Ptg[] ptgs) { // similar to tAttrSpace - RPN is violated continue; } + if (!attrPtg.isSum()) { + throw new RuntimeException("Unexpected tAttr: " + attrPtg.toString()); + } } final OperationPtg o = (OperationPtg) ptg; diff --git a/src/java/org/apache/poi/hssf/model/Sheet.java b/src/java/org/apache/poi/hssf/model/Sheet.java index 2af25e7481b..45090e85cf1 100644 --- a/src/java/org/apache/poi/hssf/model/Sheet.java +++ b/src/java/org/apache/poi/hssf/model/Sheet.java @@ -1,4 +1,3 @@ - /* ==================================================================== Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -16,7 +15,6 @@ Licensed to the Apache Software Foundation (ASF) under one or more limitations under the License. ==================================================================== */ - package org.apache.poi.hssf.model; import org.apache.poi.hssf.record.*; @@ -57,9 +55,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more * @see org.apache.poi.hssf.usermodel.HSSFSheet * @version 1.0-pre */ - -public class Sheet implements Model -{ +public final class Sheet implements Model { public static final short LeftMargin = 0; public static final short RightMargin = 1; public static final short TopMargin = 2; @@ -97,9 +93,9 @@ public class Sheet implements Model protected ObjectProtectRecord objprotect = null; protected ScenarioProtectRecord scenprotect = null; protected PasswordRecord password = null; - protected List condFormatting = new ArrayList();; + protected List condFormatting = new ArrayList(); - /** Add an UncalcedRecord if not true indicating formulas have not been calculated */ + /** Add an UncalcedRecord if not true indicating formulas have not been calculated */ protected boolean uncalced = false; public static final byte PANE_LOWER_RIGHT = (byte)0; @@ -108,7 +104,7 @@ public class Sheet implements Model public static final byte PANE_UPPER_LEFT = (byte)3; /** - * Creates new Sheet with no intialization --useless at this point + * Creates new Sheet with no initialization --useless at this point * @see #createSheet(List,int,int) */ public Sheet() @@ -166,7 +162,7 @@ else if (rec.getSid() == EOFRecord.sid) } } else if (rec.getSid() == UncalcedRecord.sid) { - retval.uncalced = true; + retval.uncalced = true; } else if (rec.getSid() == DimensionsRecord.sid) { @@ -188,14 +184,14 @@ else if (rec.getSid() == MergeCellsRecord.sid) } else if ( rec.getSid() == CFHeaderRecord.sid ) { - CFRecordsAggregate cfAgg = CFRecordsAggregate.createCFAggregate(recs, k); - retval.condFormatting.add(cfAgg); - rec = cfAgg; + CFRecordsAggregate cfAgg = CFRecordsAggregate.createCFAggregate(recs, k); + retval.condFormatting.add(cfAgg); + rec = cfAgg; } else if ( rec.getSid() == CFRuleRecord.sid ) { - // Skip it since it is processed by CFRecordsAggregate - rec = null; + // Skip it since it is processed by CFRecordsAggregate + rec = null; } else if (rec.getSid() == ColumnInfoRecord.sid) { @@ -244,7 +240,7 @@ else if ( rec.getSid() == RowRecord.sid ) if ( isfirstrow ) { retval.rows = new RowRecordsAggregate(); - rec = retval.rows; + rec = retval.rows; isfirstrow = false; } retval.rows.insertRow(row); @@ -256,7 +252,7 @@ else if ( rec.getSid() == PrintGridlinesRecord.sid ) else if ( rec.getSid() == GridsetRecord.sid ) { retval.gridset = (GridsetRecord) rec; - } + } else if ( rec.getSid() == HeaderRecord.sid && bofEofNestingLevel == 1) { retval.header = (HeaderRecord) rec; @@ -301,32 +297,32 @@ else if ( rec.getSid() == IndexRecord.sid ) { rec = null; } - - else if ( rec.getSid() == ProtectRecord.sid ) - { - retval.protect = (ProtectRecord) rec; - } - else if ( rec.getSid() == ObjectProtectRecord.sid ) - { - retval.objprotect = (ObjectProtectRecord) rec; - } - else if ( rec.getSid() == ScenarioProtectRecord.sid ) - { - retval.scenprotect = (ScenarioProtectRecord) rec; - } - else if ( rec.getSid() == PasswordRecord.sid ) - { - retval.password = (PasswordRecord) rec; - } - else if (rec.getSid() == PageBreakRecord.HORIZONTAL_SID) - { - retval.rowBreaks = (PageBreakRecord)rec; - } - else if (rec.getSid() == PageBreakRecord.VERTICAL_SID) - { - retval.colBreaks = (PageBreakRecord)rec; - } - + + else if ( rec.getSid() == ProtectRecord.sid ) + { + retval.protect = (ProtectRecord) rec; + } + else if ( rec.getSid() == ObjectProtectRecord.sid ) + { + retval.objprotect = (ObjectProtectRecord) rec; + } + else if ( rec.getSid() == ScenarioProtectRecord.sid ) + { + retval.scenprotect = (ScenarioProtectRecord) rec; + } + else if ( rec.getSid() == PasswordRecord.sid ) + { + retval.password = (PasswordRecord) rec; + } + else if (rec.getSid() == PageBreakRecord.HORIZONTAL_SID) + { + retval.rowBreaks = (PageBreakRecord)rec; + } + else if (rec.getSid() == PageBreakRecord.VERTICAL_SID) + { + retval.colBreaks = (PageBreakRecord)rec; + } + if (rec != null) { records.add(rec); @@ -351,9 +347,9 @@ else if (rec.getSid() == PageBreakRecord.VERTICAL_SID) /** * Clones the low level records of this sheet and returns the new sheet instance. * This method is implemented by adding methods for deep cloning to all records that - * can be added to a sheet. The Record object does not implement cloneable. + * can be added to a sheet. The Record object does not implement cloneable. * When adding a new record, implement a public clone method if and only if the record - * belongs to a sheet. + * belongs to a sheet. */ public Sheet cloneSheet() { @@ -374,7 +370,7 @@ public Sheet cloneSheet() ValueRecordsAggregate vrAgg = (ValueRecordsAggregate)rec; for (Iterator cellIter = vrAgg.getIterator();cellIter.hasNext();) { Record valRec = (Record)cellIter.next(); - + if (valRec instanceof FormulaRecordAggregate) { FormulaRecordAggregate fmAgg = (FormulaRecordAggregate)valRec; Record fmAggRec = fmAgg.getFormulaRecord(); @@ -459,9 +455,9 @@ public static Sheet createSheet() records.add(retval.rowBreaks); retval.colBreaks = new PageBreakRecord(PageBreakRecord.VERTICAL_SID); records.add(retval.colBreaks); - + retval.header = (HeaderRecord) retval.createHeader(); - records.add( retval.header ); + records.add( retval.header ); retval.footer = (FooterRecord) retval.createFooter(); records.add( retval.footer ); records.add( retval.createHCenter() ); @@ -479,11 +475,11 @@ public static Sheet createSheet() retval.dimsloc = records.size()-1; records.add(retval.windowTwo = retval.createWindowTwo()); retval.setLoc(records.size() - 1); - retval.selection = + retval.selection = (SelectionRecord) retval.createSelection(); records.add(retval.selection); - retval.protect = (ProtectRecord) retval.createProtect(); - records.add(retval.protect); + retval.protect = (ProtectRecord) retval.createProtect(); + records.add(retval.protect); records.add(retval.createEOF()); @@ -511,26 +507,25 @@ private void checkRows() } } - //public int addMergedRegion(short rowFrom, short colFrom, short rowTo, - public int addMergedRegion(int rowFrom, short colFrom, int rowTo, - short colTo) - { - // Validate input - if(rowTo < rowFrom) { - throw new IllegalArgumentException("The row to ("+rowTo+") must be >= the row from ("+rowFrom+")"); - } - if(colTo < colFrom) { - throw new IllegalArgumentException("The col to ("+colTo+") must be >= the col from ("+colFrom+")"); - } - + public int addMergedRegion(int rowFrom, short colFrom, int rowTo, short colTo) { + // Validate input + if (rowTo < rowFrom) { + throw new IllegalArgumentException("The 'to' row (" + rowTo + + ") must not be less than the 'from' row (" + rowFrom + ")"); + } + if (colTo < colFrom) { + throw new IllegalArgumentException("The 'to' col (" + colTo + + ") must not be less than the 'from' col (" + colFrom + ")"); + } + if (merged == null || merged.getNumAreas() == 1027) { merged = ( MergeCellsRecord ) createMergedCells(); - mergedRecords.add(merged); + mergedRecords.add(merged); records.add(records.size() - 1, merged); } merged.addArea(rowFrom, colFrom, rowTo, colTo); - return numMergedRegions++; + return numMergedRegions++; } public void removeMergedRegion(int index) @@ -538,15 +533,15 @@ public void removeMergedRegion(int index) //safety checks if (index >= numMergedRegions || mergedRecords.size() == 0) return; - + int pos = 0; int startNumRegions = 0; - + //optimisation for current record if (numMergedRegions - index < merged.getNumAreas()) { pos = mergedRecords.size() - 1; - startNumRegions = numMergedRegions - merged.getNumAreas(); + startNumRegions = numMergedRegions - merged.getNumAreas(); } else { @@ -558,7 +553,7 @@ public void removeMergedRegion(int index) pos = n; break; } - startNumRegions += record.getNumAreas(); + startNumRegions += record.getNumAreas(); } } @@ -567,17 +562,17 @@ public void removeMergedRegion(int index) numMergedRegions--; if (rec.getNumAreas() == 0) { - mergedRecords.remove(pos); - //get rid of the record from the sheet - records.remove(merged); + mergedRecords.remove(pos); + //get rid of the record from the sheet + records.remove(merged); if (merged == rec) { - //pull up the LAST record for operations when we finally - //support continue records for mergedRegions - if (mergedRecords.size() > 0) { - merged = (MergeCellsRecord) mergedRecords.get(mergedRecords.size() - 1); - } else { - merged = null; - } + //pull up the LAST record for operations when we finally + //support continue records for mergedRegions + if (mergedRecords.size() > 0) { + merged = (MergeCellsRecord) mergedRecords.get(mergedRecords.size() - 1); + } else { + merged = null; + } } } } @@ -587,10 +582,10 @@ public MergeCellsRecord.MergedRegion getMergedRegionAt(int index) //safety checks if (index >= numMergedRegions || mergedRecords.size() == 0) return null; - + int pos = 0; int startNumRegions = 0; - + //optimisation for current record if (numMergedRegions - index < merged.getNumAreas()) { @@ -607,7 +602,7 @@ public MergeCellsRecord.MergedRegion getMergedRegionAt(int index) pos = n; break; } - startNumRegions += record.getNumAreas(); + startNumRegions += record.getNumAreas(); } } return ((MergeCellsRecord) mergedRecords.get(pos)).getAreaAt(index - startNumRegions); @@ -620,62 +615,62 @@ public int getNumMergedRegions() // Find correct position to add new CF record private int findConditionalFormattingPosition() { - // This is default. - // If the algorithm does not find the right position, - // this one will be used (this is a position before EOF record) - int index = records.size()-2; - - for( int i=index; i>=0; i-- ) - { - Record rec = (Record)records.get(i); - short sid = rec.getSid(); - - // CFRecordsAggregate records already exist, just add to the end - if (rec instanceof CFRecordsAggregate) { return i+1; } - - if( sid == (short)0x00ef ) { return i+1; }// PHONETICPR - if( sid == (short)0x015f ) { return i+1; }// LABELRANGES - if( sid == MergeCellsRecord.sid ) { return i+1; } - if( sid == (short)0x0099 ) { return i+1; }// STANDARDWIDTH - if( sid == SelectionRecord.sid ) { return i+1; } - if( sid == PaneRecord.sid ) { return i+1; } - if( sid == SCLRecord.sid ) { return i+1; } - if( sid == WindowTwoRecord.sid ) { return i+1; } - } - - return index; + // This is default. + // If the algorithm does not find the right position, + // this one will be used (this is a position before EOF record) + int index = records.size()-2; + + for( int i=index; i>=0; i-- ) + { + Record rec = (Record)records.get(i); + short sid = rec.getSid(); + + // CFRecordsAggregate records already exist, just add to the end + if (rec instanceof CFRecordsAggregate) { return i+1; } + + if( sid == (short)0x00ef ) { return i+1; }// PHONETICPR + if( sid == (short)0x015f ) { return i+1; }// LABELRANGES + if( sid == MergeCellsRecord.sid ) { return i+1; } + if( sid == (short)0x0099 ) { return i+1; }// STANDARDWIDTH + if( sid == SelectionRecord.sid ) { return i+1; } + if( sid == PaneRecord.sid ) { return i+1; } + if( sid == SCLRecord.sid ) { return i+1; } + if( sid == WindowTwoRecord.sid ) { return i+1; } + } + + return index; } public int addConditionalFormatting(CFRecordsAggregate cfAggregate) { - int index = findConditionalFormattingPosition(); - records.add(index, cfAggregate); - condFormatting.add(cfAggregate); - return condFormatting.size()-1; + int index = findConditionalFormattingPosition(); + records.add(index, cfAggregate); + condFormatting.add(cfAggregate); + return condFormatting.size()-1; } public void removeConditionalFormatting(int index) { if (index >= 0 && index <= condFormatting.size()-1 ) { - CFRecordsAggregate cfAggregate = getCFRecordsAggregateAt(index); - records.remove(cfAggregate); - condFormatting.remove(index); + CFRecordsAggregate cfAggregate = getCFRecordsAggregateAt(index); + records.remove(cfAggregate); + condFormatting.remove(index); } } - + public CFRecordsAggregate getCFRecordsAggregateAt(int index) { if (index >= 0 && index <= condFormatting.size()-1 ) { - return (CFRecordsAggregate) condFormatting.get(index); + return (CFRecordsAggregate) condFormatting.get(index); } return null; } - + public int getNumConditionalFormattings() { - return condFormatting.size(); + return condFormatting.size(); } /** @@ -711,8 +706,6 @@ public int getNumRecords() * * @see org.apache.poi.hssf.record.DimensionsRecord */ - - //public void setDimensions(short firstrow, short firstcol, short lastrow, public void setDimensions(int firstrow, short firstcol, int lastrow, short lastcol) { @@ -735,7 +728,7 @@ public void setDimensions(int firstrow, short firstcol, int lastrow, /** * set the locator for where we should look for the next value record. The - * algorythm will actually start here and find the correct location so you + * algorithm will actually start here and find the correct location so you * can set this to 0 and watch performance go down the tubes but it will work. * After a value is set this is automatically advanced. Its also set by the * create method. So you probably shouldn't mess with this unless you have @@ -813,13 +806,13 @@ public int serialize(int offset, byte [] data) for (int k = 0; k < records.size(); k++) { Record record = (( Record ) records.get(k)); - + // Don't write out UncalcedRecord entries, as // we handle those specially just below if (record instanceof UncalcedRecord) { - continue; + continue; } - + // Once the rows have been found in the list of records, start // writing out the blocked row information. This includes the DBCell references if (record instanceof RowRecordsAggregate) { @@ -829,13 +822,13 @@ public int serialize(int offset, byte [] data) } else { pos += record.serialize(pos, data ); // rec.length; } - + // If the BOF record was just serialized then add the IndexRecord if (record.getSid() == BOFRecord.sid) { // Add an optional UncalcedRecord if (uncalced) { - UncalcedRecord rec = new UncalcedRecord(); - pos += rec.serialize(pos, data); + UncalcedRecord rec = new UncalcedRecord(); + pos += rec.serialize(pos, data); } //Can there be more than one BOF for a sheet? If not then we can //remove this guard. So be safe it is left here. @@ -871,7 +864,7 @@ public int serialize(int offset, byte [] data) log.log(POILogger.DEBUG, "Sheet.serialize returning "); return pos-offset; } - + private int serializeIndexRecord(final int BOFRecordIndex, final int offset, byte[] data) { IndexRecord index = new IndexRecord(); index.setFirstRow(rows.getFirstRowNum()); @@ -906,7 +899,7 @@ private int serializeIndexRecord(final int BOFRecordIndex, final int offset, byt } return index.serialize(offset, data); } - + /** * Create a row record. (does not add it to the records contained in this sheet) @@ -930,8 +923,6 @@ public RowRecord createRow(int row) * @return LabelSSTRecord newly created containing your SST Index, row,col. * @see org.apache.poi.hssf.record.SSTRecord */ - - //public LabelSSTRecord createLabelSST(short row, short col, int index) public LabelSSTRecord createLabelSST(int row, short col, int index) { log.logFormatted(POILogger.DEBUG, "create labelsst row,col,index %,%,%", @@ -957,8 +948,6 @@ public LabelSSTRecord createLabelSST(int row, short col, int index) * * @return NumberRecord for that row, col containing that value as added to the sheet */ - - //public NumberRecord createNumber(short row, short col, double value) public NumberRecord createNumber(int row, short col, double value) { log.logFormatted(POILogger.DEBUG, "create number row,col,value %,%,%", @@ -968,7 +957,6 @@ public NumberRecord createNumber(int row, short col, double value) }); NumberRecord rec = new NumberRecord(); - //rec.setRow(( short ) row); rec.setRow(row); rec.setColumn(col); rec.setValue(value); @@ -982,18 +970,14 @@ public NumberRecord createNumber(int row, short col, double value) * @param row - the row the BlankRecord is a member of * @param col - the column the BlankRecord is a member of */ - - //public BlankRecord createBlank(short row, short col) public BlankRecord createBlank(int row, short col) { - //log.logFormatted(POILogger.DEBUG, "create blank row,col %,%", new short[] log.logFormatted(POILogger.DEBUG, "create blank row,col %,%", new int[] { row, col }); BlankRecord rec = new BlankRecord(); - //rec.setRow(( short ) row); rec.setRow(row); rec.setColumn(col); rec.setXFIndex(( short ) 0x0f); @@ -1009,12 +993,9 @@ public BlankRecord createBlank(int row, short col) * @param formula - a String representing the formula. To be parsed to PTGs * @return bogus/useless formula record */ - - //public FormulaRecord createFormula(short row, short col, String formula) public FormulaRecord createFormula(int row, short col, String formula) { log.logFormatted(POILogger.DEBUG, "create formula row,col,formula %,%,%", - //new short[] new int[] { row, col @@ -1052,8 +1033,6 @@ public FormulaRecord createFormula(int row, short col, String formula) * @param row the row to add the cell value to * @param col the cell value record itself. */ - - //public void addValueRecord(short row, CellValueRecordInterface col) public void addValueRecord(int row, CellValueRecordInterface col) { checkCells(); @@ -1075,29 +1054,6 @@ public void addValueRecord(int row, CellValueRecordInterface col) d.setFirstCol(col.getColumn()); } cells.insertCell(col); - - /* - * for (int k = loc; k < records.size(); k++) - * { - * Record rec = ( Record ) records.get(k); - * - * if (rec.getSid() == RowRecord.sid) - * { - * RowRecord rowrec = ( RowRecord ) rec; - * - * if (rowrec.getRowNumber() == col.getRow()) - * { - * records.add(k + 1, col); - * loc = k; - * if (rowrec.getLastCol() <= col.getColumn()) - * { - * rowrec.setLastCol((( short ) (col.getColumn() + 1))); - * } - * break; - * } - * } - * } - */ } /** @@ -1109,8 +1065,6 @@ public void addValueRecord(int row, CellValueRecordInterface col) * @param col - a record supporting the CellValueRecordInterface. * @see org.apache.poi.hssf.record.CellValueRecordInterface */ - - //public void removeValueRecord(short row, CellValueRecordInterface col) public void removeValueRecord(int row, CellValueRecordInterface col) { checkCells(); @@ -1118,27 +1072,6 @@ public void removeValueRecord(int row, CellValueRecordInterface col) new int[]{row, dimsloc} ); loc = dimsloc; cells.removeCell(col); - - /* - * for (int k = loc; k < records.size(); k++) - * { - * Record rec = ( Record ) records.get(k); - * - * // checkDimsLoc(rec,k); - * if (rec.isValue()) - * { - * CellValueRecordInterface cell = - * ( CellValueRecordInterface ) rec; - * - * if ((cell.getRow() == col.getRow()) - * && (cell.getColumn() == col.getColumn())) - * { - * records.remove(k); - * break; - * } - * } - * } - */ } /** @@ -1160,26 +1093,10 @@ public void replaceValueRecord(CellValueRecordInterface newval) //The ValueRecordsAggregate use a tree map underneath. //The tree Map uses the CellValueRecordInterface as both the //key and the value, if we dont do a remove, then - //the previous instance of the key is retained, effectively using + //the previous instance of the key is retained, effectively using //double the memory cells.removeCell(newval); cells.insertCell(newval); - - /* - * CellValueRecordInterface oldval = getNextValueRecord(); - * - * while (oldval != null) - * { - * if (oldval.isEqual(newval)) - * { - * records.set(( short ) (getLoc() - 1), newval); - * return; - * } - * oldval = getNextValueRecord(); - * } - * addValueRecord(newval.getRow(), newval); - * setLoc(dimsloc); - */ } /** @@ -1218,41 +1135,6 @@ public void addRow(RowRecord row) rows.insertRow(row); - /* - * for (int k = loc; k < records.size(); k++) - * { - * Record rec = ( Record ) records.get(k); - * - * if (rec.getSid() == IndexRecord.sid) - * { - * index = ( IndexRecord ) rec; - * } - * if (rec.getSid() == RowRecord.sid) - * { - * RowRecord rowrec = ( RowRecord ) rec; - * - * if (rowrec.getRowNumber() > row.getRowNumber()) - * { - * records.add(k, row); - * loc = k; - * break; - * } - * } - * if (rec.getSid() == WindowTwoRecord.sid) - * { - * records.add(k, row); - * loc = k; - * break; - * } - * } - * if (index != null) - * { - * if (index.getLastRowAdd1() <= row.getRowNumber()) - * { - * index.setLastRowAdd1(row.getRowNumber() + 1); - * } - * } - */ if (log.check( POILogger.DEBUG )) log.log(POILogger.DEBUG, "exit addRow"); } @@ -1268,33 +1150,9 @@ public void addRow(RowRecord row) public void removeRow(RowRecord row) { checkRows(); - // IndexRecord index = null; setLoc(getDimsLoc()); rows.removeRow(row); - - /* - * for (int k = loc; k < records.size(); k++) - * { - * Record rec = ( Record ) records.get(k); - * - * // checkDimsLoc(rec,k); - * if (rec.getSid() == RowRecord.sid) - * { - * RowRecord rowrec = ( RowRecord ) rec; - * - * if (rowrec.getRowNumber() == row.getRowNumber()) - * { - * records.remove(k); - * break; - * } - * } - * if (rec.getSid() == WindowTwoRecord.sid) - * { - * break; - * } - * } - */ } /** @@ -1325,65 +1183,7 @@ public CellValueRecordInterface getNextValueRecord() return null; } return ( CellValueRecordInterface ) valueRecIterator.next(); - - /* - * if (this.getLoc() < records.size()) - * { - * for (int k = getLoc(); k < records.size(); k++) - * { - * Record rec = ( Record ) records.get(k); - * - * this.setLoc(k + 1); - * if (rec instanceof CellValueRecordInterface) - * { - * return ( CellValueRecordInterface ) rec; - * } - * } - * } - * return null; - */ - } - - /** - * get the NEXT RowRecord or CellValueRecord(from LOC). The first record that - * is a Row record or CellValueRecord(starting at LOC) will be returned. - *

- * This method is "loc" sensitive. Meaning you need to set LOC to where you - * want it to start searching. If you don't know do this: setLoc(getDimsLoc). - * When adding several rows you can just start at the last one by leaving loc - * at what this sets it to. For this method, set loc to dimsloc to start with. - * subsequent calls will return rows in (physical) sequence or NULL when you get to the end. - * - * @return RowRecord representing the next row record or CellValueRecordInterface - * representing the next cellvalue or NULL if there are no more - * @see #setLoc(int) - * - */ - -/* public Record getNextRowOrValue() - { - POILogger.DEBUG((new StringBuffer("getNextRow loc= ")).append(loc) - .toString()); - if (this.getLoc() < records.size()) - { - for (int k = this.getLoc(); k < records.size(); k++) - { - Record rec = ( Record ) records.get(k); - - this.setLoc(k + 1); - if (rec.getSid() == RowRecord.sid) - { - return rec; - } - else if (rec.isValue()) - { - return rec; - } - } - } - return null; } - */ /** * get the NEXT RowRecord (from LOC). The first record that is a Row record @@ -1413,20 +1213,6 @@ public RowRecord getNextRow() return null; } return ( RowRecord ) rowRecIterator.next(); - -/* if (this.getLoc() < records.size()) - { - for (int k = this.getLoc(); k < records.size(); k++) - { - Record rec = ( Record ) records.get(k); - - this.setLoc(k + 1); - if (rec.getSid() == RowRecord.sid) - { - return ( RowRecord ) rec; - } - } - }*/ } /** @@ -1445,34 +1231,10 @@ public RowRecord getNextRow() * @see #setLoc(int) * */ - - //public RowRecord getRow(short rownum) - public RowRecord getRow(int rownum) - { + public RowRecord getRow(int rownum) { if (log.check( POILogger.DEBUG )) log.log(POILogger.DEBUG, "getNextRow loc= " + loc); return rows.getRow(rownum); - - /* - * if (this.getLoc() < records.size()) - * { - * for (int k = this.getLoc(); k < records.size(); k++) - * { - * Record rec = ( Record ) records.get(k); - * - * this.setLoc(k + 1); - * if (rec.getSid() == RowRecord.sid) - * { - * if ((( RowRecord ) rec).getRowNumber() == rownum) - * { - * return ( RowRecord ) rec; - * } - * } - * } - * } - */ - - // return null; } /** @@ -1489,7 +1251,6 @@ protected Record createBOF() retval.setVersion(( short ) 0x600); retval.setType(( short ) 0x010); - // retval.setBuild((short)0x10d3); retval.setBuild(( short ) 0x0dbb); retval.setBuildYear(( short ) 1996); retval.setHistoryBitMask(0xc1); @@ -1807,7 +1568,7 @@ protected Record createDefaultColWidth() * @see org.apache.poi.hssf.record.ColumnInfoRecord * @return record containing a ColumnInfoRecord */ - + // TODO change return type to ColumnInfoRecord protected Record createColInfo() { return ColumnInfoRecordsAggregate.createColInfo(); @@ -1830,12 +1591,12 @@ public short getDefaultColumnWidth() public boolean isGridsPrinted() { - if (gridset == null) { - gridset = (GridsetRecord)createGridset(); - //Insert the newlycreated Gridset record at the end of the record (just before the EOF) - int loc = findFirstRecordLocBySid(EOFRecord.sid); - records.add(loc, gridset); - } + if (gridset == null) { + gridset = (GridsetRecord)createGridset(); + //Insert the newlycreated Gridset record at the end of the record (just before the EOF) + int loc = findFirstRecordLocBySid(EOFRecord.sid); + records.add(loc, gridset); + } return !gridset.getGridset(); } @@ -1918,16 +1679,16 @@ public short getColumnWidth(short column) } return retval; } - + /** - * get the index to the ExtendedFormatRecord "associated" with - * the column at specified 0-based index. (In this case, an - * ExtendedFormatRecord index is actually associated with a + * get the index to the ExtendedFormatRecord "associated" with + * the column at specified 0-based index. (In this case, an + * ExtendedFormatRecord index is actually associated with a * ColumnInfoRecord which spans 1 or more columns) *
* Returns the index to the default ExtendedFormatRecord (0xF) * if no ColumnInfoRecord exists that includes the column - * index specified. + * index specified. * @param column * @return index of ExtendedFormatRecord associated with * ColumnInfoRecord that includes the column index or the @@ -2116,38 +1877,38 @@ protected Record createSelection() retval.setNumRefs(( short ) 0x0); return retval; } - - public short getTopRow() + + public short getTopRow() { - return (windowTwo==null) ? (short) 0 : windowTwo.getTopRow(); + return (windowTwo==null) ? (short) 0 : windowTwo.getTopRow(); } - - public void setTopRow(short topRow) + + public void setTopRow(short topRow) { - if (windowTwo!=null) - { - windowTwo.setTopRow(topRow); - } + if (windowTwo!=null) + { + windowTwo.setTopRow(topRow); + } } - + /** * Sets the left column to show in desktop window pane. * @param leftCol the left column to show in desktop window pane */ public void setLeftCol(short leftCol){ - if (windowTwo!=null) - { - windowTwo.setLeftCol(leftCol); - } + if (windowTwo!=null) + { + windowTwo.setLeftCol(leftCol); + } } - - public short getLeftCol() + + public short getLeftCol() { - return (windowTwo==null) ? (short) 0 : windowTwo.getLeftCol(); + return (windowTwo==null) ? (short) 0 : windowTwo.getLeftCol(); } - - - + + + /** * Returns the active row * @@ -2162,7 +1923,7 @@ public int getActiveCellRow() } return selection.getActiveCellRow(); } - + /** * Sets the active row * @@ -2177,7 +1938,7 @@ public void setActiveCellRow(int row) selection.setActiveCellRow(row); } } - + /** * Returns the active column * @@ -2192,7 +1953,7 @@ public short getActiveCellCol() } return selection.getActiveCellCol(); } - + /** * Sets the active column * @@ -2278,9 +2039,9 @@ public int getSize() } // Add space for UncalcedRecord if (uncalced) { - retval += UncalcedRecord.getStaticRecordSize(); + retval += UncalcedRecord.getStaticRecordSize(); } - + return retval; } @@ -2367,16 +2128,19 @@ public int findFirstRecordLocBySid( short sid ) */ public HeaderRecord getHeader () { - return header; + return header; } + public WindowTwoRecord getWindowTwo() { + return windowTwo; + } /** * Sets the HeaderRecord. * @param newHeader The new HeaderRecord for the sheet. */ public void setHeader (HeaderRecord newHeader) { - header = newHeader; + header = newHeader; } /** @@ -2385,7 +2149,7 @@ public void setHeader (HeaderRecord newHeader) */ public FooterRecord getFooter () { - return footer; + return footer; } /** @@ -2394,7 +2158,7 @@ public FooterRecord getFooter () */ public void setFooter (FooterRecord newFooter) { - footer = newFooter; + footer = newFooter; } /** @@ -2403,7 +2167,7 @@ public void setFooter (FooterRecord newFooter) */ public PrintSetupRecord getPrintSetup () { - return printSetup; + return printSetup; } /** @@ -2412,7 +2176,7 @@ public PrintSetupRecord getPrintSetup () */ public void setPrintSetup (PrintSetupRecord newPrintSetup) { - printSetup = newPrintSetup; + printSetup = newPrintSetup; } /** @@ -2421,7 +2185,7 @@ public void setPrintSetup (PrintSetupRecord newPrintSetup) */ public PrintGridlinesRecord getPrintGridlines () { - return printGridlines; + return printGridlines; } /** @@ -2430,7 +2194,7 @@ public PrintGridlinesRecord getPrintGridlines () */ public void setPrintGridlines (PrintGridlinesRecord newPrintGridlines) { - printGridlines = newPrintGridlines; + printGridlines = newPrintGridlines; } /** @@ -2447,23 +2211,23 @@ public void setSelected(boolean sel) { * @return the size of the margin */ public double getMargin(short margin) { - if (getMargins()[margin] != null) - return margins[margin].getMargin(); - else { - switch ( margin ) - { - case LeftMargin: - return .75; - case RightMargin: - return .75; - case TopMargin: - return 1.0; - case BottomMargin: - return 1.0; - default : - throw new RuntimeException( "Unknown margin constant: " + margin ); - } - } + if (getMargins()[margin] != null) + return margins[margin].getMargin(); + else { + switch ( margin ) + { + case LeftMargin: + return .75; + case RightMargin: + return .75; + case TopMargin: + return 1.0; + case BottomMargin: + return 1.0; + default : + throw new RuntimeException( "Unknown margin constant: " + margin ); + } + } } /** @@ -2472,32 +2236,32 @@ public double getMargin(short margin) { * @param size the size of the margin */ public void setMargin(short margin, double size) { - Margin m = getMargins()[margin]; - if (m == null) { - switch ( margin ) - { - case LeftMargin: - m = new LeftMarginRecord(); - records.add( getDimsLoc() + 1, m ); - break; - case RightMargin: - m = new RightMarginRecord(); - records.add( getDimsLoc() + 1, m ); - break; - case TopMargin: - m = new TopMarginRecord(); - records.add( getDimsLoc() + 1, m ); - break; - case BottomMargin: - m = new BottomMarginRecord(); - records.add( getDimsLoc() + 1, m ); - break; - default : - throw new RuntimeException( "Unknown margin constant: " + margin ); - } - margins[margin] = m; - } - m.setMargin( size ); + Margin m = getMargins()[margin]; + if (m == null) { + switch ( margin ) + { + case LeftMargin: + m = new LeftMarginRecord(); + records.add( getDimsLoc() + 1, m ); + break; + case RightMargin: + m = new RightMarginRecord(); + records.add( getDimsLoc() + 1, m ); + break; + case TopMargin: + m = new TopMarginRecord(); + records.add( getDimsLoc() + 1, m ); + break; + case BottomMargin: + m = new BottomMarginRecord(); + records.add( getDimsLoc() + 1, m ); + break; + default : + throw new RuntimeException( "Unknown margin constant: " + margin ); + } + margins[margin] = m; + } + m.setMargin( size ); } public int getEofLoc() @@ -2514,10 +2278,10 @@ public int getEofLoc() */ public void createFreezePane(int colSplit, int rowSplit, int topRow, int leftmostColumn ) { - int paneLoc = findFirstRecordLocBySid(PaneRecord.sid); - if (paneLoc != -1) - records.remove(paneLoc); - + int paneLoc = findFirstRecordLocBySid(PaneRecord.sid); + if (paneLoc != -1) + records.remove(paneLoc); + int loc = findFirstRecordLocBySid(WindowTwoRecord.sid); PaneRecord pane = new PaneRecord(); pane.setX((short)colSplit); @@ -2563,10 +2327,10 @@ else if (colSplit == 0) */ public void createSplitPane(int xSplitPos, int ySplitPos, int topRow, int leftmostColumn, int activePane ) { - int paneLoc = findFirstRecordLocBySid(PaneRecord.sid); - if (paneLoc != -1) - records.remove(paneLoc); - + int paneLoc = findFirstRecordLocBySid(PaneRecord.sid); + if (paneLoc != -1) + records.remove(paneLoc); + int loc = findFirstRecordLocBySid(WindowTwoRecord.sid); PaneRecord r = new PaneRecord(); r.setX((short)xSplitPos); @@ -2583,7 +2347,7 @@ public void createSplitPane(int xSplitPos, int ySplitPos, int topRow, int leftmo sel.setPane(PANE_LOWER_RIGHT); } - + /** * Returns the information regarding the currently configured pane (split or freeze). * @return null if no pane configured, or the pane information. @@ -2592,9 +2356,9 @@ public PaneInformation getPaneInformation() { PaneRecord rec = (PaneRecord)findFirstRecordBySid(PaneRecord.sid); if (rec == null) return null; - + return new PaneInformation(rec.getX(), rec.getY(), rec.getTopRow(), - rec.getLeftColumn(), (byte)rec.getActivePane(), windowTwo.getFreezePanes()); + rec.getLeftColumn(), (byte)rec.getActivePane(), windowTwo.getFreezePanes()); } public SelectionRecord getSelection() @@ -2660,12 +2424,12 @@ protected ScenarioProtectRecord createScenarioProtect() */ public ProtectRecord getProtect() { - if (protect == null) { - protect = (ProtectRecord)createProtect(); - //Insert the newlycreated protect record at the end of the record (just before the EOF) - int loc = findFirstRecordLocBySid(EOFRecord.sid); - records.add(loc, protect); - } + if (protect == null) { + protect = (ProtectRecord)createProtect(); + //Insert the newlycreated protect record at the end of the record (just before the EOF) + int loc = findFirstRecordLocBySid(EOFRecord.sid); + records.add(loc, protect); + } return protect; } @@ -2674,12 +2438,12 @@ public ProtectRecord getProtect() */ public PasswordRecord getPassword() { - if (password == null) { - password = createPassword(); - //Insert the newly created password record at the end of the record (just before the EOF) - int loc = findFirstRecordLocBySid(EOFRecord.sid); - records.add(loc, password); - } + if (password == null) { + password = createPassword(); + //Insert the newly created password record at the end of the record (just before the EOF) + int loc = findFirstRecordLocBySid(EOFRecord.sid); + records.add(loc, password); + } return password; } @@ -2714,7 +2478,7 @@ public void setDisplayGridlines(boolean show) { * @return whether gridlines are displayed */ public boolean isDisplayGridlines() { - return windowTwo.getDisplayGridlines(); + return windowTwo.getDisplayGridlines(); } /** @@ -2730,7 +2494,7 @@ public void setDisplayFormulas(boolean show) { * @return whether formulas are displayed */ public boolean isDisplayFormulas() { - return windowTwo.getDisplayFormulas(); + return windowTwo.getDisplayFormulas(); } /** @@ -2746,24 +2510,24 @@ public void setDisplayRowColHeadings(boolean show) { * @return whether RowColHeadings are displayed */ public boolean isDisplayRowColHeadings() { - return windowTwo.getDisplayRowColHeadings(); + return windowTwo.getDisplayRowColHeadings(); } - + /** - * @return whether an uncalced record must be inserted or not at generation - */ - public boolean getUncalced() { - return uncalced; - } - /** - * @param uncalced whether an uncalced record must be inserted or not at generation - */ - public void setUncalced(boolean uncalced) { - this.uncalced = uncalced; - } + * @return whether an uncalced record must be inserted or not at generation + */ + public boolean getUncalced() { + return uncalced; + } + /** + * @param uncalced whether an uncalced record must be inserted or not at generation + */ + public void setUncalced(boolean uncalced) { + this.uncalced = uncalced; + } - /** + /** * Returns the array of margins. If not created, will create. * * @return the array of marings. @@ -2771,7 +2535,7 @@ public void setUncalced(boolean uncalced) { protected Margin[] getMargins() { if (margins == null) margins = new Margin[4]; - return margins; + return margins; } /** @@ -2789,11 +2553,11 @@ public int aggregateDrawingRecords(DrawingManager2 drawingManager, boolean creat boolean noDrawingRecordsFound = (loc == -1); if (noDrawingRecordsFound) { - if(!createIfMissing) { - // None found, and not allowed to add in - return -1; - } - + if(!createIfMissing) { + // None found, and not allowed to add in + return -1; + } + EscherAggregate aggregate = new EscherAggregate( drawingManager ); loc = findFirstRecordLocBySid(EscherAggregate.sid); if (loc == -1) @@ -2847,43 +2611,43 @@ public void preSerialize() * @param breaks The page record to be shifted * @param start Starting "main" value to shift breaks * @param stop Ending "main" value to shift breaks - * @param count number of units (rows/columns) to shift by + * @param count number of units (rows/columns) to shift by */ public void shiftBreaks(PageBreakRecord breaks, short start, short stop, int count) { - - if(rowBreaks == null) - return; - Iterator iterator = breaks.getBreaksIterator(); - List shiftedBreak = new ArrayList(); - while(iterator.hasNext()) - { - PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - short breakLocation = breakItem.main; - boolean inStart = (breakLocation >= start); - boolean inEnd = (breakLocation <= stop); - if(inStart && inEnd) - shiftedBreak.add(breakItem); - } - - iterator = shiftedBreak.iterator(); - while (iterator.hasNext()) { - PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - breaks.removeBreak(breakItem.main); - breaks.addBreak((short)(breakItem.main+count), breakItem.subFrom, breakItem.subTo); - } - } - + + if(rowBreaks == null) + return; + Iterator iterator = breaks.getBreaksIterator(); + List shiftedBreak = new ArrayList(); + while(iterator.hasNext()) + { + PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); + short breakLocation = breakItem.main; + boolean inStart = (breakLocation >= start); + boolean inEnd = (breakLocation <= stop); + if(inStart && inEnd) + shiftedBreak.add(breakItem); + } + + iterator = shiftedBreak.iterator(); + while (iterator.hasNext()) { + PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); + breaks.removeBreak(breakItem.main); + breaks.addBreak((short)(breakItem.main+count), breakItem.subFrom, breakItem.subTo); + } + } + /** * Sets a page break at the indicated row * @param row */ - public void setRowBreak(int row, short fromCol, short toCol) { - if (rowBreaks == null) { + public void setRowBreak(int row, short fromCol, short toCol) { + if (rowBreaks == null) { int loc = findFirstRecordLocBySid(WindowTwoRecord.sid); rowBreaks = new PageBreakRecord(PageBreakRecord.HORIZONTAL_SID); records.add(loc, rowBreaks); - } - rowBreaks.addBreak((short)row, fromCol, toCol); + } + rowBreaks.addBreak((short)row, fromCol, toCol); } /** @@ -2891,9 +2655,9 @@ public void setRowBreak(int row, short fromCol, short toCol) { * @param row */ public void removeRowBreak(int row) { - if (rowBreaks == null) - throw new IllegalArgumentException("Sheet does not define any row breaks"); - rowBreaks.removeBreak((short)row); + if (rowBreaks == null) + throw new IllegalArgumentException("Sheet does not define any row breaks"); + rowBreaks.removeBreak((short)row); } /** @@ -2902,7 +2666,7 @@ public void removeRowBreak(int row) { * @return true if the specified row has a page break */ public boolean isRowBroken(int row) { - return (rowBreaks == null) ? false : rowBreaks.getBreak((short)row) != null; + return (rowBreaks == null) ? false : rowBreaks.getBreak((short)row) != null; } /** @@ -2910,12 +2674,12 @@ public boolean isRowBroken(int row) { * */ public void setColumnBreak(short column, short fromRow, short toRow) { - if (colBreaks == null) { + if (colBreaks == null) { int loc = findFirstRecordLocBySid(WindowTwoRecord.sid); colBreaks = new PageBreakRecord(PageBreakRecord.VERTICAL_SID); records.add(loc, colBreaks); - } - colBreaks.addBreak(column, fromRow, toRow); + } + colBreaks.addBreak(column, fromRow, toRow); } /** @@ -2923,10 +2687,10 @@ public void setColumnBreak(short column, short fromRow, short toRow) { * */ public void removeColumnBreak(short column) { - if (colBreaks == null) - throw new IllegalArgumentException("Sheet does not define any column breaks"); - - colBreaks.removeBreak(column); + if (colBreaks == null) + throw new IllegalArgumentException("Sheet does not define any column breaks"); + + colBreaks.removeBreak(column); } /** @@ -2935,9 +2699,9 @@ public void removeColumnBreak(short column) { * @return true if the specified column has a page break */ public boolean isColumnBroken(short column) { - return (colBreaks == null) ? false : colBreaks.getBreak(column) != null; + return (colBreaks == null) ? false : colBreaks.getBreak(column) != null; } - + /** * Shifts the horizontal page breaks for the indicated count * @param startingRow @@ -2945,7 +2709,7 @@ public boolean isColumnBroken(short column) { * @param count */ public void shiftRowBreaks(int startingRow, int endingRow, int count) { - shiftBreaks(rowBreaks, (short)startingRow, (short)endingRow, (short)count); + shiftBreaks(rowBreaks, (short)startingRow, (short)endingRow, (short)count); } /** @@ -2955,39 +2719,39 @@ public void shiftRowBreaks(int startingRow, int endingRow, int count) { * @param count */ public void shiftColumnBreaks(short startingCol, short endingCol, short count) { - shiftBreaks(colBreaks, startingCol, endingCol, count); + shiftBreaks(colBreaks, startingCol, endingCol, count); } - + /** * Returns all the row page breaks * @return all the row page breaks */ public Iterator getRowBreaks() { - return rowBreaks.getBreaksIterator(); + return rowBreaks.getBreaksIterator(); } - + /** * Returns the number of row page breaks * @return the number of row page breaks */ public int getNumRowBreaks(){ - return (rowBreaks == null) ? 0 : (int)rowBreaks.getNumBreaks(); + return (rowBreaks == null) ? 0 : (int)rowBreaks.getNumBreaks(); } - + /** * Returns all the column page breaks * @return all the column page breaks */ public Iterator getColumnBreaks(){ - return colBreaks.getBreaksIterator(); + return colBreaks.getBreaksIterator(); } - + /** * Returns the number of column page breaks * @return the number of column page breaks */ public int getNumColumnBreaks(){ - return (colBreaks == null) ? 0 : (int)colBreaks.getNumBreaks(); + return (colBreaks == null) ? 0 : (int)colBreaks.getNumBreaks(); } public void setColumnGroupCollapsed( short columnNumber, boolean collapsed ) @@ -3030,213 +2794,40 @@ public void protectSheet( String password, boolean objects, boolean scenarios ) records.add(protIdx+2,srec); scenprotect = srec; } - } + } /** - * unprotect objects in the sheet (will not protect them, but any set to false are + * unprotect objects in the sheet (will not protect them, but any set to false are * unprotected. * @param sheet is unprotected (false = unprotect) * @param objects are unprotected (false = unprotect) * @param scenarios are unprotected (false = unprotect) */ public void unprotectSheet( boolean sheet, boolean objects, boolean scenarios ) { - int protIdx = -1; + if (!sheet) { ProtectRecord prec = getProtect(); prec.setProtect(sheet); PasswordRecord pass = getPassword(); pass.setPassword((short)00); - } + } if(objprotect != null && !objects) { objprotect.setProtect(false); } if(scenprotect != null && !scenarios) { scenprotect.setProtect(false); } - } + } /** * @return {sheet is protected, objects are proteced, scenarios are protected} */ public boolean[] isProtected() { - return new boolean[] { (protect != null && protect.getProtect()), + return new boolean[] { (protect != null && protect.getProtect()), (objprotect != null && objprotect.getProtect()), (scenprotect != null && scenprotect.getProtect())}; } - -// private void collapseColumn( short columnNumber ) -// { -// int idx = findColumnIdx( columnNumber, 0 ); -// if (idx == -1) -// return; -// -// // Find the start of the group. -// ColumnInfoRecord columnInfo = (ColumnInfoRecord) columnSizes.get( findStartOfColumnOutlineGroup( idx ) ); -// -// // Hide all the columns until the end of the group -// columnInfo = writeHidden( columnInfo, idx, true ); -// -// // Write collapse field -// setColumn( (short) ( columnInfo.getLastColumn() + 1 ), null, null, null, Boolean.TRUE); -// } - -// private void expandColumn( short columnNumber ) -// { -// int idx = findColumnIdx( columnNumber, 0 ); -// if (idx == -1) -// return; -// -// // If it is already exapanded do nothing. -// if (!isColumnGroupCollapsed(idx)) -// return; -// -// // Find the start of the group. -// int startIdx = findStartOfColumnOutlineGroup( idx ); -// ColumnInfoRecord columnInfo = getColInfo( startIdx ); -// -// // Find the end of the group. -// int endIdx = findEndOfColumnOutlineGroup( idx ); -// ColumnInfoRecord endColumnInfo = getColInfo( endIdx ); -// -// // expand: -// // colapsed bit must be unset -// // hidden bit gets unset _if_ surrounding groups are expanded you can determine -// // this by looking at the hidden bit of the enclosing group. You will have -// // to look at the start and the end of the current group to determine which -// // is the enclosing group -// // hidden bit only is altered for this outline level. ie. don't uncollapse contained groups -// if (!isColumnGroupHiddenByParent( idx )) -// { -// for (int i = startIdx; i <= endIdx; i++) -// { -// if (columnInfo.getOutlineLevel() == getColInfo(i).getOutlineLevel()) -// getColInfo(i).setHidden( false ); -// } -// } -// -// // Write collapse field -// setColumn( (short) ( columnInfo.getLastColumn() + 1 ), null, null, null, Boolean.FALSE); -// } - -// private boolean isColumnGroupCollapsed( int idx ) -// { -// int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup( idx ); -// if (endOfOutlineGroupIdx >= columnSizes.size()) -// return false; -// if (getColInfo(endOfOutlineGroupIdx).getLastColumn() + 1 != getColInfo(endOfOutlineGroupIdx + 1).getFirstColumn()) -// return false; -// else -// return getColInfo(endOfOutlineGroupIdx+1).getCollapsed(); -// } - -// private boolean isColumnGroupHiddenByParent( int idx ) -// { -// // Look out outline details of end -// int endLevel; -// boolean endHidden; -// int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup( idx ); -// if (endOfOutlineGroupIdx >= columnSizes.size()) -// { -// endLevel = 0; -// endHidden = false; -// } -// else if (getColInfo(endOfOutlineGroupIdx).getLastColumn() + 1 != getColInfo(endOfOutlineGroupIdx + 1).getFirstColumn()) -// { -// endLevel = 0; -// endHidden = false; -// } -// else -// { -// endLevel = getColInfo( endOfOutlineGroupIdx + 1).getOutlineLevel(); -// endHidden = getColInfo( endOfOutlineGroupIdx + 1).getHidden(); -// } -// -// // Look out outline details of start -// int startLevel; -// boolean startHidden; -// int startOfOutlineGroupIdx = findStartOfColumnOutlineGroup( idx ); -// if (startOfOutlineGroupIdx <= 0) -// { -// startLevel = 0; -// startHidden = false; -// } -// else if (getColInfo(startOfOutlineGroupIdx).getFirstColumn() - 1 != getColInfo(startOfOutlineGroupIdx - 1).getLastColumn()) -// { -// startLevel = 0; -// startHidden = false; -// } -// else -// { -// startLevel = getColInfo( startOfOutlineGroupIdx - 1).getOutlineLevel(); -// startHidden = getColInfo( startOfOutlineGroupIdx - 1 ).getHidden(); -// } -// -// if (endLevel > startLevel) -// { -// return endHidden; -// } -// else -// { -// return startHidden; -// } -// } - -// private ColumnInfoRecord getColInfo(int idx) -// { -// return columns.getColInfo( idx ); -// } - -// private int findStartOfColumnOutlineGroup(int idx) -// { -// // Find the start of the group. -// ColumnInfoRecord columnInfo = (ColumnInfoRecord) columnSizes.get( idx ); -// int level = columnInfo.getOutlineLevel(); -// while (idx != 0) -// { -// ColumnInfoRecord prevColumnInfo = (ColumnInfoRecord) columnSizes.get( idx - 1 ); -// if (columnInfo.getFirstColumn() - 1 == prevColumnInfo.getLastColumn()) -// { -// if (prevColumnInfo.getOutlineLevel() < level) -// { -// break; -// } -// idx--; -// columnInfo = prevColumnInfo; -// } -// else -// { -// break; -// } -// } -// -// return idx; -// } - -// private int findEndOfColumnOutlineGroup(int idx) -// { -// // Find the end of the group. -// ColumnInfoRecord columnInfo = (ColumnInfoRecord) columnSizes.get( idx ); -// int level = columnInfo.getOutlineLevel(); -// while (idx < columnSizes.size() - 1) -// { -// ColumnInfoRecord nextColumnInfo = (ColumnInfoRecord) columnSizes.get( idx + 1 ); -// if (columnInfo.getLastColumn() + 1 == nextColumnInfo.getFirstColumn()) -// { -// if (nextColumnInfo.getOutlineLevel() < level) -// { -// break; -// } -// idx++; -// columnInfo = nextColumnInfo; -// } -// else -// { -// break; -// } -// } -// -// return idx; -// } + public void groupRowRange(int fromRow, int toRow, boolean indent) { @@ -3272,8 +2863,8 @@ private void recalcRowGutter() // Grab the guts record, adding if needed GutsRecord guts = (GutsRecord) findFirstRecordBySid( GutsRecord.sid ); if(guts == null) { - guts = new GutsRecord(); - records.add(guts); + guts = new GutsRecord(); + records.add(guts); } // Set the levels onto it guts.setRowLevelMax( (short) ( maxLevel + 1 ) ); @@ -3291,126 +2882,4 @@ public void setRowGroupCollapsed( int row, boolean collapse ) rows.expandRow( row ); } } - - -// private void collapseRow( int rowNumber ) -// { -// -// // Find the start of the group. -// int startRow = rows.findStartOfRowOutlineGroup( rowNumber ); -// RowRecord rowRecord = (RowRecord) rows.getRow( startRow ); -// -// // Hide all the columns until the end of the group -// int lastRow = rows.writeHidden( rowRecord, startRow, true ); -// -// // Write collapse field -// if (getRow(lastRow + 1) != null) -// { -// getRow(lastRow + 1).setColapsed( true ); -// } -// else -// { -// RowRecord row = createRow( lastRow + 1); -// row.setColapsed( true ); -// rows.insertRow( row ); -// } -// } - -// private int findStartOfRowOutlineGroup(int row) -// { -// // Find the start of the group. -// RowRecord rowRecord = rows.getRow( row ); -// int level = rowRecord.getOutlineLevel(); -// int currentRow = row; -// while (rows.getRow( currentRow ) != null) -// { -// rowRecord = rows.getRow( currentRow ); -// if (rowRecord.getOutlineLevel() < level) -// return currentRow + 1; -// currentRow--; -// } -// -// return currentRow + 1; -// } - -// private int writeHidden( RowRecord rowRecord, int row, boolean hidden ) -// { -// int level = rowRecord.getOutlineLevel(); -// while (rowRecord != null && rows.getRow(row).getOutlineLevel() >= level) -// { -// rowRecord.setZeroHeight( hidden ); -// row++; -// rowRecord = rows.getRow( row ); -// } -// return row - 1; -// } - -// private int findEndOfRowOutlineGroup( int row ) -// { -// int level = getRow( row ).getOutlineLevel(); -// int currentRow; -// for (currentRow = row; currentRow < rows.getLastRowNum(); currentRow++) -// { -// if (getRow(currentRow) == null || getRow(currentRow).getOutlineLevel() < level) -// { -// break; -// } -// } -// -// return currentRow-1; -// } - -// private boolean isRowGroupCollapsed( int row ) -// { -// int collapseRow = rows.findEndOfRowOutlineGroup( row ) + 1; -// -// if (getRow(collapseRow) == null) -// return false; -// else -// return getRow( collapseRow ).getColapsed(); -// } - - -// private boolean isRowGroupHiddenByParent( int row ) -// { -// // Look out outline details of end -// int endLevel; -// boolean endHidden; -// int endOfOutlineGroupIdx = rows.findEndOfRowOutlineGroup( row ); -// if (getRow( endOfOutlineGroupIdx + 1 ) == null) -// { -// endLevel = 0; -// endHidden = false; -// } -// else -// { -// endLevel = getRow( endOfOutlineGroupIdx + 1).getOutlineLevel(); -// endHidden = getRow( endOfOutlineGroupIdx + 1).getZeroHeight(); -// } -// -// // Look out outline details of start -// int startLevel; -// boolean startHidden; -// int startOfOutlineGroupIdx = rows.findStartOfRowOutlineGroup( row ); -// if (startOfOutlineGroupIdx - 1 < 0 || getRow(startOfOutlineGroupIdx - 1) == null) -// { -// startLevel = 0; -// startHidden = false; -// } -// else -// { -// startLevel = getRow( startOfOutlineGroupIdx - 1).getOutlineLevel(); -// startHidden = getRow( startOfOutlineGroupIdx - 1 ).getZeroHeight(); -// } -// -// if (endLevel > startLevel) -// { -// return endHidden; -// } -// else -// { -// return startHidden; -// } -// } - } diff --git a/src/java/org/apache/poi/hssf/record/LabelRecord.java b/src/java/org/apache/poi/hssf/record/LabelRecord.java index 2dc2d940f4d..c3fd5fb3dd8 100644 --- a/src/java/org/apache/poi/hssf/record/LabelRecord.java +++ b/src/java/org/apache/poi/hssf/record/LabelRecord.java @@ -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,13 +14,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ - -/* - * LabelRecord.java - * - * Created on November 11, 2001, 12:51 PM - */ package org.apache.poi.hssf.record; /** @@ -33,14 +26,10 @@ Licensed to the Apache Software Foundation (ASF) under one or more * @version 2.0-pre * @see org.apache.poi.hssf.record.LabelSSTRecord */ - -public class LabelRecord - extends Record - implements CellValueRecordInterface -{ +public final class LabelRecord extends Record implements CellValueRecordInterface { public final static short sid = 0x204; - //private short field_1_row; - private int field_1_row; + + private int field_1_row; private short field_2_column; private short field_3_xf_index; private short field_4_string_len; @@ -85,35 +74,30 @@ protected void validateSid(short id) protected void fillFields(RecordInputStream in) { - //field_1_row = LittleEndian.getShort(data, 0 + offset); field_1_row = in.readUShort(); field_2_column = in.readShort(); field_3_xf_index = in.readShort(); field_4_string_len = in.readShort(); field_5_unicode_flag = in.readByte(); if (field_4_string_len > 0) { - if (isUnCompressedUnicode()) { - field_6_value = in.readUnicodeLEString(field_4_string_len); - } else { - field_6_value = in.readCompressedUnicode(field_4_string_len); + if (isUnCompressedUnicode()) { + field_6_value = in.readUnicodeLEString(field_4_string_len); + } else { + field_6_value = in.readCompressedUnicode(field_4_string_len); + } + } else { + field_6_value = ""; } - } else field_6_value = null; } -/* READ ONLY ACCESS... THIS IS FOR COMPATIBILITY ONLY...USE LABELSST! - public void setRow(short row) { - field_1_row = row; - } - - public void setColumn(short col) { - field_2_column = col; - } - - public void setXFIndex(short index) { - field_3_xf_index = index; - } - */ - //public short getRow() +/* + * READ ONLY ACCESS... THIS IS FOR COMPATIBILITY ONLY...USE LABELSST! public + * void setRow(short row) { field_1_row = row; } + * + * public void setColumn(short col) { field_2_column = col; } + * + * public void setXFIndex(short index) { field_3_xf_index = index; } + */ public int getRow() { return field_1_row; diff --git a/src/java/org/apache/poi/hssf/record/PaneRecord.java b/src/java/org/apache/poi/hssf/record/PaneRecord.java index 6f13ad0922b..f02e4116555 100644 --- a/src/java/org/apache/poi/hssf/record/PaneRecord.java +++ b/src/java/org/apache/poi/hssf/record/PaneRecord.java @@ -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,13 +14,12 @@ Licensed to the Apache Software Foundation (ASF) under one or more See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ - package org.apache.poi.hssf.record; - -import org.apache.poi.util.*; +import org.apache.poi.util.HexDump; +import org.apache.poi.util.LittleEndian; /** * Describes the frozen and unfozen panes. @@ -30,9 +28,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more * @author Glen Stampoultzis (glens at apache.org) */ -public class PaneRecord - extends Record -{ +public final class PaneRecord extends Record { public final static short sid = 0x41; private short field_1_x; private short field_2_y; @@ -42,7 +38,10 @@ public class PaneRecord public final static short ACTIVE_PANE_LOWER_RIGHT = 0; public final static short ACTIVE_PANE_UPPER_RIGHT = 1; public final static short ACTIVE_PANE_LOWER_LEFT = 2; + // TODO - remove obsolete field (it was deprecated May-2008 v3.1) + /** @deprecated use ACTIVE_PANE_UPPER_LEFT */ public final static short ACTIVE_PANE_UPER_LEFT = 3; + public final static short ACTIVE_PANE_UPPER_LEFT = 3; public PaneRecord() @@ -82,7 +81,6 @@ protected void fillFields(RecordInputStream in) field_3_topRow = in.readShort(); field_4_leftColumn = in.readShort(); field_5_activePane = in.readShort(); - } public String toString() @@ -229,7 +227,7 @@ public void setLeftColumn(short field_4_leftColumn) * ACTIVE_PANE_LOWER_RIGHT * ACTIVE_PANE_UPPER_RIGHT * ACTIVE_PANE_LOWER_LEFT - * ACTIVE_PANE_UPER_LEFT + * ACTIVE_PANE_UPPER_LEFT */ public short getActivePane() { @@ -244,16 +242,10 @@ public short getActivePane() * ACTIVE_PANE_LOWER_RIGHT * ACTIVE_PANE_UPPER_RIGHT * ACTIVE_PANE_LOWER_LEFT - * ACTIVE_PANE_UPER_LEFT + * ACTIVE_PANE_UPPER_LEFT */ public void setActivePane(short field_5_activePane) { this.field_5_activePane = field_5_activePane; } - - -} // END OF CLASS - - - - +} diff --git a/src/java/org/apache/poi/hssf/record/RowRecord.java b/src/java/org/apache/poi/hssf/record/RowRecord.java index a2815d28730..cbfc0ec5942 100644 --- a/src/java/org/apache/poi/hssf/record/RowRecord.java +++ b/src/java/org/apache/poi/hssf/record/RowRecord.java @@ -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,7 +14,6 @@ Licensed to the Apache Software Foundation (ASF) under one or more See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ - package org.apache.poi.hssf.record; @@ -31,20 +29,18 @@ Licensed to the Apache Software Foundation (ASF) under one or more * @author Jason Height (jheight at chariot dot net dot au) * @version 2.0-pre */ - -public class RowRecord - extends Record - implements Comparable -{ - public final static short sid = 0x208; +public final class RowRecord extends Record implements Comparable { + public final static short sid = 0x208; - /** The maximum row number that excel can handle (zero bazed) ie 65536 rows is + private static final int OPTION_BITS_ALWAYS_SET = 0x0100; + private static final int DEFAULT_HEIGHT_BIT = 0x8000; + + /** The maximum row number that excel can handle (zero based) ie 65536 rows is * max number of rows. */ public final static int MAX_ROW_NUMBER = 65535; - //private short field_1_row_number; - private int field_1_row_number; + private int field_1_row_number; private short field_2_first_col; private short field_3_last_col; // plus 1 private short field_4_height; @@ -52,7 +48,8 @@ public class RowRecord // for generated sheets. private short field_6_reserved; - private short field_7_option_flags; + /** 16 bit options flags */ + private int field_7_option_flags; private static final BitField outlineLevel = BitFieldFactory.getInstance(0x07); // bit 3 reserved @@ -62,8 +59,17 @@ public class RowRecord private static final BitField formatted = BitFieldFactory.getInstance(0x80); private short field_8_xf_index; // only if isFormatted - public RowRecord() - { + public RowRecord(int rowNumber) { + field_1_row_number = rowNumber; + field_2_first_col = -1; + field_3_last_col = -1; + field_4_height = (short)DEFAULT_HEIGHT_BIT; + field_4_height = (short)DEFAULT_HEIGHT_BIT; + field_5_optimize = ( short ) 0; + field_6_reserved = ( short ) 0; + field_7_option_flags = OPTION_BITS_ALWAYS_SET; // seems necessary for outlining + + field_8_xf_index = ( short ) 0xf; } /** @@ -86,7 +92,6 @@ protected void validateSid(short id) protected void fillFields(RecordInputStream in) { - //field_1_row_number = LittleEndian.getShort(data, 0 + offset); field_1_row_number = in.readUShort(); field_2_first_col = in.readShort(); field_3_last_col = in.readShort(); @@ -156,7 +161,7 @@ public void setOptimize(short optimize) public void setOptionFlags(short options) { - field_7_option_flags = options; + field_7_option_flags = options | OPTION_BITS_ALWAYS_SET; } // option bitfields @@ -169,20 +174,18 @@ public void setOptionFlags(short options) public void setOutlineLevel(short ol) { - field_7_option_flags = - outlineLevel.setShortValue(field_7_option_flags, ol); + field_7_option_flags = outlineLevel.setValue(field_7_option_flags, ol); } /** - * set whether or not to colapse this row - * @param c - colapse or not + * set whether or not to collapse this row + * @param c - collapse or not * @see #setOptionFlags(short) */ public void setColapsed(boolean c) { - field_7_option_flags = colapsed.setShortBoolean(field_7_option_flags, - c); + field_7_option_flags = colapsed.setBoolean(field_7_option_flags, c); } /** @@ -193,8 +196,7 @@ public void setColapsed(boolean c) public void setZeroHeight(boolean z) { - field_7_option_flags = - zeroHeight.setShortBoolean(field_7_option_flags, z); + field_7_option_flags = zeroHeight.setBoolean(field_7_option_flags, z); } /** @@ -205,8 +207,7 @@ public void setZeroHeight(boolean z) public void setBadFontHeight(boolean f) { - field_7_option_flags = - badFontHeight.setShortBoolean(field_7_option_flags, f); + field_7_option_flags = badFontHeight.setBoolean(field_7_option_flags, f); } /** @@ -217,8 +218,7 @@ public void setBadFontHeight(boolean f) public void setFormatted(boolean f) { - field_7_option_flags = formatted.setShortBoolean(field_7_option_flags, - f); + field_7_option_flags = formatted.setBoolean(field_7_option_flags, f); } // end bitfields @@ -293,7 +293,7 @@ public short getOptimize() public short getOptionFlags() { - return field_7_option_flags; + return (short)field_7_option_flags; } // option bitfields @@ -306,7 +306,7 @@ public short getOptionFlags() public short getOutlineLevel() { - return outlineLevel.getShortValue(field_7_option_flags); + return (short)outlineLevel.getValue(field_7_option_flags); } /** @@ -410,7 +410,6 @@ public int serialize(int offset, byte [] data) { LittleEndian.putShort(data, 0 + offset, sid); LittleEndian.putShort(data, 2 + offset, ( short ) 16); - //LittleEndian.putShort(data, 4 + offset, getRowNumber()); LittleEndian.putShort(data, 4 + offset, ( short ) getRowNumber()); LittleEndian.putShort(data, 6 + offset, getFirstCol() == -1 ? (short)0 : getFirstCol()); LittleEndian.putShort(data, 8 + offset, getLastCol() == -1 ? (short)0 : getLastCol()); @@ -419,7 +418,6 @@ public int serialize(int offset, byte [] data) LittleEndian.putShort(data, 14 + offset, field_6_reserved); LittleEndian.putShort(data, 16 + offset, getOptionFlags()); -// LittleEndian.putShort(data,18,getOutlineLevel()); LittleEndian.putShort(data, 18 + offset, getXFIndex()); return getRecordSize(); } @@ -469,8 +467,7 @@ public boolean equals(Object obj) } public Object clone() { - RowRecord rec = new RowRecord(); - rec.field_1_row_number = field_1_row_number; + RowRecord rec = new RowRecord(field_1_row_number); rec.field_2_first_col = field_2_first_col; rec.field_3_last_col = field_3_last_col; rec.field_4_height = field_4_height; diff --git a/src/java/org/apache/poi/hssf/record/WindowOneRecord.java b/src/java/org/apache/poi/hssf/record/WindowOneRecord.java index f101cb59af8..4c836f2ee83 100644 --- a/src/java/org/apache/poi/hssf/record/WindowOneRecord.java +++ b/src/java/org/apache/poi/hssf/record/WindowOneRecord.java @@ -57,8 +57,8 @@ public class WindowOneRecord BitFieldFactory.getInstance(0x20); // display tabs at the bottom // all the rest are "reserved" - private short field_6_selected_tab; - private short field_7_displayed_tab; + private int field_6_active_sheet; + private int field_7_first_visible_tab; private short field_8_num_selected_tabs; private short field_9_tab_width_ratio; @@ -91,8 +91,8 @@ protected void fillFields(RecordInputStream in) field_3_width = in.readShort(); field_4_height = in.readShort(); field_5_options = in.readShort(); - field_6_selected_tab = in.readShort(); - field_7_displayed_tab = in.readShort(); + field_6_active_sheet = in.readShort(); + field_7_first_visible_tab = in.readShort(); field_8_num_selected_tabs = in.readShort(); field_9_tab_width_ratio = in.readShort(); } @@ -202,24 +202,33 @@ public void setDisplayTabs(boolean disptabs) // end bitfields + public void setActiveSheetIndex(int index) { + field_6_active_sheet = index; + } /** - * set the selected tab number - * @param s tab number + * deprecated May 2008 + * @deprecated - Misleading name - use setActiveSheetIndex() */ - public void setSelectedTab(short s) { - field_6_selected_tab = s; + setActiveSheetIndex(s); } /** - * set the displayed tab number - * @param t tab number + * Sets the first visible sheet in the worksheet tab-bar. This method does not + * hide, select or focus sheets. It just sets the scroll position in the tab-bar. + * @param t the sheet index of the tab that will become the first in the tab-bar */ + public void setFirstVisibleTab(int t) { + field_7_first_visible_tab = t; + } - public void setDisplayedTab(short t) - { - field_7_displayed_tab = t; + /** + * deprecated May 2008 + * @deprecated - Misleading name - use setFirstVisibleTab() + */ + public void setDisplayedTab(short t) { + setFirstVisibleTab(t); } /** @@ -347,24 +356,36 @@ public boolean getDisplayTabs() // end options bitfields + /** - * get the selected tab number - * @return Tab number + * @return the index of the currently displayed sheet + */ + public int getActiveSheetIndex() { + return field_6_active_sheet; + } + /** + * deprecated May 2008 + * @deprecated - Misleading name - use getActiveSheetIndex() */ - public short getSelectedTab() { - return field_6_selected_tab; + return (short) getActiveSheetIndex(); } /** - * get the displayed tab number - * @return Tab number + * @return the first visible sheet in the worksheet tab-bar. + * I.E. the scroll position of the tab-bar. + */ + public int getFirstVisibleTab() { + return field_7_first_visible_tab; + } + /** + * deprecated May 2008 + * @deprecated - Misleading name - use getFirstVisibleTab() */ - public short getDisplayedTab() { - return field_7_displayed_tab; + return (short) getFirstVisibleTab(); } /** @@ -412,10 +433,10 @@ public String toString() .append(getDisplayVerticalScrollbar()).append("\n"); buffer.append(" .tabs = ").append(getDisplayTabs()) .append("\n"); - buffer.append(" .selectedtab = ") - .append(Integer.toHexString(getSelectedTab())).append("\n"); - buffer.append(" .displayedtab = ") - .append(Integer.toHexString(getDisplayedTab())).append("\n"); + buffer.append(" .activeSheet = ") + .append(Integer.toHexString(getActiveSheetIndex())).append("\n"); + buffer.append(" .firstVisibleTab = ") + .append(Integer.toHexString(getFirstVisibleTab())).append("\n"); buffer.append(" .numselectedtabs = ") .append(Integer.toHexString(getNumSelectedTabs())).append("\n"); buffer.append(" .tabwidthratio = ") @@ -434,8 +455,8 @@ public int serialize(int offset, byte [] data) LittleEndian.putShort(data, 8 + offset, getWidth()); LittleEndian.putShort(data, 10 + offset, getHeight()); LittleEndian.putShort(data, 12 + offset, getOptions()); - LittleEndian.putShort(data, 14 + offset, getSelectedTab()); - LittleEndian.putShort(data, 16 + offset, getDisplayedTab()); + LittleEndian.putUShort(data, 14 + offset, getActiveSheetIndex()); + LittleEndian.putUShort(data, 16 + offset, getFirstVisibleTab()); LittleEndian.putShort(data, 18 + offset, getNumSelectedTabs()); LittleEndian.putShort(data, 20 + offset, getTabWidthRatio()); return getRecordSize(); diff --git a/src/java/org/apache/poi/hssf/record/WindowTwoRecord.java b/src/java/org/apache/poi/hssf/record/WindowTwoRecord.java index f6b51996d5d..e2bb6d5609d 100644 --- a/src/java/org/apache/poi/hssf/record/WindowTwoRecord.java +++ b/src/java/org/apache/poi/hssf/record/WindowTwoRecord.java @@ -54,7 +54,7 @@ public class WindowTwoRecord private BitField displayGuts = BitFieldFactory.getInstance(0x80); private BitField freezePanesNoSplit = BitFieldFactory.getInstance(0x100); private BitField selected = BitFieldFactory.getInstance(0x200); - private BitField paged = BitFieldFactory.getInstance(0x400); + private BitField active = BitFieldFactory.getInstance(0x400); private BitField savedInPageBreakPreview = BitFieldFactory.getInstance(0x800); // 4-7 reserved @@ -222,12 +222,16 @@ public void setSelected(boolean sel) * is the sheet currently displayed in the window * @param p displayed or not */ - - public void setPaged(boolean p) - { - field_1_options = paged.setShortBoolean(field_1_options, p); + public void setActive(boolean p) { + field_1_options = active.setShortBoolean(field_1_options, p); + } + /** + * deprecated May 2008 + * @deprecated use setActive() + */ + public void setPaged(boolean p) { + setActive(p); } - /** * was the sheet saved in page break view * @param p pagebreaksaved or not @@ -416,9 +420,15 @@ public boolean getSelected() * @return displayed or not */ - public boolean getPaged() - { - return paged.isSet(field_1_options); + public boolean isActive() { + return active.isSet(field_1_options); + } + /** + * deprecated May 2008 + * @deprecated use isActive() + */ + public boolean getPaged() { + return isActive(); } /** @@ -520,7 +530,7 @@ public String toString() .append(getFreezePanesNoSplit()).append("\n"); buffer.append(" .selected = ").append(getSelected()) .append("\n"); - buffer.append(" .paged = ").append(getPaged()) + buffer.append(" .active = ").append(isActive()) .append("\n"); buffer.append(" .svdinpgbrkpv= ") .append(getSavedInPageBreakPreview()).append("\n"); diff --git a/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java index bed1f0748e4..65af632d3fb 100644 --- a/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java +++ b/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java @@ -35,19 +35,17 @@ Licensed to the Apache Software Foundation (ASF) under one or more * @author Jason Height (jheight at chariot dot net dot au) */ -public class RowRecordsAggregate - extends Record -{ - int firstrow = -1; - int lastrow = -1; - Map records = null; - int size = 0; +public final class RowRecordsAggregate extends Record { + private int firstrow = -1; + private int lastrow = -1; + private Map records = null; // TODO - use a proper key in this map + private int size = 0; /** Creates a new instance of ValueRecordsAggregate */ public RowRecordsAggregate() { - records = new TreeMap(); + records = new TreeMap(); } public void insertRow(RowRecord row) @@ -74,15 +72,13 @@ public void removeRow(RowRecord row) records.remove(row); } - public RowRecord getRow(int rownum) - { - // Row must be between 0 and 65535 - if(rownum < 0 || rownum > 65535) { - throw new IllegalArgumentException("The row number must be between 0 and 65535"); - } + public RowRecord getRow(int rownum) { + // Row must be between 0 and 65535 + if(rownum < 0 || rownum > 65535) { + throw new IllegalArgumentException("The row number must be between 0 and 65535"); + } - RowRecord row = new RowRecord(); - row.setRowNumber(rownum); + RowRecord row = new RowRecord(rownum); return ( RowRecord ) records.get(row); } @@ -333,7 +329,7 @@ public void collapseRow( int rowNumber ) // Find the start of the group. int startRow = findStartOfRowOutlineGroup( rowNumber ); - RowRecord rowRecord = (RowRecord) getRow( startRow ); + RowRecord rowRecord = getRow( startRow ); // Hide all the columns until the end of the group int lastRow = writeHidden( rowRecord, startRow, true ); @@ -358,17 +354,8 @@ public void collapseRow( int rowNumber ) * @return RowRecord created for the passed in row number * @see org.apache.poi.hssf.record.RowRecord */ - public static RowRecord createRow(int row) - { - RowRecord rowrec = new RowRecord(); - - //rowrec.setRowNumber(( short ) row); - rowrec.setRowNumber(row); - rowrec.setHeight(( short ) 0xff); - rowrec.setOptimize(( short ) 0x0); - rowrec.setOptionFlags(( short ) 0x100); // seems necessary for outlining - rowrec.setXFIndex(( short ) 0xf); - return rowrec; + public static RowRecord createRow(int rowNumber) { + return new RowRecord(rowNumber); } public boolean isRowGroupCollapsed( int row ) @@ -399,12 +386,12 @@ public void expandRow( int rowNumber ) int endIdx = findEndOfRowOutlineGroup( idx ); // expand: - // colapsed bit must be unset + // collapsed bit must be unset // hidden bit gets unset _if_ surrounding groups are expanded you can determine // this by looking at the hidden bit of the enclosing group. You will have // to look at the start and the end of the current group to determine which // is the enclosing group - // hidden bit only is altered for this outline level. ie. don't uncollapse contained groups + // hidden bit only is altered for this outline level. ie. don't un-collapse contained groups if ( !isRowGroupHiddenByParent( idx ) ) { for ( int i = startIdx; i <= endIdx; i++ ) diff --git a/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java b/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java index 7d44b008f88..12f26bfdee5 100755 --- a/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java +++ b/src/java/org/apache/poi/hssf/record/constant/ConstantValueParser.java @@ -24,9 +24,8 @@ Licensed to the Apache Software Foundation (ASF) under one or more /** * To support Constant Values (2.5.7) as required by the CRN record. - * This class should probably also be used for two dimensional arrays which are encoded by + * This class is also used for two dimensional arrays which are encoded by * EXTERNALNAME (5.39) records and Array tokens.

- * TODO - code in ArrayPtg should be merged with this code. It currently supports only 2 of the constant types * * @author Josh Micich */ diff --git a/src/java/org/apache/poi/hssf/record/constant/ErrorConstant.java b/src/java/org/apache/poi/hssf/record/constant/ErrorConstant.java index 2fc79a948f4..3421dd4a8e5 100644 --- a/src/java/org/apache/poi/hssf/record/constant/ErrorConstant.java +++ b/src/java/org/apache/poi/hssf/record/constant/ErrorConstant.java @@ -47,18 +47,31 @@ private ErrorConstant(int errorCode) { public int getErrorCode() { return _errorCode; } + public String getText() { + if(HSSFErrorConstants.isValidCode(_errorCode)) { + return HSSFErrorConstants.getText(_errorCode); + } + return "unknown error code (" + _errorCode + ")"; + } public static ErrorConstant valueOf(int errorCode) { switch (errorCode) { - case HSSFErrorConstants.ERROR_NULL: return NULL; - case HSSFErrorConstants.ERROR_DIV_0: return DIV_0; - case HSSFErrorConstants.ERROR_VALUE: return VALUE; - case HSSFErrorConstants.ERROR_REF: return REF; - case HSSFErrorConstants.ERROR_NAME: return NAME; - case HSSFErrorConstants.ERROR_NUM: return NUM; - case HSSFErrorConstants.ERROR_NA: return NA; + case HSSFErrorConstants.ERROR_NULL: return NULL; + case HSSFErrorConstants.ERROR_DIV_0: return DIV_0; + case HSSFErrorConstants.ERROR_VALUE: return VALUE; + case HSSFErrorConstants.ERROR_REF: return REF; + case HSSFErrorConstants.ERROR_NAME: return NAME; + case HSSFErrorConstants.ERROR_NUM: return NUM; + case HSSFErrorConstants.ERROR_NA: return NA; } System.err.println("Warning - unexpected error code (" + errorCode + ")"); return new ErrorConstant(errorCode); } + public String toString() { + StringBuffer sb = new StringBuffer(64); + sb.append(getClass().getName()).append(" ["); + sb.append(getText()); + sb.append("]"); + return sb.toString(); + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java b/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java index 01942be55cf..251009b2870 100644 --- a/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java +++ b/src/java/org/apache/poi/hssf/record/formula/ArrayPtg.java @@ -17,22 +17,17 @@ Licensed to the Apache Software Foundation (ASF) under one or more package org.apache.poi.hssf.record.formula; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.StringUtil; - -import org.apache.poi.hssf.util.CellReference; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.record.RecordFormatException; import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.SSTRecord; import org.apache.poi.hssf.record.UnicodeString; +import org.apache.poi.hssf.record.constant.ConstantValueParser; +import org.apache.poi.hssf.record.constant.ErrorConstant; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.util.LittleEndian; /** * ArrayPtg - handles arrays * - * The ArrayPtg is a little wierd, the size of the Ptg when parsing initially only + * The ArrayPtg is a little weird, the size of the Ptg when parsing initially only * includes the Ptg sid and the reserved bytes. The next Ptg in the expression then follows. * It is only after the "size" of all the Ptgs is met, that the ArrayPtg data is actually * held after this. So Ptg.createParsedExpression keeps track of the number of @@ -40,209 +35,160 @@ Licensed to the Apache Software Foundation (ASF) under one or more * * @author Jason Height (jheight at chariot dot net dot au) */ - -public class ArrayPtg extends Ptg -{ - public final static byte sid = 0x20; - protected byte field_1_reserved; - protected byte field_2_reserved; - protected byte field_3_reserved; - protected byte field_4_reserved; - protected byte field_5_reserved; - protected byte field_6_reserved; - protected byte field_7_reserved; - - - protected short token_1_columns; - protected short token_2_rows; - protected Object[][] token_3_arrayValues; - - protected ArrayPtg() { - //Required for clone methods - } - - public ArrayPtg(RecordInputStream in) - { - field_1_reserved = in.readByte(); - field_2_reserved = in.readByte(); - field_3_reserved = in.readByte(); - field_4_reserved = in.readByte(); - field_5_reserved = in.readByte(); - field_6_reserved = in.readByte(); - field_7_reserved = in.readByte(); - } - - /** - * Read in the actual token (array) values. This occurs - * AFTER the last Ptg in the expression. - * See page 304-305 of Excel97-2007BinaryFileFormat(xls)Specification.pdf - */ - public void readTokenValues(RecordInputStream in) { - token_1_columns = (short)(0x00ff & in.readByte()); - token_2_rows = in.readShort(); - - //The token_1_columns and token_2_rows do not follow the documentation. - //The number of physical rows and columns is actually +1 of these values. - //Which is not explicitly documented. - token_1_columns++; - token_2_rows++; - - token_3_arrayValues = new Object[token_1_columns][token_2_rows]; - - for (int x=0;x= token_1_columns) { + throw new IllegalArgumentException("Specified colIx (" + colIx + + ") is outside the allowed range (0.." + (token_1_columns-1) + ")"); + } + if(rowIx < 0 || rowIx >= token_2_rows) { + throw new IllegalArgumentException("Specified rowIx (" + rowIx + + ") is outside the allowed range (0.." + (token_2_rows-1) + ")"); + } + return rowIx * token_1_columns + colIx; + } + + public void writeBytes(byte[] data, int offset) { + + LittleEndian.putByte(data, offset + 0, sid + ptgClass); + System.arraycopy(field_1_reserved, 0, data, offset+1, RESERVED_FIELD_LEN); + } + + public int writeTokenValueBytes(byte[] data, int offset) { + + LittleEndian.putByte(data, offset + 0, token_1_columns-1); + LittleEndian.putShort(data, offset + 1, (short)(token_2_rows-1)); + ConstantValueParser.encode(data, offset + 3, token_3_arrayValues); + return 3 + ConstantValueParser.getEncodedSize(token_3_arrayValues); + } + + public short getRowCount() { + return token_2_rows; + } + + public short getColumnCount() { + return token_1_columns; + } + + /** This size includes the size of the array Ptg plus the Array Ptg Token value size*/ + public int getSize() + { + int size = 1+7+1+2; + size += ConstantValueParser.getEncodedSize(token_3_arrayValues); + return size; + } + + public String toFormulaString(HSSFWorkbook book) + { + StringBuffer b = new StringBuffer(); + b.append("{"); + for (int x=0;x 0) { + b.append(";"); } - } - } - - public String toString() - { - StringBuffer buffer = new StringBuffer("[ArrayPtg]\n"); - - buffer.append("columns = ").append(getColumnCount()).append("\n"); - buffer.append("rows = ").append(getRowCount()).append("\n"); - for (int x=0;x 0) { + b.append(","); + } + Object o = token_3_arrayValues[getValueIndex(x, y)]; + b.append(getConstantText(o)); + } + } + b.append("}"); + return b.toString(); + } + + private static String getConstantText(Object o) { + + if (o == null) { + return ""; // TODO - how is 'empty value' represented in formulas? + } + if (o instanceof UnicodeString) { + return "\"" + ((UnicodeString)o).getString() + "\""; + } + if (o instanceof Double) { + return ((Double)o).toString(); + } + if (o instanceof Boolean) { + ((Boolean)o).toString(); + } + if (o instanceof ErrorConstant) { + return ((ErrorConstant)o).getText(); + } + throw new IllegalArgumentException("Unexpected constant class (" + o.getClass().getName() + ")"); + } + + public byte getDefaultOperandClass() { + return Ptg.CLASS_ARRAY; + } + + public Object clone() { + ArrayPtg ptg = new ArrayPtg(); + ptg.field_1_reserved = (byte[]) field_1_reserved.clone(); + + ptg.token_1_columns = token_1_columns; + ptg.token_2_rows = token_2_rows; + ptg.token_3_arrayValues = (Object[]) token_3_arrayValues.clone(); + ptg.setClass(ptgClass); + return ptg; + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java b/src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java index 616f737b847..5be866e963f 100644 --- a/src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java +++ b/src/java/org/apache/poi/hssf/record/formula/ArrayPtgA.java @@ -17,56 +17,31 @@ Licensed to the Apache Software Foundation (ASF) under one or more package org.apache.poi.hssf.record.formula; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.StringUtil; - -import org.apache.poi.hssf.util.CellReference; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.record.RecordFormatException; import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.SSTRecord; -import org.apache.poi.hssf.record.UnicodeString; /** * ArrayPtgA - handles arrays * * @author Jason Height (jheight at chariot dot net dot au) */ - -public class ArrayPtgA extends ArrayPtg -{ +public final class ArrayPtgA extends ArrayPtg { public final static byte sid = 0x60; - protected ArrayPtgA() { - super(); + private ArrayPtgA() { //Required for clone methods } - public ArrayPtgA(RecordInputStream in) - { + public ArrayPtgA(RecordInputStream in) { super(in); } public Object clone() { ArrayPtgA ptg = new ArrayPtgA(); - ptg.field_1_reserved = field_1_reserved; - ptg.field_2_reserved = field_2_reserved; - ptg.field_3_reserved = field_3_reserved; - ptg.field_4_reserved = field_4_reserved; - ptg.field_5_reserved = field_5_reserved; - ptg.field_6_reserved = field_6_reserved; - ptg.field_7_reserved = field_7_reserved; + ptg.field_1_reserved = (byte[]) field_1_reserved.clone(); ptg.token_1_columns = token_1_columns; ptg.token_2_rows = token_2_rows; - ptg.token_3_arrayValues = new Object[getColumnCount()][getRowCount()]; - for (int x=0;x255) { - throw new IllegalArgumentException("String literals in formulas cant be bigger than 255 characters ASCII"); + if (value.length() > 255) { + throw new IllegalArgumentException( + "String literals in formulas can't be bigger than 255 characters ASCII"); } - this.field_2_options=0; - field_2_options = (byte)this.fHighByte.setBoolean(field_2_options, StringUtil.hasMultibyte(value)); - this.field_3_string=value; - this.field_1_length=value.length(); //for the moment, we support only ASCII strings in formulas we create + field_2_options = 0; + field_2_options = (byte) fHighByte.setBoolean(field_2_options, StringUtil + .hasMultibyte(value)); + field_3_string = value; + field_1_length = value.length(); // for the moment, we support only ASCII strings in formulas we create } - /* - public void setValue(String value) - { - field_1_value = value; - }*/ - - - public String getValue() - { + public String getValue() { return field_3_string; } - public void writeBytes(byte [] array, int offset) - { - array[ offset + 0 ] = sid; - array[ offset + 1 ] = (byte)field_1_length; - array[ offset + 2 ] = field_2_options; + public void writeBytes(byte[] array, int offset) { + array[offset + 0] = sid; + array[offset + 1] = (byte) field_1_length; + array[offset + 2] = field_2_options; if (fHighByte.isSet(field_2_options)) { - StringUtil.putUnicodeLE(getValue(),array,offset+3); - }else { - StringUtil.putCompressedUnicode(getValue(),array,offset+3); + StringUtil.putUnicodeLE(getValue(), array, offset + 3); + } else { + StringUtil.putCompressedUnicode(getValue(), array, offset + 3); } } - public int getSize() - { + public int getSize() { if (fHighByte.isSet(field_2_options)) { - return 2*field_1_length+3; + return 2 * field_1_length + 3; } else { - return field_1_length+3; + return field_1_length + 3; } } - public String toFormulaString(HSSFWorkbook book) - { - return "\""+getValue()+"\""; + public String toFormulaString(HSSFWorkbook book) { + String value = field_3_string; + int len = value.length(); + StringBuffer sb = new StringBuffer(len + 4); + sb.append(FORMULA_DELIMITER); + + for (int i = 0; i < len; i++) { + char c = value.charAt(i); + if (c == FORMULA_DELIMITER) { + sb.append(FORMULA_DELIMITER); + } + sb.append(c); + } + + sb.append(FORMULA_DELIMITER); + return sb.toString(); } + public byte getDefaultOperandClass() { - return Ptg.CLASS_VALUE; - } + return Ptg.CLASS_VALUE; + } - public Object clone() { - StringPtg ptg = new StringPtg(); - ptg.field_1_length = field_1_length; - ptg.field_2_options=field_2_options; - ptg.field_3_string=field_3_string; - return ptg; - } + public Object clone() { + StringPtg ptg = new StringPtg(); + ptg.field_1_length = field_1_length; + ptg.field_2_options = field_2_options; + ptg.field_3_string = field_3_string; + return ptg; + } + public String toString() { + StringBuffer sb = new StringBuffer(64); + sb.append(getClass().getName()).append(" ["); + sb.append(field_3_string); + sb.append("]"); + return sb.toString(); + } } - diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/Area2DEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/Area2DEval.java index 4b9a64c1c0e..5ae98b39fed 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/Area2DEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/Area2DEval.java @@ -22,79 +22,11 @@ /** * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * + * */ -public final class Area2DEval implements AreaEval { -// TODO -refactor with Area3DEval - private final AreaPtg _delegate; +public final class Area2DEval extends AreaEvalBase { - private final ValueEval[] _values; - - public Area2DEval(Ptg ptg, ValueEval[] values) { - if(ptg == null) { - throw new IllegalArgumentException("ptg must not be null"); - } - if(values == null) { - throw new IllegalArgumentException("values must not be null"); - } - for(int i=values.length-1; i>=0; i--) { - if(values[i] == null) { - throw new IllegalArgumentException("value array elements must not be null"); - } - } - // TODO - check size of array vs size of AreaPtg - _delegate = (AreaPtg) ptg; - _values = values; - } - - public int getFirstColumn() { - return _delegate.getFirstColumn(); - } - - public int getFirstRow() { - return _delegate.getFirstRow(); - } - - public int getLastColumn() { - return _delegate.getLastColumn(); - } - - public int getLastRow() { - return _delegate.getLastRow(); - } - - public ValueEval[] getValues() { - return _values; - } - - public ValueEval getValueAt(int row, int col) { - ValueEval retval; - int index = ((row-getFirstRow())*(getLastColumn()-getFirstColumn()+1))+(col-getFirstColumn()); - if (index <0 || index >= _values.length) - retval = ErrorEval.VALUE_INVALID; - else - retval = _values[index]; - return retval; - } - - public boolean contains(int row, int col) { - return (getFirstRow() <= row) && (getLastRow() >= row) - && (getFirstColumn() <= col) && (getLastColumn() >= col); - } - - public boolean containsRow(int row) { - return (getFirstRow() <= row) && (getLastRow() >= row); - } - - public boolean containsColumn(short col) { - return (getFirstColumn() <= col) && (getLastColumn() >= col); - } - - public boolean isColumn() { - return _delegate.getFirstColumn() == _delegate.getLastColumn(); - } - - public boolean isRow() { - return _delegate.getFirstRow() == _delegate.getLastRow(); - } -} + public Area2DEval(Ptg ptg, ValueEval[] values) { + super((AreaPtg) ptg, values); + } +} \ No newline at end of file diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/Area3DEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/Area3DEval.java index 2f539142d15..89209e21b6b 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/Area3DEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/Area3DEval.java @@ -22,84 +22,18 @@ /** * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * + * */ -public final class Area3DEval implements AreaEval { - // TODO -refactor with Area3DEval - private final Area3DPtg _delegate; +public final class Area3DEval extends AreaEvalBase { - private final ValueEval[] _values; + private final int _externSheetIndex; - public Area3DEval(Ptg ptg, ValueEval[] values) { - if(ptg == null) { - throw new IllegalArgumentException("ptg must not be null"); - } - if(values == null) { - throw new IllegalArgumentException("values must not be null"); - } - for(int i=values.length-1; i>=0; i--) { - if(values[i] == null) { - throw new IllegalArgumentException("value array elements must not be null"); - } - } - // TODO - check size of array vs size of AreaPtg - _values = values; - _delegate = (Area3DPtg) ptg; - } + public Area3DEval(Ptg ptg, ValueEval[] values) { + super((Area3DPtg) ptg, values); + _externSheetIndex = ((Area3DPtg) ptg).getExternSheetIndex(); + } - public int getFirstColumn() { - return _delegate.getFirstColumn(); - } - - public int getFirstRow() { - return _delegate.getFirstRow(); - } - - public int getLastColumn() { - return (short) _delegate.getLastColumn(); - } - - public int getLastRow() { - return _delegate.getLastRow(); - } - - public ValueEval[] getValues() { - return _values; - } - - public ValueEval getValueAt(int row, int col) { - ValueEval retval; - int index = (row-getFirstRow())*(col-getFirstColumn()); - if (index <0 || index >= _values.length) - retval = ErrorEval.VALUE_INVALID; - else - retval = _values[index]; - return retval; - } - - public boolean contains(int row, int col) { - return (getFirstRow() <= row) && (getLastRow() >= row) - && (getFirstColumn() <= col) && (getLastColumn() >= col); - } - - public boolean containsRow(int row) { - return (getFirstRow() <= row) && (getLastRow() >= row); - } - - public boolean containsColumn(short col) { - return (getFirstColumn() <= col) && (getLastColumn() >= col); - } - - - public boolean isColumn() { - return _delegate.getFirstColumn() == _delegate.getLastColumn(); - } - - public boolean isRow() { - return _delegate.getFirstRow() == _delegate.getLastRow(); - } - - public int getExternSheetIndex() { - return _delegate.getExternSheetIndex(); - } + public int getExternSheetIndex() { + return _externSheetIndex; + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/AreaEvalBase.java b/src/java/org/apache/poi/hssf/record/formula/eval/AreaEvalBase.java new file mode 100644 index 00000000000..9436ae0aa9d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/AreaEvalBase.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.poi.hssf.record.formula.eval; + +import org.apache.poi.hssf.record.formula.AreaI; + +/** + * @author Josh Micich + */ +abstract class AreaEvalBase implements AreaEval { + + private final int _firstColumn; + private final int _firstRow; + private final int _lastColumn; + private final int _lastRow; + private final ValueEval[] _values; + private final int _nColumns; + private final int _nRows; + + protected AreaEvalBase(AreaI ptg, ValueEval[] values) { + if (values == null) { + throw new IllegalArgumentException("values must not be null"); + } + _firstRow = ptg.getFirstRow(); + _firstColumn = ptg.getFirstColumn(); + _lastRow = ptg.getLastRow(); + _lastColumn = ptg.getLastColumn(); + + _nColumns = _lastColumn - _firstColumn + 1; + _nRows = _lastRow - _firstRow + 1; + + int expectedItemCount = _nRows * _nColumns; + if ((values.length != expectedItemCount)) { + // Note - this math may need alteration when POI starts to support full column or full row refs + throw new IllegalArgumentException("Array size should be (" + expectedItemCount + + ") but was (" + values.length + ")"); + } + + + + for (int i = values.length - 1; i >= 0; i--) { + if (values[i] == null) { + throw new IllegalArgumentException("value array elements must not be null"); + } + } + _values = values; + } + + public final int getFirstColumn() { + return _firstColumn; + } + + public final int getFirstRow() { + return _firstRow; + } + + public final int getLastColumn() { + return _lastColumn; + } + + public final int getLastRow() { + return _lastRow; + } + + public final ValueEval[] getValues() { + // TODO - clone() - but some junits rely on not cloning at the moment + return _values; + } + + public final ValueEval getValueAt(int row, int col) { + int rowOffsetIx = row - _firstRow; + int colOffsetIx = col - _firstColumn; + + if(rowOffsetIx < 0 || rowOffsetIx >= _nRows) { + throw new IllegalArgumentException("Specified row index (" + row + + ") is outside the allowed range (" + _firstRow + ".." + _lastRow + ")"); + } + if(colOffsetIx < 0 || colOffsetIx >= _nColumns) { + throw new IllegalArgumentException("Specified column index (" + col + + ") is outside the allowed range (" + _firstColumn + ".." + col + ")"); + } + + int index = rowOffsetIx * _nColumns + colOffsetIx; + return _values[index]; + } + + public final boolean contains(int row, int col) { + return _firstRow <= row && _lastRow >= row + && _firstColumn <= col && _lastColumn >= col; + } + + public final boolean containsRow(int row) { + return (_firstRow <= row) && (_lastRow >= row); + } + + public final boolean containsColumn(short col) { + return (_firstColumn <= col) && (_lastColumn >= col); + } + + public final boolean isColumn() { + return _firstColumn == _lastColumn; + } + + public final boolean isRow() { + return _firstRow == _lastRow; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadataReader.java b/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadataReader.java index 2cdc540e6f2..5ce73271993 100644 --- a/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadataReader.java +++ b/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadataReader.java @@ -21,6 +21,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -36,15 +37,14 @@ Licensed to the Apache Software Foundation (ASF) under one or more final class FunctionMetadataReader { private static final String METADATA_FILE_NAME = "functionMetadata.txt"; + + /** plain ASCII text metadata file uses three dots for ellipsis */ + private static final String ELLIPSIS = "..."; private static final Pattern TAB_DELIM_PATTERN = Pattern.compile("\t"); private static final Pattern SPACE_DELIM_PATTERN = Pattern.compile(" "); private static final byte[] EMPTY_BYTE_ARRAY = { }; - // special characters from the ooo document - private static final int CHAR_ELLIPSIS_8230 = 8230; - private static final int CHAR_NDASH_8211 = 8211; - private static final String[] DIGIT_ENDING_FUNCTION_NAMES = { // Digits at the end of a function might be due to a left-over footnote marker. // except in these cases @@ -58,7 +58,12 @@ public static FunctionMetadataRegistry createRegistry() { throw new RuntimeException("resource '" + METADATA_FILE_NAME + "' not found"); } - BufferedReader br = new BufferedReader(new InputStreamReader(is)); + BufferedReader br; + try { + br = new BufferedReader(new InputStreamReader(is,"UTF-8")); + } catch(UnsupportedEncodingException e) { + throw new RuntimeException(e); + } FunctionDataBuilder fdb = new FunctionDataBuilder(400); try { @@ -123,7 +128,9 @@ private static byte[] parseOperandTypeCodes(String codes) { } String[] array = SPACE_DELIM_PATTERN.split(codes); int nItems = array.length; - if(array[nItems-1].charAt(0) == CHAR_ELLIPSIS_8230) { + if(ELLIPSIS.equals(array[nItems-1])) { + // final ellipsis is optional, and ignored + // (all unspecified params are assumed to be the same as the last) nItems --; } byte[] result = new byte[nItems]; @@ -137,7 +144,6 @@ private static boolean isDash(String codes) { if(codes.length() == 1) { switch (codes.charAt(0)) { case '-': - case CHAR_NDASH_8211: // this is what the ooo doc has return true; } } @@ -153,7 +159,7 @@ private static byte parseOperandTypeCode(String code) { case 'R': return Ptg.CLASS_REF; case 'A': return Ptg.CLASS_ARRAY; } - throw new IllegalArgumentException("Unexpected operand type code '" + code + "'"); + throw new IllegalArgumentException("Unexpected operand type code '" + code + "' (" + (int)code.charAt(0) + ")"); } /** diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java index 81a33825672..7d2a53d2079 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -817,8 +817,7 @@ public void setCellErrorValue(byte value) int row=record.getRow(); short col=record.getColumn(); short styleIndex=record.getXFIndex(); - if ((cellType != CELL_TYPE_ERROR) && (cellType != CELL_TYPE_FORMULA)) - { + if (cellType != CELL_TYPE_ERROR) { setCellType(CELL_TYPE_ERROR, false, row, col, styleIndex); } (( BoolErrRecord ) record).setValue(value); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java index 0a9c3dfa80d..cf4f83b311c 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java @@ -232,8 +232,7 @@ public HSSFCell evaluateInCell(HSSFCell cell) { cell.setCellValue(cv.getBooleanValue()); break; case HSSFCell.CELL_TYPE_ERROR: - cell.setCellType(HSSFCell.CELL_TYPE_ERROR); - cell.setCellValue(cv.getErrorValue()); + cell.setCellErrorValue(cv.getErrorValue()); break; case HSSFCell.CELL_TYPE_NUMERIC: cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFName.java b/src/java/org/apache/poi/hssf/usermodel/HSSFName.java index 91b3fcd0f1c..e24ca23ea85 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFName.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFName.java @@ -139,4 +139,13 @@ public void setReference(String ref){ } + /** + * Tests if this name points to a cell that no longer exists + * + * @return true if the name refers to a deleted cell, false otherwise + */ + public boolean isDeleted(){ + String ref = getReference(); + return "#REF!".endsWith(ref); + } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java index 0444843d2e0..def79f6d366 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java @@ -21,7 +21,6 @@ Licensed to the Apache Software Foundation (ASF) under one or more import java.util.NoSuchElementException; import org.apache.poi.hssf.model.Sheet; -import org.apache.poi.hssf.model.Workbook; import org.apache.poi.hssf.record.CellValueRecordInterface; import org.apache.poi.hssf.record.RowRecord; @@ -37,11 +36,9 @@ public final class HSSFRow implements Comparable { // used for collections public final static int INITIAL_CAPACITY = 5; - //private short rowNum; + private int rowNum; private HSSFCell[] cells=new HSSFCell[INITIAL_CAPACITY]; -// private short firstcell = -1; -// private short lastcell = -1; /** * reference to low level representation @@ -61,7 +58,8 @@ public final class HSSFRow implements Comparable { private Sheet sheet; - protected HSSFRow() + // TODO - ditch this constructor + HSSFRow() { } @@ -73,18 +71,12 @@ protected HSSFRow() * @param rowNum the row number of this row (0 based) * @see org.apache.poi.hssf.usermodel.HSSFSheet#createRow(int) */ - - //protected HSSFRow(Workbook book, Sheet sheet, short rowNum) - protected HSSFRow(HSSFWorkbook book, Sheet sheet, int rowNum) + HSSFRow(HSSFWorkbook book, Sheet sheet, int rowNum) { this.rowNum = rowNum; this.book = book; this.sheet = sheet; - row = new RowRecord(); - row.setOptionFlags( (short)0x100 ); // seems necessary for outlining to work. - row.setHeight((short) 0xff); - row.setLastCol((short) -1); - row.setFirstCol((short) -1); + row = new RowRecord(rowNum); setRowNum(rowNum); } @@ -98,8 +90,7 @@ protected HSSFRow(HSSFWorkbook book, Sheet sheet, int rowNum) * @param record the low level api object this row should represent * @see org.apache.poi.hssf.usermodel.HSSFSheet#createRow(int) */ - - protected HSSFRow(HSSFWorkbook book, Sheet sheet, RowRecord record) + HSSFRow(HSSFWorkbook book, Sheet sheet, RowRecord record) { this.book = book; this.sheet = sheet; @@ -200,12 +191,11 @@ protected HSSFCell createCellFromRecord(CellValueRecordInterface cell) * @param rowNum the row number (0-based) * @throws IndexOutOfBoundsException if the row number is not within the range 0-65535. */ - - //public void setRowNum(short rowNum) - public void setRowNum(int rowNum) - { - if ((rowNum < 0) || (rowNum > RowRecord.MAX_ROW_NUMBER)) - throw new IndexOutOfBoundsException("Row number must be between 0 and "+RowRecord.MAX_ROW_NUMBER+", was <"+rowNum+">"); + public void setRowNum(int rowNum) { + if ((rowNum < 0) || (rowNum > RowRecord.MAX_ROW_NUMBER)) { + throw new IllegalArgumentException("Invalid row number (" + rowNum + + ") outside allowable range (0.." + RowRecord.MAX_ROW_NUMBER + ")"); + } this.rowNum = rowNum; if (row != null) { @@ -217,8 +207,6 @@ public void setRowNum(int rowNum) * get row number this row represents * @return the row number (0 based) */ - - //public short getRowNum() public int getRowNum() { return rowNum; @@ -479,8 +467,10 @@ private short findFirstCell(short firstcell) } /** - * @return cell iterator of the physically defined cells. Note element 4 may - * actually be row cell depending on how many are defined! + * @return cell iterator of the physically defined cells. + * Note that the 4th element might well not be cell 4, as the iterator + * will not return un-defined (null) cells. + * Call getCellNum() on the returned cells to know which cell they are. */ public Iterator cellIterator() { diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java index b56122688ed..ced8719809b 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java @@ -136,6 +136,7 @@ private void setPropertiesFromSheet(Sheet sheet) { int sloc = sheet.getLoc(); RowRecord row = sheet.getNextRow(); + boolean rowRecordsAlreadyPresent = row!=null; while (row != null) { @@ -160,6 +161,18 @@ private void setPropertiesFromSheet(Sheet sheet) if ( ( lastrow == null ) || ( lastrow.getRowNum() != cval.getRow() ) ) { hrow = getRow( cval.getRow() ); + if (hrow == null) { + // Some tools (like Perl module Spreadsheet::WriteExcel - bug 41187) skip the RowRecords + // Excel, OpenOffice.org and GoogleDocs are all OK with this, so POI should be too. + if (rowRecordsAlreadyPresent) { + // if at least one row record is present, all should be present. + throw new RuntimeException("Unexpected missing row when some rows already present"); + } + // create the row record on the fly now. + RowRecord rowRec = new RowRecord(cval.getRow()); + sheet.addRow(rowRec); + hrow = createRowFromRecord(rowRec); + } } if ( hrow != null ) { @@ -699,6 +712,7 @@ public Region getMergedRegionAt(int index) /** * @return an iterator of the PHYSICAL rows. Meaning the 3rd element may not * be the third row if say for instance the second row is undefined. + * Call getRowNum() on each row if you care which one it is. */ public Iterator rowIterator() { @@ -963,13 +977,34 @@ public HSSFFooter getFooter() return new HSSFFooter( getSheet().getFooter() ); } + /** + * Note - this is not the same as whether the sheet is focused (isActive) + * @return true if this sheet is currently selected + */ + public boolean isSelected() { + return getSheet().getWindowTwo().getSelected(); + } /** * Sets whether sheet is selected. * @param sel Whether to select the sheet or deselect the sheet. */ public void setSelected( boolean sel ) { - getSheet().setSelected( sel ); + getSheet().getWindowTwo().setSelected(sel); + } + /** + * @return true if this sheet is currently focused + */ + public boolean isActive() { + return getSheet().getWindowTwo().isActive(); + } + /** + * Sets whether sheet is selected. + * @param sel Whether to select the sheet or deselect the sheet. + */ + public void setActive(boolean sel ) + { + getSheet().getWindowTwo().setActive(sel); } /** @@ -1671,6 +1706,23 @@ public void setDefaultColumnStyle(short column, HSSFCellStyle style) { * @param column the column index */ public void autoSizeColumn(short column) { + autoSizeColumn(column, false); + } + + /** + * Adjusts the column width to fit the contents. + * + * This process can be relatively slow on large sheets, so this should + * normally only be called once per column, at the end of your + * processing. + * + * You can specify whether the content of merged cells should be considered or ignored. + * Default is to ignore merged cells. + * + * @param column the column index + * @param useMergedCells whether to use the contents of merged cells when calculating the width of the column + */ + public void autoSizeColumn(short column, boolean useMergedCells) { AttributedString str; TextLayout layout; /** @@ -1679,13 +1731,13 @@ public void autoSizeColumn(short column) { * '0' looks to be a good choice. */ char defaultChar = '0'; - + /** * This is the multiple that the font height is scaled by when determining the * boundary of rotated text. */ double fontHeightMultiple = 2.0; - + FontRenderContext frc = new FontRenderContext(null, true, true); HSSFWorkbook wb = new HSSFWorkbook(book); @@ -1697,21 +1749,27 @@ public void autoSizeColumn(short column) { int defaultCharWidth = (int)layout.getAdvance(); double width = -1; + rows: for (Iterator it = rowIterator(); it.hasNext();) { HSSFRow row = (HSSFRow) it.next(); HSSFCell cell = row.getCell(column); - boolean isCellInMergedRegion = false; - for (int i = 0 ; i < getNumMergedRegions() && ! isCellInMergedRegion; i++) { - isCellInMergedRegion = getMergedRegionAt(i).contains(row.getRowNum(), column); + if (cell == null) continue; + + int colspan = 1; + for (int i = 0 ; i < getNumMergedRegions(); i++) { + if (getMergedRegionAt(i).contains(row.getRowNum(), column)) { + if (!useMergedCells) { + // If we're not using merged cells, skip this one and move on to the next. + continue rows; + } + cell = row.getCell(getMergedRegionAt(i).getColumnFrom()); + colspan = 1+ getMergedRegionAt(i).getColumnTo() - getMergedRegionAt(i).getColumnFrom(); + } } - if (cell == null | isCellInMergedRegion) continue; - HSSFCellStyle style = cell.getCellStyle(); HSSFFont font = wb.getFontAt(style.getFontIndex()); - //the number of spaces to indent the text in the cell - int indention = style.getIndention(); if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) { HSSFRichTextString rt = cell.getRichStringCellValue(); @@ -1744,9 +1802,9 @@ public void autoSizeColumn(short column) { trans.concatenate( AffineTransform.getScaleInstance(1, fontHeightMultiple) ); - width = Math.max(width, layout.getOutline(trans).getBounds().getWidth() / defaultCharWidth + indention); + width = Math.max(width, ((layout.getOutline(trans).getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention()); } else { - width = Math.max(width, layout.getBounds().getWidth() / defaultCharWidth + indention); + width = Math.max(width, ((layout.getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention()); } } } else { @@ -1789,19 +1847,19 @@ public void autoSizeColumn(short column) { trans.concatenate( AffineTransform.getScaleInstance(1, fontHeightMultiple) ); - width = Math.max(width, layout.getOutline(trans).getBounds().getWidth() / defaultCharWidth + indention); + width = Math.max(width, ((layout.getOutline(trans).getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention()); } else { - width = Math.max(width, layout.getBounds().getWidth() / defaultCharWidth + indention); + width = Math.max(width, ((layout.getBounds().getWidth() / colspan) / defaultCharWidth) + cell.getCellStyle().getIndention()); } } } - if (width != -1) { - if (width > Short.MAX_VALUE) { //calculated width can be greater that Short.MAX_VALUE! - width = Short.MAX_VALUE; - } - sheet.setColumnWidth(column, (short) (width * 256)); + } + if (width != -1) { + if (width > Short.MAX_VALUE) { //width can be bigger that Short.MAX_VALUE! + width = Short.MAX_VALUE; } + sheet.setColumnWidth(column, (short) (width * 256)); } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index 78fe260136f..896ef19c14b 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -140,7 +140,7 @@ public HSSFWorkbook() protected HSSFWorkbook( Workbook book ) { - super(null, null); + super(null, null); workbook = book; sheets = new ArrayList( INITIAL_CAPACITY ); names = new ArrayList( INITIAL_CAPACITY ); @@ -365,16 +365,66 @@ public void setSheetOrder(String sheetname, int pos ) { workbook.setSheetOrder(sheetname, pos); } + private void validateSheetIndex(int index) { + int lastSheetIx = sheets.size() - 1; + if (index < 0 || index > lastSheetIx) { + throw new IllegalArgumentException("Sheet index (" + + index +") is out of range (0.." + lastSheetIx + ")"); + } + } + /** - * sets the tab whose data is actually seen when the sheet is opened. - * This may be different from the "selected sheet" since excel seems to - * allow you to show the data of one sheet when another is seen "selected" - * in the tabs (at the bottom). - * @see org.apache.poi.hssf.usermodel.HSSFSheet#setSelected(boolean) - * @param index + * Selects a single sheet. This may be different to + * the 'active' sheet (which is the sheet with focus). + */ + public void setSelectedTab(int index) { + + validateSheetIndex(index); + int nSheets = sheets.size(); + for (int i=0; i + * + * Care must be taken if the removed sheet is the currently active or only selected sheet in + * the workbook. There are a few situations when Excel must have a selection and/or active + * sheet. (For example when printing - see Bug 40414).
+ * + * This method makes sure that if the removed sheet was active, another sheet will become + * active in its place. Furthermore, if the removed sheet was the only selected sheet, another + * sheet will become selected. The newly active/selected sheet will have the same index, or + * one less if the removed sheet was the last in the workbook. + * * @param index of the sheet (0-based) */ + public void removeSheetAt(int index) { + validateSheetIndex(index); + boolean wasActive = getSheetAt(index).isActive(); + boolean wasSelected = getSheetAt(index).isSelected(); - public void removeSheetAt(int index) - { sheets.remove(index); workbook.removeSheet(index); + + // set the remaining active/selected sheet + int nSheets = sheets.size(); + if (nSheets < 1) { + // nothing more to do if there are no sheets left + return; + } + // the index of the closest remaining sheet to the one just deleted + int newSheetIndex = index; + if (newSheetIndex >= nSheets) { + newSheetIndex = nSheets-1; + } + if (wasActive) { + setActiveSheet(newSheetIndex); + } + + if (wasSelected) { + boolean someOtherSheetIsStillSelected = false; + for (int i =0; i < nSheets; i++) { + if (getSheetAt(i).isSelected()) { + someOtherSheetIsStillSelected = true; + break; + } + } + if (!someOtherSheetIsStillSelected) { + setSelectedTab(newSheetIndex); + } + } } /** @@ -834,8 +942,7 @@ public void setRepeatingRowsAndColumns(int sheetIndex, HSSFPrintSetup printSetup = sheet.getPrintSetup(); printSetup.setValidSettings(false); - WindowTwoRecord w2 = (WindowTwoRecord) sheet.getSheet().findFirstRecordBySid(WindowTwoRecord.sid); - w2.setPaged(true); + sheet.setActive(true); } private NameRecord findExistingRowColHeaderNameRecord( int sheetIndex ) diff --git a/src/java/org/apache/poi/poifs/storage/BlockListImpl.java b/src/java/org/apache/poi/poifs/storage/BlockListImpl.java index 07f690c6b85..7e44fda3f35 100644 --- a/src/java/org/apache/poi/poifs/storage/BlockListImpl.java +++ b/src/java/org/apache/poi/poifs/storage/BlockListImpl.java @@ -102,7 +102,8 @@ public ListManagedBlock remove(final int index) catch (ArrayIndexOutOfBoundsException ignored) { throw new IOException("Cannot remove block[ " + index - + " ]; out of range"); + + " ]; out of range[ 0 - " + + (_blocks.length-1) + " ]"); } return result; } diff --git a/src/java/org/apache/poi/poifs/storage/RawDataBlock.java b/src/java/org/apache/poi/poifs/storage/RawDataBlock.java index 472fd8b8b59..b4630a78b40 100644 --- a/src/java/org/apache/poi/poifs/storage/RawDataBlock.java +++ b/src/java/org/apache/poi/poifs/storage/RawDataBlock.java @@ -81,8 +81,9 @@ else if (count != blockSize) { log.log(POILogger.ERROR, "Unable to read entire block; " + count + type + " read before EOF; expected " - + blockSize + " bytes. Your document" - + " has probably been truncated!" + + blockSize + " bytes. Your document " + + "was either written by software that " + + "ignores the spec, or has been truncated!" ); } else { diff --git a/src/records/definitions/pane_record.xml b/src/records/definitions/pane_record.xml index c6f93b675c1..436443113ab 100644 --- a/src/records/definitions/pane_record.xml +++ b/src/records/definitions/pane_record.xml @@ -31,7 +31,7 @@ - + diff --git a/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata-asGenerated.txt b/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata-asGenerated.txt index 60d2f1fe8bf..475131e1c0e 100644 --- a/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata-asGenerated.txt +++ b/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata-asGenerated.txt @@ -29,7 +29,7 @@ 7 MAX 1 30 V R 8 ROW 0 1 V R 9 COLUMN 0 1 V R -10 NA 0 0 V – +10 NA 0 0 V - 11 NPV 2 30 V V R 12 STDEV 1 30 V R 13 DOLLAR 1 2 V V V @@ -38,7 +38,7 @@ 16 COS 1 1 V V 17 TAN 1 1 V V 18 ARCTAN 1 1 V V -19 PI 0 0 V – +19 PI 0 0 V - 20 SQRT 1 1 V V 21 EXP 1 1 V V 22 LN 1 1 V V @@ -53,8 +53,8 @@ 31 MID 3 3 V V V V 32 LEN 1 1 V V 33 VALUE 1 1 V V -34 TRUE 0 0 V – -35 FALSE 0 0 V – +34 TRUE 0 0 V - +35 FALSE 0 0 V - 36 AND 1 30 V R 37 OR 1 30 V R 38 NOT 1 1 V V @@ -80,7 +80,7 @@ 60 RATE 3 6 V V V V V V V 61 MIRR 3 3 V R V V 62 IRR 1 2 V R V -63 RAND 0 0 V – x +63 RAND 0 0 V - x 64 MATCH 2 3 V V R R 65 DATE 3 3 V V V V 66 TIME 3 3 V V V V @@ -91,7 +91,7 @@ 71 HOUR 1 1 V V 72 MINUTE 1 1 V V 73 SECOND 1 1 V V -74 NOW 0 0 V – x +74 NOW 0 0 V - x 75 AREAS 1 1 V R 76 ROWS 1 1 V R 77 COLUMNS 1 1 V R @@ -170,10 +170,10 @@ 215 JIS 1 1 V V x 219 ADDRESS 2 5 V V V V V V 220 DAYS360 2 2 V V V x -221 TODAY 0 0 V – x +221 TODAY 0 0 V - x 222 VDB 5 7 V V V V V V V V -227 MEDIAN 1 30 V R … -228 SUMPRODUCT 1 30 V A … +227 MEDIAN 1 30 V R ... +228 SUMPRODUCT 1 30 V A ... 229 SINH 1 1 V V 230 COSH 1 1 V V 231 TANH 1 1 V V @@ -188,7 +188,7 @@ 247 DB 4 5 V V V V V V 252 FREQUENCY 2 2 A R R 261 ERROR.TYPE 1 1 V V -269 AVEDEV 1 30 V R … +269 AVEDEV 1 30 V R ... 270 BETADIST 3 5 V V V V V V 271 GAMMALN 1 1 V V 272 BETAINV 3 5 V V V V V V @@ -237,12 +237,12 @@ 315 SLOPE 2 2 V A A 316 TTEST 4 4 V A A V V 317 PROB 3 4 V A A V V -318 DEVSQ 1 30 V R … -319 GEOMEAN 1 30 V R … -320 HARMEAN 1 30 V R … -321 SUMSQ 0 30 V R … -322 KURT 1 30 V R … -323 SKEW 1 30 V R … +318 DEVSQ 1 30 V R ... +319 GEOMEAN 1 30 V R ... +320 HARMEAN 1 30 V R ... +321 SUMSQ 0 30 V R ... +322 KURT 1 30 V R ... +323 SKEW 1 30 V R ... 324 ZTEST 2 3 V R V V 325 LARGE 2 2 V R V 326 SMALL 2 2 V R V @@ -274,10 +274,10 @@ 358 GETPIVOTDATA 2 30 359 HYPERLINK 1 2 V V V 360 PHONETIC 1 1 V R -361 AVERAGEA 1 30 V R … -362 MAXA 1 30 V R … -363 MINA 1 30 V R … -364 STDEVPA 1 30 V R … -365 VARPA 1 30 V R … -366 STDEVA 1 30 V R … -367 VARA 1 30 V R … +361 AVERAGEA 1 30 V R ... +362 MAXA 1 30 V R ... +363 MINA 1 30 V R ... +364 STDEVPA 1 30 V R ... +365 VARPA 1 30 V R ... +366 STDEVA 1 30 V R ... +367 VARA 1 30 V R ... diff --git a/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt b/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt index 590b455c471..6902027de97 100644 --- a/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt +++ b/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt @@ -31,7 +31,7 @@ 7 MAX 1 30 V R 8 ROW 0 1 V R 9 COLUMN 0 1 V R -10 NA 0 0 V – +10 NA 0 0 V - 11 NPV 2 30 V V R 12 STDEV 1 30 V R 13 DOLLAR 1 2 V V V @@ -40,7 +40,7 @@ 16 COS 1 1 V V 17 TAN 1 1 V V 18 ATAN 1 1 V V -19 PI 0 0 V – +19 PI 0 0 V - 20 SQRT 1 1 V V 21 EXP 1 1 V V 22 LN 1 1 V V @@ -55,8 +55,8 @@ 31 MID 3 3 V V V V 32 LEN 1 1 V V 33 VALUE 1 1 V V -34 TRUE 0 0 V – -35 FALSE 0 0 V – +34 TRUE 0 0 V - +35 FALSE 0 0 V - 36 AND 1 30 V R 37 OR 1 30 V R 38 NOT 1 1 V V @@ -82,7 +82,7 @@ 60 RATE 3 6 V V V V V V V 61 MIRR 3 3 V R V V 62 IRR 1 2 V R V -63 RAND 0 0 V – x +63 RAND 0 0 V - x 64 MATCH 2 3 V V R R 65 DATE 3 3 V V V V 66 TIME 3 3 V V V V @@ -93,7 +93,7 @@ 71 HOUR 1 1 V V 72 MINUTE 1 1 V V 73 SECOND 1 1 V V -74 NOW 0 0 V – x +74 NOW 0 0 V - x 75 AREAS 1 1 V R 76 ROWS 1 1 V R 77 COLUMNS 1 1 V R @@ -172,10 +172,10 @@ 215 JIS 1 1 V V x 219 ADDRESS 2 5 V V V V V V 220 DAYS360 2 2 V V V x -221 TODAY 0 0 V – x +221 TODAY 0 0 V - x 222 VDB 5 7 V V V V V V V V -227 MEDIAN 1 30 V R … -228 SUMPRODUCT 1 30 V A … +227 MEDIAN 1 30 V R ... +228 SUMPRODUCT 1 30 V A ... 229 SINH 1 1 V V 230 COSH 1 1 V V 231 TANH 1 1 V V @@ -192,7 +192,7 @@ 247 DB 4 5 V V V V V V 252 FREQUENCY 2 2 A R R 261 ERROR.TYPE 1 1 V V -269 AVEDEV 1 30 V R … +269 AVEDEV 1 30 V R ... 270 BETADIST 3 5 V V V V V V 271 GAMMALN 1 1 V V 272 BETAINV 3 5 V V V V V V @@ -241,12 +241,12 @@ 315 SLOPE 2 2 V A A 316 TTEST 4 4 V A A V V 317 PROB 3 4 V A A V V -318 DEVSQ 1 30 V R … -319 GEOMEAN 1 30 V R … -320 HARMEAN 1 30 V R … -321 SUMSQ 0 30 V R … -322 KURT 1 30 V R … -323 SKEW 1 30 V R … +318 DEVSQ 1 30 V R ... +319 GEOMEAN 1 30 V R ... +320 HARMEAN 1 30 V R ... +321 SUMSQ 0 30 V R ... +322 KURT 1 30 V R ... +323 SKEW 1 30 V R ... 324 ZTEST 2 3 V R V V 325 LARGE 2 2 V R V 326 SMALL 2 2 V R V @@ -278,10 +278,10 @@ 358 GETPIVOTDATA 2 30 359 HYPERLINK 1 2 V V V 360 PHONETIC 1 1 V R -361 AVERAGEA 1 30 V R … -362 MAXA 1 30 V R … -363 MINA 1 30 V R … -364 STDEVPA 1 30 V R … -365 VARPA 1 30 V R … -366 STDEVA 1 30 V R … -367 VARA 1 30 V R … +361 AVERAGEA 1 30 V R ... +362 MAXA 1 30 V R ... +363 MINA 1 30 V R ... +364 STDEVPA 1 30 V R ... +365 VARPA 1 30 V R ... +366 STDEVA 1 30 V R ... +367 VARA 1 30 V R ... diff --git a/src/scratchpad/examples/src/org/apache/poi/hslf/examples/DataExtraction.java b/src/scratchpad/examples/src/org/apache/poi/hslf/examples/DataExtraction.java index 05bf82472f8..611466c9247 100755 --- a/src/scratchpad/examples/src/org/apache/poi/hslf/examples/DataExtraction.java +++ b/src/scratchpad/examples/src/org/apache/poi/hslf/examples/DataExtraction.java @@ -69,16 +69,9 @@ public static void main(String args[]) throws Exception { String name = ole.getInstanceName(); if ("Worksheet".equals(name)) { - //save xls on disk - FileOutputStream out = new FileOutputStream(name + "-("+(j)+").xls"); - InputStream dis = data.getData(); - byte[] chunk = new byte[2048]; - int count; - while ((count = dis.read(chunk)) >= 0) { - out.write(chunk,0,count); - } - is.close(); - out.close(); + //read xls + HSSFWorkbook wb = new HSSFWorkbook(data.getData()); + } else if ("Document".equals(name)) { HWPFDocument doc = new HWPFDocument(data.getData()); //read the word document @@ -93,7 +86,15 @@ public static void main(String args[]) throws Exception { doc.write(out); out.close(); } else { - System.err.println("Processing " + name); + FileOutputStream out = new FileOutputStream(ole.getProgID() + "-"+(j+1)+".dat"); + InputStream dis = data.getData(); + byte[] chunk = new byte[2048]; + int count; + while ((count = dis.read(chunk)) >= 0) { + out.write(chunk,0,count); + } + is.close(); + out.close(); } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java index 4abc8c1c004..4bef9033dbe 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java @@ -76,6 +76,7 @@ public static Shape createSimpeShape(EscherContainerRecord spContainer, Shape pa case ShapeTypes.TextBox: shape = new TextBox(spContainer, parent); break; + case ShapeTypes.HostControl: case ShapeTypes.PictureFrame: { EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID); EscherProperty prop = Shape.getEscherProperty(opt, EscherProperties.BLIP__PICTUREID); diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java b/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java index 5dac650258b..4030ddc0c28 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java @@ -45,7 +45,6 @@ public class TextRun protected TextBytesAtom _byteAtom; protected TextCharsAtom _charAtom; protected StyleTextPropAtom _styleAtom; - protected TextSpecInfoAtom _specAtom; protected boolean _isUnicode; protected RichTextRun[] _rtRuns; private SlideShow slideShow; @@ -319,9 +318,9 @@ public RichTextRun appendText(String s) { * touch the stylings. */ private void storeText(String s) { - // Remove a single trailing \n, as there is an implicit one at the + // Remove a single trailing \r, as there is an implicit one at the // end of every record - if(s.endsWith("\n")) { + if(s.endsWith("\r")) { s = s.substring(0, s.length()-1); } @@ -361,6 +360,18 @@ private void storeText(String s) { _isUnicode = true; } } + /** + * If TextSpecInfoAtom is present, we must update the text size in it, + * otherwise the ppt will be corrupted + */ + if(_records != null) for (int i = 0; i < _records.length; i++) { + if(_records[i] instanceof TextSpecInfoAtom){ + TextSpecInfoAtom specAtom = (TextSpecInfoAtom)_records[i]; + if((s.length() + 1) != specAtom.getCharactersCovered()){ + specAtom.reset(s.length() + 1); + } + } + } } /** @@ -446,7 +457,7 @@ public synchronized void changeTextInRichTextRun(RichTextRun run, String s) { * as the the first character has. * If you care about styling, do setText on a RichTextRun instead */ - public synchronized void setText(String s) { + public synchronized void setRawText(String s) { // Save the new text to the atoms storeText(s); RichTextRun fst = _rtRuns[0]; @@ -474,20 +485,18 @@ public synchronized void setText(String s) { _rtRuns[0] = new RichTextRun(this,0,s.length()); } - /** - * If TextSpecInfoAtom is present, we must update the text size, - * otherwise the ppt will be corrupted - */ - if(_records != null) for (int i = 0; i < _records.length; i++) { - if(_records[i] instanceof TextSpecInfoAtom){ - TextSpecInfoAtom specAtom = (TextSpecInfoAtom)_records[i]; - specAtom.setTextSize(s.length()); - } - - } } - /** + /** + * Changes the text. + * Converts '\r' into '\n' + */ + public synchronized void setText(String s) { + String text = normalize(s); + setRawText(text); + } + + /** * Ensure a StyleTextPropAtom is present for this run, * by adding if required. Normally for internal TextRun use. */ @@ -666,4 +675,12 @@ public TextRulerAtom getTextRuler(){ return null; } + + /** + * Returns a new string with line breaks converted into internal ppt representation + */ + public String normalize(String s){ + String ns = s.replaceAll("\\r?\\n", "\r"); + return ns; + } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/ExControl.java b/src/scratchpad/src/org/apache/poi/hslf/record/ExControl.java new file mode 100755 index 00000000000..e6e7da893c7 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/ExControl.java @@ -0,0 +1,95 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hslf.record; + +import java.io.OutputStream; +import java.io.IOException; + +import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.POILogger; + +/** + * Container for OLE Control object. It contains: + *

+ * 1. ExControlAtom (4091) + * 2. ExOleObjAtom (4035) + * 3. CString (4026), Instance MenuName (1) used for menus and the Links dialog box. + * 4. CString (4026), Instance ProgID (2) that stores the OLE Programmatic Identifier. + * A ProgID is a string that uniquely identifies a given object. + * 5. CString (4026), Instance ClipboardName (3) that appears in the paste special dialog. + * 6. MetaFile( 4033), optional + *

+ * + * + * @author Yegor kozlov + */ +public class ExControl extends ExEmbed { + + // Links to our more interesting children + private ExControlAtom ctrlAtom; + + /** + * Set things up, and find our more interesting children + * + * @param source the source data as a byte array. + * @param start the start offset into the byte array. + * @param len the length of the slice in the byte array. + */ + protected ExControl(byte[] source, int start, int len) { + super(source, start, len); + } + + /** + * Create a new ExEmbed, with blank fields + */ + public ExControl() { + super(); + + _children[0] = ctrlAtom = new ExControlAtom(); + } + + /** + * Gets the {@link ExControlAtom}. + * + * @return the {@link ExControlAtom}. + */ + public ExControlAtom getExControlAtom() + { + return ctrlAtom; + } + + /** + * Returns the type (held as a little endian in bytes 3 and 4) + * that this class handles. + * + * @return the record type. + */ + public long getRecordType() { + return RecordTypes.ExControl.typeID; + } + + protected RecordAtom getEmbedAtom(Record[] children){ + RecordAtom atom = null; + if(_children[0] instanceof ExControlAtom) { + atom = (ExControlAtom)_children[0]; + } else { + logger.log(POILogger.ERROR, "First child record wasn't a ExControlAtom, was of type " + _children[0].getRecordType()); + } + return atom; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/ExControlAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/ExControlAtom.java new file mode 100755 index 00000000000..ae99d0a235e --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/ExControlAtom.java @@ -0,0 +1,96 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hslf.record; + +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.poi.util.LittleEndian; + +/** + * Contains a long integer, slideID, which stores the unique slide identifier of the slide + * where this control resides. + * + * @author Yegor Kozlov + */ +public class ExControlAtom extends RecordAtom { + + + /** + * Record header. + */ + private byte[] _header; + + /** + * slideId. + */ + private int _id; + + /** + * Constructs a brand new embedded object atom record. + */ + protected ExControlAtom() { + _header = new byte[8]; + + LittleEndian.putShort(_header, 2, (short) getRecordType()); + LittleEndian.putInt(_header, 4, 4); + + } + + /** + * Constructs the ExControlAtom record from its source data. + * + * @param source the source data as a byte array. + * @param start the start offset into the byte array. + * @param len the length of the slice in the byte array. + */ + protected ExControlAtom(byte[] source, int start, int len) { + // Get the header. + _header = new byte[8]; + System.arraycopy(source, start, _header, 0, 8); + + _id = LittleEndian.getInt(source, start + 8); + } + + public int getSlideId() { + return _id; + } + + /** + * Gets the record type. + * @return the record type. + */ + public long getRecordType() { + return RecordTypes.ExControlAtom.typeID; + } + + /** + * Write the contents of the record back, so it can be written + * to disk + * + * @param out the output stream to write to. + * @throws java.io.IOException if an error occurs. + */ + public void writeOut(OutputStream out) throws IOException { + out.write(_header); + byte[] data = new byte[4]; + LittleEndian.putInt(data, _id); + out.write(data); + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbed.java b/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbed.java index 9e58e8ae187..501712e9d5f 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbed.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbed.java @@ -36,7 +36,7 @@ public class ExEmbed extends RecordContainer { private byte[] _header; // Links to our more interesting children - private ExEmbedAtom embedAtom; + private RecordAtom embedAtom; private ExOleObjAtom oleObjAtom; private CString menuName; private CString progId; @@ -91,11 +91,7 @@ public ExEmbed() { private void findInterestingChildren() { // First child should be the ExHyperlinkAtom - if(_children[0] instanceof ExEmbedAtom) { - embedAtom = (ExEmbedAtom)_children[0]; - } else { - logger.log(POILogger.ERROR, "First child record wasn't a ExEmbedAtom, was of type " + _children[0].getRecordType()); - } + embedAtom = getEmbedAtom(_children); // Second child should be the ExOleObjAtom if (_children[1] instanceof ExOleObjAtom) { @@ -115,6 +111,16 @@ private void findInterestingChildren() { } } + protected RecordAtom getEmbedAtom(Record[] children){ + RecordAtom atom = null; + if(_children[0] instanceof ExEmbedAtom) { + atom = (ExEmbedAtom)_children[0]; + } else { + logger.log(POILogger.ERROR, "First child record wasn't a ExEmbedAtom, was of type " + _children[0].getRecordType()); + } + return atom; + } + /** * Gets the {@link ExEmbedAtom}. * @@ -122,7 +128,7 @@ private void findInterestingChildren() { */ public ExEmbedAtom getExEmbedAtom() { - return embedAtom; + return (ExEmbedAtom)embedAtom; } /** diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java b/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java index 197497fd027..c7408b0fe4e 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java @@ -17,11 +17,9 @@ Licensed to the Apache Software Foundation (ASF) under one or more package org.apache.poi.hslf.record; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.util.zip.InflaterInputStream; +import java.util.zip.DeflaterOutputStream; import org.apache.poi.util.LittleEndian; @@ -92,6 +90,25 @@ public InputStream getData() { return new InflaterInputStream(compressedStream); } + /** + * Sets the embedded data. + * + * @param data the embedded data. + */ + public void setData(byte[] data) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + //first four bytes is the length of the raw data + byte[] b = new byte[4]; + LittleEndian.putInt(b, data.length); + out.write(b); + + DeflaterOutputStream def = new DeflaterOutputStream(out); + def.write(data, 0, data.length); + def.finish(); + _data = out.toByteArray(); + LittleEndian.putInt(_header, 4, _data.length); + } + /** * Gets the record type. * diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java b/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java index cedc99ce0a7..a6f00da124d 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java @@ -119,7 +119,7 @@ public class RecordTypes { public static final Type RecolorInfoAtom = new Type(4071,null); public static final Type ExQuickTimeMovie = new Type(4074,null); public static final Type ExQuickTimeMovieData = new Type(4075,null); - public static final Type ExControl = new Type(4078,null); + public static final Type ExControl = new Type(4078,ExControl.class); public static final Type SlideListWithText = new Type(4080,SlideListWithText.class); public static final Type InteractiveInfo = new Type(4082,InteractiveInfo.class); public static final Type InteractiveInfoAtom = new Type(4083,InteractiveInfoAtom.class); diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/TextSpecInfoAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/TextSpecInfoAtom.java index a8915f0498e..85cdd1e156a 100755 --- a/src/scratchpad/src/org/apache/poi/hslf/record/TextSpecInfoAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/TextSpecInfoAtom.java @@ -20,6 +20,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more import java.io.OutputStream; import java.io.IOException; +import java.util.ArrayList; /** * The special info runs contained in this text. @@ -82,4 +83,118 @@ public void writeOut(OutputStream out) throws IOException { public void setTextSize(int size){ LittleEndian.putInt(_data, 0, size); } + + /** + * Reset the content to one info run with the default values + * @param size the site of parent text + */ + public void reset(int size){ + _data = new byte[10]; + // 01 00 00 00 + LittleEndian.putInt(_data, 0, size); + // 01 00 00 00 + LittleEndian.putInt(_data, 4, 1); //mask + // 00 00 + LittleEndian.putShort(_data, 8, (short)0); //langId + + // Update the size (header bytes 5-8) + LittleEndian.putInt(_header, 4, _data.length); + } + + /** + * Get the number of characters covered by this records + * + * @return the number of characters covered by this records + */ + public int getCharactersCovered(){ + int covered = 0; + TextSpecInfoRun[] runs = getTextSpecInfoRuns(); + for (int i = 0; i < runs.length; i++) covered += runs[i].len; + return covered; + } + + public TextSpecInfoRun[] getTextSpecInfoRuns(){ + ArrayList lst = new ArrayList(); + int pos = 0; + int[] bits = {1, 0, 2}; + while(pos < _data.length) { + TextSpecInfoRun run = new TextSpecInfoRun(); + run.len = LittleEndian.getInt(_data, pos); pos += 4; + run.mask = LittleEndian.getInt(_data, pos); pos += 4; + for (int i = 0; i < bits.length; i++) { + if((run.mask & 1 << bits[i]) != 0){ + switch (bits[i]){ + case 0: + run.spellInfo = LittleEndian.getShort(_data, pos); pos += 2; + break; + case 1: + run.langId = LittleEndian.getShort(_data, pos); pos += 2; + break; + case 2: + run.altLangId = LittleEndian.getShort(_data, pos); pos += 2; + break; + } + } + } + lst.add(run); + } + return (TextSpecInfoRun[])lst.toArray(new TextSpecInfoRun[lst.size()]); + + } + + public static class TextSpecInfoRun { + //Length of special info run. + protected int len; + + //Special info mask of this run; + protected int mask; + + // info fields as indicated by the mask. + // -1 means the bit is not set + protected short spellInfo = -1; + protected short langId = -1; + protected short altLangId = -1; + + /** + * Spelling status of this text. See Spell Info table below. + * + *

Spell Info Types:

+ *
  • 0 Unchecked + *
  • 1 Previously incorrect, needs rechecking + *
  • 2 Correct + *
  • 3 Incorrect + * + * @return Spelling status of this text + */ + public short getSpellInfo(){ + return spellInfo; + } + + /** + * Windows LANGID for this text. + * + * @return Windows LANGID for this text. + */ + public short getLangId(){ + return spellInfo; + } + + /** + * Alternate Windows LANGID of this text; + * must be a valid non-East Asian LANGID if the text has an East Asian language, + * otherwise may be an East Asian LANGID or language neutral (zero). + * + * @return Alternate Windows LANGID of this text + */ + public short getAltLangId(){ + return altLangId; + } + + /** + * @return Length of special info run. + */ + public int length(){ + return len; + } + } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/ObjectData.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/ObjectData.java index 957e78868ed..bbef87a96cf 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/ObjectData.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/ObjectData.java @@ -17,6 +17,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more package org.apache.poi.hslf.usermodel; import java.io.InputStream; +import java.io.IOException; import org.apache.poi.hslf.record.ExOleObjStg; @@ -49,6 +50,15 @@ public InputStream getData() { return storage.getData(); } + /** + * Sets the embedded data. + * + * @param data the embedded data. + */ + public void setData(byte[] data) throws IOException { + storage.setData(data); + } + /** * Return the record that contains the object data. * diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java index 7458df7e637..6bc203b658f 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java @@ -162,10 +162,18 @@ public String getRawText() { * Change the text */ public void setText(String text) { - length = text.length(); - parentRun.changeTextInRichTextRun(this,text); + String s = parentRun.normalize(text); + setRawText(s); } + /** + * Change the text + */ + public void setRawText(String text) { + length = text.length(); + parentRun.changeTextInRichTextRun(this,text); + } + /** * Tells the RichTextRun its new position in the parent TextRun * @param startAt diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/ListLevel.java b/src/scratchpad/src/org/apache/poi/hwpf/model/ListLevel.java index 0adfe617f16..f6b4d8594fe 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/ListLevel.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/ListLevel.java @@ -1,4 +1,3 @@ - /* ==================================================================== Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -16,22 +15,20 @@ Licensed to the Apache Software Foundation (ASF) under one or more limitations under the License. ==================================================================== */ - package org.apache.poi.hwpf.model; +import java.util.Arrays; + import org.apache.poi.util.BitField; import org.apache.poi.util.LittleEndian; -import org.apache.poi.hwpf.usermodel.CharacterProperties; -import org.apache.poi.hwpf.usermodel.ParagraphProperties; - -import org.apache.poi.hwpf.sprm.ParagraphSprmCompressor; -import org.apache.poi.hwpf.sprm.CharacterSprmCompressor; - -import java.util.Arrays; - -public class ListLevel +/** + * + */ +public final class ListLevel { + private static final int RGBXCH_NUMS_SIZE = 9; + private int _iStartAt; private byte _nfc; private byte _info; @@ -70,7 +67,7 @@ public ListLevel(int level, boolean numbered) _grpprlPapx = new byte[0]; _grpprlChpx = new byte[0]; _numberText = new char[0]; - _rgbxchNums = new byte[9]; + _rgbxchNums = new byte[RGBXCH_NUMS_SIZE]; if (numbered) { @@ -90,12 +87,11 @@ public ListLevel(byte[] buf, int offset) _nfc = buf[offset++]; _info = buf[offset++]; - _rgbxchNums = new byte[9]; - for (int x = 0; x < 9; x++) - { - _rgbxchNums[x] = buf[offset++]; - } - _ixchFollow = buf[offset++]; + _rgbxchNums = new byte[RGBXCH_NUMS_SIZE]; + System.arraycopy(buf, offset, _rgbxchNums, 0, RGBXCH_NUMS_SIZE); + offset += RGBXCH_NUMS_SIZE; + + _ixchFollow = buf[offset++]; _dxaSpace = LittleEndian.getInt(buf, offset); offset += LittleEndian.INT_SIZE; _dxaIndent = LittleEndian.getInt(buf, offset); @@ -207,8 +203,8 @@ public byte[] toByteArray() offset += LittleEndian.INT_SIZE; buf[offset++] = _nfc; buf[offset++] = _info; - System.arraycopy(_rgbxchNums, 0, buf, offset, _rgbxchNums.length); - offset += _rgbxchNums.length; + System.arraycopy(_rgbxchNums, 0, buf, offset, RGBXCH_NUMS_SIZE); + offset += RGBXCH_NUMS_SIZE; buf[offset++] = _ixchFollow; LittleEndian.putInt(buf, offset, _dxaSpace); offset += LittleEndian.INT_SIZE; @@ -225,23 +221,33 @@ public byte[] toByteArray() System.arraycopy(_grpprlPapx, 0, buf, offset, _cbGrpprlPapx); offset += _cbGrpprlPapx; - LittleEndian.putShort(buf, offset, (short)_numberText.length); - offset += LittleEndian.SHORT_SIZE; - for (int x = 0; x < _numberText.length; x++) - { - LittleEndian.putShort(buf, offset, (short)_numberText[x]); + if (_numberText == null) { + // TODO - write junit to test this flow + LittleEndian.putUShort(buf, offset, 0); + } else { + LittleEndian.putUShort(buf, offset, _numberText.length); offset += LittleEndian.SHORT_SIZE; + for (int x = 0; x < _numberText.length; x++) + { + LittleEndian.putUShort(buf, offset, _numberText[x]); + offset += LittleEndian.SHORT_SIZE; + } } return buf; } public int getSizeInBytes() { - if (_numberText!=null) - { - return 28 + _cbGrpprlChpx + _cbGrpprlPapx + (_numberText.length * LittleEndian.SHORT_SIZE) + 2; - } else { - return 28 + _cbGrpprlChpx + _cbGrpprlPapx + 2; - } + int result = + 6 // int byte byte + + RGBXCH_NUMS_SIZE + + 13 // byte int int byte byte short + + _cbGrpprlChpx + + _cbGrpprlPapx + + 2; // numberText length + if (_numberText != null) { + result += _numberText.length * LittleEndian.SHORT_SIZE; + } + return result; } } diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextSpecInfoAtom.java b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextSpecInfoAtom.java new file mode 100755 index 00000000000..5079628aec6 --- /dev/null +++ b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextSpecInfoAtom.java @@ -0,0 +1,95 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + + +package org.apache.poi.hslf.record; + +import org.apache.poi.hslf.HSLFSlideShow; +import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp; +import org.apache.poi.hslf.model.textproperties.TextProp; +import org.apache.poi.hslf.model.textproperties.TextPropCollection; +import org.apache.poi.hslf.record.StyleTextPropAtom.*; +import org.apache.poi.hslf.usermodel.SlideShow; +import org.apache.poi.util.HexDump; + +import junit.framework.TestCase; +import java.io.ByteArrayOutputStream; +import java.util.LinkedList; +import java.util.Arrays; + +/** + * Tests TextSpecInfoAtom + * + * @author Yegor Kozlov + */ +public class TestTextSpecInfoAtom extends TestCase { + + //from a real file + private byte[] data_1 = new byte[] { + 0x00, 0x00, (byte)0xAA, 0x0F, 0x2C, 0x00, 0x00, 0x00, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + + public void testRead() throws Exception { + TextSpecInfoAtom spec = new TextSpecInfoAtom(data_1, 0, data_1.length); + TextSpecInfoAtom.TextSpecInfoRun[] run = spec.getTextSpecInfoRuns(); + assertEquals(5, run.length); + + assertEquals(10, run[0].length()); + assertEquals(1, run[1].length()); + assertEquals(70, run[2].length()); + assertEquals(9, run[3].length()); + assertEquals(32, run[4].length()); + + } + + public void testWrite() throws Exception { + TextSpecInfoAtom spec = new TextSpecInfoAtom(data_1, 0, data_1.length); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + spec.writeOut(out); + + byte[] result = out.toByteArray(); + assertTrue(Arrays.equals(result, data_1)); + } + + public void testReset() throws Exception { + TextSpecInfoAtom spec = new TextSpecInfoAtom(data_1, 0, data_1.length); + spec.reset(32); //length of the parent text + + TextSpecInfoAtom.TextSpecInfoRun[] run = spec.getTextSpecInfoRuns(); + assertEquals(1, run.length); + + assertEquals(32, run[0].length()); + + //serialize and read again + ByteArrayOutputStream out = new ByteArrayOutputStream(); + spec.writeOut(out); + + byte[] result = out.toByteArray(); + TextSpecInfoAtom spec2 = new TextSpecInfoAtom(result, 0, result.length); + TextSpecInfoAtom.TextSpecInfoRun[] run2 = spec2.getTextSpecInfoRuns(); + assertEquals(1, run2.length); + + assertEquals(32, run2[0].length()); + } +} diff --git a/src/testcases/org/apache/poi/hssf/HSSFTests.java b/src/testcases/org/apache/poi/hssf/HSSFTests.java index 5b597a67c87..0a4fa66af7d 100644 --- a/src/testcases/org/apache/poi/hssf/HSSFTests.java +++ b/src/testcases/org/apache/poi/hssf/HSSFTests.java @@ -22,9 +22,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more import org.apache.poi.hssf.eventmodel.TestEventRecordFactory; import org.apache.poi.hssf.eventmodel.TestModelFactory; -import org.apache.poi.hssf.model.TestDrawingManager; -import org.apache.poi.hssf.model.TestFormulaParser; -import org.apache.poi.hssf.model.TestSheet; +import org.apache.poi.hssf.model.AllModelTests; import org.apache.poi.hssf.record.AllRecordTests; import org.apache.poi.hssf.usermodel.AllUserModelTests; import org.apache.poi.hssf.util.TestAreaReference; @@ -50,10 +48,10 @@ public static Test suite() { TestSuite suite = new TestSuite("Tests for org.apache.poi.hssf"); // $JUnit-BEGIN$ + suite.addTest(AllModelTests.suite()); suite.addTest(AllUserModelTests.suite()); suite.addTest(AllRecordTests.suite()); - suite.addTest(new TestSuite(TestFormulaParser.class)); suite.addTest(new TestSuite(TestAreaReference.class)); suite.addTest(new TestSuite(TestCellReference.class)); suite.addTest(new TestSuite(TestRangeAddress.class)); @@ -61,8 +59,6 @@ public static Test suite() { suite.addTest(new TestSuite(TestSheetReferences.class)); suite.addTest(new TestSuite(TestEventRecordFactory.class)); suite.addTest(new TestSuite(TestModelFactory.class)); - suite.addTest(new TestSuite(TestDrawingManager.class)); - suite.addTest(new TestSuite(TestSheet.class)); // $JUnit-END$ return suite; } diff --git a/src/testcases/org/apache/poi/hssf/data/24207.xls b/src/testcases/org/apache/poi/hssf/data/24207.xls new file mode 100755 index 0000000000000000000000000000000000000000..eca56425efdc749421a5d25214eaba23d68ce9c5 GIT binary patch literal 13824 zcmeHOU2IfE6#nk^Zo9Pwwk_pPsMjrq?Y1_h7-_7~)dlGnQ#vw zP#@xhtPSGV*2{I@O)^;nTt@((+f(GgPoxA6qY>DX-j~Tb&u88o%e?L^ba+~ANLgaT zBnRFms}>ezHJBh@%yB3=&B|Mpf2L)>R=$ZjM|eHdzjJLL%Yk)w2jW`pedQ75i^(l~ zsdcWYWIa~l63Z9fJ|V*$I2p8_LKX**!Wb4Vx6NLSAeIA>wUPF&_V%7+M}H#f-6T5N z?1woQSC{3#JeVGNrMyrCby!m>)ZJ6w4)3L@bqFCcx73{0ibXdfhF%~kro69*Dy!;J&1o#v$Ng8q(b#2^j>u&osQgba>-KUPne&yeB$rm_D}O)BEjZG> zV({?nbaA*bSKd)U-c>;!t01rcm;6+~MmS$nkhm#dt8sJQ*0?2Kr!n%-cxgUZc$I5~ zg=1WSW`bg6Eq3frr*rE?!ns$H^opb|I5QamoBu@sk7L!*VV8UJa!(|J9Lx4X9 zzHpAe{)=>pY$PAS5=}Re17Rwd{p9y6+lICeBvl?$d8hJsRg(9a^augwvWj<@GiA$U z6La3v(npn_mNkhb1R{%2mBRFZo0j+`mSvv;gu5(k4m9Hn-L1rZ@-?)%#>Loe7Whr~ zG#go{S{N?yq1-hXya7UctA;@Vh%0xQ!r&&o_U;^pZwdQdgTdFC1%$z;#Uu>^1_6VB zLBJqzA0u#+Cpba%f6F^5+l1+3AN?`&;{NcbCqw95cmBs7%Fd8vk1F|bl5EqSCCN5( zC#jh{>(~kjHRvwNz2C5f570EZ#yuY&5URE=A11@hSOuJ z7a!bM8U5;_6_DNdLcU=B)Vtv!r^G`2X8UOGvv(^7d+k)IbvdU;OzTN&Nn|NXtmx zdBAa|<$T~GX}ofI+|@U=T0}7z7Lg1_6VBLBJqj z5HJYbdkBbQD?Ye*z~W2GN3HS|rTEnHzYg*BFgM%$N#5jvL_~fb&%lP$(*E1PMPDnT~sT^C~$mJhj zdn_m4X~=l+X`okxusw1sJfyYP%#9t1FzvAuax%vIij#vZ4yb2 v|NF>LQaMDaU*?d^pKA5Xw=#M_#wdtqs9{)bNb3{0Gkf~}L;tnw#s2>T8j~~f literal 0 HcmV?d00001 diff --git a/src/testcases/org/apache/poi/hssf/data/36947.xls b/src/testcases/org/apache/poi/hssf/data/36947.xls new file mode 100755 index 0000000000000000000000000000000000000000..4c7bde6c2a0863465d009cf12c1b676156581ed0 GIT binary patch literal 142336 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

    !Md|h^W4VC}D*`8(4pYF%@X9L8s^uyny6OsLqO? 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�zMI2=K8${eRmIoT3B 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

    |^IH0Rw%cF!0^I)? k*FFBD#9!~(K0~Pa&-Xg>Z1wrqjnA`{`@c2sfAjkP56;(8^#A|> literal 0 HcmV?d00001 diff --git a/src/testcases/org/apache/poi/hssf/model/AllModelTests.java b/src/testcases/org/apache/poi/hssf/model/AllModelTests.java new file mode 100755 index 00000000000..19ef437063b --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/model/AllModelTests.java @@ -0,0 +1,40 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.model; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Collects all tests for org.apache.poi.hssf.model. + * + * @author Josh Micich + */ +public final class AllModelTests { + + public static Test suite() { + TestSuite result = new TestSuite(AllModelTests.class.getName()); + result.addTestSuite(TestDrawingManager.class); + result.addTestSuite(TestDrawingManager2.class); + result.addTestSuite(TestFormulaParser.class); + result.addTestSuite(TestFormulaParserEval.class); + result.addTestSuite(TestSheet.class); + result.addTestSuite(TestSheetAdditional.class); + return result; + } +} diff --git a/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java b/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java index 9ce862b9b69..1895705a564 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java +++ b/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java @@ -65,6 +65,7 @@ public final class TestFormulaParser extends TestCase { * @return parsed token array already confirmed not null */ private static Ptg[] parseFormula(String s) { + // TODO - replace multiple copies of this code with calls to this method FormulaParser fp = new FormulaParser(s, null); fp.parse(); Ptg[] result = fp.getRPNPtg(); @@ -86,7 +87,6 @@ public void testFormulaWithSpace1() { assertTrue("",(ptgs[0] instanceof IntPtg)); assertTrue("",(ptgs[1] instanceof IntPtg)); assertTrue("",(ptgs[2] instanceof AddPtg)); - } public void testFormulaWithSpace2() { @@ -169,8 +169,6 @@ public void testSimpleIf() throws Exception { assertEquals("If FALSE offset", (short)7, ifPtg.getData()); FuncVarPtg funcPtg = (FuncVarPtg)asts[8]; - - } /** @@ -190,8 +188,6 @@ public void testNestedFunctionIf() { assertTrue("It is not an if", ifFunc.isOptimizedIf()); assertTrue("Average Function set correctly", (asts[5] instanceof FuncVarPtg)); - - } public void testIfSingleCondition(){ @@ -213,8 +209,6 @@ public void testIfSingleCondition(){ assertTrue("Ptg is not a Variable Function", (asts[6] instanceof FuncVarPtg)); FuncVarPtg funcPtg = (FuncVarPtg)asts[6]; assertEquals("Arguments", 2, funcPtg.getNumberOfOperands()); - - } public void testSumIf() { @@ -223,7 +217,6 @@ public void testSumIf() { fp.parse(); Ptg[] asts = fp.getRPNPtg(); assertEquals("4 Ptgs expected", 4, asts.length); - } /** @@ -235,51 +228,35 @@ public void testNonAlphaFormula(){ String currencyCell = "F3"; String function="\"TOTAL[\"&"+currencyCell+"&\"]\""; - FormulaParser fp = new FormulaParser(function, null); - fp.parse(); - Ptg[] asts = fp.getRPNPtg(); + Ptg[] asts = parseFormula(function); assertEquals("5 ptgs expected", 5, asts.length); assertTrue ("Ptg[0] is a string", (asts[0] instanceof StringPtg)); StringPtg firstString = (StringPtg)asts[0]; assertEquals("TOTAL[", firstString.getValue()); //the PTG order isn't 100% correct but it still works - dmui - - } public void testSimpleLogical() { - FormulaParser fp=new FormulaParser("IF(A1=1,\"*\",IF(4<>1,\"first\",\"second\"))",null); - fp.parse(); - Ptg[] ptgs = fp.getRPNPtg(); - assertTrue("Ptg array should not be null", ptgs !=null); + Ptg[] ptgs = parseFormula("IF(3>=1,\"*\",IF(4<>1,\"first\",\"second\"))"); assertEquals("Ptg array length", 17, ptgs.length); assertEquals("6th Ptg is not a goto (Attr) ptg",AttrPtg.class,ptgs[5].getClass()); assertEquals("9th Ptg is not a not equal ptg",NotEqualPtg.class,ptgs[8].getClass()); assertEquals("15th Ptg is not the inner IF variable function ptg",FuncVarPtg.class,ptgs[14].getClass()); - } public void testMacroFunction() { @@ -302,16 +279,15 @@ public void testEmbeddedSlash() { Ptg[] ptg = fp.getRPNPtg(); assertTrue("first ptg is string",ptg[0] instanceof StringPtg); assertTrue("second ptg is string",ptg[1] instanceof StringPtg); - } - public void testConcatenate(){ - FormulaParser fp = new FormulaParser("CONCATENATE(\"first\",\"second\")",null); - fp.parse(); - Ptg[] ptg = fp.getRPNPtg(); - assertTrue("first ptg is string",ptg[0] instanceof StringPtg); - assertTrue("second ptg is string",ptg[1] instanceof StringPtg); - } + public void testConcatenate() { + FormulaParser fp = new FormulaParser("CONCATENATE(\"first\",\"second\")", null); + fp.parse(); + Ptg[] ptg = fp.getRPNPtg(); + assertTrue("first ptg is string", ptg[0] instanceof StringPtg); + assertTrue("second ptg is string", ptg[1] instanceof StringPtg); + } public void testWorksheetReferences() { @@ -395,16 +371,16 @@ public void testLargeInt() { /** bug 33160, testcase by Amol Deshmukh*/ public void testSimpleLongFormula() { - FormulaParser fp = new FormulaParser("40000/2", null); - fp.parse(); - Ptg[] ptgs = fp.getRPNPtg(); - assertTrue("three tokens expected, got "+ptgs.length,ptgs.length == 3); - assertTrue("IntPtg",(ptgs[0] instanceof IntPtg)); - assertTrue("IntPtg",(ptgs[1] instanceof IntPtg)); - assertTrue("DividePtg",(ptgs[2] instanceof DividePtg)); + FormulaParser fp = new FormulaParser("40000/2", null); + fp.parse(); + Ptg[] ptgs = fp.getRPNPtg(); + assertTrue("three tokens expected, got " + ptgs.length, ptgs.length == 3); + assertTrue("IntPtg", (ptgs[0] instanceof IntPtg)); + assertTrue("IntPtg", (ptgs[1] instanceof IntPtg)); + assertTrue("DividePtg", (ptgs[2] instanceof DividePtg)); } - /** bug 35027, underscore in sheet name*/ + /** bug 35027, underscore in sheet name */ public void testUnderscore() { HSSFWorkbook wb = new HSSFWorkbook(); @@ -775,8 +751,34 @@ private static void confirmStringParse(String singleQuotedValue) { StringPtg sp = (StringPtg) parseSingleToken(formula, StringPtg.class); assertEquals(expectedValue, sp.getValue()); } + public void testParseStringLiterals_bug28754() { + + StringPtg sp; + try { + sp = (StringPtg) parseSingleToken("\"test\"\"ing\"", StringPtg.class); + } catch (RuntimeException e) { + if(e.getMessage().startsWith("Cannot Parse")) { + throw new AssertionFailedError("Identified bug 28754a"); + } + throw e; + } + assertEquals("test\"ing", sp.getValue()); + + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sheet = wb.createSheet(); + wb.setSheetName(0, "Sheet1"); + + HSSFRow row = sheet.createRow(0); + HSSFCell cell = row.createCell((short)0); + cell.setCellFormula("right(\"test\"\"ing\", 3)"); + String actualCellFormula = cell.getCellFormula(); + if("RIGHT(\"test\"ing\",3)".equals(actualCellFormula)) { + throw new AssertionFailedError("Identified bug 28754b"); + } + assertEquals("RIGHT(\"test\"\"ing\",3)", actualCellFormula); + } - public void testPaseStringLiterals() { + public void testParseStringLiterals() { confirmStringParse("goto considered harmful"); confirmStringParse("goto 'considered' harmful"); @@ -810,10 +812,8 @@ public void testParserErrors() { parseExpectedException("#DIV/ 0+2"); - if (false) { // TODO - add functionality to detect func arg count mismatch - parseExpectedException("IF(TRUE)"); - parseExpectedException("countif(A1:B5, C1, D1)"); - } + parseExpectedException("IF(TRUE)"); + parseExpectedException("countif(A1:B5, C1, D1)"); } private static void parseExpectedException(String formula) { @@ -887,8 +887,16 @@ public void testTooFewOperandArgs() { assertTrue(e.getMessage().startsWith("Too few arguments suppled to operation token")); } } + /** + * Make sure that POI uses the right Func Ptg when encoding formulas. Functions with variable + * number of args should get FuncVarPtg, functions with fixed args should get FuncPtg.

    + * + * Prior to the fix for bug 44675 POI would encode FuncVarPtg for all functions. In many cases + * Excel tolerates the wrong Ptg and evaluates the formula OK (e.g. SIN), but in some cases + * (e.g. COUNTIF) Excel fails to evaluate the formula, giving '#VALUE!' instead. + */ public void testFuncPtgSelection() { - HSSFWorkbook book = new HSSFWorkbook(); + HSSFWorkbook book = new HSSFWorkbook(); Ptg[] ptgs; ptgs = FormulaParser.parse("countif(A1:A2, 1)", book); assertEquals(3, ptgs.length); diff --git a/src/testcases/org/apache/poi/hssf/model/TestSheet.java b/src/testcases/org/apache/poi/hssf/model/TestSheet.java index 964caedc2f0..9281eb80d7c 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestSheet.java +++ b/src/testcases/org/apache/poi/hssf/model/TestSheet.java @@ -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,7 +14,6 @@ Licensed to the Apache Software Foundation (ASF) under one or more See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ - package org.apache.poi.hssf.model; @@ -34,8 +32,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more * * @author Glen Stampoultzis (glens at apache.org) */ -public class TestSheet extends TestCase -{ +public final class TestSheet extends TestCase { public void testCreateSheet() throws Exception { // Check we're adding row and cell aggregates @@ -76,6 +73,21 @@ public void testAddMergedRegion() if ((regionsToAdd % 1027) != 0) recordsExpected++; assertTrue("The " + regionsToAdd + " merged regions should have been spread out over " + recordsExpected + " records, not " + recordsAdded, recordsAdded == recordsExpected); + // Check we can't add one with invalid date + try { + sheet.addMergedRegion(10, (short)10, 9, (short)12); + fail("Expected an exception to occur"); + } catch(IllegalArgumentException e) { + // occurs during successful test + assertEquals("The 'to' row (9) must not be less than the 'from' row (10)", e.getMessage()); + } + try { + sheet.addMergedRegion(10, (short)10, 12, (short)9); + fail("Expected an exception to occur"); + } catch(IllegalArgumentException e) { + // occurs during successful test + assertEquals("The 'to' col (9) must not be less than the 'from' col (10)", e.getMessage()); + } } public void testRemoveMergedRegion() @@ -113,9 +125,9 @@ public void testMovingMergedRegion() { MergeCellsRecord merged = new MergeCellsRecord(); merged.addArea(0, (short)0, 1, (short)2); - records.add(new RowRecord()); - records.add(new RowRecord()); - records.add(new RowRecord()); + records.add(new RowRecord(0)); + records.add(new RowRecord(1)); + records.add(new RowRecord(2)); records.add(merged); Sheet sheet = Sheet.createSheet(records, 0); @@ -142,20 +154,11 @@ public void testGetNumMergedRegions() */ public void testRowAggregation() { List records = new ArrayList(); - RowRecord row = new RowRecord(); - row.setRowNumber(0); - records.add(row); - - row = new RowRecord(); - row.setRowNumber(1); - records.add(row); + records.add(new RowRecord(0)); + records.add(new RowRecord(1)); records.add(new StringRecord()); - - row = new RowRecord(); - row.setRowNumber(2); - records.add(row); - + records.add(new RowRecord(2)); Sheet sheet = Sheet.createSheet(records, 0); assertNotNull("Row [2] was skipped", sheet.getRow(2)); @@ -197,9 +200,9 @@ public void testRowPageBreaks(){ Iterator iterator = sheet.getRowBreaks(); while (iterator.hasNext()) { PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - int main = (int)breakItem.main; + int main = breakItem.main; if (main != 0 && main != 10 && main != 11) fail("Invalid page break"); - if (main == 0) is0 = true; + if (main == 0) is0 = true; if (main == 10) is10= true; if (main == 11) is11 = true; } @@ -216,8 +219,6 @@ public void testRowPageBreaks(){ assertFalse("row should be removed", sheet.isRowBroken(10)); assertEquals("no more breaks", 0, sheet.getNumRowBreaks()); - - } /** @@ -256,10 +257,10 @@ public void testColPageBreaks(){ Iterator iterator = sheet.getColumnBreaks(); while (iterator.hasNext()) { PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - int main = (int)breakItem.main; + int main = breakItem.main; if (main != 0 && main != 1 && main != 10 && main != 15) fail("Invalid page break"); - if (main == 0) is0 = true; - if (main == 1) is1 = true; + if (main == 0) is0 = true; + if (main == 1) is1 = true; if (main == 10) is10= true; if (main == 15) is15 = true; } @@ -286,72 +287,69 @@ public void testColPageBreaks(){ * works as designed. */ public void testXFIndexForColumn() { - try{ - final short TEST_IDX = 10; - final short DEFAULT_IDX = 0xF; // 15 - short xfindex = Short.MIN_VALUE; - Sheet sheet = Sheet.createSheet(); - - // without ColumnInfoRecord - xfindex = sheet.getXFIndexForColAt((short) 0); - assertEquals(DEFAULT_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 1); - assertEquals(DEFAULT_IDX, xfindex); - - ColumnInfoRecord nci = ( ColumnInfoRecord ) sheet.createColInfo(); - sheet.columns.insertColumn(nci); - - // single column ColumnInfoRecord - nci.setFirstColumn((short) 2); - nci.setLastColumn((short) 2); - nci.setXFIndex(TEST_IDX); - xfindex = sheet.getXFIndexForColAt((short) 0); - assertEquals(DEFAULT_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 1); - assertEquals(DEFAULT_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 2); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 3); - assertEquals(DEFAULT_IDX, xfindex); - - // ten column ColumnInfoRecord - nci.setFirstColumn((short) 2); - nci.setLastColumn((short) 11); - nci.setXFIndex(TEST_IDX); - xfindex = sheet.getXFIndexForColAt((short) 1); - assertEquals(DEFAULT_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 2); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 6); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 11); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 12); - assertEquals(DEFAULT_IDX, xfindex); - - // single column ColumnInfoRecord starting at index 0 - nci.setFirstColumn((short) 0); - nci.setLastColumn((short) 0); - nci.setXFIndex(TEST_IDX); - xfindex = sheet.getXFIndexForColAt((short) 0); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 1); - assertEquals(DEFAULT_IDX, xfindex); - - // ten column ColumnInfoRecord starting at index 0 - nci.setFirstColumn((short) 0); - nci.setLastColumn((short) 9); - nci.setXFIndex(TEST_IDX); - xfindex = sheet.getXFIndexForColAt((short) 0); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 7); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 9); - assertEquals(TEST_IDX, xfindex); - xfindex = sheet.getXFIndexForColAt((short) 10); - assertEquals(DEFAULT_IDX, xfindex); - } - catch(Exception e){e.printStackTrace();fail(e.getMessage());} + final short TEST_IDX = 10; + final short DEFAULT_IDX = 0xF; // 15 + short xfindex = Short.MIN_VALUE; + Sheet sheet = Sheet.createSheet(); + + // without ColumnInfoRecord + xfindex = sheet.getXFIndexForColAt((short) 0); + assertEquals(DEFAULT_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 1); + assertEquals(DEFAULT_IDX, xfindex); + + ColumnInfoRecord nci = ( ColumnInfoRecord ) sheet.createColInfo(); + sheet.columns.insertColumn(nci); + + // single column ColumnInfoRecord + nci.setFirstColumn((short) 2); + nci.setLastColumn((short) 2); + nci.setXFIndex(TEST_IDX); + xfindex = sheet.getXFIndexForColAt((short) 0); + assertEquals(DEFAULT_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 1); + assertEquals(DEFAULT_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 2); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 3); + assertEquals(DEFAULT_IDX, xfindex); + + // ten column ColumnInfoRecord + nci.setFirstColumn((short) 2); + nci.setLastColumn((short) 11); + nci.setXFIndex(TEST_IDX); + xfindex = sheet.getXFIndexForColAt((short) 1); + assertEquals(DEFAULT_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 2); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 6); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 11); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 12); + assertEquals(DEFAULT_IDX, xfindex); + + // single column ColumnInfoRecord starting at index 0 + nci.setFirstColumn((short) 0); + nci.setLastColumn((short) 0); + nci.setXFIndex(TEST_IDX); + xfindex = sheet.getXFIndexForColAt((short) 0); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 1); + assertEquals(DEFAULT_IDX, xfindex); + + // ten column ColumnInfoRecord starting at index 0 + nci.setFirstColumn((short) 0); + nci.setLastColumn((short) 9); + nci.setXFIndex(TEST_IDX); + xfindex = sheet.getXFIndexForColAt((short) 0); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 7); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 9); + assertEquals(TEST_IDX, xfindex); + xfindex = sheet.getXFIndexForColAt((short) 10); + assertEquals(DEFAULT_IDX, xfindex); } - } + diff --git a/src/testcases/org/apache/poi/hssf/model/TestSheetAdditional.java b/src/testcases/org/apache/poi/hssf/model/TestSheetAdditional.java index 69ab3f2986a..f1c3b7c9cac 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestSheetAdditional.java +++ b/src/testcases/org/apache/poi/hssf/model/TestSheetAdditional.java @@ -19,125 +19,18 @@ Licensed to the Apache Software Foundation (ASF) under one or more import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import junit.framework.TestCase; import org.apache.poi.hssf.record.ColumnInfoRecord; -import org.apache.poi.hssf.record.MergeCellsRecord; -import org.apache.poi.hssf.record.PageBreakRecord; -import org.apache.poi.hssf.record.RowRecord; -import org.apache.poi.hssf.record.StringRecord; /** * @author Tony Poppleton */ -public class TestSheetAdditional extends TestCase -{ - /** - * Constructor for SheetTest. - * @param arg0 - */ - public TestSheetAdditional(String arg0) - { - super(arg0); - } +public final class TestSheetAdditional extends TestCase { - public void testAddMergedRegion() - { - Sheet sheet = Sheet.createSheet(); - int regionsToAdd = 4096; - int startRecords = sheet.getRecords().size(); - - //simple test that adds a load of regions - for (int n = 0; n < regionsToAdd; n++) - { - int index = sheet.addMergedRegion(0, (short) 0, 1, (short) 1); - assertTrue("Merged region index expected to be " + n + " got " + index, index == n); - } - - //test all the regions were indeed added - assertTrue(sheet.getNumMergedRegions() == regionsToAdd); - - //test that the regions were spread out over the appropriate number of records - int recordsAdded = sheet.getRecords().size() - startRecords; - int recordsExpected = regionsToAdd/1027; - if ((regionsToAdd % 1027) != 0) - recordsExpected++; - assertTrue("The " + regionsToAdd + " merged regions should have been spread out over " + recordsExpected + " records, not " + recordsAdded, recordsAdded == recordsExpected); - - // Check we can't add one with invalud date - try { - sheet.addMergedRegion(10, (short)10, 9, (short)12); - fail(); - } catch(IllegalArgumentException e) {} - try { - sheet.addMergedRegion(10, (short)10, 12, (short)9); - fail(); - } catch(IllegalArgumentException e) {} - } - - public void testRemoveMergedRegion() - { - Sheet sheet = Sheet.createSheet(); - int regionsToAdd = 4096; - - for (int n = 0; n < regionsToAdd; n++) - sheet.addMergedRegion(0, (short) 0, 1, (short) 1); - - int records = sheet.getRecords().size(); - - //remove a third from the beginning - for (int n = 0; n < regionsToAdd/3; n++) - { - sheet.removeMergedRegion(0); - //assert they have been deleted - assertTrue("Num of regions should be " + (regionsToAdd - n - 1) + " not " + sheet.getNumMergedRegions(), sheet.getNumMergedRegions() == regionsToAdd - n - 1); - } - - //assert any record removing was done - int recordsRemoved = (regionsToAdd/3)/1027; //doesn't work for particular values of regionsToAdd - assertTrue("Expected " + recordsRemoved + " record to be removed from the starting " + records + ". Currently there are " + sheet.getRecords().size() + " records", records - sheet.getRecords().size() == recordsRemoved); - } - - /** - * Bug: 22922 (Reported by Xuemin Guan) - *

    - * Remove mergedregion fails when a sheet loses records after an initial CreateSheet - * fills up the records. - * - */ - public void testMovingMergedRegion() { - List records = new ArrayList(); - - MergeCellsRecord merged = new MergeCellsRecord(); - merged.addArea(0, (short)0, 1, (short)2); - records.add(new RowRecord()); - records.add(new RowRecord()); - records.add(new RowRecord()); - records.add(merged); - - Sheet sheet = Sheet.createSheet(records, 0); - sheet.records.remove(0); - - //stub object to throw off list INDEX operations - sheet.removeMergedRegion(0); - assertEquals("Should be no more merged regions", 0, sheet.getNumMergedRegions()); - } - - public void testGetMergedRegionAt() - { - //TODO - } - - public void testGetNumMergedRegions() - { - //TODO - } - - public void DISBALEDtestGetCellWidth() throws Exception - { + public void testGetCellWidth() { Sheet sheet = Sheet.createSheet(); ColumnInfoRecord nci = ( ColumnInfoRecord ) sheet.createColInfo(); @@ -146,14 +39,8 @@ public void DISBALEDtestGetCellWidth() throws Exception nci.setLastColumn((short)10); nci.setColumnWidth((short)100); - Field f = null; - f = Sheet.class.getDeclaredField("columnSizes"); - f.setAccessible(true); - List columnSizes = new ArrayList(); - f.set(sheet,columnSizes); - columnSizes.add(nci); - sheet.records.add(1 + sheet.dimsloc, nci); - sheet.dimsloc++; + + sheet.columns.insertColumn(nci); assertEquals((short)100,sheet.getColumnWidth((short)5)); assertEquals((short)100,sheet.getColumnWidth((short)6)); @@ -172,151 +59,6 @@ public void DISBALEDtestGetCellWidth() throws Exception assertEquals((short)100,sheet.getColumnWidth((short)10)); } - /** - * Makes sure all rows registered for this sheet are aggregated, they were being skipped - * - */ - public void testRowAggregation() { - List records = new ArrayList(); - RowRecord row = new RowRecord(); - row.setRowNumber(0); - records.add(row); - - row = new RowRecord(); - row.setRowNumber(1); - records.add(row); - - records.add(new StringRecord()); - - row = new RowRecord(); - row.setRowNumber(2); - records.add(row); - - - Sheet sheet = Sheet.createSheet(records, 0); - assertNotNull("Row [2] was skipped", sheet.getRow(2)); - - } - - /** - * Make sure page break functionality works (in memory) - * - */ - public void testRowPageBreaks(){ - short colFrom = 0; - short colTo = 255; - - Sheet sheet = Sheet.createSheet(); - sheet.setRowBreak(0, colFrom, colTo); - - assertTrue("no row break at 0", sheet.isRowBroken(0)); - assertEquals("1 row break available", 1, sheet.getNumRowBreaks()); - - sheet.setRowBreak(0, colFrom, colTo); - sheet.setRowBreak(0, colFrom, colTo); - - assertTrue("no row break at 0", sheet.isRowBroken(0)); - assertEquals("1 row break available", 1, sheet.getNumRowBreaks()); - - sheet.setRowBreak(10, colFrom, colTo); - sheet.setRowBreak(11, colFrom, colTo); - - assertTrue("no row break at 10", sheet.isRowBroken(10)); - assertTrue("no row break at 11", sheet.isRowBroken(11)); - assertEquals("3 row break available", 3, sheet.getNumRowBreaks()); - - - boolean is10 = false; - boolean is0 = false; - boolean is11 = false; - - Iterator iterator = sheet.getRowBreaks(); - while (iterator.hasNext()) { - PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - int main = (int)breakItem.main; - if (main != 0 && main != 10 && main != 11) fail("Invalid page break"); - if (main == 0) is0 = true; - if (main == 10) is10= true; - if (main == 11) is11 = true; - } - - assertTrue("one of the breaks didnt make it", is0 && is10 && is11); - - sheet.removeRowBreak(11); - assertFalse("row should be removed", sheet.isRowBroken(11)); - - sheet.removeRowBreak(0); - assertFalse("row should be removed", sheet.isRowBroken(0)); - - sheet.removeRowBreak(10); - assertFalse("row should be removed", sheet.isRowBroken(10)); - - assertEquals("no more breaks", 0, sheet.getNumRowBreaks()); - - - } - - /** - * Make sure column pag breaks works properly (in-memory) - * - */ - public void testColPageBreaks(){ - short rowFrom = 0; - short rowTo = (short)65535; - - Sheet sheet = Sheet.createSheet(); - sheet.setColumnBreak((short)0, rowFrom, rowTo); - - assertTrue("no col break at 0", sheet.isColumnBroken((short)0)); - assertEquals("1 col break available", 1, sheet.getNumColumnBreaks()); - - sheet.setColumnBreak((short)0, rowFrom, rowTo); - - assertTrue("no col break at 0", sheet.isColumnBroken((short)0)); - assertEquals("1 col break available", 1, sheet.getNumColumnBreaks()); - - sheet.setColumnBreak((short)1, rowFrom, rowTo); - sheet.setColumnBreak((short)10, rowFrom, rowTo); - sheet.setColumnBreak((short)15, rowFrom, rowTo); - - assertTrue("no col break at 1", sheet.isColumnBroken((short)1)); - assertTrue("no col break at 10", sheet.isColumnBroken((short)10)); - assertTrue("no col break at 15", sheet.isColumnBroken((short)15)); - assertEquals("4 col break available", 4, sheet.getNumColumnBreaks()); - - boolean is10 = false; - boolean is0 = false; - boolean is1 = false; - boolean is15 = false; - - Iterator iterator = sheet.getColumnBreaks(); - while (iterator.hasNext()) { - PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - int main = (int)breakItem.main; - if (main != 0 && main != 1 && main != 10 && main != 15) fail("Invalid page break"); - if (main == 0) is0 = true; - if (main == 1) is1 = true; - if (main == 10) is10= true; - if (main == 15) is15 = true; - } - - assertTrue("one of the breaks didnt make it", is0 && is1 && is10 && is15); - - sheet.removeColumnBreak((short)15); - assertFalse("column break should not be there", sheet.isColumnBroken((short)15)); - - sheet.removeColumnBreak((short)0); - assertFalse("column break should not be there", sheet.isColumnBroken((short)0)); - - sheet.removeColumnBreak((short)1); - assertFalse("column break should not be there", sheet.isColumnBroken((short)1)); - - sheet.removeColumnBreak((short)10); - assertFalse("column break should not be there", sheet.isColumnBroken((short)10)); - - assertEquals("no more breaks", 0, sheet.getNumColumnBreaks()); - } - } diff --git a/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java b/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java index d2a1b368410..2b8e3c3ab55 100755 --- a/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java +++ b/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java @@ -67,6 +67,7 @@ public static Test suite() { result.addTestSuite(TestFormulaRecord.class); result.addTestSuite(TestFrameRecord.class); result.addTestSuite(TestHyperlinkRecord.class); + result.addTestSuite(TestLabelRecord.class); result.addTestSuite(TestLegendRecord.class); result.addTestSuite(TestLineFormatRecord.class); result.addTestSuite(TestLinkedDataRecord.class); diff --git a/src/testcases/org/apache/poi/hssf/record/TestExternalNameRecord.java b/src/testcases/org/apache/poi/hssf/record/TestExternalNameRecord.java index 714c0358ff7..7a9acb087b2 100644 --- a/src/testcases/org/apache/poi/hssf/record/TestExternalNameRecord.java +++ b/src/testcases/org/apache/poi/hssf/record/TestExternalNameRecord.java @@ -38,6 +38,8 @@ public final class TestExternalNameRecord extends TestCase { // data taken from bugzilla 44774 att 21790 private static final byte[] dataPlainName = { 0, 0, 0, 0, 0, 0, 9, 0, 82, 97, 116, 101, 95, 68, 97, 116, 101, 9, 0, 58, 0, 0, 0, 0, 4, 0, 8, 0 + // TODO - the last 2 bytes of formula data (8,0) seem weird. They encode to ConcatPtg, UnknownPtg + // UnknownPtg is otherwise not created by any other test cases }; private static ExternalNameRecord createSimpleENR(byte[] data) { diff --git a/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java b/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java index abe6943c799..4f5e3908730 100644 --- a/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java +++ b/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java @@ -19,16 +19,14 @@ Licensed to the Apache Software Foundation (ASF) under one or more import java.io.ByteArrayInputStream; +import java.util.List; + +import junit.framework.TestCase; import org.apache.poi.hssf.record.formula.AttrPtg; -import org.apache.poi.hssf.record.formula.ConcatPtg; import org.apache.poi.hssf.record.formula.FuncVarPtg; import org.apache.poi.hssf.record.formula.IntPtg; -import org.apache.poi.hssf.record.formula.RangePtg; import org.apache.poi.hssf.record.formula.ReferencePtg; -import org.apache.poi.hssf.record.formula.UnknownPtg; - -import junit.framework.TestCase; /** * Tests the serialization and deserialization of the FormulaRecord @@ -57,7 +55,7 @@ public void testCreateFormulaRecord () { */ public void testCheckNanPreserve() { byte[] formulaByte = new byte[29]; - for (int i = 0; i < formulaByte.length; i++) formulaByte[i] = (byte)0; + formulaByte[4] = (byte)0x0F; formulaByte[6] = (byte)0x02; formulaByte[8] = (byte)0x07; @@ -91,8 +89,6 @@ public void testCheckNanPreserve() { public void testExpFormula() { byte[] formulaByte = new byte[27]; - for (int i = 0; i < formulaByte.length; i++) formulaByte[i] = (byte)0; - formulaByte[4] =(byte)0x0F; formulaByte[14]=(byte)0x08; formulaByte[18]=(byte)0xE0; @@ -109,15 +105,14 @@ public void testExpFormula() { public void testWithConcat() throws Exception { // =CHOOSE(2,A2,A3,A4) - byte[] data = new byte[] { + byte[] data = { 6, 0, 68, 0, 1, 0, 1, 0, 15, 0, 0, 0, 0, 0, 0, 0, 57, 64, 0, 0, 12, 0, 12, -4, 46, 0, 30, 2, 0, // Int - 2 25, 4, 3, 0, // Attr - 8, 0, // Concat - 17, 0, // Range - 26, 0, 35, 0, // Bit like an attr + 8, 0, 17, 0, 26, 0, // jumpTable + 35, 0, // chooseOffset 36, 1, 0, 0, -64, // Ref - A2 25, 8, 21, 0, // Attr 36, 2, 0, 0, -64, // Ref - A3 @@ -126,30 +121,24 @@ public void testWithConcat() throws Exception { 25, 8, 3, 0, // Attr 66, 4, 100, 0 // CHOOSE }; - RecordInputStream inp = new RecordInputStream( - new ByteArrayInputStream(data) - ); + RecordInputStream inp = new RecordInputStream( new ByteArrayInputStream(data)); inp.nextRecord(); FormulaRecord fr = new FormulaRecord(inp); - assertEquals(14, fr.getNumberOfExpressionTokens()); - assertEquals(IntPtg.class, fr.getParsedExpression().get(0).getClass()); - assertEquals(AttrPtg.class, fr.getParsedExpression().get(1).getClass()); - assertEquals(ConcatPtg.class, fr.getParsedExpression().get(2).getClass()); - assertEquals(UnknownPtg.class, fr.getParsedExpression().get(3).getClass()); - assertEquals(RangePtg.class, fr.getParsedExpression().get(4).getClass()); - assertEquals(UnknownPtg.class, fr.getParsedExpression().get(5).getClass()); - assertEquals(AttrPtg.class, fr.getParsedExpression().get(6).getClass()); - assertEquals(ReferencePtg.class, fr.getParsedExpression().get(7).getClass()); - assertEquals(AttrPtg.class, fr.getParsedExpression().get(8).getClass()); - assertEquals(ReferencePtg.class, fr.getParsedExpression().get(9).getClass()); - assertEquals(AttrPtg.class, fr.getParsedExpression().get(10).getClass()); - assertEquals(ReferencePtg.class, fr.getParsedExpression().get(11).getClass()); - assertEquals(AttrPtg.class, fr.getParsedExpression().get(12).getClass()); - assertEquals(FuncVarPtg.class, fr.getParsedExpression().get(13).getClass()); + List ptgs = fr.getParsedExpression(); + assertEquals(9, ptgs.size()); + assertEquals(IntPtg.class, ptgs.get(0).getClass()); + assertEquals(AttrPtg.class, ptgs.get(1).getClass()); + assertEquals(ReferencePtg.class, ptgs.get(2).getClass()); + assertEquals(AttrPtg.class, ptgs.get(3).getClass()); + assertEquals(ReferencePtg.class, ptgs.get(4).getClass()); + assertEquals(AttrPtg.class, ptgs.get(5).getClass()); + assertEquals(ReferencePtg.class, ptgs.get(6).getClass()); + assertEquals(AttrPtg.class, ptgs.get(7).getClass()); + assertEquals(FuncVarPtg.class, ptgs.get(8).getClass()); - FuncVarPtg choose = (FuncVarPtg)fr.getParsedExpression().get(13); + FuncVarPtg choose = (FuncVarPtg)ptgs.get(8); assertEquals("CHOOSE", choose.getName()); } diff --git a/src/testcases/org/apache/poi/hssf/record/TestLabelRecord.java b/src/testcases/org/apache/poi/hssf/record/TestLabelRecord.java new file mode 100644 index 00000000000..10f363652ed --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/TestLabelRecord.java @@ -0,0 +1,41 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record; + +import org.apache.poi.hssf.HSSFTestDataSamples; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; +/** + * Tests for LabelRecord + * + * @author Josh Micich + */ +public final class TestLabelRecord extends TestCase { + + public void testEmptyString() { + HSSFWorkbook wb; + try { + wb = HSSFTestDataSamples.openSampleWorkbook("ex42570-20305.xls"); + } catch (NullPointerException e) { + throw new AssertionFailedError("Identified bug 42570"); + } + HSSFTestDataSamples.writeOutAndReadBack(wb); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/aggregates/TestRowRecordsAggregate.java b/src/testcases/org/apache/poi/hssf/record/aggregates/TestRowRecordsAggregate.java index 50f67129cea..239fc2b8870 100644 --- a/src/testcases/org/apache/poi/hssf/record/aggregates/TestRowRecordsAggregate.java +++ b/src/testcases/org/apache/poi/hssf/record/aggregates/TestRowRecordsAggregate.java @@ -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,34 +14,28 @@ Licensed to the Apache Software Foundation (ASF) under one or more See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ - + package org.apache.poi.hssf.record.aggregates; -import org.apache.poi.hssf.record.*; +import junit.framework.TestCase; -public class TestRowRecordsAggregate extends junit.framework.TestCase { - public TestRowRecordsAggregate(String name) { - super (name); - } +import org.apache.poi.hssf.record.RowRecord; + +/** + * + */ +public final class TestRowRecordsAggregate extends TestCase { public void testRowGet() { RowRecordsAggregate rra = new RowRecordsAggregate(); - RowRecord rr = new RowRecord(); - rr.setRowNumber(( short ) 4); + RowRecord rr = new RowRecord(4); rra.insertRow(rr); - RowRecord rr2 = new RowRecord(); rr2.setRowNumber((short) 1); - rra.insertRow(rr2); + rra.insertRow(new RowRecord(1)); RowRecord rr1 = rra.getRow(4); - assertTrue("Row Record should not be null", rr1!=null); - assertTrue("Row number is 1",rr1.getRowNumber() == 4); + assertNotNull(rr1); + assertEquals("Row number is 1", 4, rr1.getRowNumber()); assertTrue("Row record retrieved is identical ", rr1 == rr); } - - public static void main(String [] args) { - System.out - .println("Testing org.apache.poi.hssf.record.aggregates.RowRecordAggregate"); - junit.textui.TestRunner.run(TestRowRecordsAggregate.class); - } } diff --git a/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java b/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java index 80f6616fa6b..a685fd2cb69 100644 --- a/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java @@ -40,6 +40,7 @@ public static Test suite() { result.addTestSuite(TestArea3DPtg.class); result.addTestSuite(TestAreaErrPtg.class); result.addTestSuite(TestAreaPtg.class); + result.addTestSuite(TestArrayPtg.class); result.addTestSuite(TestErrPtg.class); result.addTestSuite(TestExternalFunctionFormulas.class); result.addTestSuite(TestFuncPtg.class); diff --git a/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java b/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java new file mode 100644 index 00000000000..16f80bb791a --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java @@ -0,0 +1,95 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula; + +import java.util.Arrays; + +import org.apache.poi.hssf.record.TestcaseRecordInputStream; +import org.apache.poi.hssf.record.UnicodeString; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; +/** + * Tests for ArrayPtg + * + * @author Josh Micich + */ +public final class TestArrayPtg extends TestCase { + + private static final byte[] ENCODED_PTG_DATA = { + 0x40, 0x00, + 0x08, 0x00, + 0, 0, 0, 0, 0, 0, 0, 0, + }; + private static final byte[] ENCODED_CONSTANT_DATA = { + 2, // 3 columns + 1, 0, // 2 rows + 4, 1, 0, 0, 0, 0, 0, 0, 0, // TRUE + 2, 4, 0, 0, 65, 66, 67, 68, // "ABCD" + 2, 1, 0, 0, 69, // "E" + 1, 0, 0, 0, 0, 0, 0, 0, 0, // 0 + 4, 0, 0, 0, 0, 0, 0, 0, 0, // FALSE + 2, 2, 0, 0, 70, 71, // "FG" + }; + + /** + * Lots of problems with ArrayPtg's encoding of + */ + public void testReadWriteTokenValueBytes() { + + ArrayPtg ptg = new ArrayPtgV(new TestcaseRecordInputStream(ArrayPtgV.sid, ENCODED_PTG_DATA)); + + ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA)); + assertEquals(3, ptg.getColumnCount()); + assertEquals(2, ptg.getRowCount()); + Object[] values = ptg.token_3_arrayValues; + assertEquals(6, values.length); + + + assertEquals(Boolean.TRUE, values[0]); + assertEquals(new UnicodeString("ABCD"), values[1]); + assertEquals(new Double(0), values[3]); + assertEquals(Boolean.FALSE, values[4]); + assertEquals(new UnicodeString("FG"), values[5]); + + byte[] outBuf = new byte[ENCODED_CONSTANT_DATA.length]; + ptg.writeTokenValueBytes(outBuf, 0); + + if(outBuf[0] == 4) { + throw new AssertionFailedError("Identified bug 42564b"); + } + assertTrue(Arrays.equals(ENCODED_CONSTANT_DATA, outBuf)); + } + + /** + * make sure constant elements are stored row by row + */ + public void testElementOrdering() { + ArrayPtg ptg = new ArrayPtgV(new TestcaseRecordInputStream(ArrayPtgV.sid, ENCODED_PTG_DATA)); + ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA)); + assertEquals(3, ptg.getColumnCount()); + assertEquals(2, ptg.getRowCount()); + + assertEquals(0, ptg.getValueIndex(0, 0)); + assertEquals(1, ptg.getValueIndex(1, 0)); + assertEquals(2, ptg.getValueIndex(2, 0)); + assertEquals(3, ptg.getValueIndex(0, 1)); + assertEquals(4, ptg.getValueIndex(1, 1)); + assertEquals(5, ptg.getValueIndex(2, 1)); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/TestFuncPtg.java b/src/testcases/org/apache/poi/hssf/record/formula/TestFuncPtg.java index fd2b1cd1242..89997b59d1a 100644 --- a/src/testcases/org/apache/poi/hssf/record/formula/TestFuncPtg.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/TestFuncPtg.java @@ -1,4 +1,3 @@ - /* ==================================================================== Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -26,45 +25,31 @@ Licensed to the Apache Software Foundation (ASF) under one or more * * @author Danny Mui (dmui at apache dot org) */ +public final class TestFuncPtg extends TestCase { -public class TestFuncPtg extends TestCase -{ - - public TestFuncPtg( String name ) - { - super( name ); - } - - - public static void main( java.lang.String[] args ) - { - junit.textui.TestRunner.run( TestFuncPtg.class ); - } - - /** - * Make sure the left overs are re-serialized on excel file reads to avoid - * the "Warning: Data may have been lost" prompt in excel. - *

    - * This ptg represents a LEN function extracted from excel - */ - - public void testLeftOvers() - { - byte[] fakeData = new byte[4]; - - //fakeData[0] = (byte) 0x41; - fakeData[0] = (byte) 0x20; //function index - fakeData[1] = (byte) 0; - fakeData[2] = (byte) 8; + public void testRead() { + // This ptg represents a LEN function extracted from excel + byte[] fakeData = { + 0x20, //function index + 0, + }; FuncPtg ptg = new FuncPtg( new TestcaseRecordInputStream((short)0, (short)fakeData.length, fakeData) ); - assertEquals( "Len formula index is not 32(20H)", (int) 0x20, ptg.getFunctionIndex() ); + assertEquals( "Len formula index is not 32(20H)", 0x20, ptg.getFunctionIndex() ); assertEquals( "Number of operands in the len formula", 1, ptg.getNumberOfOperands() ); assertEquals( "Function Name", "LEN", ptg.getName() ); assertEquals( "Ptg Size", 3, ptg.getSize() ); - //assertEquals("first leftover byte is not 0", (byte)0, ptg.leftOvers[0]); - //assertEquals("second leftover byte is not 8", (byte)8, ptg.leftOvers[1]); - + } + + public void testClone() { + FuncPtg funcPtg = new FuncPtg(27); // ROUND() - takes 2 args + + FuncPtg clone = (FuncPtg) funcPtg.clone(); + if (clone.getNumberOfOperands() == 0) { + fail("clone() did copy field numberOfOperands"); + } + assertEquals(2, clone.getNumberOfOperands()); + assertEquals("ROUND", clone.getName()); } } diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java index 5098c789a76..8887445ad38 100755 --- a/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java @@ -28,7 +28,8 @@ Licensed to the Apache Software Foundation (ASF) under one or more public class AllFormulaEvalTests { public static Test suite() { - TestSuite result = new TestSuite("Tests for org.apache.poi.hssf.record.formula.eval"); + TestSuite result = new TestSuite(AllFormulaEvalTests.class.getName()); + result.addTestSuite(TestAreaEval.class); result.addTestSuite(TestCircularReferences.class); result.addTestSuite(TestExternalFunction.class); result.addTestSuite(TestFormulaBugs.class); diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestAreaEval.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestAreaEval.java new file mode 100644 index 00000000000..6c855707ba4 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestAreaEval.java @@ -0,0 +1,62 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula.eval; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +import org.apache.poi.hssf.record.formula.Area3DPtg; + +/** + * Tests for AreaEval + * + * @author Josh Micich + */ +public final class TestAreaEval extends TestCase { + + public void testGetValue_bug44950() { + + Area3DPtg ptg = new Area3DPtg("B2:D3", (short)0); + NumberEval one = new NumberEval(1); + ValueEval[] values = { + one, + new NumberEval(2), + new NumberEval(3), + new NumberEval(4), + new NumberEval(5), + new NumberEval(6), + }; + AreaEval ae = new Area3DEval(ptg, values); + if (one == ae.getValueAt(1, 2)) { + throw new AssertionFailedError("Identified bug 44950 a"); + } + confirm(1, ae, 1, 1); + confirm(2, ae, 1, 2); + confirm(3, ae, 1, 3); + confirm(4, ae, 2, 1); + confirm(5, ae, 2, 2); + confirm(6, ae, 2, 3); + + } + + private static void confirm(int expectedValue, AreaEval ae, int row, int col) { + NumberEval v = (NumberEval) ae.getValueAt(row, col); + assertEquals(expectedValue, v.getNumberValue(), 0.0); + } + +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/function/ExcelFileFormatDocFunctionExtractor.java b/src/testcases/org/apache/poi/hssf/record/formula/function/ExcelFileFormatDocFunctionExtractor.java index 48a76e31d83..47137df4f64 100644 --- a/src/testcases/org/apache/poi/hssf/record/formula/function/ExcelFileFormatDocFunctionExtractor.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/function/ExcelFileFormatDocFunctionExtractor.java @@ -25,6 +25,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; +import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; @@ -60,7 +61,32 @@ public final class ExcelFileFormatDocFunctionExtractor { private static final String SOURCE_DOC_FILE_NAME = "excelfileformat.odt"; + /** + * For simplicity, the output file is strictly simple ASCII. + * This method detects any unexpected characters. + */ + /* package */ static boolean isSimpleAscii(char c) { + + if (c>=0x21 && c<=0x7E) { + // everything from '!' to '~' (includes letters, digits, punctuation + return true; + } + // some specific whitespace chars below 0x21: + switch(c) { + case ' ': + case '\t': + case '\r': + case '\n': + return true; + } + return false; + } + + private static final class FunctionData { + // special characters from the ooo document + private static final int CHAR_ELLIPSIS_8230 = 8230; + private static final int CHAR_NDASH_8211 = 8211; private final int _index; private final boolean _hasFootnote; @@ -78,10 +104,30 @@ public FunctionData(int funcIx, boolean hasFootnote, String funcName, int minPar _name = funcName; _minParams = minParams; _maxParams = maxParams; - _returnClass = returnClass; - _paramClasses = paramClasses; + _returnClass = convertSpecialChars(returnClass); + _paramClasses = convertSpecialChars(paramClasses); _isVolatile = isVolatile; } + private static String convertSpecialChars(String ss) { + StringBuffer sb = new StringBuffer(ss.length() + 4); + for(int i=0; i 0) { + throw new AssertionFailedError("identified bug 44306"); + } } } @@ -887,13 +886,66 @@ public void test28774() { writeOutAndReadBack(wb); assertTrue("no errors writing sample xls", true); } - + /** * Had a problem apparently, not sure what as it * works just fine... */ public void test44891() throws Exception { - HSSFWorkbook wb = openSample("44891.xls"); + HSSFWorkbook wb = openSample("44891.xls"); + assertTrue("no errors reading sample xls", true); + writeOutAndReadBack(wb); + assertTrue("no errors writing sample xls", true); + } + + /** + * Bug 44235: Ms Excel can't open save as excel file + * + * Works fine with poi-3.1-beta1. + */ + public void test44235() throws Exception { + HSSFWorkbook wb = openSample("44235.xls"); + assertTrue("no errors reading sample xls", true); + writeOutAndReadBack(wb); + assertTrue("no errors writing sample xls", true); + } + + /** + * Bug 21334: "File error: data may have been lost" with a file + * that contains macros and this formula: + * {=SUM(IF(FREQUENCY(IF(LEN(V4:V220)>0,MATCH(V4:V220,V4:V220,0),""),IF(LEN(V4:V220)>0,MATCH(V4:V220,V4:V220,0),""))>0,1))} + */ + public void test21334() { + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sh = wb.createSheet(); + HSSFCell cell = sh.createRow(0).createCell((short)0); + String formula = "SUM(IF(FREQUENCY(IF(LEN(V4:V220)>0,MATCH(V4:V220,V4:V220,0),\"\"),IF(LEN(V4:V220)>0,MATCH(V4:V220,V4:V220,0),\"\"))>0,1))"; + cell.setCellFormula(formula); + + HSSFWorkbook wb_sv = writeOutAndReadBack(wb); + HSSFCell cell_sv = wb_sv.getSheetAt(0).getRow(0).getCell((short)0); + assertEquals(formula, cell_sv.getCellFormula()); + } + + public void test36947() throws Exception { + HSSFWorkbook wb = openSample("36947.xls"); + assertTrue("no errors reading sample xls", true); + writeOutAndReadBack(wb); + assertTrue("no errors writing sample xls", true); + } + + /** + * Bug 42448: Can't parse SUMPRODUCT(A!C7:A!C67, B8:B68) / B69 + */ + public void test42448(){ + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFCell cell = wb.createSheet().createRow(0).createCell((short)0); + cell.setCellFormula("SUMPRODUCT(A!C7:A!C67, B8:B68) / B69"); + assertTrue("no errors parsing formula", true); + } + + public void test39634() throws Exception { + HSSFWorkbook wb = openSample("39634.xls"); assertTrue("no errors reading sample xls", true); writeOutAndReadBack(wb); assertTrue("no errors writing sample xls", true); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java index 0ef64291734..349cfa8a850 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java @@ -22,12 +22,14 @@ Licensed to the Apache Software Foundation (ASF) under one or more import java.util.Iterator; import java.util.List; +import junit.framework.AssertionFailedError; import junit.framework.TestCase; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; import org.apache.poi.hssf.record.formula.AreaPtg; import org.apache.poi.hssf.record.formula.FuncVarPtg; + /** * */ @@ -51,42 +53,41 @@ protected void setUp() { */ public void test44636() throws Exception { // Open the existing file, tweak one value and - // re-calculate + // re-calculate HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("44636.xls"); - HSSFSheet sheet = wb.getSheetAt (0); - HSSFRow row = sheet.getRow (0); + HSSFSheet sheet = wb.getSheetAt(0); + HSSFRow row = sheet.getRow(0); - row.getCell((short)0).setCellValue(4.2); - row.getCell((short)2).setCellValue(25); + row.getCell((short) 0).setCellValue(4.2); + row.getCell((short) 2).setCellValue(25); HSSFFormulaEvaluator.evaluateAllFormulaCells(wb); - assertEquals(4.2*25, row.getCell((short)3).getNumericCellValue(), 0.0001); + assertEquals(4.2 * 25, row.getCell((short) 3).getNumericCellValue(), 0.0001); // Save - File existing = new File(tmpDirName,"44636-existing.xls"); + File existing = new File(tmpDirName, "44636-existing.xls"); FileOutputStream out = new FileOutputStream(existing); wb.write(out); out.close(); System.err.println("Existing file for bug #44636 written to " + existing.toString()); - // Now, do a new file from scratch wb = new HSSFWorkbook(); sheet = wb.createSheet(); row = sheet.createRow(0); - row.createCell((short)0).setCellValue(1.2); - row.createCell((short)1).setCellValue(4.2); + row.createCell((short) 0).setCellValue(1.2); + row.createCell((short) 1).setCellValue(4.2); row = sheet.createRow(1); - row.createCell((short)0).setCellFormula("SUM(A1:B1)"); + row.createCell((short) 0).setCellFormula("SUM(A1:B1)"); HSSFFormulaEvaluator.evaluateAllFormulaCells(wb); - assertEquals(5.4, row.getCell((short)0).getNumericCellValue(), 0.0001); + assertEquals(5.4, row.getCell((short) 0).getNumericCellValue(), 0.0001); // Save - File scratch = new File(tmpDirName,"44636-scratch.xls"); + File scratch = new File(tmpDirName, "44636-scratch.xls"); out = new FileOutputStream(scratch); wb.write(out); out.close(); @@ -105,62 +106,62 @@ public void test44297() { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("44297.xls"); HSSFRow row; - HSSFCell cell; + HSSFCell cell; - HSSFSheet sheet = wb.getSheetAt(0); + HSSFSheet sheet = wb.getSheetAt(0); HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb); row = sheet.getRow(0); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("31+46", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(77, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(1); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("30+53", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(83, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(2); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("SUM(A1:A2)", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(160, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(4); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("32767+32768", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(65535, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(7); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("32744+42333", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(75077, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(8); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("327680.0/32768", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(10, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(9); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("32767+32769", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(65536, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(10); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("35000+36000", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(71000, eva.evaluate(cell).getNumberValue(), 0); row = sheet.getRow(11); - cell = row.getCell((short)0); + cell = row.getCell((short) 0); assertEquals("-1000000.0-3000000.0", cell.getCellFormula()); eva.setCurrentRow(row); assertEquals(-4000000, eva.evaluate(cell).getNumberValue(), 0); @@ -176,30 +177,29 @@ public void test44410() { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("SingleLetterRanges.xls"); - HSSFSheet sheet = wb.getSheetAt(0); + HSSFSheet sheet = wb.getSheetAt(0); HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb); - // =index(C:C,2,1) -> 2 + // =index(C:C,2,1) -> 2 HSSFRow rowIDX = sheet.getRow(3); - // =sum(C:C) -> 6 + // =sum(C:C) -> 6 HSSFRow rowSUM = sheet.getRow(4); - // =sum(C:D) -> 66 + // =sum(C:D) -> 66 HSSFRow rowSUM2D = sheet.getRow(5); // Test the sum - HSSFCell cellSUM = rowSUM.getCell((short)0); + HSSFCell cellSUM = rowSUM.getCell((short) 0); - FormulaRecordAggregate frec = - (FormulaRecordAggregate)cellSUM.getCellValueRecord(); + FormulaRecordAggregate frec = (FormulaRecordAggregate) cellSUM.getCellValueRecord(); List ops = frec.getFormulaRecord().getParsedExpression(); assertEquals(2, ops.size()); assertEquals(AreaPtg.class, ops.get(0).getClass()); assertEquals(FuncVarPtg.class, ops.get(1).getClass()); - // Actually stored as C1 to C65536 - // (last row is -1 === 65535) - AreaPtg ptg = (AreaPtg)ops.get(0); + // Actually stored as C1 to C65536 + // (last row is -1 === 65535) + AreaPtg ptg = (AreaPtg) ops.get(0); assertEquals(2, ptg.getFirstColumn()); assertEquals(2, ptg.getLastColumn()); assertEquals(0, ptg.getFirstRow()); @@ -207,26 +207,25 @@ public void test44410() { assertEquals("C:C", ptg.toFormulaString(wb)); // Will show as C:C, but won't know how many - // rows it covers as we don't have the sheet - // to hand when turning the Ptgs into a string + // rows it covers as we don't have the sheet + // to hand when turning the Ptgs into a string assertEquals("SUM(C:C)", cellSUM.getCellFormula()); eva.setCurrentRow(rowSUM); // But the evaluator knows the sheet, so it - // can do it properly + // can do it properly assertEquals(6, eva.evaluate(cellSUM).getNumberValue(), 0); - // Test the index // Again, the formula string will be right but - // lacking row count, evaluated will be right - HSSFCell cellIDX = rowIDX.getCell((short)0); + // lacking row count, evaluated will be right + HSSFCell cellIDX = rowIDX.getCell((short) 0); assertEquals("INDEX(C:C,2,1)", cellIDX.getCellFormula()); eva.setCurrentRow(rowIDX); assertEquals(2, eva.evaluate(cellIDX).getNumberValue(), 0); // Across two colums - HSSFCell cellSUM2D = rowSUM2D.getCell((short)0); + HSSFCell cellSUM2D = rowSUM2D.getCell((short) 0); assertEquals("SUM(C:D)", cellSUM2D.getCellFormula()); eva.setCurrentRow(rowSUM2D); assertEquals(66, eva.evaluate(cellSUM2D).getNumberValue(), 0); @@ -240,7 +239,7 @@ public void testEvaluateBooleanInCell_bug44508() { HSSFSheet sheet = wb.createSheet(); wb.setSheetName(0, "Sheet1"); HSSFRow row = sheet.createRow(0); - HSSFCell cell = row.createCell((short)0); + HSSFCell cell = row.createCell((short) 0); cell.setCellFormula("1=1"); @@ -253,29 +252,46 @@ public void testEvaluateBooleanInCell_bug44508() { } assertEquals(true, cell.getBooleanCellValue()); } - + public void testClassCast_bug44861() throws Exception { - HSSFWorkbook wb = HSSFTestDataSamples. - openSampleWorkbook("44861.xls"); - + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("44861.xls"); + // Check direct HSSFFormulaEvaluator.evaluateAllFormulaCells(wb); - + // And via calls int numSheets = wb.getNumberOfSheets(); - for(int i=0; i_u~_S$=|y=Tw! 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 KM%cT5ch74h#2SOr*lD5>Y)+ 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

    e+|2gGg^LAUu3GUv8H8K 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%0DJBFd&>0V42 z{H&Zzv+uL+j$KtBH5SgHGwkj(YO+{;PI$B!4b+ZLZx=>mj<$KAdf|f-dYA}vTHJ8V zvPJn=ifA;g?;1}|ncRgM`ME0X`MKdVdgY9*S8`eR6&W z+R{hMVVzaptlFj_dU(|M6qX(hV4yZ$VMYwpaowbh4WIz4j!oxcbTkBLRacu>s|j;C z*97#B_34$f*2)=Uqh38oIV3;=B+!olZaB%mLCdeX`}XMNIRI1Enrj0H1AZl@sd5sP z=Ms}2X@)mcwFQ`SOj_a?B`&Pe&47Jo6{Ty?`!h8uZ);q5G;Y(#S-0-Xi{*q-Qn~Wr z+6z!s(n<>FF0*K^arZ@;%Z*W&w<~uEg7Ush_XIA&$@?HOhpwD4HtOD$6i5OjKmyGK z5R@eE3AjNu%T5STmgf?sduOe?)|}*w%&IU{@l8N0`GsJtS(k%U03VW*YiM`K(WV&c)8Mo?RE(kHyUSk;@kIg8O!wQf<>C<^D6g3vC$ zCSEJem(LCIsx=-jElwz*WL&soP7c?gWkRPpW225eNKqs}0wmChz~l#k)?Hgy?z#pC zu(k)3cMi%$<=j|*15esmwNgC7_sPYDUhQ%MTP~UNf+svO+K44Lt}qyC!y_dWc0;Q? zQrC^j4b-6lhptlcY|iP1{zISFQWm11Qc~5D%-meATH{d~N?yTSUk`mYH8*+Dw4!a} zDaJ;P09l;`NPq+e5SYLGn)4JUxXFsK=1r0EKIsyMmiU87!sP~z@O{?Zu`BPR#*)e- zqlg$9g^#Y@D?C!x05E#1!gSr_oWi}FbiMWRv$;7t)aiEWDI0j^2vX_aawbYiC8Qe~ z8!0i_xRo=;M#@OwDH0$75?GHw?$+Jw8HvEM-16LnwRL4hdyuixb|o?^dA2)X2 zR`Moa?l6vsW0ESlfj7?Y@Ia;|)^h8*7>JHYM%AvH%Eyl)1ft4g^hKja4AjL&YYQl| zz8q<7qrSZU;+HL6A3c{9Vnbsi<#FP1+k1?S{8(jz1W14cwnSjWK7nH2x@+q>V<+rd zfr)c7ZVjpDx-%-_|iwR zmdsQJ4>w^Z7*CwR{X5MYe+&a^h_1sq$Q3?8jj3y zeuwY$nTed4bAs=7OZD&w-~85_NCxGeNz3?&+f@c?;YMsMvwMybEY1m+;qoh;VteyY_vESSbzjbfCSbcQ0{Se(N0;Oo8T-ct_r-uE(R(> z8pBXU`S|gepLmx1G32>Zw*7ary2wX4{7)5uwobJ9n|VI|z+GRk-u?deNpax)rTV;Gi=Ydli1 zIIUcwM-x*zYtYIWW21NgFoy(4fCRQdzETg4Tou0(Q*2PMGGd_i9Xtw_m|@?hr8H&s z8PrguA+nL}8qzDqMoQB#*GXWX@u63 z@6|c%?M}M1&YV`Rbu-6m)kIVEd6IyWWAHt4Ch6`##f%I(d^5~^|-8&%OAN*J173Fyk$V~bgi(W>qgIau_oZm6dcb+(hUTO-6a`av*bU3M!@F+RP zJcPx;)&j$~5+o)^9yt?~tIZ&HJEw_qeZkh<>7><3X+RSP6u6c z+gZj&Hg2p%0wh2J;|bXIBwF;!t*uY+7uH>CR^CU^!%*{cZpoGF#c*VV@1uBUEn{hG zb(6rIdo>~W9zjD7kML;*>A(i*#gW#iaBiR?Tx*ovrMj}D0Z?6I; z&B0~9%og@SP>iur0ECAmKmsJNB?7sX-$Bc-lb7cL(t-Qt4-M<5f#k(Qa~P_4+>6Vp z$w(9e6>UfOKFS*Ufd&mpfQmb;?C>Q;Z6{M-(DySaP7K{N0v}~w;FSIc-OyQ!)2Fc) zVkSPPQF3kdWZk}*N(70q)VD22V{FtNDFu=M z36MZP0?P6$PIdq5c$YRXfH~ehkqN{4siAdS7@E@=`Y-B`bY!50@)TdPieqK)eVm4q z{ffJfkO z0_!FwtgS1?cJzsIootJ88ei5)R#!fPp!hy5>!&$C5lnKp4lzGTd)%~|Flb#b)P_fh zut#^FGEf_VqZ7Mai`#E~#omMlr<=5izUxH=k|Ho{?euD_s036`odjE$;r zu`mgc013<`pxid&o7K>q5zBJ{OT}263JP~WR3bCw@tz#>!l)woQ?QV!e9t@Q`xLgA z#w2GDTIB_ka#daAREh1t85+DH*Sd~ESjcZW(2`-hg)?E8+iJ`}o_fc|A zZWo1habb7A!_YOos=%QeG&_=FCk$FirZ7Cp4Q45-OB%6D5=-Aq z413!vFUnw;unrUu&P{5ts*V4Yx!g`3cY#`c0!z(@Xg8;Sca<0$nY)P$Z-pL#ufBbP>;kUl^tW+HpJnx`G-IPGTr5liBtQbw3Cvl3jqibRPWR=xn5ANDT)2BqE)2~* z^{*^FSG~@i^o*cP(!fD+Ox)crr@P;gG-_IA&dfpi)9i8$<(3wtb=Y2-qt$39T^i-m z_}X-pX}S3hX;t&Ls?lU&C62_!Az4MqjLD41aY2%zM)y;>;oW@^g0WHezN0`AAORBS zN8IoViH1h=P>e;4IJ$Ku3{5(@0FrYn zYE?}-w&;kYoSg5I+uuqG2{Nbo9YMR358?CXy6jV*`V@Mh@82}H5g2pRHfisi@CXAk z**XSrZNFo?6n&QyC|fBHkCZJ~gNC&h$@0o|52neIC21w*tGZc8s(Ko;rbMyEGH4~I zM&Fe)#zu`j#p)zL0wge=K<4%T%Y?+UdBeXUBmJuKmsH%oj}e9AGEls z_*vynhZ$1NSmc{!mRHRAN(e_{A-Te~4Yu5KH8FF=_c6yYir}en%J^$jtdlaTuz2+2$K{ z(&LLg4#oFrap>mw9Rcw9hq*Aq7SYbvKW7(-90osLJ*T1R9JwC4XMh( zr@M2)kzcrxkXw*|gyeEam4;P?liSA5Ktn*2Bh!u@*FEKPh}hMuvbwf#ZX_eWR+Lhn zv5^9Yr$~SVNMIWTlpDC=wpn6R?$$bCZGF&MbBWa`QyzvY0gBlH$^8`UjT<)t{c{~; z4$B}v=Xb<$VW7-m9p=JcAU!NYoVH4g?gojA5){{aXn2$xs9hotJja!jUp{DavGU~c zpbSgHMLsu|yI{w_%MGWh2O162O<4voNXu1WY?LFzd=el564(rZq06sHD|5HL32W=~ zjgB~ZD0cT^M=$65#3jp{p5u3v>och2x{r)@H%jR>3?x4u zFs+mzU|e{VbNQi67Zi$7g?p&VcnGF^7lm^|o_OMkc;dSpLu`~=Q|fS{ul-^budIX%ncLYrON zsTH_#{t)E1qhyID$)V!SiRVl1p-oo>1E8eQsxr#Ui@kPbyuERvFb+^Kj(&m0!&I&( zh8eBQ$UDFM9dwoSD! zx}`K*I;VqlT}LR8^E;+_h&EicwUm8=T2U*OSFFI;P+Y~y;Ze>>?=n-sU)e(~Z$kO3 z!-OjytjNXd=t|od%gyC-CX4MVD>UPvDFIopWkSYAi(StGBtQZrumJ)SmR|!abNeES z&lN~8A1cPSY>E`>qeNzYAzsn2*P|UtUrBz?JLmhf#4)*;3=Uc^zoW1hh8A1*k#Vn^Qi3jqxKx@MQI>Ol4oEN=~k@vdLXO7r-+Y!+|F@mU69k$ya)_+=M_A zWiAILTMpe|Oa8Y-tWsAAg?nvQF*Z{8^Arh?010e~K+;*pO{wELpfp!mm6pW@rE`AD zAY%h7lDB$f`o~cecdS?RmU98To2K|a<~T-)3w!w;0qRu_Cv@LvyOezn4Ac^b`qHIK zxp9u_9m6AKpmu3R2`pe>c}FOE$~B2{f#oH0lO6h-uXxH_?tRV^X0Jr?JA7Q2RQ2F8b3R?KZNH&Fl=owtU4>5KobX7AM0-t^TyG-3YMmfA@gc`N zr%FbGvJllW?{ZjrVTWnC-D@;mI0#Gl1Z76AoG~^EfcH2=K#p4$28I8_sK@Z}e-AzM zkWV9lf$vKqfvZT>RPLcNWsm>~8~_1aA9DA)j_ZIP1Z3u#gC@S%pu}Wj11lCIGey0Q zfn&}EcHhn#6vyP;L)@(bN(X%ibCSc`hn`!uF8L!^-kg$6BX3pS2Z8;Bg=t?{;=;}n&GA+71~T*|>>X zn06Ss7y{_4+%WWWt15vJhx;=mBhnh-_y{AIBmojQ00Ow$mLq-ucblbXq!SF)mcN9ndMPO6Iz_Zx427l8czVIki5i z;@;v^7yWZhbdj&jRxoiBw%m$2dudW1<=rpn-!d9=bGZw4n4m|cXkD7wF^v)KM|+Uy z;w>{as_!g}Q{0&mb?0tMK}U5w#Bj#t9HCOZ)~rDSBybD_a@UiN>wpqdE&}krxh&j0 zJ=s{PzY>|bFf`}uL1!taJ&ij~k^}rH2+#RGEozMRJKC9ak%0Sn5-c(|ev|FEY2-;N z{!AA?8W*S>ZLfnlkz7CU%^93!MPT>cBR#xmys#^C*-TqjR2CS(zh#9+wi2h6>vNZt zGsZ?S^Hk1?@sOY2L4t8os-u`k0!L0D=aP5vUt)I3t+iz}Gj1rElk?XG85`&jTyp)P z^H%&}kQkv`Zdn;!pmdPIC3FN7zhlt$WI%q-q2iN*>Kq*mt#scsayozpy#8P?`@{B8 zt!(Yo?&}25@O-J)Gnoj=7aqdoq%>p#6dt`Rl(Se&X$WnhyB8%W1(dnmh#ieWH)YH~ zc|=Z%ZjGmMz0(*?I;|KRsl9`q2j<-UIoC7u^D(zD1}C^GDlMKQ0TLKa09T~k6=p=+ zSU}G;*JXK5*LkwBfigLt1^Kwx=CBM}Doy$z*gsHwpO!c#XI&S+BjCK^VUj9rAJmCm zEFH0F<7WuAjZZ0=20OS^IWOFT- zphd%To;iALvF>64#zrYbZZR$gUiSRf(ijvI9F`O_=8*si%pjmV2-Lm~7#pAj0YldW zohIYfnqy1j93?VS*6tfUj#v$sliMFsg4dQfCg&A)@jG%h&d<+1GKxFsbB*p{UiqdExhvOATV%LeQKf(s7D zSfP77;+Ev6iE@4RWy}f2MlVN)*`_bb_zAc11V+uqpO}6*cpi}e2^0}foR>zoDA#=M zHdwf}{^c)!86|Chxw|?pztGAi6Sbar;)$HGGG7Tpl{M2ry#U3M9f8aor4~mk@!}wUAvZJg8Y`943J4mhT1x`;B0QdCxzPr7f%C; zlIBnb3ppii;R24y1(TE7%1nF`LaJd-=jL)PcBxxQx@4#zx(zzF{4jYvbc&%n%H;$l zKlQ0k0X1Wzv+?GhohuowB_m=xWiWR5teyFa!iprYO#-!lq#f??Wk8~`0)*bKi%B+X^w(w}Oliv4wsC?MF zaXiG;p?SxyROWKrbg!JpAAh{$nlO1t6j}$(PdGM0pDbQ!3PB!9G2B;6BKeXL%`zlF z0&5Xa+?I}aRBs*p>)a)-@KxIlZpjxq__;7N2L$<^+la*C&OxA9p_xfl15y64*IInC z(fOJ4-2hvsEP9bx0qsjqj|L3k5w1>t6pc>cn$vxi0^4a5E@fz<%WFn*FpQ=h$S)ro ztHf=Aw(%iuc_$eg;mS1sav0-ZD+fD?x^m?6T* zwb(1a(80&eqN+vQS#*-^XUiY&f#!u~Cbi1-8hp28`2)=aqN*-#FAT5-R*O!{h;@2}6_m*xcT# zv8VKYtP=c=D&exQ@+!ax_f0lEGp)Q?74z(pW9XFmn?}A1a&zCIDBmG)0!KUP(;S=b z&LlPrI7#$1O#$x zZG(LC+?S4Uc?=Xw9@a(}bFR824t`Z20<{Y_(vp>=aL3vPu(Wu*^pT%A#+!gnSMiJM#KdxvvvP|Ac^3RJya zSu)UAh6G4}1W14cNPq-LfCM&9;J9KVyfMSKi+V*`cp{O{*KK_IQautN0TLhq5+DH* zAc2kqjwm+5XBT>f1(f3mAkgFo8amE4iXs6LAOR8}0TLhq64)|0TLhq5+DH*AORBC z8iB)%jqvL`t3(EdM)5Axqi28kq5=MH-n@DH#lP#O5ku}qb&qRc*5h5*5krT`NKYE~y67BtQZrKmsH{0wh2JByey9wjCQ`H)8%?2wFsh zad1896~?oF_+G=HkWmqfm$AGKOppKxkN^pg011!)36Q|S5!iNYG(Rvp=%`4JK14|K zzjw~?NOl3!BtQZrKmsH{0wh2Jhecq+vC-t8J;h$jHovyeGNAB8B0eOcZ1!|Nb@}q; z7KK@t1W14cNPq-LfCNZ@1lA(3)z}Cwc6YZuClJxY@kK>)Kp{e!8ED?PaYMGwGzpLZ z36KB@kN^pg00|rfflbCnaISN4O!xfL`FWmcKM;i{A^F+5gP8qPk_1SA1W14cNPq-L zKoZzqY&7lr3vl7Fp(0@%efsLvtKEakq(HuSbo67129f{?kN^pg011%5@e$ZwY&7TT zFZ^)PY3^-cPj1c^F0f5?eA9&%kpKyh011!)36KB@95I27#YS_U`#SMm4FrV<4U_vl zeKSwzdBr2XLeMl4AOR8}0TLhq5;z?KTZ)b5yk^Ax3^%&x?9ZL%=G^IAKWHflkN^pg z011!)2^807C2Ft?36KB@kN^pg011!)39L(C8?n*QcVABY%L^srYxH;1 z@k_oXYOo9mkN^pg011!)36KB@tVm!3vC+^U-Cf(F z#g8)BdW5w|fCNZ@1W14cNPq<95Lh)f8u#69KEc&8e8xTH$nSZ#^b6~f011!)36KB@ zkN^n`C9qy>G;Y&~-(P4PGUL9>fT*icH&!PB5+DH*AOR8}0TLjAK?K%|jRtKR;lV9L zU4v+yj##`KBp*=hnC8~e>5L*;N&+N60wh2JBtQa(MPQ}aXxyd|_B;-&2R5rMzGTrc zB=VxTb+p+Yr(z^P0wh2JBtQZraN-13ij4+s8u7z)eTVa)&(?A4sBbq>8VQg936KB@ zkN^pgKoCPgZhhNNq_`MfCNZ@1W14c%mmhmjksxK z?yglTj@UYa%vEe*qa;8ABtQZrKmsH{0wjUvdWv7LoY@y_iv&o31W14c z4wS&$*l5J3ySZsJVd$Ms$H9Y!XN>^p(MKPxjoMKKK_onJxaWrwEx}%>UG+C%yp=Zr z)Bq0s3p)#!3lv6`XP$Wmb;}#7EjbfxRrf6xc4HWb+#e|Uzm1IQMH6Ng*jmh8Yr9$h z3l}a_we{sMf4O!N*~()%q);)l?KZ_&iv&pEPzcP8jo^wb%#_M(y>%Yh6Y=3~A>=E~+=Pz)Tn3W*0o}?w1a| zv${mFGr{WS%se}1i*%+%i*0Sqzg|>0C}7rqYq62xl5V!$b}3^m5+H#?AuusEs$J6w zF5&Uvv}MXe>C6dwB9w_cq9q4!drVMUHZj@Jj^W@*r0u)|Jky1jy-<=K@e)|v9myQ@ zQHh31nVDddCajnVdP83WUD33->8<(Kv4(n%S^rJNMi_FsnaQ(e+m(sWQzSqFM?hd! zY-I2hk{2_d2@m%O@E@WHhUGcmYsthk2!@9)k_xwHVx3?k;gMltPV28)=c~P6q=d%s zXeL;x_IA>EW_8d|*^Z6SWNZF)EgZA{wbK(%T@D%#mo8nZwc3?8+djw;iX{OO*a(4H zu~GL|RW{;UZloJ$s?mMxXwJLb+X;-^ZFwW%(M%V=8Mu*5I5AE*gdDLOy{k33A63CYXWPL00|rlfmyLpa7}7F zoZw9#N(Zi@r|seHT&E9OT=rxT%)vp+wZ3lt>fzB$7vA?sVWQUg8q}4xS7&B|9b|Y% zu}?kqRAHx=6ziy1yQr=C*R>Xz^{<_t-D9Kn6)&^xC8LyONPq+mm%x2&vfBy$8EXug3ny(UbM00|r=fhn<3a6xK39Jj}Cls!DisJ?rF2H&&9F5Hb92b-%7_1snj#vX2` z_`^m52*5k&6??4}@xzu{L?z_Alv#AX@FT5;tAWk2s&#>9f*sw1upI-wOOVuMrjNF_ z%jjK8NG%);RGX@c(=*VdS8UYlst)zcw%drY7738Rp%54!8^L)Au8}Q=a77OV?Q!dg z$75RhF|OMk7aY3Azy+>%;Zs1kT{pG`Al*ObRf2S;3tys-ETcGI=$aN>hVZENvAUUH zHN^WfQX0=CDKWN*rJ_uCYPij-fKMxcXdw8~MSB;3Z97NOoM zV|%6xU&RxJlg?LTROEH28V@LpjYD6zBry|gtt}<`D`nb;IwUCa7f(&LcTt~B6{v+{ zzVIfer_y?RY=o7n_9ZB(q1pCL^*EIw0TSp=V0>%@pF&=Z8q>8NYj%`{O$#2y70Bi2hJB_aogv#lkL_%AqHiVa&nn7!PZ_> zb2?Y$w>YYe%K)p`TLovu!nJVB@j);>7u#)*jm($yoNi{@SL|OlO#&n^fx!6KsP+n) zyNtQ~2}syPA%VV6OZNR7gZYuaF5WkyD}5N}&d$GA&vfAn$CWQ8FCFcUl^5$0wUK@8 zi!w98=7v))KR{tVYzdEAwvKXk8M5hI+HCtF z4h-r{0whpQV0>(pyDS;#m;M9~{q6*9Kfx0<^qP&&HH*93T z_x%Y}!y;o}1;EhoK2~=f7Q1q$3%{sLP~h>$AMdh_7l?I-a_kkRlX7yIGr<<>?~CPh zw&k1mXw4z7H>5COv+F=>6*BR~%<;jr*vPyM?`_N_%(frs*r3`ZKmvsX2FFGQ2O)PE zLq4x$g}pkhm~DF|*TucmwngME-#tre4uLsKm3*_qnABl0(=bC9Wp2NK&D*N7YbID_ zI3-V28B$W%b{#NpBqWVeGD}Q2nlcK9;2Rb&WHVKeGA%VfM zQSIe3c>(j8g*LI+Gy;9s^?HQ`hKPI|F+X|>6TKi5S~SyzFH~tzF+;>GyR7!x0W-l$ zJxkJq2pc?E+j2;Wjk3%jd$%c88eWp#Y;0s+#wfAcl`-4C&90|bBtQba2pmpqRJ(55 zixB1L1j=tjizRE_&zxel5qa(7Qn_}M`L)XQf{;`u&YbDO$E{Duf%o0ziy^fif|&_+ zab^Vt24Od>N!UKj7?`toILO{@ie01;6fnmJwO6*PRUgCC$bnrYhi2Qi+4a(#}zH|?R}NbPn-F9?ObJky0QRH;ibJdgvw+wc-h zZlKm`H4|)3=UjfRErsR5JlA3_-?l7~la|Xb)c-h&bDwatSsJ%lfcj;cSk1Hj}kSUnS8Ovmzx!8cD1i6GPP zefODQ18o-%$90zBYGC*b%A$cmfpPY3P;y}V;-UHKSKHSmcW~S99>7Moda-D1P{3^a z2K${VkpKyFByc#f5k3dr(Qbs;!LSYGCkBOKhA_#-O>4YE`XT!_8K7kBtx|+txNv%ORR( zdsUCHFbR;r!4Wu|*vNbdxAn>0@7=XkJhfW2&x|RzuU=awN)yRbL%R&)Hrc3>IaHrO z_{P->v<(hNM@8r(^O&3oRvAmlQvt?~hlZ_*b)jkXD zEJa}Cw;re2o`cVP5+H%&ATTmEGI$5dwat79w{_GzuDtup&;7Qo?n%`$ctc7rcR{Df zPoC=1XikV>7UV>Y$lthnIg=+uMQ*5|p_~qS{!FmRQLSX^nzx)a{Oq#ffdIv{nWrY- zk_!8!mVnuczOj*c>lg1Qc{0;%_boC(0wi#h1P&)QnvDOxkG_8QkMCo6w20mIn~%Ah z*kW@f1#-f3`6V*VWoG)w1|>JHUeY2w733p!PZ)xq}nCZV0FoBD1mOZ z_6{l!V*|yua9C@s*@}*_k@>@PSFc``%%|Bd8)cdVNZ|MgFg8l{>8=wnl)lQL0BC{EfHC*ofg#3exxU3_hT82U8j~SU2 z93QmDM)(M%qFC;f{4ia>Cs!qxZ?-*Xmxm-k0!K#RaAKorm$Bz=Kc9?^xOCl8>1498m6YO>dJQ&t0W4N%_HZiEY zL33rm^g2~*tl5gj*vR(9Zdm8P*c}s_W_#Q;b4Y*$j)}m?*a$1Iwbv@8y!jGd+g+Ew z@`+q*#PBGFY4C<}y$t^}mT$<($8)@k0+ig#RLK=ILcJK>{SOI)Ra~5sa(7Rw?E2%NcWMz2%b+DzOp6qo5bAT)Cq3 zTGc7sYy;u8!>UG6*w#v6E!-+MrB9&t#?>48G~J-6$Pu0ib~^*C)?bF^$~HhSR{deE zy@Sec(+jRO)@(&>Un6dCJ!oD|^Ah|>2olq5$JhP!eJ`BFIzgZw4@rOo4u!zs#72wP z#a_tuz{s8DyGNdO?Hy9NeK9t2a6H=yiJ30E!5oAy%78JS!ix^0uO~CX)^ad(L}3*} ze-%oW#cJ&xRNfp_NL#w6YmGHqQG4ZgGY%U+wHmte@fW*ebhVNVw&QD=<*!Mhr1{6A zW9yhh0wgev0Ar(+Y!~thv;AkepNux3Ufgk3lj{_jw!y~|4?6~p*Sku>gr|@ifi>_p$SX;4~KC(f>&8lZmEZOh)jY#+@1~QFR z4Emc}Od76anj6w90=3d;@|0~4FDXjN)YU$+vkHggDGXE_f!f$8+4^E8B8>8=Vo_R9 zpxkyD7-5_juCmDQ$k?_>ZC%4!BtQa<1O~@O9WS5di$`W8ckbS)3XELg6My$8xZAWG z_Id@RRtNKdDXBQqM=sGPD6?7h8o%)YmkJUJU6_DLm&2K0w=m%0z}BjP@;2194cS^b z&|0-{%Hx9oNXMJIqI1;`F)MPCrwVPyjmcNnw~GQqIFw(L;lp(?ALfw2HVF)ljj$8o zFDmVc(Fn_5HVQ(hlMRmy4xlm&48H=I91={fphP+Olp*y2N%F z^t<3jhDxyxaw53ZK3SfhW{8O~hXgiAU~p_CuL>pCD!t5Te($*Q?jYzXKRnIw$lw4f zU0iafDj5Sx6UkF0GRbU}Z`LiC&x+x^pY{>c^T)dUL2-*oil zQ6?4=ROBHEkie!0433TPIJtgtsybV8C2OI3-$!3x9t_1LPcS@!cT?4adf{GAKDI+(yW6{EfwB2|j`^-S zG&Ztr{pyy+XBTakH#ooLqr^sX(@4JNC^w(XO9ERSb<~Xnj*P(I*vQ}@#1}B1vv?(I z>73hlZpYzHZO*BMNAfP=yUCnr={{MvRsmVJd)hDsy6d0_+^l-Forv-njf$m{Pt62d z%c?Jm_`}8}`m}UbiF{e6ue}?WCJir1oA0XQVk7fs3rg&jWfpDsF9pb0P2Tn7V350~ zu?hYKN^q04m?i-d*dT$yu@Nkmm!ihB?Srp{)IaylFVsdt$?_)^9{EQF8haMiJKiyB zl_?w{wqi4VWP^sARj;-aH??Vmj+hCymX%?gIrVWaX zFgDB&5OlZQZ-~lGpj>R^3qy_g+j{YnTf>C?v3d%!NN7DmQ zEiW4dLDGqYNAlU~pr;Iny*}WLZmn%S7zuq3{VlOvtG){8(l)DJ?RDdcC!WwPHJpV* zgkfoO9%q6rA6l-Y0Y$P3-Uz8}+LdqFG=e6zjV6^p*34Qsw&4wWBVr@O4RKUa-c#Le z_X4F>$=FDKt~)opy)<+1SB`=uNq_`e2#k-7`d&fhC91{lxNZ>NG#;KpcqE_2_E&v# zB6mNDdulPKR)HEhA^K zuDrpPD1$PKGCLO7ta^sg6Jf)L@gZK@CM25u~F?$2gSYF*LJ`72TNsJGByfYeEjjpmE~K1O>3V5QXi&C zfCRb|7#|z?3ruhou^q;*ICequCyW`$b%uJrrZTB%y@Vu_iPs&6lyp-fG3HXW#l49kVLjokQ z9RlNHBlsP;ONcFh#Iw3@`Q(G`kx){?v4%%jVYhW(vKHLZj&mZ}gp%2@=~&cEA31J) zF=w;tVVWylmOF)kRK6w)+Yx~+J{zVxP&vXg!RBb>@^d-|`7i;0K;+lEa{>$Vd%ZAP z*qkpG*mc~8-s-{xy4VJ!V{FuG$+OU8Ure{%-{S)He24=%Nc%rb6aUm)@{Z<-VNThY zvla=Ez#IbOV>q;`L>6Lku;ZZMl$#s3-b+oGCgu+9o8g9RX^f5@T z)nr`x66T9hi=rO(fxt)p!P9{kgOTPv6s5X61tBHc24zr73Mokk63P!tgm0mYZC5Ym zumxM34j56fdh6!Y!m$l+*jPJ{a*73!M+?1N6S;idcDbx8wL+(RfifRy`GbzQ-~?yA zBc!(*)Z!rtkidKbQ(~jOessr6spI|J?dN-iL4h1>N8xEbyv#JeV@J2>FZ2E`(URyJ z@78KEl+`#N*&w-=%((I;%rPp)DNrui=ExX&r-VteOt~#9mTY{@UK+ll6+zRCjRGLG zhq#aQikLA%YFl5N+Fqb6sl-N7hhV`k7ir0X%`^#+z(xp6iH*AZIDO$=`pPGQn5N|r z@el+e-s-F5rliT$F@N`HNp!qD0#vOgL)nh=kqwe-$&4#s$lO1pGES34$ILvKNP*5RhpU_86<}=SQP>jg-%pVPsaA)@sqOd1WJfEpk$(&ingk1e z{#5tHT}gmx5+H#t1g6ABa>bXj@X?^d_KXn)!0jURi{FMaWszxw>w?%ci8qRFAu zZTwJG(5F~B>}z-+fAO$y>w&a!KC(gbB8q7R0!q0<`BU@LbPF0v17kfJKkc2Gn0RC2B zPIT-|r(~@r(zNdBaXzv^axIy0<;ywu4a5x=Ejmz1TMWIElv9#vFltT}T=x5J2|F5d zlrL!oesM_$%`8)*wk%^C-ms`KHtM^TXd4)dw##K*uP{1Y0!*fZ07zEpyHz%GXt6C4 zI2{7BVx#U3POmOPa8nf*iZ?Dbe3o`qYC zjUN1sw;k&z6$~S>dzjmOWw~}Z86cEb8RsJ#B-fG|SH2veE4gBLRN_Fz<`{Y>7E+iq zuA6LeJkJ1)p*d$NMy4};b zg(e$SG7EJuNLCu1e5%k!SV@}8)auZy-K3mxKC(e_EtzrUldKjqv0Dt^YMfS5 zGMpMb?TN*JMXizr484<-Q<5pwUMoE(DsnW|vN3MA{T@`(zg1;oCH0)b_#oE7uy2Gx zlG|K~>qGV8IgF{78o~KCQ#0gA{jk-TphYM|E@8Qj%Q~ShR z3$YO&4Kw?miXrkQR+3gkwVxX2BO4@_(3n%E1#IAS^i{YqB=U9{ddJtTP4p#DB@Gv0 zd`qSKD}y?LDh-Dg-k`%9)bGRGwd6h<0;ow7H$4K4KJ7y-0wi~L$FUGZZ=pKMV!=Uh>DvdWF z#YXd~T1zodZEe-YM%};I9jiUT_T=lfh=f2x#zS5cJZTZ@$s7_OfsGTG8ymp^@z;zl z2?Sdk2YfW@jo36AwA@@fw1)Q4I3L*{xt7eh^1YZNputrIj)`I21-0-8_txwlDpnYJ zN0FwV8rMyb>?i>;K;aL-N8r*849*U!rqW_#SgRWpLz-tXRx8>$qVRPnIswx&LE&E|Il*sGpHA;hvo!f6wdZe3;NhHU`m-StAOR8} z0TLhq5+DH*SR^n#Hp1G9&6U<`ami+}tIY)v#OUx1XR+I7)`t~IfCNZ@1W14cNPq-L zU<85bu@Q_I@#e~$S3O7c!1iT!e+&|_6yFlte!o*g5+DH*AOR8}0TMVh0&B!ZBffYB zcbh*tJ!0@8h%synEmj$!DrJ%Y36KB@kN^pg011#l3xPFaBk0@lhe^B}4w)?^ST`ns zClyC*8u9(G7&UW9fCNZ@1W14cNPq-ZC$Lg%G~yK&1WA0duJ3>v5g4JH_+7!i-9%|5 zKmsH{0wh2JBtQaP2&@zvLH7}#K7-$V`SRs1U?^n7-X1!Ln?@X3BtQZrKmsH{0wh2J z+a$1FY&2-=2;TR#YuC03`+&5%bmmVRMf5+DH*AOR8}0TLjAp#)ZqjmB*q@#k~Qqh`=o z1YNMjnAO}btVjYRKmsH{0wh2JBrux5s<9D_8@F}D&(;~n&Y%y|xxnbcg$o9iScL>g zfCNZ@1W14cNPq<95Li1lx^d&ipvSi$7B9`rp?EZ{4Ep{8`T{$7eADP?#t97}0TLhq z5+DH*Ac3PKuy$+&sQB>qxbO(C&KzaGjW7!PI^#M5zacw9XUZf25+DH*AOR8}0TLjA zUIaD}8(}+PoJ$VL*qZ7^>xkvx+vnqY0Z&dIF*=$?0wh2JBtQZrKmsIi90WEH8v!IX z6~;N{c$$l!0MJJ(zIr~6KP2P(4!Qz7O9CW70wh2JBtQZrKmw~1*hXvw4C6k^;JkkR z=uvL0jr%DhN1mTx$dPA036KB@kN^pg011%5rU+~%HX8crXy>H!(+u&@8~5=A$DE&F zh?z5o1W14cNPq-LfCNZjn*=r!8v)PIZvi-0ogeo0!*J;5x*cu&m!Dwpz?mQc5+DH* zAOR8}0TS3afi1;G_$ULm8N6FPD8bi{FeLGW;RMu-L^nSBsU8WC011!)36KB@kboqx zrPv614gI+zA8a8kIOW%mhJKPxLgo(|$*IOP36KB@kN^pg011%5#tCdJHUh0Vo;zH4 zG_>)~8KK_LUz75I5fc1#`iSnMOcEdg5+DH*AOR8}fpG-37aPIW(H{u#E<6H-acH+D z87~-31ACfr=hk|h`j7w#kN^pg011!)2~-i-WNb9&#UmFXAzV0xU*Ewl&V(0?JkqK$ z$igH*0wh2JBtQZrKmsJN1p=FljR0oOi${I~>EgwU$NF*%BEMN8k`*qnV$r3tWB| zA#MLdc2}=nT`MXAA_TAFMkpnd011!)36KB@kN^pgz#IaH5F3F6J}a=I?+^DMt>X=z zn>TOH>6XG)u&s6e{P}gsFfc0YEEXdH5+DH*AOR8}0TS3afdh$+Kymf($ZaVh5J5Py z;X%H~s>ATx!e@Z{Q0@#8=dA!wxx|`Y`lBT&d10$t3d5Q!`fCNZ@1W14cNZ>#T z9AIn&(s+z*zZC zpHbo=86F{W>I(xOuRG9B8*DsOdhD^s`t}s1kpKyh011!)36KB@kia$xw8cg)9(wRM z-X`Ook~B7!M(}_mzwuDxu+-xVMk7WkWs(31kN^pg011!)32c)vj-8FL(jR`@tNenDzzA5l07kN^pg011!)36KB@Y>hxZHVQtu z?IWA^1YS#;fPtU)w#8w5j&8!>WD_Jn0wh2JBtQZrKmr>i5XDA#6UhGrQF|Dalz_LC z=8(WsVf;Wtd4z|BIqr-*dHQz{_#CXW}2ooeg0wh2JBtQZr zKmsJti@;KBgm$`wM{oJ$gS}MVh#VIu;qwiTKKkhBEhPj)=g*%kNPq-LfCNZ@ z1W14cPJ}>xYy>d1;nD3oe5K|@#uLpX0TLhq5+DH*AOR8}fkP!=ij81wd3bc+M_+%a zaHuy4kN^pg011!)36KB@kif|hu*OCJR2Uw;fCNZ@1W14cNPq-LfCNsAK#$l6$a3M) zFMaWsPYfu{B>@s30TLhq5+DH*AOR9MNCKT=BiNn{kG}f+*A5a3l_miaAOR8}0TLhq z5+DH*I57hKVk3Zy!=n?UNpnen1W14cNPq-LfCNZ@1P+xz*VqUUWO($JPd<34Sg1D% zkN^pg011!)36KB@kidx%=p7pYpAU~NedQA;Mw8}}011!)36KB@kN^pg00|r_fdR1* zP`L2ux!cblDi-QZ0wh2JBtQZrKmsH{0wi!^1jfWhfQSd`_{&BoHkfEG36KB@kN^pg z011!)2^=tiUG#U){kz>ge+vKh|NH%a=k9;??)RYNA3pc@|LD2hAHDzH-8uZBxgS3FXYPNgoILYK&i&co%vt>(Lfu#X2x{(jKX~@v`|#iIeQ&pW z?QZv1fA-x!|99Sb|Ia-9-v8o#KljdezJGV_+>h+ey?S5rzyGz@?f&?s*X{l%{QEQi z^XqmO@b5qRUtYKSAMx);|HbQeuY2VmIFt6`fBuKRyZePd|Fu8&U*G$RAGr6=zVel4 z*-w7x+^Zq%>~G)dD_(sM{(BA$oO{h~ci-+`qK$K}`I)ox&}R4HH^6ih_~4)1efD?n z?!o_|&OZP5?C#y?fA~-AegOab+1En9eG7Yg_Do(Zw=eX&@bAOFceii$o>#x>%nT%9 z6dK(p&}^*8e-0zhz2I#67zY|LE@DLF&ruApP9#**Bltz4n0*{ScCW?16J1 ze&Y`M?>_Y7yWQXZ13&TUA4ie1^sNW}^*;UDH@x-@IR3y-efxnA{U^HzUirIzVz0^X zM;rUUy(W8w)0%w#Op~{soqti2|6upKas03U;F%_`*gf`#VEkT({jj;RZ*bql?r-0E z;ISXyef<^R*Tie}3!nK{&|>%YSD$I|PlXnHv}rB=8an&jYfuY+XIlK=4(;v9owc_Y zmT&L>*thqIt)7p?ve&szTMABKIu7bkun{(boM zyS=o%?HJYHw;c`b{;%76+yAQ{_`dB(zxE9u{PD9+`Gx29ov{1suQ*fZSA;tIp_EqV ztr+9yUh@~u&VOH>5B{m$r~e34`QZI$&HuYN=TJa!5(RYl>Cd3$4}9YG1N-j(5y;&C z?LoNNks65q`&r9>`K)Bn@`vx={d@cRF#h-Bf6rRq3s1Jb2l1Cax9^A#{G+>P?f(-{r>L*7!Hr!>&C?2 zzxS29x83uFSDf2@=-&N=-d_UG?f${N_w3%W`-eEU!~dfDalG68!o5F&|L)SF`U>>?tP8FiGTZv@B#eW zEAxx^w;vfF$G?5U{|f*1D*bQxx4*XhHva7=|2Oe(KP_+J-+pY~3z>Vv{sjK_hw;Dr zKKlOU^{@QhpMC%P-}~@SzxUz$|JJ+y&O6=ty>9!zec9LJ-(P+BZ@vHT{p@?+dH;X< z@VkHh;rG1rJ@0?t{r}m!{>yj0?_CeS=f!eobzb{}XLZifKXv{U`}%vm-uZLydhh$+ z`JVUfe%j^jZTi#y@$MB5;D3Mq&HwP9J^#R`&+XH@4?gts5C6)i&+Y5&d+__p-G8Rt z!|%QSXWsRmcRc*}-gp0>!@0eTgZOhJYOkuB)K2OBNI54)%Ko0P@3Q#szd0LOzlc6O t_uuY2@`D%&KYH(e0-ig&Rqk&Ad&&1;bl%#JhJE^MSnPK1`uOX1|38S?d9nZi literal 0 HcmV?d00001 diff --git a/src/testcases/org/apache/poi/poifs/data/ShortLastBlock.wps b/src/testcases/org/apache/poi/poifs/data/ShortLastBlock.wps new file mode 100644 index 0000000000000000000000000000000000000000..1b1a627a998094870e92231ca6b0bf94f56e2a65 GIT binary patch literal 140787 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� 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 Y@2o|Cn|VMrt-0x_Z}$U3Dp76!2TTB+H~;_u literal 0 HcmV?d00001 diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java index d792dcf2275..1cde86918b9 100755 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSFileSystem.java @@ -17,6 +17,9 @@ Licensed to the Apache Software Foundation (ASF) under one or more package org.apache.poi.poifs.filesystem; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; @@ -115,6 +118,40 @@ public void testAlwaysClose() { assertTrue("input stream was not closed", testIS.isClosed()); // but still should close } + + /** + * Test for bug # 48898 - problem opening an OLE2 + * file where the last block is short (i.e. not a full + * multiple of 512 bytes) + * + * As yet, this problem remains. One school of thought is + * not not issue an EOF when we discover the last block + * is short, but this seems a bit wrong. + * The other is to fix the handling of the last block in + * POIFS, since it seems to be slight wrong + */ + public void DISABLEDtestShortLastBlock() throws Exception { + String[] files = new String[] { + "ShortLastBlock.qwp", "ShortLastBlock.wps" + }; + String pdirname = System.getProperty("POIFS.testdata.path"); + + for(int i=0; i