summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
author(no author) <(no author)@unknown>2002-06-15 03:21:07 +0000
committer(no author) <(no author)@unknown>2002-06-15 03:21:07 +0000
commit02031ec26e8757f6daa140677f03f924b6fee952 (patch)
treeecf8954959b72ce95a5886054aeae2dacf501646 /src
parent899521e1d61088cd280a0be0167f6c7cb5f2178a (diff)
downloadpoi-02031ec26e8757f6daa140677f03f924b6fee952.tar.gz
poi-02031ec26e8757f6daa140677f03f924b6fee952.zip
This commit was manufactured by cvs2svn to create tag 'REL_1_5_1'.
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/tags/REL_1_5_1@352699 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/documentation/images/logoRaPiGmbH1.pngbin0 -> 5976 bytes
-rw-r--r--src/documentation/images/logoRaPiGmbH2.pngbin0 -> 6001 bytes
-rw-r--r--src/documentation/images/logoRaPiGmbH3.pngbin0 -> 3594 bytes
-rw-r--r--src/documentation/images/logoRaPiGmbH4.pngbin0 -> 2658 bytes
-rw-r--r--src/documentation/images/logoRaPiGmbH5.pngbin0 -> 7423 bytes
-rw-r--r--src/documentation/images/logoRaPiGmbH6.pngbin0 -> 6640 bytes
-rw-r--r--src/documentation/images/logoRaPiGmbH7.pngbin0 -> 9630 bytes
-rw-r--r--src/documentation/xdocs/book.xml1
-rw-r--r--src/documentation/xdocs/branching.xml97
-rw-r--r--src/documentation/xdocs/changes.xml6
-rwxr-xr-xsrc/documentation/xdocs/historyandfuture.xml2
-rw-r--r--src/documentation/xdocs/hssf/how-to.xml49
-rw-r--r--src/documentation/xdocs/hssf/quick-guide.xml30
-rw-r--r--src/documentation/xdocs/news/logocontest.xml177
-rw-r--r--src/examples/src/org/apache/poi/hssf/usermodel/examples/NewLinesInCells.java100
-rw-r--r--src/java/org/apache/poi/hssf/dev/BiffViewer.java8
-rw-r--r--src/java/org/apache/poi/hssf/model/Workbook.java17
-rw-r--r--src/java/org/apache/poi/hssf/record/ContinueRecord.java7
-rw-r--r--src/java/org/apache/poi/hssf/record/RecordProcessor.java202
-rw-r--r--src/java/org/apache/poi/hssf/record/RowRecord.java4
-rw-r--r--src/java/org/apache/poi/hssf/record/SSTDeserializer.java562
-rw-r--r--src/java/org/apache/poi/hssf/record/SSTRecord.java901
-rw-r--r--src/java/org/apache/poi/hssf/record/SSTSerializer.java356
-rw-r--r--src/java/org/apache/poi/hssf/record/UnicodeString.java67
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFRow.java28
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java159
-rw-r--r--src/java/org/apache/poi/util/HexDump.java40
-rw-r--r--src/java/org/apache/poi/util/HexRead.java116
-rw-r--r--src/java/org/apache/poi/util/LittleEndian.java29
-rw-r--r--src/java/org/apache/poi/util/POILogFactory.java31
-rw-r--r--src/java/org/apache/poi/util/POILogger.java127
-rwxr-xr-xsrc/testcases/org/apache/poi/hssf/data/BigSSTRecord1032
-rw-r--r--src/testcases/org/apache/poi/hssf/data/duprich1.xlsbin0 -> 21504 bytes
-rw-r--r--src/testcases/org/apache/poi/hssf/data/duprich2.xlsbin0 -> 13824 bytes
-rw-r--r--src/testcases/org/apache/poi/hssf/data/evencontinuation.txt16
-rw-r--r--src/testcases/org/apache/poi/hssf/data/richtextdata.txt21
-rw-r--r--src/testcases/org/apache/poi/hssf/data/stringacross2continuations.txt7
-rw-r--r--src/testcases/org/apache/poi/hssf/data/stringacross2continuationsCR1.txt9
-rw-r--r--src/testcases/org/apache/poi/hssf/data/stringacross2continuationsCR2.txt7
-rw-r--r--src/testcases/org/apache/poi/hssf/record/TestSSTRecord.java646
-rw-r--r--src/testcases/org/apache/poi/hssf/usermodel/TestHSSFRow.java39
-rw-r--r--src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java10
-rw-r--r--src/testcases/org/apache/poi/util/TestLittleEndian.java6
-rw-r--r--src/testcases/org/apache/poi/util/TestPOILogFactory.java47
-rw-r--r--src/testcases/org/apache/poi/util/TestPOILogger.java51
45 files changed, 2924 insertions, 2083 deletions
diff --git a/src/documentation/images/logoRaPiGmbH1.png b/src/documentation/images/logoRaPiGmbH1.png
new file mode 100644
index 0000000000..3bef8bb6e9
--- /dev/null
+++ b/src/documentation/images/logoRaPiGmbH1.png
Binary files differ
diff --git a/src/documentation/images/logoRaPiGmbH2.png b/src/documentation/images/logoRaPiGmbH2.png
new file mode 100644
index 0000000000..d842217557
--- /dev/null
+++ b/src/documentation/images/logoRaPiGmbH2.png
Binary files differ
diff --git a/src/documentation/images/logoRaPiGmbH3.png b/src/documentation/images/logoRaPiGmbH3.png
new file mode 100644
index 0000000000..0419155689
--- /dev/null
+++ b/src/documentation/images/logoRaPiGmbH3.png
Binary files differ
diff --git a/src/documentation/images/logoRaPiGmbH4.png b/src/documentation/images/logoRaPiGmbH4.png
new file mode 100644
index 0000000000..3b8d44d6e4
--- /dev/null
+++ b/src/documentation/images/logoRaPiGmbH4.png
Binary files differ
diff --git a/src/documentation/images/logoRaPiGmbH5.png b/src/documentation/images/logoRaPiGmbH5.png
new file mode 100644
index 0000000000..f96ef9ef91
--- /dev/null
+++ b/src/documentation/images/logoRaPiGmbH5.png
Binary files differ
diff --git a/src/documentation/images/logoRaPiGmbH6.png b/src/documentation/images/logoRaPiGmbH6.png
new file mode 100644
index 0000000000..53ee5e9eab
--- /dev/null
+++ b/src/documentation/images/logoRaPiGmbH6.png
Binary files differ
diff --git a/src/documentation/images/logoRaPiGmbH7.png b/src/documentation/images/logoRaPiGmbH7.png
new file mode 100644
index 0000000000..498499d9df
--- /dev/null
+++ b/src/documentation/images/logoRaPiGmbH7.png
Binary files differ
diff --git a/src/documentation/xdocs/book.xml b/src/documentation/xdocs/book.xml
index e5ab10098e..1d4b945e38 100644
--- a/src/documentation/xdocs/book.xml
+++ b/src/documentation/xdocs/book.xml
@@ -39,6 +39,7 @@
<menu label="Get Involved">
<menu-item label="Contributing" href="contrib.html"/>
+ <menu-item label="Branching" href="branching.html"/>
<menu-item label="Bug Database" href="http://nagoya.apache.org/bugzilla/buglist.cgi?product=POI"/>
<menu-item label="CVS" href="http://jakarta.apache.org/site/cvsindex.html"/>
<menu-item label="Mail Lists" href="http://jakarta.apache.org/site/mail.html"/>
diff --git a/src/documentation/xdocs/branching.xml b/src/documentation/xdocs/branching.xml
new file mode 100644
index 0000000000..4246d83443
--- /dev/null
+++ b/src/documentation/xdocs/branching.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "./dtd/document-v11.dtd">
+
+<document>
+
+ <header>
+ <title>Branching</title>
+ <authors>
+ <person id="GJS" name="Glen Stampoultzis" email="glens@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section title="Branching Conventions">
+ <p>
+ Branches are tagged in the following way:
+ </p>
+ <ul>
+ <li>REL_1_5_BRANCH</li>
+ <li>REL_2_0_BRANCH</li>
+ </ul>
+ <p>
+ Merge points should be tagged as follows:
+ </p>
+ <ul>
+ <li>REL_1_5_BRANCH_MERGE1</li>
+ <li>REL_1_5_BRANCH_MERGE2</li>
+ <li>etc...</li>
+ </ul>
+ <p>
+ Releases should be tagged as:
+ </p>
+ <ul>
+ <li>REL_1_5</li>
+ <li>REL_1_5_1</li>
+ <li>REL_1_5_2</li>
+ <li>etc...</li>
+ </ul>
+
+ </section>
+ <section title="Branching Advise">
+ <p>
+ Don't forget which branch you are currently on. This is critically
+ important. Committing stuff to the wrong branch causes all sorts of
+ headaches. Best to name your checkout after the branch you are on.
+ </p>
+ </section>
+ <section title="Who Manages Branching?">
+ <p>
+ All branching is currently managed by Glen Stampoultzis. If you wish
+ to create your own branch please let him know. Merging is also
+ handled by Glen. Just pop him a mail if you feel it's necessary to
+ create a branch or perform a merge.
+ </p>
+ <p>
+ The reason to go through a single point for branching is that it can be
+ an easy thing to get wrong. Having a single person managing branches
+ means there is less chance of getting getting our wires crossed with this
+ difficult area of CVS.
+ </p>
+ </section>
+ <section title="Currently Active Branches">
+ <p>
+ The following branches are currently active:
+ </p>
+ <table>
+ <tr>
+ <th>
+ <b>Branch</b>
+ </th>
+ <th>
+ <b>Description</b>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ HEAD
+ </td>
+ <td>
+ This is the trunk and is always active. Currently it is being used to continue development
+ of the 2.0 release.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ REL_1_5_BRANCH
+ </td>
+ <td>
+ All bug fixes not specifically relevant to the 2.0 work should be placed in this branch.
+ From here they will merged back to the trunk and the merge point marked.
+ </td>
+ </tr>
+ </table>
+ </section>
+ </body>
+
+</document> \ No newline at end of file
diff --git a/src/documentation/xdocs/changes.xml b/src/documentation/xdocs/changes.xml
index 36223b2ff6..9540dcfd76 100644
--- a/src/documentation/xdocs/changes.xml
+++ b/src/documentation/xdocs/changes.xml
@@ -11,7 +11,11 @@
<person id="NKB" name="Nicola Ken Barozzi" email="barozzi@nicolaken.com"/>
<person id="POI-DEVELOPERS" name="Poi Developers" email="poi-dev@jakarta.apache.org"/>
</devs>
- <release version="1.5" date="Coming Soon">
+ <release version="1.5.1" date="16 June 2002">
+ <action dev="GJS" type="update">Removed depedency on commons logging. Now define poi.logging system property to enable logging to standard out.</action>
+ <action dev="GJS" type="fix">Fixed SST string handling so that spreadsheets with rich text or extended text will be read correctly.</action>
+ </release>
+ <release version="1.5" date="06 May 2002">
<action dev="NKB" type="update">New project build.</action>
<action dev="NKB" type="update">New project documentation system based on Cocoon.</action>
<action dev="POI-DEVELOPERS" type="update">Package rename</action>
diff --git a/src/documentation/xdocs/historyandfuture.xml b/src/documentation/xdocs/historyandfuture.xml
index 3855480f69..741f6aad5c 100755
--- a/src/documentation/xdocs/historyandfuture.xml
+++ b/src/documentation/xdocs/historyandfuture.xml
@@ -3,7 +3,7 @@
<document>
<header>
- <title></title>
+ <title>Project History</title>
<authors>
<person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
</authors>
diff --git a/src/documentation/xdocs/hssf/how-to.xml b/src/documentation/xdocs/hssf/how-to.xml
index 8c5d930dba..2ad13bec85 100644
--- a/src/documentation/xdocs/hssf/how-to.xml
+++ b/src/documentation/xdocs/hssf/how-to.xml
@@ -397,55 +397,20 @@ export CLASSPATH=$CLASSPATH:$HSSFDIR/hssf.jar:$HSSFDIR/poi-poifs.jar:$HSSFDIR/po
<ul>
<li>Type:
<code>java org.apache.poi.hssf.dev.HSSF ~/input.xls output.xls</code>
- <p>
+ <br/>
+ <br/>
This is the read/write/modify test. It reads in the spreadsheet, modifies a cell, and writes it back out.
Failing this test is not necessarily a bad thing. If HSSF tries to modify a non-existant sheet then this will
-most likely fail. No big deal. </p></li>
+most likely fail. No big deal. </li>
</ul>
</section>
- <section title="HSSF Logging facility">
-<p>HSSF now has a logging facility (using
- <link href="http://jakarta.apache.org/commons/logging.html">commons logging</link>)
-that will record massive amounts of debugging information. Its mostly
-useful to us hssf-developing geeks, but might be useful in tracking
-down problems.
-</p>
-<p>So Why use commons logging rather than log4j? Well the following discussion from
-the jakarta-general mailing list sums it up pretty well. (Thanks Morgan)
-</p>
-<p><em>Here's the problem, as I see it.</em>
-</p>
-<p><em>Suppose Commons component A decides to adopt Log4J, Commons component B
-decides to adopt LogKit, and Commons component C adopts JDK1.4 logging.
-They will all minimally function with the right jars in the classpath.
-However you (the end-user) are left with maintaining configuration for 3
-different logging APIs, which is tedious at best. When you take into
-account cool features like variable log levels, Log4J appenders and the
-like, you're pretty much guaranteed to swallow up useful configuration
-options because sophisticated configurations are too difficult to maintain
-over mutiple logging implementations.</em>
-</p>
-<p>
-<em>Contrarily, if all three Commons components use a logging facade, you can
-focus all your configuration efforts on one logging implementation. Sure,
-there is a trade-off; you don't have access to all the features, and the
-interface between the facade and the implementation must be maintained. But
-the benefits are not just political; they potentially make the end-users
-configuration much easier.</em>
-</p>
-<p><em>Even if all Commons components used the same logging implementation (Log4J
-for example), other projects in Jakarta-land may choose otherwise. If you
-add enough Jakarta projects to your environment, you eventually end up with
-the scenario described above. It's a worthwhile effort to attempt a logging
-solution that plays well with the Jakarta community at large. I think in
-many cases the Commons Logging component can fill that role.</em>
-</p>
+ <section title="HSSF Logging Facility">
<p>
-Refer to the commons logging package level javadoc for more information concerning how to
-<link href="http://jakarta.apache.org/commons/logging/api/index.html">configure commons logging.</link>
+ POI has a small amount of logging code embedded within it. Defining the system property
+ poi.logging will enable logging to standard out.
</p>
</section>
- <section title="HSSF Developer's tools">
+ <section title="HSSF Developer's Tools">
<p>HSSF has a number of tools useful for developers to debug/develop
stuff using HSSF (and more generally XLS files). We've already
diff --git a/src/documentation/xdocs/hssf/quick-guide.xml b/src/documentation/xdocs/hssf/quick-guide.xml
index 2d660255dd..53eaee8c25 100644
--- a/src/documentation/xdocs/hssf/quick-guide.xml
+++ b/src/documentation/xdocs/hssf/quick-guide.xml
@@ -28,6 +28,7 @@
<li><link href="#MergedCells">Merging cells</link></li>
<li><link href="#WorkingWithFonts">Working with fonts</link></li>
<li><link href="#ReadWriteWorkbook">Reading and writing</link></li>
+ <li><link href="#NewLinesInCells">Use newlines in cells.</link></li>
</ul>
</section>
<section title="Features">
@@ -294,6 +295,35 @@
fileOut.close();
</source>
</section>
+ <anchor id="UseNewLinesInCells"/>
+ <section title="Using newlines in cells">
+ <source>
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet s = wb.createSheet();
+ HSSFRow r = null;
+ HSSFCell c = null;
+ HSSFCellStyle cs = wb.createCellStyle();
+ HSSFFont f = wb.createFont();
+ HSSFFont f2 = wb.createFont();
+
+ cs = wb.createCellStyle();
+
+ cs.setFont( f2 );
+ //Word Wrap MUST be turned on
+ cs.setWrapText( true );
+
+ r = s.createRow( (short) 2 );
+ r.setHeight( (short) 0x349 );
+ c = r.createCell( (short) 2 );
+ c.setCellType( HSSFCell.CELL_TYPE_STRING );
+ c.setCellValue( "Use \n with word wrap on to create a new line" );
+ c.setCellStyle( cs );
+ s.setColumnWidth( (short) 2, (short) ( ( 50 * 8 ) / ( (double) 1 / 20 ) ) );
+
+ FileOutputStream fileOut = new FileOutputStream( "workbook.xls" );
+ wb.write( fileOut );
+ fileOut.close();</source>
+ </section>
</section>
</section>
</body>
diff --git a/src/documentation/xdocs/news/logocontest.xml b/src/documentation/xdocs/news/logocontest.xml
index 9c45d06c66..9d9179c865 100644
--- a/src/documentation/xdocs/news/logocontest.xml
+++ b/src/documentation/xdocs/news/logocontest.xml
@@ -2,114 +2,139 @@
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "document-v11.dtd">
<document>
- <header>
- <title></title>
- <authors>
- <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
- </authors>
- </header>
-
- <body>
- <section title="POI logos">
- <p>
- Here are the current logo submissions. Thanks to the artists!
- </p>
- <section title="Michael Mosmann">
- <p>
- <img src="images/logoMichaelMosmann.png"/>
+ <header>
+ <title></title>
+ <authors>
+ <person id="AO" name="Andrew C. Oliver" email="acoliver@apache.org"/>
+ <person id="GS" name="Glen Stampoultzis" email="glens@apache.org"/>
+ </authors>
+ </header>
+
+ <body>
+ <section title="POI logos">
+ <p>
+ Here are the current logo submissions. Thanks to the artists!
+ </p>
+ <section title="Michael Mosmann">
+ <p>
+ <img src="images/logoMichaelMosmann.png"/>
</p>
- </section>
- <section title="Lo�c Lef�vre">
+ </section>
+ <section title="Lo�c Lef�vre">
<p>
- <img src="images/logoLoicLefevre.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoLoicLefevre2.png"/>
+ <img src="images/logoLoicLefevre.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoLoicLefevre2.png"/>
</p>
- </section>
- <section title="Glen Stampoultzis">
+ </section>
+ <section title="Glen Stampoultzis">
<p>
- <img src="images/logoGlenStampoutlzis.png"/>
+ <img src="images/logoGlenStampoutlzis.png"/>
</p>
- </section>
- <section title="Marcus Gustafsson">
+ </section>
+ <section title="Marcus Gustafsson">
<p>
- <img src="images/logoGustafsson1.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoGustafsson2.png"/>
+ <img src="images/logoGustafsson1.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoGustafsson2.png"/>
</p>
- </section>
- <section title="Adrianus Handoyo">
+ </section>
+ <section title="Adrianus Handoyo">
<p>
- <img src="images/logoAdria1.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoAdria2.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoAdria3.png"/>
+ <img src="images/logoAdria1.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoAdria2.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoAdria3.png"/>
</p>
- </section>
- <section title="RussellBeattie">
+ </section>
+ <section title="RussellBeattie">
<p>
- <img src="images/logoRussellBeattie1.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoRussellBeattie2.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoRussellBeattie3.png"/>
+ <img src="images/logoRussellBeattie1.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoRussellBeattie2.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoRussellBeattie3.png"/>
</p>
<p>
- <img src="images/logoRussellBeattie4.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoRussellBeattie5.png"/>
+ <img src="images/logoRussellBeattie4.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoRussellBeattie5.png"/>
</p>
- </section>
- <section title="Daniel Fernandez">
+ </section>
+ <section title="Daniel Fernandez">
<p>
- <img src="images/logoDanielFernandez.png"/>
+ <img src="images/logoDanielFernandez.png"/>
</p>
- </section>
- <section title="Andrew Clements">
+ </section>
+ <section title="Andrew Clements">
<p>
- <img src="images/logoAndrewClements.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoAndrewClements2.png"/>
+ <img src="images/logoAndrewClements.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoAndrewClements2.png"/>
</p>
- </section>
- <section title="Wendy Wise">
+ </section>
+ <section title="Wendy Wise">
<p>
- <img src="images/logoWendyWise.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoWendyWise2.png"/>
+ <img src="images/logoWendyWise.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoWendyWise2.png"/>
</p>
- </section>
- <section title="Nikhil Karmokar">
+ </section>
+ <section title="Nikhil Karmokar">
<p>
- <img src="images/logoKarmokar1.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoKarmokar1s.png"/>
+ <img src="images/logoKarmokar1.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoKarmokar1s.png"/>
</p>
<p>
- <img src="images/logoKarmokar2.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoKarmokar2s.png"/>
+ <img src="images/logoKarmokar2.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoKarmokar2s.png"/>
</p>
<p>
- <img src="images/logoKarmokar3.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoKarmokar3s.png"/>
+ <img src="images/logoKarmokar3.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoKarmokar3s.png"/>
</p>
<p>
- <img src="images/logoKarmokar4.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoKarmokar4s.png"/>
+ <img src="images/logoKarmokar4.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoKarmokar4s.png"/>
</p>
<p>
- <img src="images/logoKarmokar5.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoKarmokar5s.png"/>
+ <img src="images/logoKarmokar5.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoKarmokar5s.png"/>
</p>
<p>
- <img src="images/logoKarmokar6.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoKarmokar6s.png"/>
+ <img src="images/logoKarmokar6.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoKarmokar6s.png"/>
</p>
- </section>
- <section title="Lieven Janssen">
+ </section>
+ <section title="Lieven Janssen">
+ <p>
+ <img src="images/logoJanssen1.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoJanssen2.png"/>
+ </p>
+ </section>
+ <section title="RaPi GmbH">
<p>
- <img src="images/logoJanssen1.png"/>&nbsp;&nbsp;&nbsp;
- <img src="images/logoJanssen2.png"/>
+ Contact Person: Fancy at: fancy at my-feiqi.com
</p>
+ <p>
+ <img src="images/logoRaPiGmbH1.png"/>&nbsp;&nbsp;&nbsp;
+ <img src="images/logoRaPiGmbH2.png"/>
+ </p>
+ <p>
+ <img src="images/logoRaPiGmbH3.png"/>
+ </p>
+ <p>
+ <img src="images/logoRaPiGmbH4.png"/>
+ </p>
+ <p>
+ <img src="images/logoRaPiGmbH5.png"/>
+ </p>
+ <p>
+ <img src="images/logoRaPiGmbH6.png"/>
+ </p>
+ <p>
+ <img src="images/logoRaPiGmbH7.png"/>
+ </p>
+ </section>
+
</section>
-
- </section>
- </body>
- <footer>
- <legal>
- Copyright (c) @year@ The Apache Software Foundation All rights reserved.
- $Revision$ $Date$
- </legal>
- </footer>
+ </body>
+ <footer>
+ <legal>
+ Copyright (c) @year@ The Apache Software Foundation All rights reserved.
+ $Revision$ $Date$
+ </legal>
+ </footer>
</document>
diff --git a/src/examples/src/org/apache/poi/hssf/usermodel/examples/NewLinesInCells.java b/src/examples/src/org/apache/poi/hssf/usermodel/examples/NewLinesInCells.java
new file mode 100644
index 0000000000..517234fc97
--- /dev/null
+++ b/src/examples/src/org/apache/poi/hssf/usermodel/examples/NewLinesInCells.java
@@ -0,0 +1,100 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache POI" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache POI", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.poi.hssf.usermodel.examples;
+
+import org.apache.poi.hssf.usermodel.*;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Demonstrates how to use newlines in cells.
+ *
+ * @author Glen Stampoultzis (glens at apache.org)
+ * @author Fauzia Lala <fauzia.lala at wcom.com>
+ */
+public class NewLinesInCells
+{
+ public static void main( String[] args ) throws IOException
+ {
+
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet s = wb.createSheet();
+ HSSFRow r = null;
+ HSSFCell c = null;
+ HSSFCellStyle cs = wb.createCellStyle();
+ HSSFFont f = wb.createFont();
+ HSSFFont f2 = wb.createFont();
+
+ cs = wb.createCellStyle();
+
+ cs.setFont( f2 );
+ //Word Wrap MUST be turned on
+ cs.setWrapText( true );
+
+ r = s.createRow( (short) 2 );
+ r.setHeight( (short) 0x349 );
+ c = r.createCell( (short) 2 );
+ c.setCellType( HSSFCell.CELL_TYPE_STRING );
+ c.setCellValue( "Use \n with word wrap on to create a new line" );
+ c.setCellStyle( cs );
+ s.setColumnWidth( (short) 2, (short) ( ( 50 * 8 ) / ( (double) 1 / 20 ) ) );
+
+ FileOutputStream fileOut = new FileOutputStream( "workbook.xls" );
+ wb.write( fileOut );
+ fileOut.close();
+
+ }
+}
diff --git a/src/java/org/apache/poi/hssf/dev/BiffViewer.java b/src/java/org/apache/poi/hssf/dev/BiffViewer.java
index 12267d23d8..7d366f1455 100644
--- a/src/java/org/apache/poi/hssf/dev/BiffViewer.java
+++ b/src/java/org/apache/poi/hssf/dev/BiffViewer.java
@@ -631,12 +631,12 @@ public class BiffViewer
retval = new LinkedDataRecord(rectype, size, data);
break;
- case FormulaRecord.sid:
- retval = new FormulaRecord(rectype, size, data);
- break;
+// case FormulaRecord.sid:
+// retval = new FormulaRecord(rectype, size, data);
+// break;
case SheetPropertiesRecord.sid:
- retval = new FormulaRecord(rectype, size, data);
+ retval = new SheetPropertiesRecord(rectype, size, data);
break;
diff --git a/src/java/org/apache/poi/hssf/model/Workbook.java b/src/java/org/apache/poi/hssf/model/Workbook.java
index d45153f9c9..55fe659322 100644
--- a/src/java/org/apache/poi/hssf/model/Workbook.java
+++ b/src/java/org/apache/poi/hssf/model/Workbook.java
@@ -643,26 +643,11 @@ public class Workbook
{
log.log(DEBUG, "Serializing Workbook with offsets");
- // ArrayList bytes = new ArrayList(records.size());
-// int arraysize = getSize(); // 0;
int pos = 0;
-// for (int k = 0; k < records.size(); k++)
-// {
-// bytes.add((( Record ) records.get(k)).serialize());
-//
-// }
-// for (int k = 0; k < bytes.size(); k++)
-// {
-// arraysize += (( byte [] ) bytes.get(k)).length;
-// }
for (int k = 0; k < records.size(); k++)
{
-
- // byte[] rec = (( byte [] ) bytes.get(k));
- // System.arraycopy(rec, 0, data, offset + pos, rec.length);
- pos += (( Record ) records.get(k)).serialize(pos + offset,
- data); // rec.length;
+ pos += (( Record ) records.get(k)).serialize(pos + offset, data); // rec.length;
}
log.log(DEBUG, "Exiting serialize workbook");
return pos;
diff --git a/src/java/org/apache/poi/hssf/record/ContinueRecord.java b/src/java/org/apache/poi/hssf/record/ContinueRecord.java
index 2b67a62d40..5017ade922 100644
--- a/src/java/org/apache/poi/hssf/record/ContinueRecord.java
+++ b/src/java/org/apache/poi/hssf/record/ContinueRecord.java
@@ -161,9 +161,7 @@ public class ContinueRecord
// how many continue records do we need
// System.out.println("In ProcessContinue");
- int records =
- (data.length
- / 8214); // we've a 1 offset but we're also off by one due to rounding...so it balances out
+ int records = (data.length / 8214); // we've a 1 offset but we're also off by one due to rounding...so it balances out
int offset = 8214;
// System.out.println("we have "+records+" continue records to process");
@@ -174,8 +172,7 @@ public class ContinueRecord
for (int cr = 0; cr < records; cr++)
{
ContinueRecord contrec = new ContinueRecord();
- int arraysize = Math.min((8214 - 4),
- (data.length - offset));
+ int arraysize = Math.min((8214 - 4), (data.length - offset));
byte[] crdata = new byte[ arraysize ];
System.arraycopy(data, offset, crdata, 0, arraysize);
diff --git a/src/java/org/apache/poi/hssf/record/RecordProcessor.java b/src/java/org/apache/poi/hssf/record/RecordProcessor.java
new file mode 100644
index 0000000000..13bfc3a188
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/RecordProcessor.java
@@ -0,0 +1,202 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache POI" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache POI", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndianConsts;
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * Process a single record. That is, an SST record or a continue record.
+ * Refactored from code originally in SSTRecord.
+ *
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+class RecordProcessor
+{
+ private byte[] data;
+ private int recordOffset;
+ private int available;
+ private SSTRecordHeader sstRecordHeader;
+
+ public RecordProcessor( byte[] data, int available, int numStrings, int numUniqueStrings )
+ {
+ this.data = data;
+ this.available = available;
+ this.sstRecordHeader = new SSTRecordHeader(numStrings, numUniqueStrings);
+ }
+
+ public int getAvailable()
+ {
+ return available;
+ }
+
+ public void writeRecordHeader( int offset, int totalWritten, int recordLength, boolean first_record )
+ {
+ if ( first_record )
+ {
+ available -= 8;
+ recordOffset = sstRecordHeader.writeSSTHeader( data, recordOffset + offset + totalWritten, recordLength );
+ }
+ else
+ {
+ recordOffset = writeContinueHeader( data, recordOffset + offset + totalWritten, recordLength );
+ }
+ }
+
+ public byte[] writeStringRemainder( boolean lastStringCompleted, byte[] stringreminant, int offset, int totalWritten )
+ {
+ if ( !lastStringCompleted )
+ {
+ // write reminant -- it'll all fit neatly
+ System.arraycopy( stringreminant, 0, data, recordOffset + offset + totalWritten, stringreminant.length );
+ adjustPointers( stringreminant.length );
+ }
+ else
+ {
+ // write as much of the remnant as possible
+ System.arraycopy( stringreminant, 0, data, recordOffset + offset + totalWritten, available );
+ byte[] leftover = new byte[( stringreminant.length - available ) + LittleEndianConsts.BYTE_SIZE];
+
+ System.arraycopy( stringreminant, available, leftover, LittleEndianConsts.BYTE_SIZE, stringreminant.length - available );
+ leftover[0] = stringreminant[0];
+ stringreminant = leftover;
+ adjustPointers( available ); // Consume all available remaining space
+ }
+ return stringreminant;
+ }
+
+ public void writeWholeString( UnicodeString unistr, int offset, int totalWritten )
+ {
+ unistr.serialize( recordOffset + offset + totalWritten, data );
+ int rsize = unistr.getRecordSize();
+ adjustPointers( rsize );
+ }
+
+ public byte[] writePartString( UnicodeString unistr, int offset, int totalWritten )
+ {
+ byte[] stringReminant;
+ byte[] ucs = unistr.serialize();
+
+ System.arraycopy( ucs, 0, data, recordOffset + offset + totalWritten, available );
+ stringReminant = new byte[( ucs.length - available ) + LittleEndianConsts.BYTE_SIZE];
+ System.arraycopy( ucs, available, stringReminant, LittleEndianConsts.BYTE_SIZE, ucs.length - available );
+ stringReminant[0] = ucs[LittleEndianConsts.SHORT_SIZE];
+ available = 0;
+ return stringReminant;
+ }
+
+
+ private int writeContinueHeader( final byte[] data, final int pos,
+ final int recsize )
+ {
+ int offset = pos;
+
+ LittleEndian.putShort( data, offset, ContinueRecord.sid );
+ offset += LittleEndianConsts.SHORT_SIZE;
+ LittleEndian.putShort( data, offset, (short) ( recsize ) );
+ offset += LittleEndianConsts.SHORT_SIZE;
+ return offset - pos;
+ }
+
+
+ private void adjustPointers( int amount )
+ {
+ recordOffset += amount;
+ available -= amount;
+ }
+}
+
+class SSTRecordHeader
+{
+ int numStrings;
+ int numUniqueStrings;
+
+ /**
+ *
+ */
+ public SSTRecordHeader( int numStrings, int numUniqueStrings )
+ {
+ this.numStrings = numStrings;
+ this.numUniqueStrings = numUniqueStrings;
+ }
+
+ /**
+ * Writes out the SST record. This consists of the sid, the record size, the number of
+ * strings and the number of unique strings.
+ *
+ * @param data The data buffer to write the header to.
+ * @param bufferIndex The index into the data buffer where the header should be written.
+ * @param recSize The number of records written.
+ *
+ * @return The bufer of bytes modified.
+ */
+ public int writeSSTHeader( byte[] data, int bufferIndex, int recSize )
+ {
+ int offset = bufferIndex;
+
+ LittleEndian.putShort( data, offset, SSTRecord.sid );
+ offset += LittleEndianConsts.SHORT_SIZE;
+ LittleEndian.putShort( data, offset, (short) ( recSize ) );
+ offset += LittleEndianConsts.SHORT_SIZE;
+// LittleEndian.putInt( data, offset, getNumStrings() );
+ LittleEndian.putInt( data, offset, numStrings );
+ offset += LittleEndianConsts.INT_SIZE;
+// LittleEndian.putInt( data, offset, getNumUniqueStrings() );
+ LittleEndian.putInt( data, offset, numUniqueStrings );
+ offset += LittleEndianConsts.INT_SIZE;
+ return offset - bufferIndex;
+ }
+
+} \ No newline at end of file
diff --git a/src/java/org/apache/poi/hssf/record/RowRecord.java b/src/java/org/apache/poi/hssf/record/RowRecord.java
index 65b627ea55..fc29fcbd26 100644
--- a/src/java/org/apache/poi/hssf/record/RowRecord.java
+++ b/src/java/org/apache/poi/hssf/record/RowRecord.java
@@ -452,8 +452,8 @@ public class RowRecord
LittleEndian.putShort(data, 0 + offset, sid);
LittleEndian.putShort(data, 2 + offset, ( short ) 16);
LittleEndian.putShort(data, 4 + offset, getRowNumber());
- LittleEndian.putShort(data, 6 + offset, getFirstCol());
- LittleEndian.putShort(data, 8 + offset, getLastCol());
+ LittleEndian.putShort(data, 6 + offset, getFirstCol() == -1 ? (short)0 : getFirstCol());
+ LittleEndian.putShort(data, 8 + offset, getLastCol() == -1 ? (short)0 : getLastCol());
LittleEndian.putShort(data, 10 + offset, getHeight());
LittleEndian.putShort(data, 12 + offset, getOptimize());
LittleEndian.putShort(data, 14 + offset, field_6_reserved);
diff --git a/src/java/org/apache/poi/hssf/record/SSTDeserializer.java b/src/java/org/apache/poi/hssf/record/SSTDeserializer.java
new file mode 100644
index 0000000000..c4698df0fb
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/SSTDeserializer.java
@@ -0,0 +1,562 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache POI" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache POI", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.poi.hssf.record;
+
+import org.apache.poi.util.BinaryTree;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianConsts;
+
+/**
+ * Handles the task of deserializing a SST string. The two main entry points are
+ *
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+class SSTDeserializer
+{
+
+ private BinaryTree strings;
+ /** this is the number of characters we expect in the first sub-record in a subsequent continuation record */
+ private int continuationExpectedChars;
+ /** this is the string we were working on before hitting the end of the current record. This string is NOT finished. */
+ private String unfinishedString;
+ /** this is true if the string uses wide characters */
+ private boolean wideChar;
+ /** this is true if the string is a rich text string */
+ private boolean richText;
+ /** this is true if the string is a far east string or some other wierd string */
+ private boolean extendedText;
+ /** Number of formatting runs in this rich text field */
+ private short runCount;
+ /** Number of characters in current string */
+ private int charCount;
+ private int extensionLength;
+
+
+ public SSTDeserializer( BinaryTree strings )
+ {
+ this.strings = strings;
+ initVars();
+ }
+
+ private void initVars()
+ {
+ runCount = 0;
+ continuationExpectedChars = 0;
+ unfinishedString = "";
+// bytesInCurrentSegment = 0;
+// stringDataOffset = 0;
+ wideChar = false;
+ richText = false;
+ extendedText = false;
+ }
+
+ /**
+ * This is the starting point where strings are constructed. Note that
+ * strings may span across multiple continuations. Read the SST record
+ * carefully before beginning to hack.
+ */
+ public void manufactureStrings( final byte[] data, final int initialOffset, short dataSize )
+ {
+ initVars();
+
+ int offset = initialOffset;
+ while ( ( offset - initialOffset ) < dataSize )
+ {
+ int remaining = dataSize - offset + initialOffset;
+
+ if ( ( remaining > 0 ) && ( remaining < LittleEndianConsts.SHORT_SIZE ) )
+ {
+ throw new RecordFormatException( "Cannot get length of the last string in SSTRecord" );
+ }
+ if ( remaining == LittleEndianConsts.SHORT_SIZE )
+ {
+ setContinuationExpectedChars( LittleEndian.getUShort( data, offset ) );
+ unfinishedString = "";
+ break;
+ }
+ charCount = LittleEndian.getUShort( data, offset );
+ readStringHeader( data, offset );
+ boolean stringContinuesOverContinuation = remaining < totalStringSize();
+ if ( stringContinuesOverContinuation )
+ {
+ int remainingBytes = ( initialOffset + dataSize ) - offset - stringHeaderOverhead();
+ setContinuationExpectedChars( charCount - calculateCharCount( remainingBytes ) );
+ charCount -= getContinuationExpectedChars();
+ }
+ else
+ {
+ setContinuationExpectedChars( 0 );
+ }
+ processString( data, offset, charCount );
+ offset += totalStringSize();
+ if ( getContinuationExpectedChars() != 0 )
+ {
+ break;
+ }
+ }
+ }
+
+// private void dump( final byte[] data, int offset, int length )
+// {
+// try
+// {
+// System.out.println( "------------------- SST DUMP -------------------------" );
+// HexDump.dump( (byte[]) data, offset, System.out, offset, length );
+// }
+// catch ( IOException e )
+// {
+// }
+// catch ( ArrayIndexOutOfBoundsException e )
+// {
+// }
+// catch ( IllegalArgumentException e )
+// {
+// }
+// }
+
+ /**
+ * Detemines the option types for the string (ie, compressed or uncompressed unicode, rich text string or
+ * plain string etc) and calculates the length and offset for the string.
+ *
+ */
+ private void readStringHeader( final byte[] data, final int index )
+ {
+
+ byte optionFlag = data[index + LittleEndianConsts.SHORT_SIZE];
+
+ wideChar = ( optionFlag & 1 ) == 1;
+ extendedText = ( optionFlag & 4 ) == 4;
+ richText = ( optionFlag & 8 ) == 8;
+ runCount = 0;
+ if ( richText )
+ {
+ runCount = LittleEndian.getShort( data, index + SSTRecord.STRING_MINIMAL_OVERHEAD );
+ }
+ extensionLength = 0;
+ if ( extendedText )
+ {
+ extensionLength = LittleEndian.getInt( data, index + SSTRecord.STRING_MINIMAL_OVERHEAD
+ + (richText ? LittleEndianConsts.SHORT_SIZE : 0) );
+ }
+
+ }
+
+
+ /**
+ * Reads a string or the first part of a string.
+ *
+ * @param characters the number of characters to write.
+ *
+ * @return the number of bytes written.
+ */
+ private int processString( final byte[] data, final int dataIndex, final int characters )
+ {
+
+ // length is the length we store it as. not the length that is read.
+ int length = SSTRecord.STRING_MINIMAL_OVERHEAD + calculateByteCount( characters );
+ byte[] unicodeStringBuffer = new byte[length];
+
+ int offset = 0;
+
+ // Set the length in characters
+ LittleEndian.putUShort( unicodeStringBuffer, offset, characters );
+ offset += LittleEndianConsts.SHORT_SIZE;
+ // Set the option flags
+ unicodeStringBuffer[offset] = data[dataIndex + offset];
+ // Copy in the string data
+ int bytesRead = unicodeStringBuffer.length - SSTRecord.STRING_MINIMAL_OVERHEAD;
+ arraycopy( data, dataIndex + stringHeaderOverhead(), unicodeStringBuffer, SSTRecord.STRING_MINIMAL_OVERHEAD, bytesRead );
+ // Create the unicode string
+ UnicodeString string = new UnicodeString( UnicodeString.sid,
+ (short) unicodeStringBuffer.length,
+ unicodeStringBuffer );
+
+ if ( isStringFinished() )
+ {
+ Integer integer = new Integer( strings.size() );
+ addToStringTable( strings, integer, string );
+ }
+ else
+ {
+ unfinishedString = string.getString();
+ }
+
+ return bytesRead;
+ }
+
+ private boolean isStringFinished()
+ {
+ return getContinuationExpectedChars() == 0;
+ }
+
+ /**
+ * Okay, we are doing some major cheating here. Because we can't handle rich text strings properly
+ * we end up getting duplicate strings. To get around this I'm doing two things: 1. Converting rich
+ * text to normal text and 2. If there's a duplicate I'm adding a space onto the end. Sneaky perhaps
+ * but it gets the job done until we can handle this a little better.
+ */
+ static public void addToStringTable( BinaryTree strings, Integer integer, UnicodeString string )
+ {
+
+ if ( string.isRichText() )
+ string.setOptionFlags( (byte) ( string.getOptionFlags() & ( ~8 ) ) );
+ if ( string.isExtendedText() )
+ string.setOptionFlags( (byte) ( string.getOptionFlags() & ( ~4 ) ) );
+
+ boolean added = false;
+ while ( added == false )
+ {
+ try
+ {
+ strings.put( integer, string );
+ added = true;
+ }
+ catch ( Exception ignore )
+ {
+ string.setString( string.getString() + " " );
+ }
+ }
+
+ }
+
+
+ private int calculateCharCount( final int byte_count )
+ {
+ return byte_count / ( wideChar ? LittleEndianConsts.SHORT_SIZE : LittleEndianConsts.BYTE_SIZE );
+ }
+
+ /**
+ * Process a Continue record. A Continue record for an SST record
+ * contains the same kind of data that the SST record contains,
+ * with the following exceptions:
+ * <P>
+ * <OL>
+ * <LI>The string counts at the beginning of the SST record are
+ * not in the Continue record
+ * <LI>The first string in the Continue record might NOT begin
+ * with a size. If the last string in the previous record is
+ * continued in this record, the size is determined by that
+ * last string in the previous record; the first string will
+ * begin with a flag byte, followed by the remaining bytes (or
+ * words) of the last string from the previous
+ * record. Otherwise, the first string in the record will
+ * begin with a string length
+ * </OL>
+ *
+ * @param record the Continue record's byte data
+ */
+ public void processContinueRecord( final byte[] record )
+ {
+ if ( isStringFinished() )
+ {
+ initVars();
+ manufactureStrings( record, 0, (short) record.length );
+ }
+ else
+ {
+ // reset the wide bit because that can change across a continuation. the fact that it's
+ // actually rich text doesn't change across continuations even though the rich text
+ // may on longer be set in the "new" option flag. confusing huh?
+ wideChar = ( record[0] & 1 ) == 1;
+
+ if ( stringSpansContinuation( record.length - LittleEndianConsts.BYTE_SIZE ) )
+ {
+ processEntireContinuation( record );
+ }
+ else
+ {
+ readStringRemainder( record );
+ }
+ }
+
+ }
+
+ /**
+ * Reads the remainder string and any subsequent strings from the continuation record.
+ *
+ * @param record The entire continuation record data.
+ */
+ private void readStringRemainder( final byte[] record )
+ {
+ int stringRemainderSizeInBytes = calculateByteCount( getContinuationExpectedChars() );
+// stringDataOffset = LittleEndianConsts.BYTE_SIZE;
+ byte[] unicodeStringData = new byte[SSTRecord.STRING_MINIMAL_OVERHEAD
+ + calculateByteCount( getContinuationExpectedChars() )];
+
+ // write the string length
+ LittleEndian.putShort( unicodeStringData, 0, (short) getContinuationExpectedChars() );
+
+ // write the options flag
+ unicodeStringData[LittleEndianConsts.SHORT_SIZE] = createOptionByte( wideChar, richText, extendedText );
+
+ // copy the bytes/words making up the string; skipping
+ // past all the overhead of the str_data array
+ arraycopy( record, LittleEndianConsts.BYTE_SIZE, unicodeStringData,
+ SSTRecord.STRING_MINIMAL_OVERHEAD,
+ unicodeStringData.length - SSTRecord.STRING_MINIMAL_OVERHEAD );
+
+ // use special constructor to create the final string
+ UnicodeString string = new UnicodeString( UnicodeString.sid,
+ (short) unicodeStringData.length, unicodeStringData,
+ unfinishedString );
+ Integer integer = new Integer( strings.size() );
+
+ addToStringTable( strings, integer, string );
+
+ int newOffset = offsetForContinuedRecord( stringRemainderSizeInBytes );
+ manufactureStrings( record, newOffset, (short) ( record.length - newOffset ) );
+ }
+
+ /**
+ * Calculates the size of the string in bytes based on the character width
+ */
+ private int stringSizeInBytes()
+ {
+ return calculateByteCount( charCount );
+ }
+
+ /**
+ * Calculates the size of the string in byes. This figure includes all the over
+ * heads for the string.
+ */
+ private int totalStringSize()
+ {
+ return stringSizeInBytes()
+ + stringHeaderOverhead()
+ + LittleEndianConsts.INT_SIZE * runCount
+ + extensionLength;
+ }
+
+ private int stringHeaderOverhead()
+ {
+ return SSTRecord.STRING_MINIMAL_OVERHEAD
+ + ( richText ? LittleEndianConsts.SHORT_SIZE : 0 )
+ + ( extendedText ? LittleEndianConsts.INT_SIZE : 0 );
+ }
+
+ private int offsetForContinuedRecord( int stringRemainderSizeInBytes )
+ {
+ return stringRemainderSizeInBytes + LittleEndianConsts.BYTE_SIZE
+ + runCount * LittleEndianConsts.INT_SIZE + extensionLength;
+ }
+
+ private byte createOptionByte( boolean wideChar, boolean richText, boolean farEast )
+ {
+ return (byte) ( ( wideChar ? 1 : 0 ) + ( farEast ? 4 : 0 ) + ( richText ? 8 : 0 ) );
+ }
+
+ /**
+ * If the continued record is so long is spans into the next continue then
+ * simply suck the remaining string data into the existing <code>unfinishedString</code>.
+ *
+ * @param record The data from the continuation record.
+ */
+ private void processEntireContinuation( final byte[] record )
+ {
+ // create artificial data to create a UnicodeString
+ int dataLengthInBytes = record.length - LittleEndianConsts.BYTE_SIZE;
+ byte[] unicodeStringData = new byte[record.length + LittleEndianConsts.SHORT_SIZE];
+
+ LittleEndian.putShort( unicodeStringData, (byte) 0, (short) calculateCharCount( dataLengthInBytes ) );
+ arraycopy( record, 0, unicodeStringData, LittleEndianConsts.SHORT_SIZE, record.length );
+ UnicodeString ucs = new UnicodeString( UnicodeString.sid, (short) unicodeStringData.length, unicodeStringData );
+
+ unfinishedString = unfinishedString + ucs.getString();
+ setContinuationExpectedChars( getContinuationExpectedChars() - calculateCharCount( dataLengthInBytes ) );
+ }
+
+ private boolean stringSpansContinuation( int continuationSizeInBytes )
+ {
+ return calculateByteCount( getContinuationExpectedChars() ) > continuationSizeInBytes;
+ }
+
+ /**
+ * @return the number of characters we expect in the first
+ * sub-record in a subsequent continuation record
+ */
+
+ int getContinuationExpectedChars()
+ {
+ return continuationExpectedChars;
+ }
+
+ private void setContinuationExpectedChars( final int count )
+ {
+ continuationExpectedChars = count;
+ }
+
+ private int calculateByteCount( final int character_count )
+ {
+ return character_count * ( wideChar ? LittleEndianConsts.SHORT_SIZE : LittleEndianConsts.BYTE_SIZE );
+ }
+
+
+ /**
+ * Copies an array from the specified source array, beginning at the
+ * specified position, to the specified position of the destination array.
+ * A subsequence of array components are copied from the source
+ * array referenced by <code>src</code> to the destination array
+ * referenced by <code>dst</code>. The number of components copied is
+ * equal to the <code>length</code> argument. The components at
+ * positions <code>srcOffset</code> through
+ * <code>srcOffset+length-1</code> in the source array are copied into
+ * positions <code>dstOffset</code> through
+ * <code>dstOffset+length-1</code>, respectively, of the destination
+ * array.
+ * <p>
+ * If the <code>src</code> and <code>dst</code> arguments refer to the
+ * same array object, then the copying is performed as if the
+ * components at positions <code>srcOffset</code> through
+ * <code>srcOffset+length-1</code> were first copied to a temporary
+ * array with <code>length</code> components and then the contents of
+ * the temporary array were copied into positions
+ * <code>dstOffset</code> through <code>dstOffset+length-1</code> of the
+ * destination array.
+ * <p>
+ * If <code>dst</code> is <code>null</code>, then a
+ * <code>NullPointerException</code> is thrown.
+ * <p>
+ * If <code>src</code> is <code>null</code>, then a
+ * <code>NullPointerException</code> is thrown and the destination
+ * array is not modified.
+ * <p>
+ * Otherwise, if any of the following is true, an
+ * <code>ArrayStoreException</code> is thrown and the destination is
+ * not modified:
+ * <ul>
+ * <li>The <code>src</code> argument refers to an object that is not an
+ * array.
+ * <li>The <code>dst</code> argument refers to an object that is not an
+ * array.
+ * <li>The <code>src</code> argument and <code>dst</code> argument refer to
+ * arrays whose component types are different primitive types.
+ * <li>The <code>src</code> argument refers to an array with a primitive
+ * component type and the <code>dst</code> argument refers to an array
+ * with a reference component type.
+ * <li>The <code>src</code> argument refers to an array with a reference
+ * component type and the <code>dst</code> argument refers to an array
+ * with a primitive component type.
+ * </ul>
+ * <p>
+ * Otherwise, if any of the following is true, an
+ * <code>IndexOutOfBoundsException</code> is
+ * thrown and the destination is not modified:
+ * <ul>
+ * <li>The <code>srcOffset</code> argument is negative.
+ * <li>The <code>dstOffset</code> argument is negative.
+ * <li>The <code>length</code> argument is negative.
+ * <li><code>srcOffset+length</code> is greater than
+ * <code>src.length</code>, the length of the source array.
+ * <li><code>dstOffset+length</code> is greater than
+ * <code>dst.length</code>, the length of the destination array.
+ * </ul>
+ * <p>
+ * Otherwise, if any actual component of the source array from
+ * position <code>srcOffset</code> through
+ * <code>srcOffset+length-1</code> cannot be converted to the component
+ * type of the destination array by assignment conversion, an
+ * <code>ArrayStoreException</code> is thrown. In this case, let
+ * <b><i>k</i></b> be the smallest nonnegative integer less than
+ * length such that <code>src[srcOffset+</code><i>k</i><code>]</code>
+ * cannot be converted to the component type of the destination
+ * array; when the exception is thrown, source array components from
+ * positions <code>srcOffset</code> through
+ * <code>srcOffset+</code><i>k</i><code>-1</code>
+ * will already have been copied to destination array positions
+ * <code>dstOffset</code> through
+ * <code>dstOffset+</code><i>k</I><code>-1</code> and no other
+ * positions of the destination array will have been modified.
+ * (Because of the restrictions already itemized, this
+ * paragraph effectively applies only to the situation where both
+ * arrays have component types that are reference types.)
+ *
+ * @param src the source array.
+ * @param src_position start position in the source array.
+ * @param dst the destination array.
+ * @param dst_position pos start position in the destination data.
+ * @param length the number of array elements to be copied.
+ * @exception IndexOutOfBoundsException if copying would cause
+ * access of data outside array bounds.
+ * @exception ArrayStoreException if an element in the <code>src</code>
+ * array could not be stored into the <code>dest</code> array
+ * because of a type mismatch.
+ * @exception NullPointerException if either <code>src</code> or
+ * <code>dst</code> is <code>null</code>.
+ */
+ private void arraycopy( byte[] src, int src_position,
+ byte[] dst, int dst_position,
+ int length )
+ {
+ System.arraycopy( src, src_position, dst, dst_position, length );
+ }
+
+ /**
+ * @return the unfinished string
+ */
+ String getUnfinishedString()
+ {
+ return unfinishedString;
+ }
+
+ /**
+ * @return true if current string uses wide characters
+ */
+ boolean isWideChar()
+ {
+ return wideChar;
+ }
+
+
+}
diff --git a/src/java/org/apache/poi/hssf/record/SSTRecord.java b/src/java/org/apache/poi/hssf/record/SSTRecord.java
index d8428148ab..734a90f6f4 100644
--- a/src/java/org/apache/poi/hssf/record/SSTRecord.java
+++ b/src/java/org/apache/poi/hssf/record/SSTRecord.java
@@ -1,4 +1,3 @@
-
/* ====================================================================
* The Apache Software License, Version 1.1
*
@@ -59,7 +58,8 @@ import org.apache.poi.util.BinaryTree;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;
-import java.util.*;
+import java.util.Iterator;
+import java.util.List;
/**
* Title: Static String Table Record
@@ -71,65 +71,45 @@ import java.util.*;
* <P>
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Marc Johnson (mjohnson at apache dot org)
+ * @author Glen Stampoultzis (glens at apache.org)
* @version 2.0-pre
* @see org.apache.poi.hssf.record.LabelSSTRecord
* @see org.apache.poi.hssf.record.ContinueRecord
*/
public class SSTRecord
- extends Record
+ extends Record
{
- // how big can an SST record be? As big as any record can be: 8228
- // bytes
- private static final int _max = 8228;
-
- // standard record overhead: two shorts (record id plus data space
- // size)
- private static final int _std_record_overhead =
- 2 * LittleEndianConsts.SHORT_SIZE;
-
- // SST overhead: the standard record overhead, plus the number of
- // strings and the number of unique strings -- two ints
- private static final int _sst_record_overhead =
- (_std_record_overhead + (2 * LittleEndianConsts.INT_SIZE));
+ /** how big can an SST record be? As big as any record can be: 8228 bytes */
+ static final int MAX_RECORD_SIZE = 8228;
- // how much data can we stuff into an SST record? That would be
- // _max minus the standard SST record overhead
- private static final int _max_data_space =
- _max - _sst_record_overhead;
+ /** standard record overhead: two shorts (record id plus data space size)*/
+ static final int STD_RECORD_OVERHEAD =
+ 2 * LittleEndianConsts.SHORT_SIZE;
- // overhead for each string includes the string's character count
- // (a short) and the flag describing its characteristics (a byte)
- private static final int _string_minimal_overhead =
- LittleEndianConsts.SHORT_SIZE + LittleEndianConsts.BYTE_SIZE;
- public static final short sid = 0xfc;
+ /** SST overhead: the standard record overhead, plus the number of strings and the number of unique strings -- two ints */
+ static final int SST_RECORD_OVERHEAD =
+ ( STD_RECORD_OVERHEAD + ( 2 * LittleEndianConsts.INT_SIZE ) );
- // union of strings in the SST and EXTSST
- private int field_1_num_strings;
+ /** how much data can we stuff into an SST record? That would be _max minus the standard SST record overhead */
+ static final int MAX_DATA_SPACE = MAX_RECORD_SIZE - SST_RECORD_OVERHEAD;
- // according to docs ONLY SST
- private int field_2_num_unique_strings;
- private BinaryTree field_3_strings;
+ /** overhead for each string includes the string's character count (a short) and the flag describing its characteristics (a byte) */
+ static final int STRING_MINIMAL_OVERHEAD = LittleEndianConsts.SHORT_SIZE + LittleEndianConsts.BYTE_SIZE;
- // this is the number of characters we expect in the first
- // sub-record in a subsequent continuation record
- private int __expected_chars;
+ public static final short sid = 0xfc;
- // this is the string we were working on before hitting the end of
- // the current record. This string is NOT finished.
- private String _unfinished_string;
+ /** union of strings in the SST and EXTSST */
+ private int field_1_num_strings;
- // this is the total length of the current string being handled
- private int _total_length_bytes;
+ /** according to docs ONLY SST */
+ private int field_2_num_unique_strings;
+ private BinaryTree field_3_strings;
- // this is the offset into a string field of the actual string
- // data
- private int _string_data_offset;
-
- // this is true if the string uses wide characters
- private boolean _wide_char;
- private List _record_lengths = null;
+ /** Record lengths for initial SST record and all continue records */
+ private List _record_lengths = null;
+ private SSTDeserializer deserializer;
/**
* default constructor
@@ -137,14 +117,10 @@ public class SSTRecord
public SSTRecord()
{
- field_1_num_strings = 0;
+ field_1_num_strings = 0;
field_2_num_unique_strings = 0;
- field_3_strings = new BinaryTree();
- setExpectedChars(0);
- _unfinished_string = "";
- _total_length_bytes = 0;
- _string_data_offset = 0;
- _wide_char = false;
+ field_3_strings = new BinaryTree();
+ deserializer = new SSTDeserializer(field_3_strings);
}
/**
@@ -156,9 +132,9 @@ public class SSTRecord
* @param data of the record (should not contain sid/len)
*/
- public SSTRecord(final short id, final short size, final byte [] data)
+ public SSTRecord( final short id, final short size, final byte[] data )
{
- super(id, size, data);
+ super( id, size, data );
}
/**
@@ -171,10 +147,10 @@ public class SSTRecord
* @param offset of the record
*/
- public SSTRecord(final short id, final short size, final byte [] data,
- int offset)
+ public SSTRecord( final short id, final short size, final byte[] data,
+ int offset )
{
- super(id, size, data, offset);
+ super( id, size, data, offset );
}
/**
@@ -192,13 +168,13 @@ public class SSTRecord
* @return the index of that string in the table
*/
- public int addString(final String string)
+ public int addString( final String string )
{
int rval;
- if (string == null)
+ if ( string == null )
{
- rval = addString("", false);
+ rval = addString( "", false );
}
else
{
@@ -207,17 +183,17 @@ public class SSTRecord
// present, we have to use 16-bit encoding. Otherwise, we
// can use 8-bit encoding
boolean useUTF16 = false;
- int strlen = string.length();
+ int strlen = string.length();
- for (int j = 0; j < strlen; j++)
+ for ( int j = 0; j < strlen; j++ )
{
- if (string.charAt(j) > 255)
+ if ( string.charAt( j ) > 255 )
{
useUTF16 = true;
break;
}
}
- rval = addString(string, useUTF16);
+ rval = addString( string, useUTF16 );
}
return rval;
}
@@ -238,21 +214,21 @@ public class SSTRecord
* @return the index of that string in the table
*/
- public int addString(final String string, final boolean useUTF16)
+ public int addString( final String string, final boolean useUTF16 )
{
field_1_num_strings++;
- String str = (string == null) ? ""
- : string;
- int rval = -1;
- UnicodeString ucs = new UnicodeString();
-
- ucs.setString(str);
- ucs.setCharCount(( short ) str.length());
- ucs.setOptionFlags(( byte ) (useUTF16 ? 1
- : 0));
- Integer integer = ( Integer ) field_3_strings.getKeyForValue(ucs);
-
- if (integer != null)
+ String str = ( string == null ) ? ""
+ : string;
+ int rval = -1;
+ UnicodeString ucs = new UnicodeString();
+
+ ucs.setString( str );
+ ucs.setCharCount( (short) str.length() );
+ ucs.setOptionFlags( (byte) ( useUTF16 ? 1
+ : 0 ) );
+ Integer integer = (Integer) field_3_strings.getKeyForValue( ucs );
+
+ if ( integer != null )
{
rval = integer.intValue();
}
@@ -263,8 +239,9 @@ public class SSTRecord
// strings we've already collected
rval = field_3_strings.size();
field_2_num_unique_strings++;
- integer = new Integer(rval);
- field_3_strings.put(integer, ucs);
+ integer = new Integer( rval );
+ SSTDeserializer.addToStringTable( field_3_strings, integer, ucs );
+// field_3_strings.put( integer, ucs );
}
return rval;
}
@@ -298,7 +275,7 @@ public class SSTRecord
*
*/
- public void setNumStrings(final int count)
+ public void setNumStrings( final int count )
{
field_1_num_strings = count;
}
@@ -314,7 +291,7 @@ public class SSTRecord
* @param count number of strings
*/
- public void getNumUniqueStrings(final int count)
+ public void getNumUniqueStrings( final int count )
{
field_2_num_unique_strings = count;
}
@@ -327,16 +304,15 @@ public class SSTRecord
* @return the desired string
*/
- public String getString(final int id)
+ public String getString( final int id )
{
- return (( UnicodeString ) field_3_strings.get(new Integer(id)))
- .getString();
+ return ( (UnicodeString) field_3_strings.get( new Integer( id ) ) ).getString();
}
- public boolean getString16bit(final int id)
+ public boolean isString16bit( final int id )
{
- return ((( UnicodeString ) field_3_strings.get(new Integer(id)))
- .getOptionFlags() == 1);
+ UnicodeString unicodeString = ( (UnicodeString) field_3_strings.get( new Integer( id ) ) );
+ return ( ( unicodeString.getOptionFlags() & 0x01 ) == 1 );
}
/**
@@ -349,326 +325,24 @@ public class SSTRecord
{
StringBuffer buffer = new StringBuffer();
- buffer.append("[SST]\n");
- buffer.append(" .numstrings = ")
- .append(Integer.toHexString(getNumStrings())).append("\n");
- buffer.append(" .uniquestrings = ")
- .append(Integer.toHexString(getNumUniqueStrings())).append("\n");
- for (int k = 0; k < field_3_strings.size(); k++)
+ buffer.append( "[SST]\n" );
+ buffer.append( " .numstrings = " )
+ .append( Integer.toHexString( getNumStrings() ) ).append( "\n" );
+ buffer.append( " .uniquestrings = " )
+ .append( Integer.toHexString( getNumUniqueStrings() ) ).append( "\n" );
+ for ( int k = 0; k < field_3_strings.size(); k++ )
{
- buffer.append(" .string_" + k + " = ")
- .append((( UnicodeString ) field_3_strings
- .get(new Integer(k))).toString()).append("\n");
+ buffer.append( " .string_" + k + " = " )
+ .append( ( (UnicodeString) field_3_strings
+ .get( new Integer( k ) ) ).toString() ).append( "\n" );
}
- buffer.append("[/SST]\n");
+ buffer.append( "[/SST]\n" );
return buffer.toString();
}
/**
- * Create a byte array consisting of an SST record and any
- * required Continue records, ready to be written out.
- * <p>
- * If an SST record and any subsequent Continue records are read
- * in to create this instance, this method should produce a byte
- * array that is identical to the byte array produced by
- * concatenating the input records' data.
- *
- * @return the byte array
- */
-
- public int serialize(int offset, byte [] data)
- {
- int rval = getRecordSize();
- int record_length_index = 0;
-
- // get the linear size of that array
- int unicodesize = calculateUnicodeSize();
-
- if (unicodesize > _max_data_space)
- {
- byte[] stringreminant = null;
- int unipos = 0;
- boolean lastneedcontinue = false;
- int stringbyteswritten = 0;
- boolean first_record = true;
- int totalWritten = 0;
- int size = 0;
-
- while (totalWritten != rval)
- {
- int pos = 0;
-
- // write the appropriate header
- int available;
-
- if (first_record)
- {
- size =
- (( Integer ) _record_lengths
- .get(record_length_index++)).intValue();
- available = size - 8;
- pos = writeSSTHeader(data,
- pos + offset
- + totalWritten, size);
- size += _std_record_overhead;
- first_record = false;
- }
- else
- {
- pos = 0;
- int to_be_written = (unicodesize - stringbyteswritten)
- + (lastneedcontinue ? 1
- : 0); // not used?
-
- size =
- (( Integer ) _record_lengths
- .get(record_length_index++)).intValue();
- available = size;
- pos = writeContinueHeader(data,
- pos + offset
- + totalWritten, size);
- size = size + _std_record_overhead;
- }
-
- // now, write the rest of the data into the current
- // record space
- if (lastneedcontinue)
- {
-
- // the last string in the previous record was not
- // written out completely
- if (stringreminant.length <= available)
- {
-
- // write reminant -- it'll all fit neatly
- System.arraycopy(stringreminant, 0, data,
- pos + offset + totalWritten,
- stringreminant.length);
- stringbyteswritten += stringreminant.length - 1;
- pos += stringreminant.length;
- lastneedcontinue = false;
- available -= stringreminant.length;
- }
- else
- {
-
- // write as much of the remnant as possible
- System.arraycopy(stringreminant, 0, data,
- pos + offset + totalWritten,
- available);
- stringbyteswritten += available - 1;
- pos += available;
- byte[] leftover =
- new byte[ (stringreminant.length - available) + LittleEndianConsts.BYTE_SIZE ];
-
- System.arraycopy(stringreminant, available, leftover,
- LittleEndianConsts.BYTE_SIZE,
- stringreminant.length - available);
- leftover[ 0 ] = stringreminant[ 0 ];
- stringreminant = leftover;
- available = 0;
- lastneedcontinue = true;
- }
- }
-
- // last string's remnant, if any, is cleaned up as
- // best as can be done ... now let's try and write
- // some more strings
- for (; unipos < field_3_strings.size(); unipos++)
- {
- Integer intunipos = new Integer(unipos);
- UnicodeString unistr =
- (( UnicodeString ) field_3_strings.get(intunipos));
-
- if (unistr.getRecordSize() <= available)
- {
- unistr.serialize(pos + offset + totalWritten, data);
- int rsize = unistr.getRecordSize();
-
- stringbyteswritten += rsize;
- pos += rsize;
- available -= rsize;
- }
- else
- {
-
- // can't write the entire string out
- if (available >= _string_minimal_overhead)
- {
-
- // we can write some of it
- byte[] ucs = unistr.serialize();
-
- System.arraycopy(ucs, 0, data,
- pos + offset + totalWritten,
- available);
- stringbyteswritten += available;
- stringreminant =
- new byte[ (ucs.length - available) + LittleEndianConsts.BYTE_SIZE ];
- System.arraycopy(ucs, available, stringreminant,
- LittleEndianConsts.BYTE_SIZE,
- ucs.length - available);
- stringreminant[ 0 ] =
- ucs[ LittleEndianConsts.SHORT_SIZE ];
- available = 0;
- lastneedcontinue = true;
- unipos++;
- }
- break;
- }
- }
- totalWritten += size;
- }
- }
- else
- {
-
- // short data: write one simple SST record
- int datasize = _sst_record_overhead + unicodesize; // not used?
-
- writeSSTHeader(
- data, 0 + offset,
- _sst_record_overhead
- + (( Integer ) _record_lengths.get(
- record_length_index++)).intValue() - _std_record_overhead);
- int pos = _sst_record_overhead;
-
- for (int k = 0; k < field_3_strings.size(); k++)
- {
- UnicodeString unistr =
- (( UnicodeString ) field_3_strings.get(new Integer(k)));
-
- System.arraycopy(unistr.serialize(), 0, data, pos + offset,
- unistr.getRecordSize());
- pos += unistr.getRecordSize();
- }
- }
- return rval;
- }
-
- // not used: remove?
- private int calculateStringsize()
- {
- int retval = 0;
-
- for (int k = 0; k < field_3_strings.size(); k++)
- {
- retval +=
- (( UnicodeString ) field_3_strings.get(new Integer(k)))
- .getRecordSize();
- }
- return retval;
- }
-
- /**
- * Process a Continue record. A Continue record for an SST record
- * contains the same kind of data that the SST record contains,
- * with the following exceptions:
- * <P>
- * <OL>
- * <LI>The string counts at the beginning of the SST record are
- * not in the Continue record
- * <LI>The first string in the Continue record might NOT begin
- * with a size. If the last string in the previous record is
- * continued in this record, the size is determined by that
- * last string in the previous record; the first string will
- * begin with a flag byte, followed by the remaining bytes (or
- * words) of the last string from the previous
- * record. Otherwise, the first string in the record will
- * begin with a string length
- * </OL>
- *
- * @param record the Continue record's byte data
- */
-
- public void processContinueRecord(final byte [] record)
- {
- if (getExpectedChars() == 0)
- {
- _unfinished_string = "";
- _total_length_bytes = 0;
- _string_data_offset = 0;
- _wide_char = false;
- manufactureStrings(record, 0, ( short ) record.length);
- }
- else
- {
- int data_length = record.length - LittleEndianConsts.BYTE_SIZE;
-
- if (calculateByteCount(getExpectedChars()) > data_length)
- {
-
- // create artificial data to create a UnicodeString
- byte[] input =
- new byte[ record.length + LittleEndianConsts.SHORT_SIZE ];
- short size = ( short ) (((record[ 0 ] & 1) == 1)
- ? (data_length
- / LittleEndianConsts.SHORT_SIZE)
- : (data_length
- / LittleEndianConsts.BYTE_SIZE));
-
- LittleEndian.putShort(input, ( byte ) 0, size);
- System.arraycopy(record, 0, input,
- LittleEndianConsts.SHORT_SIZE,
- record.length);
- UnicodeString ucs = new UnicodeString(UnicodeString.sid,
- ( short ) input.length,
- input);
-
- _unfinished_string = _unfinished_string + ucs.getString();
- setExpectedChars(getExpectedChars() - size);
- }
- else
- {
- setupStringParameters(record, -LittleEndianConsts.SHORT_SIZE,
- getExpectedChars());
- byte[] str_data = new byte[ _total_length_bytes ];
- int length = _string_minimal_overhead
- + (calculateByteCount(getExpectedChars()));
- byte[] bstring = new byte[ length ];
-
- // Copy data from the record into the string
- // buffer. Copy skips the length of a short in the
- // string buffer, to leave room for the string length.
- System.arraycopy(record, 0, str_data,
- LittleEndianConsts.SHORT_SIZE,
- str_data.length
- - LittleEndianConsts.SHORT_SIZE);
-
- // write the string length
- LittleEndian.putShort(bstring, 0,
- ( short ) getExpectedChars());
-
- // write the options flag
- bstring[ LittleEndianConsts.SHORT_SIZE ] =
- str_data[ LittleEndianConsts.SHORT_SIZE ];
-
- // copy the bytes/words making up the string; skipping
- // past all the overhead of the str_data array
- System.arraycopy(str_data, _string_data_offset, bstring,
- _string_minimal_overhead,
- bstring.length - _string_minimal_overhead);
-
- // use special constructor to create the final string
- UnicodeString string =
- new UnicodeString(UnicodeString.sid,
- ( short ) bstring.length, bstring,
- _unfinished_string);
- Integer integer = new Integer(field_3_strings.size());
-
- field_3_strings.put(integer, string);
- manufactureStrings(record,
- _total_length_bytes
- - LittleEndianConsts
- .SHORT_SIZE, ( short ) record.length);
- }
- }
- }
-
- /**
* @return sid
*/
-
public short getSid()
{
return sid;
@@ -677,30 +351,23 @@ public class SSTRecord
/**
* @return hashcode
*/
-
public int hashCode()
{
return field_2_num_unique_strings;
}
- /**
- *
- * @param o
- * @return true if equal
- */
-
- public boolean equals(Object o)
+ public boolean equals( Object o )
{
- if ((o == null) || (o.getClass() != this.getClass()))
+ if ( ( o == null ) || ( o.getClass() != this.getClass() ) )
{
return false;
}
- SSTRecord other = ( SSTRecord ) o;
+ SSTRecord other = (SSTRecord) o;
- return ((field_1_num_strings == other
- .field_1_num_strings) && (field_2_num_unique_strings == other
- .field_2_num_unique_strings) && field_3_strings
- .equals(other.field_3_strings));
+ return ( ( field_1_num_strings == other
+ .field_1_num_strings ) && ( field_2_num_unique_strings == other
+ .field_2_num_unique_strings ) && field_3_strings
+ .equals( other.field_3_strings ) );
}
/**
@@ -711,12 +378,12 @@ public class SSTRecord
* @exception RecordFormatException if validation fails
*/
- protected void validateSid(final short id)
- throws RecordFormatException
+ protected void validateSid( final short id )
+ throws RecordFormatException
{
- if (id != sid)
+ if ( id != sid )
{
- throw new RecordFormatException("NOT An SST RECORD");
+ throw new RecordFormatException( "NOT An SST RECORD" );
}
}
@@ -800,33 +467,20 @@ public class SSTRecord
* @param size size of the raw data
*/
- protected void fillFields(final byte [] data, final short size,
- int offset)
+ protected void fillFields( final byte[] data, final short size,
+ int offset )
{
// this method is ALWAYS called after construction -- using
// the nontrivial constructor, of course -- so this is where
// we initialize our fields
- field_1_num_strings = LittleEndian.getInt(data, 0 + offset);
- field_2_num_unique_strings = LittleEndian.getInt(data, 4 + offset);
- field_3_strings = new BinaryTree();
- setExpectedChars(0);
- _unfinished_string = "";
- _total_length_bytes = 0;
- _string_data_offset = 0;
- _wide_char = false;
- manufactureStrings(data, 8 + offset, size);
+ field_1_num_strings = LittleEndian.getInt( data, 0 + offset );
+ field_2_num_unique_strings = LittleEndian.getInt( data, 4 + offset );
+ field_3_strings = new BinaryTree();
+ deserializer = new SSTDeserializer(field_3_strings);
+ deserializer.manufactureStrings( data, 8 + offset, (short)(size - 8) );
}
- /**
- * @return the number of characters we expect in the first
- * sub-record in a subsequent continuation record
- */
-
- int getExpectedChars()
- {
- return __expected_chars;
- }
/**
* @return an iterator of the strings we hold. All instances are
@@ -848,372 +502,43 @@ public class SSTRecord
}
/**
- * @return the unfinished string
+ * called by the class that is responsible for writing this sucker.
+ * Subclasses should implement this so that their data is passed back in a
+ * byte array.
+ *
+ * @return byte array containing instance data
*/
- String getUnfinishedString()
+ public int serialize( int offset, byte[] data )
{
- return _unfinished_string;
+ SSTSerializer serializer = new SSTSerializer(
+ _record_lengths, field_3_strings, getNumStrings(), getNumUniqueStrings() );
+ return serializer.serialize( offset, data );
}
- /**
- * @return the total length of the current string
- */
- int getTotalLength()
+ // we can probably simplify this later...this calculates the size
+ // w/o serializing but still is a bit slow
+ public int getRecordSize()
{
- return _total_length_bytes;
- }
+ SSTSerializer serializer = new SSTSerializer(
+ _record_lengths, field_3_strings, getNumStrings(), getNumUniqueStrings() );
- /**
- * @return offset into current string data
- */
+ return serializer.getRecordSize();
+ }
- int getStringDataOffset()
+ SSTDeserializer getDeserializer()
{
- return _string_data_offset;
+ return deserializer;
}
/**
- * @return true if current string uses wide characters
+ * Strange to handle continue records this way. Is it a smell?
*/
-
- boolean isWideChar()
- {
- return _wide_char;
- }
-
- private int writeSSTHeader(final byte [] data, final int pos,
- final int recsize)
- {
- int offset = pos;
-
- LittleEndian.putShort(data, offset, sid);
- offset += LittleEndianConsts.SHORT_SIZE;
- LittleEndian.putShort(data, offset, ( short ) (recsize));
- offset += LittleEndianConsts.SHORT_SIZE;
- LittleEndian.putInt(data, offset, getNumStrings());
- offset += LittleEndianConsts.INT_SIZE;
- LittleEndian.putInt(data, offset, getNumUniqueStrings());
- offset += LittleEndianConsts.INT_SIZE;
- return offset - pos;
- }
-
- private int writeContinueHeader(final byte [] data, final int pos,
- final int recsize)
- {
- int offset = pos;
-
- LittleEndian.putShort(data, offset, ContinueRecord.sid);
- offset += LittleEndianConsts.SHORT_SIZE;
- LittleEndian.putShort(data, offset, ( short ) (recsize));
- offset += LittleEndianConsts.SHORT_SIZE;
- return offset - pos;
- }
-
- private int calculateUCArrayLength(final byte [][] ucarray)
- {
- int retval = 0;
-
- for (int k = 0; k < ucarray.length; k++)
- {
- retval += ucarray[ k ].length;
- }
- return retval;
- }
-
- private void manufactureStrings(final byte [] data, final int index,
- short size)
- {
- int offset = index;
-
- while (offset < size)
- {
- int remaining = size - offset;
-
- if ((remaining > 0)
- && (remaining < LittleEndianConsts.SHORT_SIZE))
- {
- throw new RecordFormatException(
- "Cannot get length of the last string in SSTRecord");
- }
- if (remaining == LittleEndianConsts.SHORT_SIZE)
- {
- setExpectedChars(LittleEndian.getShort(data, offset));
- _unfinished_string = "";
- break;
- }
- short char_count = LittleEndian.getShort(data, offset);
-
- setupStringParameters(data, offset, char_count);
- if (remaining < _total_length_bytes)
- {
- setExpectedChars(calculateCharCount(_total_length_bytes
- - remaining));
- char_count -= getExpectedChars();
- _total_length_bytes = remaining;
- }
- else
- {
- setExpectedChars(0);
- }
- processString(data, offset, char_count);
- offset += _total_length_bytes;
- if (getExpectedChars() != 0)
- {
- break;
- }
- }
- }
-
- private void setupStringParameters(final byte [] data, final int index,
- final int char_count)
- {
- byte flag = data[ index + LittleEndianConsts.SHORT_SIZE ];
-
- _wide_char = (flag & 1) == 1;
- boolean extended = (flag & 4) == 4;
- boolean formatted_run = (flag & 8) == 8;
-
- _total_length_bytes = _string_minimal_overhead
- + calculateByteCount(char_count);
- _string_data_offset = _string_minimal_overhead;
- if (formatted_run)
- {
- short run_count = LittleEndian.getShort(data,
- index
- + _string_data_offset);
-
- _string_data_offset += LittleEndianConsts.SHORT_SIZE;
- _total_length_bytes += LittleEndianConsts.SHORT_SIZE
- + (LittleEndianConsts.INT_SIZE
- * run_count);
- }
- if (extended)
- {
- int extension_length = LittleEndian.getInt(data,
- index
- + _string_data_offset);
-
- _string_data_offset += LittleEndianConsts.INT_SIZE;
- _total_length_bytes += LittleEndianConsts.INT_SIZE
- + extension_length;
- }
- }
-
- private void processString(final byte [] data, final int index,
- final short char_count)
- {
- byte[] str_data = new byte[ _total_length_bytes ];
- int length = _string_minimal_overhead
- + calculateByteCount(char_count);
- byte[] bstring = new byte[ length ];
-
- System.arraycopy(data, index, str_data, 0, str_data.length);
- int offset = 0;
-
- LittleEndian.putShort(bstring, offset, char_count);
- offset += LittleEndianConsts.SHORT_SIZE;
- bstring[ offset ] = str_data[ offset ];
- System.arraycopy(str_data, _string_data_offset, bstring,
- _string_minimal_overhead,
- bstring.length - _string_minimal_overhead);
- UnicodeString string = new UnicodeString(UnicodeString.sid,
- ( short ) bstring.length,
- bstring);
-
- if (getExpectedChars() != 0)
- {
- _unfinished_string = string.getString();
- }
- else
- {
- Integer integer = new Integer(field_3_strings.size());
-
- field_3_strings.put(integer, string);
- }
- }
-
- private void setExpectedChars(final int count)
- {
- __expected_chars = count;
- }
-
- private int calculateByteCount(final int character_count)
- {
- return character_count * (_wide_char ? LittleEndianConsts.SHORT_SIZE
- : LittleEndianConsts.BYTE_SIZE);
- }
-
- private int calculateCharCount(final int byte_count)
+ public void processContinueRecord( byte[] record )
{
- return byte_count / (_wide_char ? LittleEndianConsts.SHORT_SIZE
- : LittleEndianConsts.BYTE_SIZE);
+ deserializer.processContinueRecord( record );
}
+}
- // we can probably simplify this later...this calculates the size
- // w/o serializing but still is a bit slow
- public int getRecordSize()
- {
- _record_lengths = new ArrayList();
- int retval = 0;
- int unicodesize = calculateUnicodeSize();
-
- if (unicodesize > _max_data_space)
- {
- UnicodeString unistr = null;
- int stringreminant = 0;
- int unipos = 0;
- boolean lastneedcontinue = false;
- int stringbyteswritten = 0;
- boolean finished = false;
- boolean first_record = true;
- int totalWritten = 0;
-
- while (!finished)
- {
- int record = 0;
- int pos = 0;
-
- if (first_record)
- {
-
- // writing SST record
- record = _max;
- pos = 12;
- first_record = false;
- _record_lengths.add(new Integer(record
- - _std_record_overhead));
- }
- else
- {
-
- // writing continue record
- pos = 0;
- int to_be_written = (unicodesize - stringbyteswritten)
- + (lastneedcontinue ? 1
- : 0);
- int size = Math.min(_max - _std_record_overhead,
- to_be_written);
-
- if (size == to_be_written)
- {
- finished = true;
- }
- record = size + _std_record_overhead;
- _record_lengths.add(new Integer(size));
- pos = 4;
- }
- if (lastneedcontinue)
- {
- int available = _max - pos;
-
- if (stringreminant <= available)
- {
-
- // write reminant
- stringbyteswritten += stringreminant - 1;
- pos += stringreminant;
- lastneedcontinue = false;
- }
- else
- {
-
- // write as much of the remnant as possible
- int toBeWritten = unistr.maxBrokenLength(available);
-
- if (available != toBeWritten)
- {
- int shortrecord = record
- - (available - toBeWritten);
-
- _record_lengths.set(
- _record_lengths.size() - 1,
- new Integer(
- shortrecord - _std_record_overhead));
- record = shortrecord;
- }
- stringbyteswritten += toBeWritten - 1;
- pos += toBeWritten;
- stringreminant -= toBeWritten - 1;
- lastneedcontinue = true;
- }
- }
- for (; unipos < field_3_strings.size(); unipos++)
- {
- int available = _max - pos;
- Integer intunipos = new Integer(unipos);
-
- unistr =
- (( UnicodeString ) field_3_strings.get(intunipos));
- if (unistr.getRecordSize() <= available)
- {
- stringbyteswritten += unistr.getRecordSize();
- pos += unistr.getRecordSize();
- }
- else
- {
- if (available >= _string_minimal_overhead)
- {
- int toBeWritten =
- unistr.maxBrokenLength(available);
-
- stringbyteswritten += toBeWritten;
- stringreminant =
- (unistr.getRecordSize() - toBeWritten)
- + LittleEndianConsts.BYTE_SIZE;
- if (available != toBeWritten)
- {
- int shortrecord = record
- - (available - toBeWritten);
-
- _record_lengths.set(
- _record_lengths.size() - 1,
- new Integer(
- shortrecord - _std_record_overhead));
- record = shortrecord;
- }
- lastneedcontinue = true;
- unipos++;
- }
- else
- {
- int shortrecord = record - available;
-
- _record_lengths.set(
- _record_lengths.size() - 1,
- new Integer(
- shortrecord - _std_record_overhead));
- record = shortrecord;
- }
- break;
- }
- }
- totalWritten += record;
- }
- retval = totalWritten;
- }
- else
- {
-
- // short data: write one simple SST record
- retval = _sst_record_overhead + unicodesize;
- _record_lengths.add(new Integer(unicodesize));
- }
- return retval;
- }
-
- private int calculateUnicodeSize()
- {
- int retval = 0;
-
- for (int k = 0; k < field_3_strings.size(); k++)
- {
- UnicodeString string =
- ( UnicodeString ) field_3_strings.get(new Integer(k));
- retval += string.getRecordSize();
- }
- return retval;
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/SSTSerializer.java b/src/java/org/apache/poi/hssf/record/SSTSerializer.java
new file mode 100644
index 0000000000..5802279145
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/SSTSerializer.java
@@ -0,0 +1,356 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache POI" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache POI", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.poi.hssf.record;
+
+import org.apache.poi.util.BinaryTree;
+import org.apache.poi.util.LittleEndianConsts;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * This class handles serialization of SST records. It utilizes the record processor
+ * class write individual records. This has been refactored from the SSTRecord class.
+ *
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+class SSTSerializer
+{
+
+ private List recordLengths;
+ private BinaryTree strings;
+ private int numStrings;
+ private int numUniqueStrings;
+ private SSTRecordHeader sstRecordHeader;
+
+ public SSTSerializer( List recordLengths, BinaryTree strings, int numStrings, int numUniqueStrings )
+ {
+ this.recordLengths = recordLengths;
+ this.strings = strings;
+ this.numStrings = numStrings;
+ this.numUniqueStrings = numUniqueStrings;
+ this.sstRecordHeader = new SSTRecordHeader(numStrings, numUniqueStrings);
+ }
+
+ /**
+ * Create a byte array consisting of an SST record and any
+ * required Continue records, ready to be written out.
+ * <p>
+ * If an SST record and any subsequent Continue records are read
+ * in to create this instance, this method should produce a byte
+ * array that is identical to the byte array produced by
+ * concatenating the input records' data.
+ *
+ * @return the byte array
+ */
+ public int serialize( int offset, byte[] data )
+ {
+ int record_size = getRecordSize();
+ int record_length_index = 0;
+
+ if ( calculateUnicodeSize() > SSTRecord.MAX_DATA_SPACE )
+ serializeLargeRecord( record_size, record_length_index, data, offset );
+ else
+ serializeSingleSSTRecord( data, offset, record_length_index );
+ return record_size;
+ }
+
+ private int calculateUnicodeSize()
+ {
+ int retval = 0;
+
+ for ( int k = 0; k < strings.size(); k++ )
+ {
+ retval += getUnicodeString(k).getRecordSize();
+ }
+ return retval;
+ }
+
+ // we can probably simplify this later...this calculates the size
+ // w/o serializing but still is a bit slow
+ public int getRecordSize()
+ {
+ recordLengths = new ArrayList();
+ int retval = 0;
+ int unicodesize = calculateUnicodeSize();
+
+ if ( unicodesize > SSTRecord.MAX_DATA_SPACE )
+ {
+ retval = calcRecordSizesForLongStrings( unicodesize );
+ }
+ else
+ {
+ // short data: write one simple SST record
+ retval = SSTRecord.SST_RECORD_OVERHEAD + unicodesize;
+ recordLengths.add( new Integer( unicodesize ) );
+ }
+ return retval;
+ }
+
+ private int calcRecordSizesForLongStrings( int unicodesize )
+ {
+ int retval;
+ UnicodeString unistr = null;
+ int stringreminant = 0;
+ int unipos = 0;
+ boolean lastneedcontinue = false;
+ int stringbyteswritten = 0;
+ boolean finished = false;
+ boolean first_record = true;
+ int totalWritten = 0;
+
+ while ( !finished )
+ {
+ int record = 0;
+ int pos = 0;
+
+ if ( first_record )
+ {
+
+ // writing SST record
+ record = SSTRecord.MAX_RECORD_SIZE;
+ pos = 12;
+ first_record = false;
+ recordLengths.add( new Integer( record - SSTRecord.STD_RECORD_OVERHEAD ) );
+ }
+ else
+ {
+
+ // writing continue record
+ pos = 0;
+ int to_be_written = ( unicodesize - stringbyteswritten ) + ( lastneedcontinue ? 1 : 0 );
+ int size = Math.min( SSTRecord.MAX_RECORD_SIZE - SSTRecord.STD_RECORD_OVERHEAD, to_be_written );
+
+ if ( size == to_be_written )
+ {
+ finished = true;
+ }
+ record = size + SSTRecord.STD_RECORD_OVERHEAD;
+ recordLengths.add( new Integer( size ) );
+ pos = 4;
+ }
+ if ( lastneedcontinue )
+ {
+ int available = SSTRecord.MAX_RECORD_SIZE - pos;
+
+ if ( stringreminant <= available )
+ {
+
+ // write reminant
+ stringbyteswritten += stringreminant - 1;
+ pos += stringreminant;
+ lastneedcontinue = false;
+ }
+ else
+ {
+
+ // write as much of the remnant as possible
+ int toBeWritten = unistr.maxBrokenLength( available );
+
+ if ( available != toBeWritten )
+ {
+ int shortrecord = record - ( available - toBeWritten );
+ recordLengths.set( recordLengths.size() - 1,
+ new Integer( shortrecord - SSTRecord.STD_RECORD_OVERHEAD ) );
+ record = shortrecord;
+ }
+ stringbyteswritten += toBeWritten - 1;
+ pos += toBeWritten;
+ stringreminant -= toBeWritten - 1;
+ lastneedcontinue = true;
+ }
+ }
+ for ( ; unipos < strings.size(); unipos++ )
+ {
+ int available = SSTRecord.MAX_RECORD_SIZE - pos;
+ Integer intunipos = new Integer( unipos );
+
+ unistr = ( (UnicodeString) strings.get( intunipos ) );
+ if ( unistr.getRecordSize() <= available )
+ {
+ stringbyteswritten += unistr.getRecordSize();
+ pos += unistr.getRecordSize();
+ }
+ else
+ {
+ if ( available >= SSTRecord.STRING_MINIMAL_OVERHEAD )
+ {
+ int toBeWritten =
+ unistr.maxBrokenLength( available );
+
+ stringbyteswritten += toBeWritten;
+ stringreminant =
+ ( unistr.getRecordSize() - toBeWritten )
+ + LittleEndianConsts.BYTE_SIZE;
+ if ( available != toBeWritten )
+ {
+ int shortrecord = record
+ - ( available - toBeWritten );
+
+ recordLengths.set(
+ recordLengths.size() - 1,
+ new Integer(
+ shortrecord - SSTRecord.STD_RECORD_OVERHEAD ) );
+ record = shortrecord;
+ }
+ lastneedcontinue = true;
+ unipos++;
+ }
+ else
+ {
+ int shortrecord = record - available;
+
+ recordLengths.set( recordLengths.size() - 1,
+ new Integer( shortrecord - SSTRecord.STD_RECORD_OVERHEAD ) );
+ record = shortrecord;
+ }
+ break;
+ }
+ }
+ totalWritten += record;
+ }
+ retval = totalWritten;
+
+ return retval;
+ }
+
+
+ private void serializeSingleSSTRecord( byte[] data, int offset, int record_length_index )
+ {
+ // short data: write one simple SST record
+
+ int len = ( (Integer) recordLengths.get( record_length_index++ ) ).intValue();
+ int recordSize = SSTRecord.SST_RECORD_OVERHEAD + len - SSTRecord.STD_RECORD_OVERHEAD;
+ sstRecordHeader.writeSSTHeader( data, 0 + offset, recordSize );
+ int pos = SSTRecord.SST_RECORD_OVERHEAD;
+
+ for ( int k = 0; k < strings.size(); k++ )
+ {
+// UnicodeString unistr = ( (UnicodeString) strings.get( new Integer( k ) ) );
+ System.arraycopy( getUnicodeString(k).serialize(), 0, data, pos + offset, getUnicodeString(k).getRecordSize() );
+ pos += getUnicodeString(k).getRecordSize();
+ }
+ }
+
+ /**
+ * Large records are serialized to an SST and to one or more CONTINUE records. Joy. They have the special
+ * characteristic that they can change the option field when a single string is split across to a
+ * CONTINUE record.
+ */
+ private void serializeLargeRecord( int record_size, int record_length_index, byte[] buffer, int offset )
+ {
+
+ byte[] stringReminant = null;
+ int stringIndex = 0;
+ boolean lastneedcontinue = false;
+ boolean first_record = true;
+ int totalWritten = 0;
+
+ while ( totalWritten != record_size )
+ {
+ int recordLength = ( (Integer) recordLengths.get( record_length_index++ ) ).intValue();
+ RecordProcessor recordProcessor = new RecordProcessor( buffer,
+ recordLength, numStrings, numUniqueStrings );
+
+ // write the appropriate header
+ recordProcessor.writeRecordHeader( offset, totalWritten, recordLength, first_record );
+ first_record = false;
+
+ // now, write the rest of the data into the current
+ // record space
+ if ( lastneedcontinue )
+ {
+ lastneedcontinue = stringReminant.length > recordProcessor.getAvailable();
+ // the last string in the previous record was not written out completely
+ stringReminant = recordProcessor.writeStringRemainder( lastneedcontinue,
+ stringReminant, offset, totalWritten );
+ }
+
+ // last string's remnant, if any, is cleaned up as best as can be done ... now let's try and write
+ // some more strings
+ for ( ; stringIndex < strings.size(); stringIndex++ )
+ {
+ UnicodeString unistr = getUnicodeString( stringIndex );
+
+ if ( unistr.getRecordSize() <= recordProcessor.getAvailable() )
+ {
+ recordProcessor.writeWholeString( unistr, offset, totalWritten );
+ }
+ else
+ {
+
+ // can't write the entire string out
+ if ( recordProcessor.getAvailable() >= SSTRecord.STRING_MINIMAL_OVERHEAD )
+ {
+
+ // we can write some of it
+ stringReminant = recordProcessor.writePartString( unistr, offset, totalWritten );
+ lastneedcontinue = true;
+ stringIndex++;
+ }
+ break;
+ }
+ }
+ totalWritten += recordLength + SSTRecord.STD_RECORD_OVERHEAD;
+ }
+ }
+
+ private UnicodeString getUnicodeString( int index )
+ {
+ Integer intunipos = new Integer( index );
+ return ( (UnicodeString) strings.get( intunipos ) );
+ }
+
+}
diff --git a/src/java/org/apache/poi/hssf/record/UnicodeString.java b/src/java/org/apache/poi/hssf/record/UnicodeString.java
index 097be19b1c..d56b660d43 100644
--- a/src/java/org/apache/poi/hssf/record/UnicodeString.java
+++ b/src/java/org/apache/poi/hssf/record/UnicodeString.java
@@ -66,6 +66,7 @@ import org.apache.poi.util.StringUtil;
* REFERENCE: PG 264 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
* @author Andrew C. Oliver
* @author Marc Johnson (mjohnson at apache dot org)
+ * @author Glen Stampoultzis (glens at apache.org)
* @version 2.0-pre
*/
@@ -77,12 +78,29 @@ public class UnicodeString
private short field_1_charCount; // = 0;
private byte field_2_optionflags; // = 0;
private String field_3_string; // = null;
+ private final int RICH_TEXT_BIT = 8;
+ private final int EXT_BIT = 4;
+
+ public UnicodeString()
+ {
+ }
+
public int hashCode()
{
- return field_1_charCount;
+ int stringHash = 0;
+ if (field_3_string != null)
+ stringHash = field_3_string.hashCode();
+ return field_1_charCount + stringHash;
}
+ /**
+ * Our handling of equals is inconsistent with compareTo. The trouble is because we don't truely understand
+ * rich text fields yet it's difficult to make a sound comparison.
+ *
+ * @param o The object to compare.
+ * @return true if the object is actually equal.
+ */
public boolean equals(Object o)
{
if ((o == null) || (o.getClass() != this.getClass()))
@@ -96,10 +114,6 @@ public class UnicodeString
&& field_3_string.equals(other.field_3_string));
}
- public UnicodeString()
- {
- }
-
/**
* construct a unicode string record and fill its fields, ID is ignored
* @param id - ignored
@@ -278,19 +292,10 @@ public class UnicodeString
public int serialize(int offset, byte [] data)
{
- int charsize = 1;
-
- if (getOptionFlags() == 1)
- {
- charsize = 2;
- }
-
- // byte[] retval = new byte[ 3 + (getString().length() * charsize) ];
LittleEndian.putShort(data, 0 + offset, getCharCount());
data[ 2 + offset ] = getOptionFlags();
-// System.out.println("Unicode: We've got "+retval[2]+" for our option flag");
- if (getOptionFlags() == 0)
+ if (!isUncompressedUnicode())
{
StringUtil.putCompressedUnicode(getString(), data, 0x3 + offset);
}
@@ -302,14 +307,14 @@ public class UnicodeString
return getRecordSize();
}
- public int getRecordSize()
+ private boolean isUncompressedUnicode()
{
- int charsize = 1;
+ return (getOptionFlags() & 0x01) == 1;
+ }
- if (getOptionFlags() == 1)
- {
- charsize = 2;
- }
+ public int getRecordSize()
+ {
+ int charsize = isUncompressedUnicode() ? 2 : 1;
return 3 + (getString().length() * charsize);
}
@@ -338,11 +343,16 @@ public class UnicodeString
return this.getString().compareTo(str.getString());
}
+ public boolean isRichText()
+ {
+ return (getOptionFlags() & RICH_TEXT_BIT) != 0;
+ }
+
int maxBrokenLength(final int proposedBrokenLength)
{
int rval = proposedBrokenLength;
- if ((field_2_optionflags & 1) == 1)
+ if (isUncompressedUnicode())
{
int proposedStringLength = proposedBrokenLength - 3;
@@ -355,12 +365,9 @@ public class UnicodeString
return rval;
}
-// public boolean equals(Object obj) {
-// if (!(obj instanceof UnicodeString)) return false;
-//
-// UnicodeString str = (UnicodeString)obj;
-//
-//
-// return this.getString().equals(str.getString());
-// }
+ public boolean isExtendedText()
+ {
+ return (getOptionFlags() & EXT_BIT) != 0;
+ }
+
}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
index 39da13e42c..e9209800e3 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
@@ -126,8 +126,8 @@ public class HSSFRow
this.sheet = sheet;
row = new RowRecord();
row.setHeight((short) 0xff);
- row.setLastCol((short)-1);
- row.setFirstCol((short)-1);
+ row.setLastCol((short) -1);
+ row.setFirstCol((short) -1);
// row.setRowNumber(rowNum);
setRowNum(rowNum);
@@ -213,11 +213,11 @@ public class HSSFRow
if (cell.getCellNum() == row.getLastCol())
{
- row.setLastCol( findLastCell(row.getLastCol()) );
+ row.setLastCol(findLastCell(row.getLastCol()));
}
if (cell.getCellNum() == row.getFirstCol())
{
- row.setFirstCol( findFirstCell(row.getFirstCol()) );
+ row.setFirstCol(findFirstCell(row.getFirstCol()));
}
}
@@ -270,11 +270,11 @@ public class HSSFRow
{
if (row.getFirstCol() == -1)
{
- row.setFirstCol( cell.getCellNum() );
+ row.setFirstCol(cell.getCellNum());
}
if (row.getLastCol() == -1)
{
- row.setLastCol( cell.getCellNum() );
+ row.setLastCol(cell.getCellNum());
}
cells.put(new Integer(cell.getCellNum()), cell);
@@ -292,8 +292,8 @@ public class HSSFRow
* get the hssfcell representing a given column (logical cell) 0-based. If you
* ask for a cell that is not defined....you get a null.
*
- * @param cellnum - 0 based column number
- * @returns HSSFCell representing that column or null if undefined.
+ * @param cellnum 0 based column number
+ * @return HSSFCell representing that column or null if undefined.
*/
public HSSFCell getCell(short cellnum)
@@ -318,7 +318,10 @@ public class HSSFRow
public short getFirstCellNum()
{
- return row.getFirstCol();
+ if (getPhysicalNumberOfCells() == 0)
+ return -1;
+ else
+ return row.getFirstCol();
}
/**
@@ -328,7 +331,10 @@ public class HSSFRow
public short getLastCellNum()
{
- return row.getLastCol();
+ if (getPhysicalNumberOfCells() == 0)
+ return -1;
+ else
+ return row.getLastCol();
}
@@ -441,7 +447,7 @@ public class HSSFRow
}
/**
- * @returns cell iterator of the physically defined cells. Note element 4 may
+ * @return cell iterator of the physically defined cells. Note element 4 may
* actually be row cell depending on how many are defined!
*/
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
index ddb5dc8a65..c6cb967622 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
@@ -1,4 +1,3 @@
-
/* ====================================================================
* The Apache Software License, Version 1.1
*
@@ -60,11 +59,14 @@
*/
package org.apache.poi.hssf.usermodel;
-import org.apache.poi.util.POILogFactory;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook;
-import org.apache.poi.hssf.record.*;
+import org.apache.poi.hssf.record.CellValueRecordInterface;
+import org.apache.poi.hssf.record.RowRecord;
+import org.apache.poi.hssf.record.VCenterRecord;
+import org.apache.poi.hssf.record.WSBoolRecord;
import org.apache.poi.hssf.util.Region;
+import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import java.util.Iterator;
@@ -74,12 +76,12 @@ import java.util.TreeMap;
* High level representation of a worksheet.
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Glen Stampoultzis (glens at apache.org)
- * @version 1.0-pre
+ * @author Libin Roman (romal at vistaportal.com)
*/
public class HSSFSheet
{
- private static final int DEBUG = POILogger.DEBUG;
+ private static final int DEBUG = POILogger.DEBUG;
/**
* Used for compile-time optimization. This is the initial size for the collection of
@@ -87,17 +89,17 @@ public class HSSFSheet
* by setting this to a higher number and recompiling a custom edition of HSSFSheet.
*/
- public final static int INITIAL_CAPACITY = 20;
+ public final static int INITIAL_CAPACITY = 20;
/**
* reference to the low level Sheet object
*/
- private Sheet sheet;
- private TreeMap rows;
- private Workbook book;
- private int firstrow;
- private int lastrow;
+ private Sheet sheet;
+ private TreeMap rows;
+ private Workbook book;
+ private int firstrow;
+ private int lastrow;
private static POILogger log = POILogFactory.getLogger(HSSFSheet.class);
/**
@@ -110,8 +112,8 @@ public class HSSFSheet
protected HSSFSheet(Workbook book)
{
- sheet = Sheet.createSheet();
- rows = new TreeMap(); // new ArrayList(INITIAL_CAPACITY);
+ sheet = Sheet.createSheet();
+ rows = new TreeMap(); // new ArrayList(INITIAL_CAPACITY);
this.book = book;
}
@@ -127,16 +129,11 @@ public class HSSFSheet
protected HSSFSheet(Workbook book, Sheet sheet)
{
this.sheet = sheet;
- rows = new TreeMap();
- this.book = book;
+ rows = new TreeMap();
+ this.book = book;
setPropertiesFromSheet(sheet);
}
- /** private default constructor prevents bogus initializationless construction */
-
- private HSSFSheet()
- {
- }
/**
* used internally to set the properties given a Sheet object
@@ -144,8 +141,8 @@ public class HSSFSheet
private void setPropertiesFromSheet(Sheet sheet)
{
- int sloc = sheet.getLoc();
- RowRecord row = sheet.getNextRow();
+ int sloc = sheet.getLoc();
+ RowRecord row = sheet.getNextRow();
while (row != null)
{
@@ -154,8 +151,8 @@ public class HSSFSheet
row = sheet.getNextRow();
}
sheet.setLoc(sloc);
- CellValueRecordInterface cval = sheet.getNextValueRecord();
- long timestart = System.currentTimeMillis();
+ CellValueRecordInterface cval = sheet.getNextValueRecord();
+ long timestart = System.currentTimeMillis();
log.log(DEBUG, "Time at start of cell creating in HSSF sheet = ",
new Long(timestart));
@@ -163,8 +160,8 @@ public class HSSFSheet
while (cval != null)
{
- long cellstart = System.currentTimeMillis();
- HSSFRow hrow = lastrow;
+ long cellstart = System.currentTimeMillis();
+ HSSFRow hrow = lastrow;
if ((lastrow == null) || (lastrow.getRowNum() != cval.getRow()))
{
@@ -236,10 +233,10 @@ public class HSSFSheet
while (iter.hasNext())
{
- HSSFCell cell = ( HSSFCell ) iter.next();
+ HSSFCell cell = (HSSFCell) iter.next();
sheet.removeValueRecord(row.getRowNum(),
- cell.getCellValueRecord());
+ cell.getCellValueRecord());
}
sheet.removeRow(row.getRowRecord());
}
@@ -251,10 +248,10 @@ public class HSSFSheet
private int findLastRow(int lastrow)
{
- int rownum = lastrow - 1;
- HSSFRow r = getRow(rownum);
+ int rownum = lastrow - 1;
+ HSSFRow r = getRow(rownum);
- while (r == null)
+ while (r == null && rownum >= 0)
{
r = getRow(--rownum);
}
@@ -267,13 +264,17 @@ public class HSSFSheet
private int findFirstRow(int firstrow)
{
- int rownum = firstrow + 1;
- HSSFRow r = getRow(rownum);
+ int rownum = firstrow + 1;
+ HSSFRow r = getRow(rownum);
- while (r == null)
+ while (r == null && rownum <= getLastRowNum())
{
r = getRow(++rownum);
}
+
+ if (rownum > getLastRowNum())
+ return -1;
+
return rownum;
}
@@ -311,8 +312,8 @@ public class HSSFSheet
{
HSSFRow row = new HSSFRow();
- row.setRowNum(( short ) rownum);
- return ( HSSFRow ) rows.get(row);
+ row.setRowNum((short) rownum);
+ return (HSSFRow) rows.get(row);
}
/**
@@ -345,26 +346,6 @@ public class HSSFSheet
}
/**
- * Seems to be unused (gjs)
- *
- * used internally to add cells from a high level row to the low level model
- * @param row the row object to represent in low level RowRecord.
- */
- private void addCellsFromRow(HSSFRow row)
- {
- Iterator iter = row.cellIterator();
-
- // for (int k = 0; k < row.getPhysicalNumberOfCells(); k++)
- while (iter.hasNext())
- {
- HSSFCell cell =
- ( HSSFCell ) iter.next(); // row.getPhysicalCellAt(k);
-
- sheet.addValueRecord(row.getRowNum(), cell.getCellValueRecord());
- }
- }
-
- /**
* set the width (in units of 1/256th of a character width)
* @param column - the column to set (0-based)
* @param width - the width in units of 1/256th of a character width
@@ -400,7 +381,7 @@ public class HSSFSheet
/**
* get the default row height for the sheet (if the rows do not define their own height) in
* twips (1/20 of a point)
- * @retun default row height
+ * @return default row height
*/
public short getDefaultRowHeight()
@@ -449,7 +430,7 @@ public class HSSFSheet
public void setDefaultRowHeightInPoints(float height)
{
- sheet.setDefaultRowHeight(( short ) (height * 20));
+ sheet.setDefaultRowHeight((short) (height * 20));
}
/**
@@ -480,10 +461,10 @@ public class HSSFSheet
public int addMergedRegion(Region region)
{
- return sheet.addMergedRegion(( short ) region.getRowFrom(),
- region.getColumnFrom(),
- ( short ) region.getRowTo(),
- region.getColumnTo());
+ return sheet.addMergedRegion((short) region.getRowFrom(),
+ region.getColumnFrom(),
+ (short) region.getRowTo(),
+ region.getColumnTo());
}
/**
@@ -494,7 +475,7 @@ public class HSSFSheet
public void setVerticallyCenter(boolean value)
{
VCenterRecord record =
- ( VCenterRecord ) sheet.findFirstRecordBySid(VCenterRecord.sid);
+ (VCenterRecord) sheet.findFirstRecordBySid(VCenterRecord.sid);
record.setVCenter(value);
}
@@ -506,7 +487,7 @@ public class HSSFSheet
public boolean getVerticallyCenter(boolean value)
{
VCenterRecord record =
- ( VCenterRecord ) sheet.findFirstRecordBySid(VCenterRecord.sid);
+ (VCenterRecord) sheet.findFirstRecordBySid(VCenterRecord.sid);
return record.getVCenter();
}
@@ -543,7 +524,7 @@ public class HSSFSheet
}
/**
- * @returns an iterator of the PHYSICAL rows. Meaning the 3rd element may not
+ * @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.
*/
@@ -571,7 +552,7 @@ public class HSSFSheet
public void setAlternativeExpression(boolean b)
{
WSBoolRecord record =
- ( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid);
+ (WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid);
record.setAlternateExpression(b);
}
@@ -584,7 +565,7 @@ public class HSSFSheet
public void setAlternativeFormula(boolean b)
{
WSBoolRecord record =
- ( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid);
+ (WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid);
record.setAlternateFormula(b);
}
@@ -597,7 +578,7 @@ public class HSSFSheet
public void setAutobreaks(boolean b)
{
WSBoolRecord record =
- ( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid);
+ (WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid);
record.setAutobreaks(b);
}
@@ -610,7 +591,7 @@ public class HSSFSheet
public void setDialog(boolean b)
{
WSBoolRecord record =
- ( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid);
+ (WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid);
record.setDialog(b);
}
@@ -624,7 +605,7 @@ public class HSSFSheet
public void setDisplayGuts(boolean b)
{
WSBoolRecord record =
- ( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid);
+ (WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid);
record.setDisplayGuts(b);
}
@@ -637,7 +618,7 @@ public class HSSFSheet
public void setFitToPage(boolean b)
{
WSBoolRecord record =
- ( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid);
+ (WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid);
record.setFitToPage(b);
}
@@ -650,7 +631,7 @@ public class HSSFSheet
public void setRowSumsBelow(boolean b)
{
WSBoolRecord record =
- ( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid);
+ (WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid);
record.setRowSumsBelow(b);
}
@@ -663,7 +644,7 @@ public class HSSFSheet
public void setRowSumsRight(boolean b)
{
WSBoolRecord record =
- ( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid);
+ (WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid);
record.setRowSumsRight(b);
}
@@ -675,8 +656,8 @@ public class HSSFSheet
public boolean getAlternateExpression()
{
- return (( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid))
- .getAlternateExpression();
+ return ((WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid))
+ .getAlternateExpression();
}
/**
@@ -686,8 +667,8 @@ public class HSSFSheet
public boolean getAlternateFormula()
{
- return (( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid))
- .getAlternateFormula();
+ return ((WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid))
+ .getAlternateFormula();
}
/**
@@ -697,8 +678,8 @@ public class HSSFSheet
public boolean getAutobreaks()
{
- return (( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid))
- .getAutobreaks();
+ return ((WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid))
+ .getAutobreaks();
}
/**
@@ -708,8 +689,8 @@ public class HSSFSheet
public boolean getDialog()
{
- return (( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid))
- .getDialog();
+ return ((WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid))
+ .getDialog();
}
/**
@@ -720,8 +701,8 @@ public class HSSFSheet
public boolean getDisplayGuts()
{
- return (( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid))
- .getDisplayGuts();
+ return ((WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid))
+ .getDisplayGuts();
}
/**
@@ -731,8 +712,8 @@ public class HSSFSheet
public boolean getFitToPage()
{
- return (( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid))
- .getFitToPage();
+ return ((WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid))
+ .getFitToPage();
}
/**
@@ -742,8 +723,8 @@ public class HSSFSheet
public boolean getRowSumsBelow()
{
- return (( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid))
- .getRowSumsBelow();
+ return ((WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid))
+ .getRowSumsBelow();
}
/**
@@ -753,7 +734,7 @@ public class HSSFSheet
public boolean getRowSumsRight()
{
- return (( WSBoolRecord ) sheet.findFirstRecordBySid(WSBoolRecord.sid))
- .getRowSumsRight();
+ return ((WSBoolRecord) sheet.findFirstRecordBySid(WSBoolRecord.sid))
+ .getRowSumsRight();
}
}
diff --git a/src/java/org/apache/poi/util/HexDump.java b/src/java/org/apache/poi/util/HexDump.java
index 4e0cfd35a3..49bca34ff0 100644
--- a/src/java/org/apache/poi/util/HexDump.java
+++ b/src/java/org/apache/poi/util/HexDump.java
@@ -81,6 +81,7 @@ public class HexDump
* @param stream the OutputStream to which the data is to be
* written
* @param index initial index into the byte array
+ * @param length number of characters to output
*
* @exception IOException is thrown if anything goes wrong writing
* the data to stream
@@ -89,11 +90,10 @@ public class HexDump
* @exception IllegalArgumentException if the output stream is
* null
*/
-
public synchronized static void dump(final byte [] data, final long offset,
- final OutputStream stream, final int index)
- throws IOException, ArrayIndexOutOfBoundsException,
- IllegalArgumentException
+ final OutputStream stream, final int index, final int length)
+ throws IOException, ArrayIndexOutOfBoundsException,
+ IllegalArgumentException
{
if ((index < 0) || (index >= data.length))
{
@@ -108,9 +108,11 @@ public class HexDump
long display_offset = offset + index;
StringBuffer buffer = new StringBuffer(74);
- for (int j = index; j < data.length; j += 16)
+
+ int data_length = Math.min(data.length,index+length);
+ for (int j = index; j < data_length; j += 16)
{
- int chars_read = data.length - j;
+ int chars_read = data_length - j;
if (chars_read > 16)
{
@@ -146,6 +148,32 @@ public class HexDump
buffer.setLength(0);
display_offset += chars_read;
}
+
+ }
+
+ /**
+ * dump an array of bytes to an OutputStream
+ *
+ * @param data the byte array to be dumped
+ * @param offset its offset, whatever that might mean
+ * @param stream the OutputStream to which the data is to be
+ * written
+ * @param index initial index into the byte array
+ *
+ * @exception IOException is thrown if anything goes wrong writing
+ * the data to stream
+ * @exception ArrayIndexOutOfBoundsException if the index is
+ * outside the data array's bounds
+ * @exception IllegalArgumentException if the output stream is
+ * null
+ */
+
+ public synchronized static void dump(final byte [] data, final long offset,
+ final OutputStream stream, final int index)
+ throws IOException, ArrayIndexOutOfBoundsException,
+ IllegalArgumentException
+ {
+ dump(data, offset, stream, index, data.length-index);
}
public static final String EOL =
diff --git a/src/java/org/apache/poi/util/HexRead.java b/src/java/org/apache/poi/util/HexRead.java
new file mode 100644
index 0000000000..c1bda6f613
--- /dev/null
+++ b/src/java/org/apache/poi/util/HexRead.java
@@ -0,0 +1,116 @@
+package org.apache.poi.util;
+
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+
+public class HexRead
+{
+ public static byte[] readTestData( String filename )
+ throws IOException
+ {
+ File file = new File( filename );
+ FileInputStream stream = new FileInputStream( file );
+ int characterCount = 0;
+ byte b = (byte) 0;
+ List bytes = new ArrayList();
+ boolean done = false;
+
+ while ( !done )
+ {
+ int count = stream.read();
+
+ switch ( count )
+ {
+
+ case '#':
+ readToEOL(stream);
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ b <<= 4;
+ b += (byte) ( count - '0' );
+ characterCount++;
+ if ( characterCount == 2 )
+ {
+ bytes.add( new Byte( b ) );
+ characterCount = 0;
+ b = (byte) 0;
+ }
+ break;
+
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ b <<= 4;
+ b += (byte) ( count + 10 - 'A' );
+ characterCount++;
+ if ( characterCount == 2 )
+ {
+ bytes.add( new Byte( b ) );
+ characterCount = 0;
+ b = (byte) 0;
+ }
+ break;
+
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ b <<= 4;
+ b += (byte) ( count + 10 - 'a' );
+ characterCount++;
+ if ( characterCount == 2 )
+ {
+ bytes.add( new Byte( b ) );
+ characterCount = 0;
+ b = (byte) 0;
+ }
+ break;
+
+ case -1:
+ done = true;
+ break;
+
+ default :
+ break;
+ }
+ }
+ stream.close();
+ Byte[] polished = (Byte[]) bytes.toArray( new Byte[0] );
+ byte[] rval = new byte[polished.length];
+
+ for ( int j = 0; j < polished.length; j++ )
+ {
+ rval[j] = polished[j].byteValue();
+ }
+ return rval;
+ }
+
+ static private void readToEOL( InputStream stream ) throws IOException
+ {
+ int c = stream.read();
+ while ( c != -1 && c != '\n' && c != '\r')
+ {
+ c = stream.read();
+ }
+ }
+
+
+}
diff --git a/src/java/org/apache/poi/util/LittleEndian.java b/src/java/org/apache/poi/util/LittleEndian.java
index 6c7a4f4d23..21b0c69ead 100644
--- a/src/java/org/apache/poi/util/LittleEndian.java
+++ b/src/java/org/apache/poi/util/LittleEndian.java
@@ -236,7 +236,6 @@ public class LittleEndian
*
* @exception ArrayIndexOutOfBoundsException may be thrown
*/
-
public static void putShort(final byte[] data, final int offset,
final short value)
{
@@ -244,6 +243,21 @@ public class LittleEndian
}
/**
+ * put an unsigned short value into a byte array
+ *
+ * @param data the byte array
+ * @param offset a starting offset into the byte array
+ * @param value the short (16-bit) value
+ *
+ * @exception ArrayIndexOutOfBoundsException may be thrown
+ */
+ public static void putUShort(final byte[] data, final int offset,
+ final int value)
+ {
+ putNumber(data, offset, value, SHORT_SIZE);
+ }
+
+ /**
* put a array of shorts into a byte array
*
* @param data the byte array
@@ -592,4 +606,17 @@ public class LittleEndian
return copy;
}
+ /**
+ * Retrieves and unsigned short. This is converted UP to a int
+ * so it can fit.
+ *
+ * @param data The data to read
+ * @param offset The offset to read the short from
+ * @return An integer representation of the short.
+ */
+ public static int getUShort( byte[] data, int offset )
+ {
+ return (int)getNumber(data, offset, SHORT_SIZE);
+ }
+
}
diff --git a/src/java/org/apache/poi/util/POILogFactory.java b/src/java/org/apache/poi/util/POILogFactory.java
index 2378ab86a7..8c52a367a9 100644
--- a/src/java/org/apache/poi/util/POILogFactory.java
+++ b/src/java/org/apache/poi/util/POILogFactory.java
@@ -1,4 +1,3 @@
-
/*
* ====================================================================
* The Apache Software License, Version 1.1
@@ -55,12 +54,8 @@
*/
package org.apache.poi.util;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-import java.util.*;
-
-import org.apache.commons.logging.*;
+import java.util.HashMap;
+import java.util.Map;
/**
* Provides logging without clients having to mess with
@@ -73,10 +68,10 @@ import org.apache.commons.logging.*;
public class POILogFactory
{
- private static LogFactory _creator = LogFactory.getFactory();
+// private static LogFactory _creator = LogFactory.getFactory();
// map of POILogger instances, with classes as keys
- private static Map _loggers = new HashMap();;
+ private static Map _loggers = new HashMap();;
/**
@@ -95,11 +90,11 @@ public class POILogFactory
* @return a POILogger for the specified class
*/
- public static POILogger getLogger(final Class theclass)
+ public static POILogger getLogger( final Class theclass )
{
- return getLogger(theclass.getName());
+ return getLogger( theclass.getName() );
}
-
+
/**
* Get a logger, based on a String
*
@@ -108,20 +103,20 @@ public class POILogFactory
* @return a POILogger for the specified class
*/
- public static POILogger getLogger(final String cat)
+ public static POILogger getLogger( final String cat )
{
POILogger logger = null;
- if (_loggers.containsKey(cat))
+ if ( _loggers.containsKey( cat ) )
{
- logger = ( POILogger ) _loggers.get(cat);
+ logger = (POILogger) _loggers.get( cat );
}
else
{
- logger = new POILogger(_creator.getInstance(cat));
- _loggers.put(cat, logger);
+ logger = new POILogger( );
+ _loggers.put( cat, logger );
}
return logger;
}
-
+
} // end public class POILogFactory
diff --git a/src/java/org/apache/poi/util/POILogger.java b/src/java/org/apache/poi/util/POILogger.java
index a6d066c38d..b47a38023e 100644
--- a/src/java/org/apache/poi/util/POILogger.java
+++ b/src/java/org/apache/poi/util/POILogger.java
@@ -55,8 +55,6 @@
*/
package org.apache.poi.util;
-import org.apache.commons.logging.Log;
-
import java.util.*;
/**
@@ -72,7 +70,7 @@ import java.util.*;
public class POILogger
{
- private Log log = null;
+// private Log log = null;
public static final int DEBUG = 1;
public static final int INFO = 3;
public static final int WARN = 5;
@@ -82,13 +80,10 @@ public class POILogger
/**
* package scope so it cannot be instantiated outside of the util
* package. You need a POILogger? Go to the POILogFactory for one
- *
- * @param log the object that does the real work of logging
*/
- POILogger(final Log log)
+ POILogger()
{
- this.log = log;
}
/**
@@ -100,91 +95,73 @@ public class POILogger
public void log(final int level, final Object obj1)
{
- if(level==FATAL)
- {
- if(log.isFatalEnabled())
- {
- log.fatal(obj1);
- }
- }
- else if(level==ERROR)
- {
- if(log.isErrorEnabled())
- {
- log.error(obj1);
- }
- }
- else if(level==WARN)
- {
- if(log.isWarnEnabled())
- {
- log.warn(obj1);
- }
- }
- else if(level==INFO)
- {
- if(log.isInfoEnabled())
- {
- log.info(obj1);
- }
- }
- else if(level==DEBUG)
- {
- if(log.isDebugEnabled())
- {
- log.debug(obj1);
- }
- }
- else
- {
- if(log.isTraceEnabled())
- {
- log.trace(obj1);
- }
- }
+ if (check(level))
+ System.out.println( obj1 );
+ }
+ private boolean isDebugEnabled()
+ {
+ return System.getProperty("poi.logging") != null;
+ }
+
+ private boolean isInfoEnabled()
+ {
+ return false;
+ }
+
+ private boolean isWarnEnabled()
+ {
+ return System.getProperty("poi.logging") != null;
+ }
+
+ private boolean isErrorEnabled()
+ {
+ return System.getProperty("poi.logging") != null;
+ }
+
+ private boolean isFatalEnabled()
+ {
+ return System.getProperty("poi.logging") != null;
}
/**
* Check if a logger is enabled to log at the specified level
*
* @param level One of DEBUG, INFO, WARN, ERROR, FATAL
- * @param obj1 The logger to check.
*/
-
- public boolean check(final Log log, final int level)
+ public boolean check(final int level)
{
if(level==FATAL)
{
- if(log.isFatalEnabled())
+ if(isFatalEnabled())
{
return true;
}
}
else if(level==ERROR)
{
- if(log.isErrorEnabled())
+ if(isErrorEnabled())
{
return true;
}
}
else if(level==WARN)
{
- if(log.isWarnEnabled())
+ if(isWarnEnabled())
{
return true;
}
}
else if(level==INFO)
{
- if(log.isInfoEnabled())
+ if(isInfoEnabled())
{
return true;
}
}
else if(level==DEBUG)
{
- if(log.isDebugEnabled())
+ if(isDebugEnabled())
{
return true;
}
@@ -204,7 +181,7 @@ public class POILogger
public void log(final int level, final Object obj1, final Object obj2)
{
- if (check(log, level))
+ if (check( level))
{
log(level, new StringBuffer(32).append(obj1).append(obj2));
}
@@ -222,13 +199,9 @@ public class POILogger
public void log(final int level, final Object obj1, final Object obj2,
final Object obj3)
{
-
-
- if (check(log, level))
+ if (check( level))
{
- log(level,
- new StringBuffer(48).append(obj1).append(obj2)
- .append(obj3));
+ log(level, new StringBuffer(48).append(obj1).append(obj2 ).append(obj3));
}
}
@@ -247,7 +220,7 @@ public class POILogger
{
- if (check(log, level))
+ if (check( level))
{
log(level,
new StringBuffer(64).append(obj1).append(obj2)
@@ -271,7 +244,7 @@ public class POILogger
{
- if (check(log, level))
+ if (check( level))
{
log(level,
new StringBuffer(80).append(obj1).append(obj2)
@@ -297,7 +270,7 @@ public class POILogger
{
- if (check(log, level))
+ if (check( level))
{
log(level ,
new StringBuffer(96).append(obj1).append(obj2)
@@ -324,7 +297,7 @@ public class POILogger
{
- if (check(log, level))
+ if (check( level))
{
log(level,
new StringBuffer(112).append(obj1).append(obj2)
@@ -353,7 +326,7 @@ public class POILogger
{
- if (check(log, level))
+ if (check( level))
{
log(level,
new StringBuffer(128).append(obj1).append(obj2)
@@ -390,7 +363,7 @@ public class POILogger
{
- if (check(log, level))
+ if (check( level))
{
log(level, new StringBuffer(32).append(obj1).append(obj2),
exception);
@@ -412,7 +385,7 @@ public class POILogger
{
- if (check(log, level))
+ if (check( level))
{
log(level, new StringBuffer(48).append(obj1).append(obj2)
.append(obj3), exception);
@@ -436,7 +409,7 @@ public class POILogger
{
- if (check(log, level))
+ if (check( level))
{
log(level, new StringBuffer(64).append(obj1).append(obj2)
.append(obj3).append(obj4), exception);
@@ -461,7 +434,7 @@ public class POILogger
{
- if (check(log, level))
+ if (check( level))
{
log(level, new StringBuffer(80).append(obj1).append(obj2)
.append(obj3).append(obj4).append(obj5), exception);
@@ -487,7 +460,7 @@ public class POILogger
{
- if (check(log, level))
+ if (check( level))
{
log(level , new StringBuffer(96).append(obj1)
.append(obj2).append(obj3).append(obj4).append(obj5)
@@ -516,7 +489,7 @@ public class POILogger
{
- if (check(log, level))
+ if (check( level))
{
log(level, new StringBuffer(112).append(obj1).append(obj2)
.append(obj3).append(obj4).append(obj5).append(obj6)
@@ -546,7 +519,7 @@ public class POILogger
{
- if (check(log, level))
+ if (check( level))
{
log(level, new StringBuffer(128).append(obj1).append(obj2)
.append(obj3).append(obj4).append(obj5).append(obj6)
@@ -703,7 +676,7 @@ public class POILogger
{
- if (check(log, level))
+ if (check( level))
{
Object[] params = flattenArrays(unflatParams);
diff --git a/src/testcases/org/apache/poi/hssf/data/BigSSTRecord b/src/testcases/org/apache/poi/hssf/data/BigSSTRecord
index 6cebff51ba..3dd8f9ebd9 100755
--- a/src/testcases/org/apache/poi/hssf/data/BigSSTRecord
+++ b/src/testcases/org/apache/poi/hssf/data/BigSSTRecord
@@ -1,516 +1,516 @@
-FC 00 20
-20 B8 05 00 00 B0 02 00 00 0C 00 00 4D 61 6E 75
-66 61 63 74 75 72 65 72 0B 00 00 50 61 72 74 20
-4E 75 6D 62 65 72 05 00 00 53 63 61 6C 65 04 00
-00 54 79 70 65 04 00 00 4E 61 6D 65 08 00 00 43
-6F 6D 6D 65 6E 74 73 08 00 00 41 4D 54 2D 45 52
-54 4C 07 00 00 48 6F 74 20 52 6F 64 10 00 00 33
-32 20 46 6F 72 64 20 52 6F 61 64 73 74 65 72 08
-00 00 4D 6F 6E 6F 67 72 61 6D 08 00 00 53 68 6F
-77 20 52 6F 64 07 00 00 48 61 6E 67 6D 61 6E 11
-00 00 50 65 74 65 72 62 69 6C 74 20 57 72 65 63
-6B 65 72 15 00 00 45 61 73 74 65 72 6E 20 41 69
-72 6C 69 6E 65 73 20 44 43 2D 33 11 00 00 4D 61
-73 65 72 61 74 69 20 4D 65 72 61 6B 20 53 53 1A
-00 00 44 6F 75 67 6C 61 73 20 50 2D 37 30 20 4E
-69 67 68 74 20 46 69 67 68 74 65 72 17 00 00 35
-35 20 43 68 65 76 79 20 53 74 72 65 65 74 20 4D
-61 63 68 69 6E 65 0C 00 00 54 77 65 65 64 79 20
-50 69 65 20 32 13 00 00 48 75 65 79 20 52 65 73
-63 75 65 20 43 68 6F 70 70 65 72 10 00 00 4D 61
-7A 64 61 20 4D 58 2D 35 20 4D 69 61 74 61 0A 00
-00 53 70 6F 72 74 73 20 43 61 72 05 00 00 54 72
-75 63 6B 06 00 00 52 6F 63 6B 65 74 09 00 00 50
-61 72 74 73 20 4B 69 74 0E 00 00 43 69 76 69 6C
-69 61 6E 20 50 6C 61 6E 65 0E 00 00 4D 69 6C 69
-74 61 72 79 20 50 6C 61 6E 65 0F 00 00 53 63 69
-65 6E 63 65 20 46 69 63 74 69 6F 6E 1A 00 00 44
-6F 6E 20 47 61 72 6C 69 74 73 20 57 79 6E 6E 27
-73 20 43 68 61 72 67 65 72 19 00 00 44 6F 6E 20
-47 61 72 6C 69 74 73 20 57 79 6E 6E 27 73 20 4A
-61 6D 6D 65 72 1A 00 00 50 61 63 6B 61 72 64 20
-42 6F 61 74 74 61 69 6C 20 53 70 65 65 64 73 74
-65 72 0E 00 00 52 65 76 65 6C 6C 20 47 65 72 6D
-61 6E 79 05 00 00 30 34 31 34 36 04 00 00 31 2F
-32 34 04 00 00 31 2F 37 32 0E 00 00 4D 65 20 32
-36 32 20 41 2D 31 61 2F 55 33 09 00 00 53 54 43
-20 53 74 61 72 74 04 00 00 34 63 2D 39 05 00 00
-31 2F 32 38 38 0C 00 00 50 72 6F 74 6F 6E 2D 4B
-20 4D 69 72 04 00 00 34 63 2D 37 0E 00 00 50 72
-6F 74 6F 6E 2D 4B 20 41 73 74 72 61 05 00 00 34
-63 2D 31 37 0E 00 00 50 72 6F 74 6F 6E 2D 4B 20
-5A 61 72 79 61 13 00 00 41 63 63 75 72 61 74 65
-20 4D 69 6E 69 61 74 75 72 65 73 04 00 00 33 34
-32 30 04 00 00 31 2F 34 38 0F 00 00 53 42 44 2D
-31 20 44 61 75 6E 74 6C 65 73 73 1B 00 00 77 2F
-56 65 72 6C 69 6E 64 65 6E 20 31 33 37 38 20 44
-65 74 61 69 6C 20 53 65 74 04 00 00 38 32 38 33
-0C 00 00 54 72 6F 75 62 6C 65 6D 61 6B 65 72 04
-00 00 32 37 33 37 0E 00 00 44 61 79 74 6F 6E 61
-20 53 70 69 64 65 72 04 00 00 38 31 32 36 04 00
-00 31 2F 32 35 06 00 00 48 65 6C 6C 65 72 05 00
-00 38 30 34 34 33 05 00 00 31 2F 31 34 34 12 00
-00 42 72 65 69 74 6C 69 6E 20 4F 72 62 69 74 65
-72 20 33 0F 00 00 53 68 61 6E 67 68 61 69 20 44
-72 61 67 6F 6E 04 00 00 31 39 39 38 04 00 00 31
-2F 39 36 0F 00 00 41 72 69 61 6E 65 20 35 20 52
-6F 63 6B 65 74 0F 00 00 52 65 76 65 6C 6C 2D 4D
-6F 6E 6F 67 72 61 6D 07 00 00 38 35 2D 35 39 33
-34 0F 00 00 50 42 59 2D 35 41 20 43 61 74 61 6C
-69 6E 61 0A 00 00 50 72 6F 4D 6F 64 65 6C 65 72
-07 00 00 47 6C 65 6E 63 6F 65 05 00 00 30 35 32
-30 32 04 00 00 31 2F 33 35 16 00 00 50 69 61 73
-65 63 6B 69 20 5A 56 2D 38 50 20 41 69 72 67 65
-65 70 08 00 00 48 61 73 65 67 61 77 61 05 00 00
-30 39 31 36 39 20 00 00 53 42 44 2D 33 20 44 61
-75 6E 74 6C 65 73 73 20 27 55 53 53 20 45 6E 74
-65 72 70 72 69 73 65 27 0C 00 00 53 69 6C 76 65
-72 20 43 6C 6F 75 64 06 00 00 53 43 34 38 30 31
-19 00 00 53 75 70 65 72 6D 61 72 69 6E 65 20 53
-70 69 74 65 66 75 6C 20 46 2E 31 34 06 00 00 52
-65 76 65 6C 6C 07 00 00 38 35 2D 31 36 35 34 0D
-00 00 50 2D 35 31 42 20 4D 75 73 74 61 6E 67 09
-00 00 50 72 6F 46 69 6E 69 73 68 06 00 00 44 72
-61 67 6F 6E 04 00 00 35 39 30 31 0B 00 00 46 6F
-6B 6B 65 72 20 44 72 2E 31 07 00 00 49 74 61 6C
-65 72 69 03 00 00 38 34 36 25 00 00 43 2D 31 33
-30 4A 20 48 65 72 63 75 6C 65 73 20 48 65 61 76
-79 20 54 72 61 6E 73 70 6F 72 74 20 50 6C 61 6E
-65 04 00 00 37 36 31 30 15 00 00 46 65 72 72 61
-72 69 20 46 35 30 20 42 61 72 63 68 65 74 74 61
-03 00 00 41 4D 54 08 00 00 54 33 37 34 2D 32 32
-35 0D 00 00 43 6F 72 76 61 69 72 20 4D 6F 6E 7A
-61 04 00 00 35 30 30 33 0B 00 00 4D 63 4C 61 72
-65 6E 20 4D 38 42 0D 00 00 52 65 76 65 6C 6C 20
-4C 6F 64 65 6C 61 05 00 00 48 2D 32 36 33 03 00
-00 75 6E 6B 23 00 00 42 6F 65 69 6E 67 20 53 53
-54 20 50 61 6E 41 6D 20 43 6C 69 70 70 65 72 20
-53 75 70 65 72 73 6F 6E 69 63 05 00 00 30 35 39
-30 39 05 00 00 31 2F 33 30 30 1D 00 00 4E 75 63
-6C 65 61 72 20 50 6F 77 65 72 65 64 20 53 70 61
-63 65 20 53 74 61 74 69 6F 6E 04 00 00 38 37 36
-34 06 00 00 31 2F 32 35 30 30 19 00 00 53 74 61
-72 20 54 72 65 6B 20 44 65 65 70 20 53 70 61 63
-65 20 4E 69 6E 65 23 00 00 46 69 62 65 72 2D 6F
-70 74 69 63 20 4C 69 67 68 74 69 6E 67 2C 20 73
-6B 69 6C 6C 20 6C 65 76 65 6C 20 33 0D 00 00 53
-6B 69 6C 6C 20 6C 65 76 65 6C 20 33 04 00 00 38
-31 35 38 16 00 00 42 6C 75 65 70 72 69 6E 74 65
-72 20 50 61 72 74 73 20 50 61 63 6B 13 00 00 45
-6E 67 69 6E 65 73 20 61 6E 64 20 67 72 69 6C 6C
-65 73 05 00 00 33 30 30 33 37 05 00 00 31 2F 32
-30 30 1E 00 00 4D 61 6E 20 49 6E 20 53 70 61 63
-65 20 52 6F 63 6B 65 74 20 43 6F 6C 6C 65 63 74
-69 6F 6E 53 00 00 4D 65 72 63 75 72 79 20 41 74
-6C 61 73 2C 20 4D 65 72 63 75 72 79 20 52 65 64
-73 74 6F 6E 65 2C 20 47 65 6D 69 6E 69 20 54 69
-74 61 6E 20 49 49 2C 20 53 61 74 75 72 6E 20 31
-42 20 41 70 6F 6C 6C 6F 2C 20 53 61 74 75 72 6E
-20 56 20 41 70 6F 6C 6C 6F 04 00 00 35 30 38 33
-04 00 00 31 2F 33 32 11 00 00 41 70 6F 6C 6C 6F
-20 53 70 61 63 65 63 72 61 66 74 09 00 00 4D 69
-6E 69 63 72 61 66 74 05 00 00 31 31 32 32 30 04
-00 00 31 2F 31 36 24 00 00 31 39 35 35 20 4D 65
-72 63 65 64 65 73 20 33 30 30 53 4C 20 22 47 75
-6C 6C 77 69 6E 67 22 20 43 6F 75 70 65 07 00 00
-38 35 2D 36 38 35 39 24 00 00 4D 75 73 74 61 6E
-67 20 4D 75 73 63 6C 65 20 54 72 69 6F 20 27 36
-30 73 2C 20 27 37 30 73 2C 20 27 38 30 73 35 00
-00 31 39 36 34 20 31 2F 32 20 43 6F 6E 76 65 72
-74 69 62 6C 65 2C 20 31 39 37 30 20 42 6F 73 73
-20 33 30 32 2C 20 31 39 38 39 20 43 6F 6E 76 65
-72 74 69 62 6C 65 06 00 00 54 61 6D 69 79 61 05
-00 00 32 34 31 37 30 0A 00 00 4D 6F 72 67 61 6E
-20 34 2F 34 07 00 00 38 35 2D 32 34 39 31 11 00
-00 36 37 20 43 6F 72 76 65 74 74 65 20 43 6F 75
-70 65 07 00 00 38 35 2D 32 35 33 34 0F 00 00 53
-68 65 6C 62 79 20 53 65 72 69 65 73 20 31 03 00
-00 35 36 32 11 00 00 41 73 74 6F 6E 20 4D 61 72
-74 69 6E 20 44 42 20 34 05 00 00 30 37 33 32 30
-13 00 00 50 6F 72 73 63 68 65 20 39 31 31 20 43
-61 72 72 65 72 61 07 00 00 54 65 73 74 6F 72 73
-03 00 00 33 38 36 04 00 00 32 39 37 32 16 00 00
-4D 65 72 63 65 64 65 73 20 33 30 30 20 53 4C 52
-20 22 37 32 32 22 08 00 00 4C 69 6E 64 62 65 72
-67 05 00 00 37 30 39 35 36 19 00 00 48 65 6C 6C
-63 61 74 73 20 76 73 2E 20 42 65 74 74 79 20 42
-6F 6D 62 65 72 0C 00 00 48 65 6C 6C 63 61 74 20
-6F 6E 6C 79 05 00 00 30 34 36 30 39 18 00 00 45
-6B 72 61 6E 6F 70 6C 61 6E 20 41 2D 39 30 20 4F
-72 6C 6A 6F 6E 6F 6B 05 00 00 31 31 36 32 36 18
-00 00 47 72 75 6D 6D 61 6E 20 58 46 35 46 2D 31
-20 53 6B 79 72 6F 63 6B 65 74 04 00 00 35 34 32
-30 0E 00 00 48 61 77 6B 65 72 20 48 61 72 72 69
-65 72 05 00 00 41 56 2D 38 41 06 00 00 65 64 75
-61 72 64 04 00 00 38 30 36 31 0F 00 00 50 2D 34
-30 30 20 41 69 72 61 63 6F 62 72 61 0B 00 00 43
-7A 65 63 68 20 4D 6F 64 65 6C 04 00 00 34 38 30
-36 16 00 00 43 75 72 74 69 73 73 20 58 50 2D 35
-35 20 41 73 63 65 6E 64 65 72 05 00 00 36 31 30
-37 34 14 00 00 44 6F 72 6E 69 65 72 20 44 6F 33
-33 35 41 20 50 66 69 65 6C 13 00 00 4B 79 75 73
-68 75 20 4A 37 57 31 20 53 68 69 6E 64 65 6E 0D
-00 00 50 6C 61 6E 65 74 20 4D 6F 64 65 6C 73 03
-00 00 30 34 33 0F 00 00 48 65 6E 73 63 68 65 6C
-20 48 73 20 50 38 37 05 00 00 52 65 73 69 6E 0D
-00 00 53 70 65 63 69 61 6C 20 48 6F 62 62 79 08
-00 00 53 48 20 34 38 30 30 33 16 00 00 4D 63 44
-6F 6E 6E 65 6C 6C 20 58 46 2D 38 35 20 47 6F 62
-6C 69 6E 2A 00 00 4D 65 73 73 65 72 73 63 68 6D
-69 74 74 20 42 66 31 30 39 45 20 27 42 75 6C 67
-61 72 69 61 6E 20 41 69 72 20 46 6F 72 63 65 27
-05 00 00 30 34 32 30 36 2D 00 00 41 69 72 62 75
-73 20 53 75 70 65 72 20 54 72 61 6E 73 70 6F 72
-74 65 72 20 41 33 30 30 2D 36 30 30 20 53 54 20
-22 42 65 6C 75 67 61 22 05 00 00 33 30 30 38 37
-0C 00 00 33 39 20 57 61 67 6F 6E 20 52 6F 64 04
-00 00 37 31 32 31 1A 00 00 31 39 33 32 20 46 6F
-72 64 20 48 69 67 68 62 6F 79 20 52 6F 61 64 73
-74 65 72 2E 00 00 4C 69 6E 63 6F 6C 6E 20 4D 69
-6E 74 20 55 6C 74 72 61 20 4D 65 74 61 6C 20 53
-65 72 69 65 73 2C 20 53 6B 69 6C 6C 20 6C 65 76
-65 6C 20 33 0C 00 00 50 6F 6C 61 72 20 4C 69 67
-68 74 73 04 00 00 35 30 31 34 21 00 00 43 61 72
-6C 20 43 61 73 70 65 72 27 73 20 55 6E 64 65 72
-74 61 6B 65 72 20 44 72 61 67 73 74 65 72 07 00
-00 38 35 2D 32 35 39 32 20 00 00 33 39 20 43 68
-65 76 79 20 53 65 64 61 6E 20 44 65 6C 69 76 65
-72 79 20 4C 6F 77 72 69 64 65 72 07 00 00 38 35
-2D 35 39 30 34 12 00 00 4E 41 53 41 20 53 70 61
-63 65 20 53 68 75 74 74 6C 65 04 00 00 32 34 30
-30 1C 00 00 31 39 32 36 20 4D 61 63 6B 20 42 75
-6C 6C 64 6F 67 20 44 75 6D 70 20 54 72 75 63 6B
-05 00 00 43 31 31 32 38 13 00 00 32 33 20 54 20
-52 6F 61 64 73 74 65 72 20 46 72 61 6D 65 05 00
-00 33 31 32 31 36 11 00 00 44 6F 64 67 65 20 56
-69 70 65 72 20 52 54 2D 31 30 07 00 00 50 72 6F
-53 68 6F 70 04 00 00 32 33 30 31 05 00 00 31 31
-32 31 32 26 00 00 31 39 33 35 20 4D 6F 72 67 61
-6E 20 53 75 70 65 72 20 53 70 6F 72 74 73 20 54
-68 72 65 65 20 57 68 65 65 6C 65 72 0C 00 00 47
-75 6E 7A 65 20 53 61 6E 67 79 6F 13 00 00 54 72
-69 75 6D 70 68 20 54 52 32 20 4C 65 20 4D 61 6E
-73 07 00 00 38 35 2D 31 39 31 31 0F 00 00 33 34
-20 46 6F 72 64 20 48 69 67 68 62 6F 79 17 00 00
-57 68 65 65 6C 73 20 6F 66 20 46 69 72 65 20 53
-6E 61 70 54 69 74 65 06 00 00 4A 6F 2D 48 61 6E
-06 00 00 47 43 2D 33 30 30 20 00 00 43 68 72 79
-73 6C 65 72 20 43 6F 72 70 6F 72 61 74 69 6F 6E
-20 54 75 72 62 69 6E 65 20 43 61 72 09 00 00 48
-31 32 38 35 3A 31 39 38 2B 00 00 54 6F 6D 6D 79
-20 49 76 6F 27 73 20 46 6F 75 72 20 45 6E 67 69
-6E 65 20 44 72 61 67 73 74 65 72 20 22 53 68 6F
-77 62 6F 61 74 22 09 00 00 48 31 32 32 34 3A 32
-30 30 17 00 00 32 32 20 4A 52 20 52 6F 61 64 73
-74 65 72 20 44 72 61 67 73 74 65 72 0F 00 00 32
-20 63 6F 6D 70 6C 65 74 65 20 63 61 72 73 04 00
-00 36 34 33 35 04 00 00 36 34 33 38 07 00 00 38
-35 2D 37 36 36 38 0F 00 00 34 31 20 43 68 65 76
-79 20 50 69 63 6B 75 70 04 00 00 36 35 38 35 17
-00 00 42 61 62 79 6C 6F 6E 20 35 20 53 74 61 72
-66 75 72 79 20 4D 6B 2E 31 1C 00 00 4D 65 73 73
-65 72 73 63 68 6D 69 74 74 20 42 66 31 30 39 45
-20 47 61 6C 6C 61 6E 64 05 00 00 36 31 30 36 37
-1B 00 00 42 72 69 73 74 6F 6C 20 42 65 61 75 66
-69 67 68 74 65 72 20 54 46 2E 4D 6B 2E 58 12 00
-00 48 65 6E 73 63 68 65 6C 20 48 73 20 31 32 39
-42 2D 32 04 00 00 33 34 31 39 0D 00 00 50 2D 35
-31 43 20 4D 75 73 74 61 6E 67 07 00 00 38 35 2D
-35 35 30 39 1B 00 00 48 65 69 6E 6B 65 6C 20 48
-65 31 31 31 20 47 65 72 6D 61 6E 20 42 6F 6D 62
-65 72 11 00 00 41 63 61 64 65 6D 79 20 4D 69 6E
-69 63 72 61 66 74 04 00 00 32 31 34 35 1E 00 00
-4C 6F 63 6B 68 65 65 64 20 50 2D 33 38 4D 20 4E
-69 67 68 74 20 4C 69 67 68 74 6E 69 6E 67 07 00
-00 38 35 2D 30 31 33 35 11 00 00 4F 53 32 55 2D
-33 20 4B 69 6E 67 66 69 73 68 65 72 3B 00 00 41
-69 63 68 69 20 42 37 41 32 20 41 74 74 61 63 6B
-20 42 6F 6D 62 65 72 20 20 52 79 75 73 65 69 20
-4B 61 69 20 28 47 72 61 63 65 29 20 27 46 6F 6C
-64 69 6E 67 20 57 69 6E 67 27 15 00 00 58 46 35
-55 2D 31 20 46 6C 79 69 6E 67 20 50 61 6E 63 61
-6B 65 04 00 00 36 37 35 37 07 00 00 49 63 65 20
-27 54 27 07 00 00 38 35 2D 35 31 30 32 04 00 00
-53 68 69 70 15 00 00 55 2E 53 2E 53 2E 20 4E 6F
-72 74 68 20 43 61 72 6F 6C 69 6E 61 0E 00 00 50
-61 72 74 73 20 62 79 20 50 61 72 6B 73 04 00 00
-31 30 30 34 0F 00 00 44 69 73 74 72 69 62 75 74
-6F 72 20 4B 69 74 12 00 00 50 53 46 20 4D 6F 64
-65 6C 20 53 75 70 70 6C 69 65 73 07 00 00 45 4B
-44 31 30 30 30 1B 00 00 4D 6F 64 65 6C 20 43 61
-72 20 45 6E 67 69 6E 65 20 44 65 74 61 69 6C 20
-4B 69 74 04 00 00 38 34 33 35 1F 00 00 43 75 73
-74 6F 6D 20 26 20 43 6F 6D 70 65 74 69 74 69 6F
-6E 20 50 61 72 74 73 20 50 61 63 6B 04 00 00 54
-36 34 32 27 00 00 22 57 69 6E 6E 69 65 20 4D 61
-65 22 20 57 69 6C 65 79 20 50 6F 73 74 27 73 20
-4C 6F 63 6B 68 65 65 64 20 56 65 67 61 06 00 00
-41 69 72 66 69 78 05 00 00 30 34 31 37 36 0C 00
-00 44 48 20 43 6F 6D 65 74 20 34 20 42 07 00 00
-38 35 2D 34 31 36 32 1B 00 00 4F 72 61 6E 67 65
-20 43 72 61 74 65 20 27 33 32 20 46 6F 72 64 20
-53 65 64 61 6E 06 00 00 38 36 30 35 50 4F 14 00
-00 46 69 61 74 20 44 6F 75 62 6C 65 20 44 72 61
-67 73 74 65 72 0B 00 00 42 6C 75 65 70 72 69 6E
-74 65 72 06 00 00 48 2D 31 33 32 31 0C 00 00 47
-72 61 6E 20 54 75 72 69 73 6D 6F 07 00 00 38 35
-2D 37 36 33 37 15 00 00 33 31 20 46 6F 72 64 20
-4D 6F 64 65 6C 20 41 20 57 6F 6F 64 79 03 00 00
-4D 50 43 07 00 00 32 30 30 2D 32 30 30 16 00 00
-47 61 6E 67 62 75 73 74 65 72 73 20 32 38 20 4C
-69 6E 63 6F 6C 6E 07 00 00 38 35 2D 32 35 36 39
-19 00 00 43 68 65 76 79 20 53 2D 31 30 20 4C 6F
-77 72 69 64 65 72 20 33 27 6E 20 31 04 00 00 32
-32 31 31 04 00 00 35 35 30 35 1C 00 00 48 6F 72
-74 65 6E 20 48 6F 20 32 32 39 41 2D 31 20 46 6C
-79 69 6E 67 20 57 69 6E 67 05 00 00 30 35 32 30
-31 1C 00 00 4D 63 44 6F 6E 6E 65 6C 6C 20 58 56
-2D 31 20 43 6F 6E 76 65 72 74 69 70 6C 61 6E 65
-07 00 00 38 35 2D 35 38 31 30 0F 00 00 53 52 2D
-37 31 20 42 6C 61 63 6B 62 69 72 64 04 00 00 34
-35 32 32 19 00 00 4D 65 73 73 65 72 73 63 68 6D
-69 74 74 20 42 66 2D 31 30 39 20 47 2D 31 30 16
-00 00 50 72 65 6D 69 75 6D 2C 20 73 6B 69 6C 6C
-20 6C 65 76 65 6C 20 34 04 00 00 38 36 34 36 0B
-00 00 48 6F 62 62 79 20 43 72 61 66 74 06 00 00
-48 43 31 35 34 39 16 00 00 56 61 6D 70 69 72 65
-20 46 33 20 4A 65 74 20 46 69 67 68 74 65 72 04
-00 00 33 34 30 31 0B 00 00 41 2D 33 36 20 41 70
-61 63 68 65 05 00 00 30 34 33 33 35 15 00 00 42
-6C 6F 68 6D 20 26 20 56 6F 73 73 20 42 56 20 50
-2D 31 39 34 09 00 00 30 31 33 30 4D 30 31 30 30
-34 00 00 43 6F 72 64 20 50 68 61 65 74 6F 6E 20
-53 65 64 61 6E 20 31 39 33 37 20 38 31 32 20 53
-75 70 65 72 63 68 61 72 67 65 64 20 43 6F 6E 76
-65 72 74 69 62 6C 65 07 00 00 38 35 2D 32 35 37
-39 15 00 00 56 57 20 42 65 65 74 6C 65 20 43 6F
-6E 76 65 72 74 69 62 6C 65 04 00 00 37 34 33 38
-10 00 00 42 4D 57 20 5A 2D 31 20 52 6F 61 64 73
-74 65 72 04 00 00 36 31 34 38 0B 00 00 44 69 61
-62 6C 6F 20 41 65 72 6F 0B 00 00 55 6E 69 6F 6E
-20 4D 6F 64 65 6C 2B 00 00 50 65 74 65 20 42 72
-6F 63 6B 27 73 20 53 43 43 41 20 43 68 61 6D 70
-69 6F 6E 20 42 52 45 2F 44 61 74 73 75 6E 20 32
-34 30 2D 5A 05 00 00 32 34 31 32 39 0D 00 00 4A
-61 67 75 61 72 20 58 4A 20 32 32 30 05 00 00 30
-33 31 30 31 13 00 00 53 70 69 72 69 74 20 6F 66
-20 53 74 2E 20 4C 6F 75 69 73 05 00 00 30 36 31
-37 31 15 00 00 4F 72 69 6F 6E 20 32 30 30 31 20
-53 70 61 63 65 63 72 61 66 74 04 00 00 38 37 36
-36 05 00 00 31 2F 36 35 30 18 00 00 53 74 61 72
-20 54 72 65 6B 20 55 2E 53 2E 53 2E 20 52 65 6C
-69 61 6E 74 07 00 00 38 35 2D 31 38 33 35 15 00
-00 4E 41 53 41 2F 4D 63 44 6F 6E 6E 65 6C 6C 20
-47 65 6D 69 6E 69 04 00 00 31 39 39 37 24 00 00
-43 68 61 6E 67 20 5A 68 65 6E 67 20 32 20 28 43
-5A 2D 32 45 29 20 4C 61 75 6E 63 68 20 56 65 68
-69 63 6C 65 05 00 00 31 31 32 31 30 04 00 00 31
-2F 32 30 13 00 00 4D 61 6B 6F 20 53 68 61 72 6B
-20 53 68 6F 77 20 43 61 72 08 00 00 44 72 61 67
-73 74 65 72 08 00 00 4C 6F 77 72 69 64 65 72 04
-00 00 36 30 36 36 2F 00 00 57 69 6C 64 20 57 69
-6C 6C 69 65 20 42 6F 72 73 63 68 20 22 57 69 6E
-67 65 64 20 45 78 70 72 65 73 73 22 20 41 6C 74
-65 72 65 64 20 52 6F 64 04 00 00 36 31 38 32 0F
-00 00 31 39 33 33 20 57 69 6C 6C 79 73 20 56 61
-6E 07 00 00 38 35 2D 30 35 34 30 34 00 00 49 6E
-61 75 67 75 72 61 6C 20 4D 41 54 43 4F 20 54 6F
-6F 6C 73 20 53 75 70 65 72 6E 61 74 69 6F 6E 61
-6C 73 20 4E 69 74 72 6F 20 46 75 6E 6E 79 20 43
-61 72 04 00 00 36 33 35 35 1E 00 00 31 39 35 37
-20 43 68 65 76 72 6F 6C 65 74 20 43 6F 72 76 65
-74 74 65 20 47 61 73 73 65 72 07 00 00 38 35 2D
-37 36 37 35 04 00 00 50 43 36 31 2A 00 00 47 72
-65 65 6E 20 48 6F 72 6E 65 74 20 46 6F 72 64 20
-22 54 22 20 53 68 6F 77 20 61 6E 64 20 47 6F 20
-52 6F 61 64 73 74 65 72 04 00 00 38 32 31 35 18
-00 00 31 39 34 30 20 46 6F 72 64 20 53 65 64 61
-6E 20 44 65 6C 69 76 65 72 79 07 00 00 38 35 2D
-37 36 32 38 16 00 00 33 37 20 46 6F 72 64 20 50
-61 6E 65 6C 20 44 65 6C 69 76 65 72 79 04 00 00
-31 32 39 34 10 00 00 47 79 70 73 79 20 44 75 6E
-65 20 42 75 67 67 79 06 00 00 48 2D 31 32 33 31
-23 00 00 43 68 72 79 73 6C 65 72 20 4E 65 77 20
-59 6F 72 6B 65 72 20 43 75 73 74 6F 6D 69 7A 69
-6E 67 20 4B 69 74 05 00 00 33 30 30 38 31 0E 00
-00 36 32 20 54 68 75 6E 64 65 72 62 69 72 64 04
-00 00 36 38 39 39 11 00 00 31 39 33 32 20 46 6F
-72 64 20 50 68 61 65 74 6F 6E 05 00 00 33 30 32
-37 30 0D 00 00 31 39 36 38 20 50 6C 79 6D 6F 75
-74 68 04 00 00 38 38 34 32 17 00 00 47 72 75 6D
-6D 61 6E 20 46 37 46 2D 33 4E 20 54 69 67 65 72
-63 61 74 04 00 00 48 32 34 34 14 00 00 4D 61 72
-74 69 6E 20 50 36 4D 20 53 65 61 6D 61 73 74 65
-72 04 00 00 35 35 30 30 0E 00 00 42 2D 32 35 48
-20 4D 69 74 63 68 65 6C 6C 04 00 00 33 34 30 32
-0D 00 00 50 2D 35 31 41 20 4D 75 73 74 61 6E 67
-04 00 00 36 34 32 31 3E 00 00 44 61 6D 62 75 73
-74 65 72 20 47 72 61 6E 64 20 53 6C 61 6D 20 42
-6F 6D 62 65 72 20 4C 61 6E 63 61 73 74 65 72 20
-42 49 20 53 70 65 63 69 61 6C 20 32 32 30 30 30
-6C 62 2E 20 42 6F 6D 62 05 00 00 31 34 34 34 33
-1E 00 00 4C 6F 63 6B 68 65 65 64 20 53 75 70 65
-72 2D 47 20 43 6F 6E 73 74 65 6C 6C 61 74 69 6F
-6E 04 00 00 35 36 31 30 13 00 00 57 69 6C 6C 69
-61 6D 73 20 42 72 6F 73 2E 20 49 6E 63 2E 07 00
-00 34 38 2D 33 31 39 31 10 00 00 43 6F 72 62 65
-6E 20 53 75 70 65 72 2D 41 63 65 05 00 00 30 35
-30 30 32 10 00 00 52 65 74 72 69 65 76 65 72 20
-52 6F 63 6B 65 74 03 00 00 43 61 72 04 00 00 38
-35 38 38 1D 00 00 50 6C 79 6D 6F 75 74 68 20 50
-72 6F 77 6C 65 72 20 77 69 74 68 20 54 72 61 69
-6C 65 72 04 00 00 35 30 30 31 14 00 00 43 6F 72
-76 65 74 74 65 20 47 72 61 6E 64 20 53 70 6F 72
-74 04 00 00 37 31 30 38 1D 00 00 43 6F 72 76 65
-74 74 65 20 49 6E 64 79 20 22 44 72 65 61 6D 20
-4D 61 63 68 69 6E 65 22 04 00 00 38 30 35 39 0C
-00 00 54 68 65 20 4D 75 6E 73 74 65 72 73 20 00
-00 42 6C 75 65 70 72 69 6E 74 65 72 3B 20 4D 75
-6E 73 74 65 72 73 20 4B 6F 61 63 68 20 6F 6E 6C
-79 07 00 00 38 35 2D 34 31 36 36 05 00 00 43 6F
-75 6E 74 3C 00 00 77 2F 43 75 74 74 69 6E 67 20
-45 64 67 65 20 43 45 43 34 38 30 38 36 20 48 65
-31 31 31 5A 20 22 5A 77 69 6C 6C 69 6E 67 22 20
-6B 69 74 2C 20 73 6B 69 6C 6C 20 6C 65 76 65 6C
-20 33 07 00 00 38 35 2D 37 36 36 36 23 00 00 43
-75 73 74 6F 6D 20 53 69 6C 76 65 72 61 64 6F 20
-61 6E 64 20 57 61 76 65 72 69 64 65 72 20 42 6F
-61 74 07 00 00 38 35 2D 36 38 35 38 16 00 00 53
-6E 61 6B 65 20 26 20 4D 6F 6E 67 6F 6F 73 65 20
-43 6F 6D 62 6F 07 00 00 38 35 2D 34 31 35 39 24
-00 00 4A 6F 65 20 41 6D 61 74 6F 20 53 75 70 65
-72 6D 61 6E 20 54 6F 70 20 46 75 65 6C 20 44 72
-61 67 73 74 65 72 04 00 00 37 35 34 31 0D 00 00
-53 6B 69 6C 6C 20 6C 65 76 65 6C 20 35 09 00 00
-48 38 32 35 2D 31 30 44 30 28 00 00 43 6F 63 61
-20 43 6F 6C 61 20 46 6F 72 64 20 4C 6F 75 69 73
-76 69 6C 6C 65 20 44 65 6C 69 76 65 72 79 20 54
-72 75 63 6B 07 00 00 38 35 2D 32 31 35 36 04 00
-00 32 39 35 34 0B 00 00 50 6F 72 73 63 68 65 20
-39 30 34 04 00 00 32 39 33 35 25 00 00 4C 61 6D
-62 6F 72 67 68 69 6E 69 20 43 6F 75 6E 74 61 63
-68 20 32 35 74 68 20 41 6E 6E 69 76 65 72 73 61
-72 79 07 00 00 38 35 2D 37 36 31 36 1F 00 00 41
-6D 65 72 69 63 61 6E 20 49 6E 74 65 72 6E 61 74
-69 6F 6E 61 6C 20 44 72 61 67 73 74 65 72 07 00
-00 38 35 2D 35 32 34 31 0D 00 00 50 2D 35 31 44
-20 4D 75 73 74 61 6E 67 07 00 00 38 35 2D 35 37
-31 30 11 00 00 52 42 2D 33 36 48 20 50 65 61 63
-65 6D 61 6B 65 72 05 00 00 30 35 31 30 34 14 00
-00 52 65 70 75 62 6C 69 63 20 52 43 2E 33 20 53
-65 61 62 65 65 05 00 00 50 41 31 35 32 05 00 00
-36 31 30 36 36 25 00 00 44 65 48 61 76 69 6C 6C
-61 6E 64 20 4D 6F 73 71 75 69 74 6F 20 42 20 4D
-6B 2E 49 56 2F 50 52 20 4D 6B 2E 49 56 07 00 00
-38 35 2D 37 35 34 36 10 00 00 50 2D 36 31 20 42
-6C 61 63 6B 20 57 69 64 6F 77 07 00 00 38 35 2D
-36 36 35 32 25 00 00 42 2D 31 37 46 20 46 6C 79
-69 6E 67 20 46 6F 72 74 72 65 73 73 20 22 4D 65
-6D 70 68 69 73 20 42 65 6C 6C 65 22 04 00 00 37
-35 30 30 0D 00 00 47 61 74 65 73 20 4C 65 61 72
-6A 65 74 03 00 00 35 31 39 15 00 00 47 72 75 6D
-6D 61 6E 20 46 38 46 2D 32 20 42 65 61 72 63 61
-74 04 00 00 37 35 32 33 12 00 00 46 2D 31 30 34
-43 20 53 74 61 72 66 69 67 68 74 65 72 05 00 00
-36 31 30 37 30 15 00 00 56 6F 75 67 68 74 20 46
-34 55 2D 31 41 20 43 6F 72 73 61 69 72 07 00 00
-38 35 2D 37 36 36 34 19 00 00 42 61 6C 64 77 69
-6E 2D 4D 6F 74 69 6F 6E 20 44 72 61 67 20 43 6F
-62 72 61 04 00 00 38 34 35 35 14 00 00 35 37 20
-43 68 65 76 72 6F 6C 65 74 20 42 65 6C 20 41 69
-72 16 00 00 50 72 6F 53 68 6F 70 2C 20 73 6B 69
-6C 6C 20 6C 65 76 65 6C 20 33 05 00 00 33 30 30
-35 32 0D 00 00 34 31 20 46 6F 72 64 20 57 6F 6F
-64 79 07 00 00 38 35 2D 32 35 35 37 19 00 00 36
-30 20 43 68 65 76 79 20 48 61 72 64 74 6F 70 20
-4C 6F 77 72 69 64 65 72 07 00 00 38 35 2D 37 36
-33 38 09 00 00 41 65 72 6F 76 65 74 74 65 07 00
-00 38 35 2D 30 30 39 34 1B 00 00 4C 69 27 6C 20
-43 6F 66 66 69 6E 20 43 75 73 74 6F 6D 20 53 68
-6F 77 20 52 6F 64 04 00 00 38 32 39 30 0A 00 00
-53 27 43 6F 6F 6C 20 42 75 73 07 00 00 38 35 2D
-32 35 39 37 12 00 00 53 74 72 65 65 74 20 46 69
-67 68 74 65 72 20 54 77 6F 04 00 00 37 36 30 39
-12 00 00 54 68 61 6D 65 73 20 50 61 6E 65 6C 20
-54 72 75 63 6B 07 00 00 38 35 2D 37 36 30 36 15
-00 00 44 61 6E 20 46 69 6E 6B 27 73 20 53 70 65
-65 64 77 61 67 6F 6E 05 00 00 30 35 35 30 35 1A
-00 00 4D 61 72 74 69 6E 20 4D 2D 31 33 30 20 43
-68 69 6E 61 20 43 6C 69 70 70 65 72 07 00 00 38
-35 2D 30 30 31 35 0E 00 00 46 6F 72 64 20 54 72
-69 2D 4D 6F 74 6F 72 04 00 00 50 41 33 30 1A 00
-00 57 72 69 67 68 74 20 42 72 6F 74 68 65 72 73
-20 4B 69 74 74 79 20 48 61 77 6B 07 00 00 38 35
-2D 35 30 38 31 13 00 00 46 69 72 73 74 20 4C 75
-6E 61 72 20 4C 61 6E 64 69 6E 67 07 00 00 38 35
-2D 35 38 33 39 18 00 00 4D 65 73 73 65 72 73 63
-68 6D 69 74 74 20 42 66 20 31 31 30 20 47 2D 32
-04 00 00 43 48 34 31 04 00 00 4A 30 30 34 05 00
-00 4A 54 31 32 33 04 00 00 4A 54 32 32 04 00 00
-4A 54 37 31 04 00 00 53 50 36 33 04 00 00 42 54
-31 36 0C 00 00 4F 56 2D 31 42 20 4D 6F 68 61 77
-6B 03 00 00 30 36 38 0B 00 00 56 2D 32 32 20 4F
-73 70 72 65 79 04 00 00 38 36 31 35 13 00 00 58
-2F 59 42 2D 33 35 20 46 6C 79 69 6E 67 20 57 69
-6E 67 05 00 00 31 31 32 30 38 1B 00 00 31 39 33
-33 20 43 61 64 69 6C 6C 61 63 20 56 2D 31 36 20
-54 6F 77 6E 20 43 61 72 04 00 00 36 36 31 38 27
-00 00 53 74 61 72 20 54 72 65 6B 20 33 20 50 69
-65 63 65 20 55 2E 53 2E 53 2E 20 45 6E 74 65 72
-70 72 69 73 65 20 53 65 74 12 00 00 4D 69 73 73
-69 6E 67 20 54 56 20 76 65 72 73 69 6F 6E 04 00
-00 38 39 31 35 0E 00 00 53 74 61 72 20 44 65 73
-74 72 6F 79 65 72 04 00 00 38 31 39 33 0A 00 00
-44 65 61 74 68 20 53 74 61 72 08 00 00 53 6E 61
-70 54 69 74 65 07 00 00 38 35 2D 33 36 32 31 07
-00 00 38 35 2D 33 36 32 32 17 00 00 42 61 62 79
-6C 6F 6E 20 35 20 53 70 61 63 65 20 53 74 61 74
-69 6F 6E 04 00 00 36 38 35 38 1F 00 00 53 74 61
-72 20 54 72 65 6B 20 33 20 50 69 65 63 65 20 41
-64 76 65 72 73 61 72 79 20 53 65 74 04 00 00 38
-37 36 32 06 00 00 31 2F 31 30 30 30 29 00 00 53
-74 61 72 20 54 72 65 6B 20 47 65 6E 65 72 61 74
-69 6F 6E 73 20 55 2E 53 2E 53 2E 20 45 6E 74 65
-72 70 72 69 73 65 20 42 04 00 00 38 38 38 33 03
-00 00 31 2F 34 05 00 00 4F 74 68 65 72 12 00 00
-56 69 73 69 62 6C 65 20 56 2D 38 20 45 6E 67 69
-6E 65 04 00 00 37 31 32 30 1C 00 00 31 39 36 39
-20 50 6F 6E 74 69 61 63 20 47 54 4F 20 22 54 68
-65 20 4A 75 64 67 65 22 09 00 00 31 2F 32 34 2D
-31 2F 32 35 05 00 00 31 2F 31 33 30 05 00 00 31
-2F 35 37 30 05 00 00 54 6F 20 64 6F 33 00 00 47
-75 73 20 47 72 69 73 73 6F 6D 20 4D 65 6D 6F 72
-69 61 6C 20 43 6F 6D 62 6F 20 77 2F 54 77 6F 20
-43 6F 6C 6C 65 63 74 6F 72 73 20 50 61 74 63 68
-65 73 09 00 00 46 69 72 65 20 49 72 6F 6E 0C 00
-00 77 2F 64 65 74 61 69 6C 20 73 65 74 2C 00 00
-77 2F 64 65 74 61 69 6C 20 73 65 74 20 61 6E 64
-20 69 6E 74 65 72 69 6F 72 20 73 65 74 2C 20 72
-65 73 69 6E 20 65 6E 67 69 6E 65 73 03 00 00 49
-43 4D 0E 00 00 53 70 69 74 66 69 72 65 20 4D 6B
-2E 49 58 1A 00 00 4D 65 73 73 65 72 73 63 68 6D
-69 74 74 20 4D 65 20 34 31 30 42 2D 32 2F 55 34
-0A 00 00 4D 6F 64 65 6C 63 72 61 66 74 12 00 00
-46 2D 38 32 42 20 54 77 69 6E 20 4D 75 73 74 61
-6E 67 1F 00 00 31 39 35 33 20 53 74 75 64 65 62
-61 6B 65 72 20 53 74 61 72 6C 69 6E 65 72 20 43
-6F 75 70 65 04 00 00 32 34 33 36 0E 00 00 42 75
-67 61 74 74 69 20 45 42 20 31 31 30 2D 00 00 53
-74 61 72 20 54 72 65 6B 20 4B 6C 69 6E 67 6F 6E
-20 42 69 72 64 20 6F 66 20 50 72 65 79 20 46 6C
-69 67 68 74 20 44 69 73 70 6C 61 79 16 00 00 50
-6F 72 73 63 68 65 20 39 31 31 20 53 6C 61 6E 74
-20 4E 6F 73 65 05 00 00 36 31 30 37 33 25 00 00
-44 6F 75 67 6C 61 73 20 41 2D 31 4A 20 53 6B 79
-72 61 69 64 65 72 20 55 2E 53 2E 20 41 69 72 20
-46 6F 72 63 65 04 00 00 36 33 33 39 04 00 00 36
-39 35 35 04 00 00 37 35 33 30 06 00 00 34 38 2D
-30 32 30 05 00 00 31 2F 34 35 30 0F 00 00 55 2E
-53 2E 53 2E 20 4D 69 73 73 6F 75 72 69 05 00 00
-36 31 30 35 37 15 00 00 48 65 69 6E 6B 65 6C 20
-48 65 32 31 39 20 41 2D 37 20 55 48 55 05 00 00
-36 31 30 34 31 05 00 00 31 31 36 32 34 32 00 00
-43 6F 6E 73 6F 6C 69 64 61 74 65 64 20 42 2D 32
-34 4A 20 4C 69 62 65 72 61 74 6F 72 20 54 68 65
-20 44 72 61 67 6F 6E 20 26 20 48 69 73 20 54 61
-69
+FC 00 20
+20 B8 05 00 00 B0 02 00 00 0C 00 00 4D 61 6E 75
+66 61 63 74 75 72 65 72 0B 00 00 50 61 72 74 20
+4E 75 6D 62 65 72 05 00 00 53 63 61 6C 65 04 00
+00 54 79 70 65 04 00 00 4E 61 6D 65 08 00 00 43
+6F 6D 6D 65 6E 74 73 08 00 00 41 4D 54 2D 45 52
+54 4C 07 00 00 48 6F 74 20 52 6F 64 10 00 00 33
+32 20 46 6F 72 64 20 52 6F 61 64 73 74 65 72 08
+00 00 4D 6F 6E 6F 67 72 61 6D 08 00 00 53 68 6F
+77 20 52 6F 64 07 00 00 48 61 6E 67 6D 61 6E 11
+00 00 50 65 74 65 72 62 69 6C 74 20 57 72 65 63
+6B 65 72 15 00 00 45 61 73 74 65 72 6E 20 41 69
+72 6C 69 6E 65 73 20 44 43 2D 33 11 00 00 4D 61
+73 65 72 61 74 69 20 4D 65 72 61 6B 20 53 53 1A
+00 00 44 6F 75 67 6C 61 73 20 50 2D 37 30 20 4E
+69 67 68 74 20 46 69 67 68 74 65 72 17 00 00 35
+35 20 43 68 65 76 79 20 53 74 72 65 65 74 20 4D
+61 63 68 69 6E 65 0C 00 00 54 77 65 65 64 79 20
+50 69 65 20 32 13 00 00 48 75 65 79 20 52 65 73
+63 75 65 20 43 68 6F 70 70 65 72 10 00 00 4D 61
+7A 64 61 20 4D 58 2D 35 20 4D 69 61 74 61 0A 00
+00 53 70 6F 72 74 73 20 43 61 72 05 00 00 54 72
+75 63 6B 06 00 00 52 6F 63 6B 65 74 09 00 00 50
+61 72 74 73 20 4B 69 74 0E 00 00 43 69 76 69 6C
+69 61 6E 20 50 6C 61 6E 65 0E 00 00 4D 69 6C 69
+74 61 72 79 20 50 6C 61 6E 65 0F 00 00 53 63 69
+65 6E 63 65 20 46 69 63 74 69 6F 6E 1A 00 00 44
+6F 6E 20 47 61 72 6C 69 74 73 20 57 79 6E 6E 27
+73 20 43 68 61 72 67 65 72 19 00 00 44 6F 6E 20
+47 61 72 6C 69 74 73 20 57 79 6E 6E 27 73 20 4A
+61 6D 6D 65 72 1A 00 00 50 61 63 6B 61 72 64 20
+42 6F 61 74 74 61 69 6C 20 53 70 65 65 64 73 74
+65 72 0E 00 00 52 65 76 65 6C 6C 20 47 65 72 6D
+61 6E 79 05 00 00 30 34 31 34 36 04 00 00 31 2F
+32 34 04 00 00 31 2F 37 32 0E 00 00 4D 65 20 32
+36 32 20 41 2D 31 61 2F 55 33 09 00 00 53 54 43
+20 53 74 61 72 74 04 00 00 34 63 2D 39 05 00 00
+31 2F 32 38 38 0C 00 00 50 72 6F 74 6F 6E 2D 4B
+20 4D 69 72 04 00 00 34 63 2D 37 0E 00 00 50 72
+6F 74 6F 6E 2D 4B 20 41 73 74 72 61 05 00 00 34
+63 2D 31 37 0E 00 00 50 72 6F 74 6F 6E 2D 4B 20
+5A 61 72 79 61 13 00 00 41 63 63 75 72 61 74 65
+20 4D 69 6E 69 61 74 75 72 65 73 04 00 00 33 34
+32 30 04 00 00 31 2F 34 38 0F 00 00 53 42 44 2D
+31 20 44 61 75 6E 74 6C 65 73 73 1B 00 00 77 2F
+56 65 72 6C 69 6E 64 65 6E 20 31 33 37 38 20 44
+65 74 61 69 6C 20 53 65 74 04 00 00 38 32 38 33
+0C 00 00 54 72 6F 75 62 6C 65 6D 61 6B 65 72 04
+00 00 32 37 33 37 0E 00 00 44 61 79 74 6F 6E 61
+20 53 70 69 64 65 72 04 00 00 38 31 32 36 04 00
+00 31 2F 32 35 06 00 00 48 65 6C 6C 65 72 05 00
+00 38 30 34 34 33 05 00 00 31 2F 31 34 34 12 00
+00 42 72 65 69 74 6C 69 6E 20 4F 72 62 69 74 65
+72 20 33 0F 00 00 53 68 61 6E 67 68 61 69 20 44
+72 61 67 6F 6E 04 00 00 31 39 39 38 04 00 00 31
+2F 39 36 0F 00 00 41 72 69 61 6E 65 20 35 20 52
+6F 63 6B 65 74 0F 00 00 52 65 76 65 6C 6C 2D 4D
+6F 6E 6F 67 72 61 6D 07 00 00 38 35 2D 35 39 33
+34 0F 00 00 50 42 59 2D 35 41 20 43 61 74 61 6C
+69 6E 61 0A 00 00 50 72 6F 4D 6F 64 65 6C 65 72
+07 00 00 47 6C 65 6E 63 6F 65 05 00 00 30 35 32
+30 32 04 00 00 31 2F 33 35 16 00 00 50 69 61 73
+65 63 6B 69 20 5A 56 2D 38 50 20 41 69 72 67 65
+65 70 08 00 00 48 61 73 65 67 61 77 61 05 00 00
+30 39 31 36 39 20 00 00 53 42 44 2D 33 20 44 61
+75 6E 74 6C 65 73 73 20 27 55 53 53 20 45 6E 74
+65 72 70 72 69 73 65 27 0C 00 00 53 69 6C 76 65
+72 20 43 6C 6F 75 64 06 00 00 53 43 34 38 30 31
+19 00 00 53 75 70 65 72 6D 61 72 69 6E 65 20 53
+70 69 74 65 66 75 6C 20 46 2E 31 34 06 00 00 52
+65 76 65 6C 6C 07 00 00 38 35 2D 31 36 35 34 0D
+00 00 50 2D 35 31 42 20 4D 75 73 74 61 6E 67 09
+00 00 50 72 6F 46 69 6E 69 73 68 06 00 00 44 72
+61 67 6F 6E 04 00 00 35 39 30 31 0B 00 00 46 6F
+6B 6B 65 72 20 44 72 2E 31 07 00 00 49 74 61 6C
+65 72 69 03 00 00 38 34 36 25 00 00 43 2D 31 33
+30 4A 20 48 65 72 63 75 6C 65 73 20 48 65 61 76
+79 20 54 72 61 6E 73 70 6F 72 74 20 50 6C 61 6E
+65 04 00 00 37 36 31 30 15 00 00 46 65 72 72 61
+72 69 20 46 35 30 20 42 61 72 63 68 65 74 74 61
+03 00 00 41 4D 54 08 00 00 54 33 37 34 2D 32 32
+35 0D 00 00 43 6F 72 76 61 69 72 20 4D 6F 6E 7A
+61 04 00 00 35 30 30 33 0B 00 00 4D 63 4C 61 72
+65 6E 20 4D 38 42 0D 00 00 52 65 76 65 6C 6C 20
+4C 6F 64 65 6C 61 05 00 00 48 2D 32 36 33 03 00
+00 75 6E 6B 23 00 00 42 6F 65 69 6E 67 20 53 53
+54 20 50 61 6E 41 6D 20 43 6C 69 70 70 65 72 20
+53 75 70 65 72 73 6F 6E 69 63 05 00 00 30 35 39
+30 39 05 00 00 31 2F 33 30 30 1D 00 00 4E 75 63
+6C 65 61 72 20 50 6F 77 65 72 65 64 20 53 70 61
+63 65 20 53 74 61 74 69 6F 6E 04 00 00 38 37 36
+34 06 00 00 31 2F 32 35 30 30 19 00 00 53 74 61
+72 20 54 72 65 6B 20 44 65 65 70 20 53 70 61 63
+65 20 4E 69 6E 65 23 00 00 46 69 62 65 72 2D 6F
+70 74 69 63 20 4C 69 67 68 74 69 6E 67 2C 20 73
+6B 69 6C 6C 20 6C 65 76 65 6C 20 33 0D 00 00 53
+6B 69 6C 6C 20 6C 65 76 65 6C 20 33 04 00 00 38
+31 35 38 16 00 00 42 6C 75 65 70 72 69 6E 74 65
+72 20 50 61 72 74 73 20 50 61 63 6B 13 00 00 45
+6E 67 69 6E 65 73 20 61 6E 64 20 67 72 69 6C 6C
+65 73 05 00 00 33 30 30 33 37 05 00 00 31 2F 32
+30 30 1E 00 00 4D 61 6E 20 49 6E 20 53 70 61 63
+65 20 52 6F 63 6B 65 74 20 43 6F 6C 6C 65 63 74
+69 6F 6E 53 00 00 4D 65 72 63 75 72 79 20 41 74
+6C 61 73 2C 20 4D 65 72 63 75 72 79 20 52 65 64
+73 74 6F 6E 65 2C 20 47 65 6D 69 6E 69 20 54 69
+74 61 6E 20 49 49 2C 20 53 61 74 75 72 6E 20 31
+42 20 41 70 6F 6C 6C 6F 2C 20 53 61 74 75 72 6E
+20 56 20 41 70 6F 6C 6C 6F 04 00 00 35 30 38 33
+04 00 00 31 2F 33 32 11 00 00 41 70 6F 6C 6C 6F
+20 53 70 61 63 65 63 72 61 66 74 09 00 00 4D 69
+6E 69 63 72 61 66 74 05 00 00 31 31 32 32 30 04
+00 00 31 2F 31 36 24 00 00 31 39 35 35 20 4D 65
+72 63 65 64 65 73 20 33 30 30 53 4C 20 22 47 75
+6C 6C 77 69 6E 67 22 20 43 6F 75 70 65 07 00 00
+38 35 2D 36 38 35 39 24 00 00 4D 75 73 74 61 6E
+67 20 4D 75 73 63 6C 65 20 54 72 69 6F 20 27 36
+30 73 2C 20 27 37 30 73 2C 20 27 38 30 73 35 00
+00 31 39 36 34 20 31 2F 32 20 43 6F 6E 76 65 72
+74 69 62 6C 65 2C 20 31 39 37 30 20 42 6F 73 73
+20 33 30 32 2C 20 31 39 38 39 20 43 6F 6E 76 65
+72 74 69 62 6C 65 06 00 00 54 61 6D 69 79 61 05
+00 00 32 34 31 37 30 0A 00 00 4D 6F 72 67 61 6E
+20 34 2F 34 07 00 00 38 35 2D 32 34 39 31 11 00
+00 36 37 20 43 6F 72 76 65 74 74 65 20 43 6F 75
+70 65 07 00 00 38 35 2D 32 35 33 34 0F 00 00 53
+68 65 6C 62 79 20 53 65 72 69 65 73 20 31 03 00
+00 35 36 32 11 00 00 41 73 74 6F 6E 20 4D 61 72
+74 69 6E 20 44 42 20 34 05 00 00 30 37 33 32 30
+13 00 00 50 6F 72 73 63 68 65 20 39 31 31 20 43
+61 72 72 65 72 61 07 00 00 54 65 73 74 6F 72 73
+03 00 00 33 38 36 04 00 00 32 39 37 32 16 00 00
+4D 65 72 63 65 64 65 73 20 33 30 30 20 53 4C 52
+20 22 37 32 32 22 08 00 00 4C 69 6E 64 62 65 72
+67 05 00 00 37 30 39 35 36 19 00 00 48 65 6C 6C
+63 61 74 73 20 76 73 2E 20 42 65 74 74 79 20 42
+6F 6D 62 65 72 0C 00 00 48 65 6C 6C 63 61 74 20
+6F 6E 6C 79 05 00 00 30 34 36 30 39 18 00 00 45
+6B 72 61 6E 6F 70 6C 61 6E 20 41 2D 39 30 20 4F
+72 6C 6A 6F 6E 6F 6B 05 00 00 31 31 36 32 36 18
+00 00 47 72 75 6D 6D 61 6E 20 58 46 35 46 2D 31
+20 53 6B 79 72 6F 63 6B 65 74 04 00 00 35 34 32
+30 0E 00 00 48 61 77 6B 65 72 20 48 61 72 72 69
+65 72 05 00 00 41 56 2D 38 41 06 00 00 65 64 75
+61 72 64 04 00 00 38 30 36 31 0F 00 00 50 2D 34
+30 30 20 41 69 72 61 63 6F 62 72 61 0B 00 00 43
+7A 65 63 68 20 4D 6F 64 65 6C 04 00 00 34 38 30
+36 16 00 00 43 75 72 74 69 73 73 20 58 50 2D 35
+35 20 41 73 63 65 6E 64 65 72 05 00 00 36 31 30
+37 34 14 00 00 44 6F 72 6E 69 65 72 20 44 6F 33
+33 35 41 20 50 66 69 65 6C 13 00 00 4B 79 75 73
+68 75 20 4A 37 57 31 20 53 68 69 6E 64 65 6E 0D
+00 00 50 6C 61 6E 65 74 20 4D 6F 64 65 6C 73 03
+00 00 30 34 33 0F 00 00 48 65 6E 73 63 68 65 6C
+20 48 73 20 50 38 37 05 00 00 52 65 73 69 6E 0D
+00 00 53 70 65 63 69 61 6C 20 48 6F 62 62 79 08
+00 00 53 48 20 34 38 30 30 33 16 00 00 4D 63 44
+6F 6E 6E 65 6C 6C 20 58 46 2D 38 35 20 47 6F 62
+6C 69 6E 2A 00 00 4D 65 73 73 65 72 73 63 68 6D
+69 74 74 20 42 66 31 30 39 45 20 27 42 75 6C 67
+61 72 69 61 6E 20 41 69 72 20 46 6F 72 63 65 27
+05 00 00 30 34 32 30 36 2D 00 00 41 69 72 62 75
+73 20 53 75 70 65 72 20 54 72 61 6E 73 70 6F 72
+74 65 72 20 41 33 30 30 2D 36 30 30 20 53 54 20
+22 42 65 6C 75 67 61 22 05 00 00 33 30 30 38 37
+0C 00 00 33 39 20 57 61 67 6F 6E 20 52 6F 64 04
+00 00 37 31 32 31 1A 00 00 31 39 33 32 20 46 6F
+72 64 20 48 69 67 68 62 6F 79 20 52 6F 61 64 73
+74 65 72 2E 00 00 4C 69 6E 63 6F 6C 6E 20 4D 69
+6E 74 20 55 6C 74 72 61 20 4D 65 74 61 6C 20 53
+65 72 69 65 73 2C 20 53 6B 69 6C 6C 20 6C 65 76
+65 6C 20 33 0C 00 00 50 6F 6C 61 72 20 4C 69 67
+68 74 73 04 00 00 35 30 31 34 21 00 00 43 61 72
+6C 20 43 61 73 70 65 72 27 73 20 55 6E 64 65 72
+74 61 6B 65 72 20 44 72 61 67 73 74 65 72 07 00
+00 38 35 2D 32 35 39 32 20 00 00 33 39 20 43 68
+65 76 79 20 53 65 64 61 6E 20 44 65 6C 69 76 65
+72 79 20 4C 6F 77 72 69 64 65 72 07 00 00 38 35
+2D 35 39 30 34 12 00 00 4E 41 53 41 20 53 70 61
+63 65 20 53 68 75 74 74 6C 65 04 00 00 32 34 30
+30 1C 00 00 31 39 32 36 20 4D 61 63 6B 20 42 75
+6C 6C 64 6F 67 20 44 75 6D 70 20 54 72 75 63 6B
+05 00 00 43 31 31 32 38 13 00 00 32 33 20 54 20
+52 6F 61 64 73 74 65 72 20 46 72 61 6D 65 05 00
+00 33 31 32 31 36 11 00 00 44 6F 64 67 65 20 56
+69 70 65 72 20 52 54 2D 31 30 07 00 00 50 72 6F
+53 68 6F 70 04 00 00 32 33 30 31 05 00 00 31 31
+32 31 32 26 00 00 31 39 33 35 20 4D 6F 72 67 61
+6E 20 53 75 70 65 72 20 53 70 6F 72 74 73 20 54
+68 72 65 65 20 57 68 65 65 6C 65 72 0C 00 00 47
+75 6E 7A 65 20 53 61 6E 67 79 6F 13 00 00 54 72
+69 75 6D 70 68 20 54 52 32 20 4C 65 20 4D 61 6E
+73 07 00 00 38 35 2D 31 39 31 31 0F 00 00 33 34
+20 46 6F 72 64 20 48 69 67 68 62 6F 79 17 00 00
+57 68 65 65 6C 73 20 6F 66 20 46 69 72 65 20 53
+6E 61 70 54 69 74 65 06 00 00 4A 6F 2D 48 61 6E
+06 00 00 47 43 2D 33 30 30 20 00 00 43 68 72 79
+73 6C 65 72 20 43 6F 72 70 6F 72 61 74 69 6F 6E
+20 54 75 72 62 69 6E 65 20 43 61 72 09 00 00 48
+31 32 38 35 3A 31 39 38 2B 00 00 54 6F 6D 6D 79
+20 49 76 6F 27 73 20 46 6F 75 72 20 45 6E 67 69
+6E 65 20 44 72 61 67 73 74 65 72 20 22 53 68 6F
+77 62 6F 61 74 22 09 00 00 48 31 32 32 34 3A 32
+30 30 17 00 00 32 32 20 4A 52 20 52 6F 61 64 73
+74 65 72 20 44 72 61 67 73 74 65 72 0F 00 00 32
+20 63 6F 6D 70 6C 65 74 65 20 63 61 72 73 04 00
+00 36 34 33 35 04 00 00 36 34 33 38 07 00 00 38
+35 2D 37 36 36 38 0F 00 00 34 31 20 43 68 65 76
+79 20 50 69 63 6B 75 70 04 00 00 36 35 38 35 17
+00 00 42 61 62 79 6C 6F 6E 20 35 20 53 74 61 72
+66 75 72 79 20 4D 6B 2E 31 1C 00 00 4D 65 73 73
+65 72 73 63 68 6D 69 74 74 20 42 66 31 30 39 45
+20 47 61 6C 6C 61 6E 64 05 00 00 36 31 30 36 37
+1B 00 00 42 72 69 73 74 6F 6C 20 42 65 61 75 66
+69 67 68 74 65 72 20 54 46 2E 4D 6B 2E 58 12 00
+00 48 65 6E 73 63 68 65 6C 20 48 73 20 31 32 39
+42 2D 32 04 00 00 33 34 31 39 0D 00 00 50 2D 35
+31 43 20 4D 75 73 74 61 6E 67 07 00 00 38 35 2D
+35 35 30 39 1B 00 00 48 65 69 6E 6B 65 6C 20 48
+65 31 31 31 20 47 65 72 6D 61 6E 20 42 6F 6D 62
+65 72 11 00 00 41 63 61 64 65 6D 79 20 4D 69 6E
+69 63 72 61 66 74 04 00 00 32 31 34 35 1E 00 00
+4C 6F 63 6B 68 65 65 64 20 50 2D 33 38 4D 20 4E
+69 67 68 74 20 4C 69 67 68 74 6E 69 6E 67 07 00
+00 38 35 2D 30 31 33 35 11 00 00 4F 53 32 55 2D
+33 20 4B 69 6E 67 66 69 73 68 65 72 3B 00 00 41
+69 63 68 69 20 42 37 41 32 20 41 74 74 61 63 6B
+20 42 6F 6D 62 65 72 20 20 52 79 75 73 65 69 20
+4B 61 69 20 28 47 72 61 63 65 29 20 27 46 6F 6C
+64 69 6E 67 20 57 69 6E 67 27 15 00 00 58 46 35
+55 2D 31 20 46 6C 79 69 6E 67 20 50 61 6E 63 61
+6B 65 04 00 00 36 37 35 37 07 00 00 49 63 65 20
+27 54 27 07 00 00 38 35 2D 35 31 30 32 04 00 00
+53 68 69 70 15 00 00 55 2E 53 2E 53 2E 20 4E 6F
+72 74 68 20 43 61 72 6F 6C 69 6E 61 0E 00 00 50
+61 72 74 73 20 62 79 20 50 61 72 6B 73 04 00 00
+31 30 30 34 0F 00 00 44 69 73 74 72 69 62 75 74
+6F 72 20 4B 69 74 12 00 00 50 53 46 20 4D 6F 64
+65 6C 20 53 75 70 70 6C 69 65 73 07 00 00 45 4B
+44 31 30 30 30 1B 00 00 4D 6F 64 65 6C 20 43 61
+72 20 45 6E 67 69 6E 65 20 44 65 74 61 69 6C 20
+4B 69 74 04 00 00 38 34 33 35 1F 00 00 43 75 73
+74 6F 6D 20 26 20 43 6F 6D 70 65 74 69 74 69 6F
+6E 20 50 61 72 74 73 20 50 61 63 6B 04 00 00 54
+36 34 32 27 00 00 22 57 69 6E 6E 69 65 20 4D 61
+65 22 20 57 69 6C 65 79 20 50 6F 73 74 27 73 20
+4C 6F 63 6B 68 65 65 64 20 56 65 67 61 06 00 00
+41 69 72 66 69 78 05 00 00 30 34 31 37 36 0C 00
+00 44 48 20 43 6F 6D 65 74 20 34 20 42 07 00 00
+38 35 2D 34 31 36 32 1B 00 00 4F 72 61 6E 67 65
+20 43 72 61 74 65 20 27 33 32 20 46 6F 72 64 20
+53 65 64 61 6E 06 00 00 38 36 30 35 50 4F 14 00
+00 46 69 61 74 20 44 6F 75 62 6C 65 20 44 72 61
+67 73 74 65 72 0B 00 00 42 6C 75 65 70 72 69 6E
+74 65 72 06 00 00 48 2D 31 33 32 31 0C 00 00 47
+72 61 6E 20 54 75 72 69 73 6D 6F 07 00 00 38 35
+2D 37 36 33 37 15 00 00 33 31 20 46 6F 72 64 20
+4D 6F 64 65 6C 20 41 20 57 6F 6F 64 79 03 00 00
+4D 50 43 07 00 00 32 30 30 2D 32 30 30 16 00 00
+47 61 6E 67 62 75 73 74 65 72 73 20 32 38 20 4C
+69 6E 63 6F 6C 6E 07 00 00 38 35 2D 32 35 36 39
+19 00 00 43 68 65 76 79 20 53 2D 31 30 20 4C 6F
+77 72 69 64 65 72 20 33 27 6E 20 31 04 00 00 32
+32 31 31 04 00 00 35 35 30 35 1C 00 00 48 6F 72
+74 65 6E 20 48 6F 20 32 32 39 41 2D 31 20 46 6C
+79 69 6E 67 20 57 69 6E 67 05 00 00 30 35 32 30
+31 1C 00 00 4D 63 44 6F 6E 6E 65 6C 6C 20 58 56
+2D 31 20 43 6F 6E 76 65 72 74 69 70 6C 61 6E 65
+07 00 00 38 35 2D 35 38 31 30 0F 00 00 53 52 2D
+37 31 20 42 6C 61 63 6B 62 69 72 64 04 00 00 34
+35 32 32 19 00 00 4D 65 73 73 65 72 73 63 68 6D
+69 74 74 20 42 66 2D 31 30 39 20 47 2D 31 30 16
+00 00 50 72 65 6D 69 75 6D 2C 20 73 6B 69 6C 6C
+20 6C 65 76 65 6C 20 34 04 00 00 38 36 34 36 0B
+00 00 48 6F 62 62 79 20 43 72 61 66 74 06 00 00
+48 43 31 35 34 39 16 00 00 56 61 6D 70 69 72 65
+20 46 33 20 4A 65 74 20 46 69 67 68 74 65 72 04
+00 00 33 34 30 31 0B 00 00 41 2D 33 36 20 41 70
+61 63 68 65 05 00 00 30 34 33 33 35 15 00 00 42
+6C 6F 68 6D 20 26 20 56 6F 73 73 20 42 56 20 50
+2D 31 39 34 09 00 00 30 31 33 30 4D 30 31 30 30
+34 00 00 43 6F 72 64 20 50 68 61 65 74 6F 6E 20
+53 65 64 61 6E 20 31 39 33 37 20 38 31 32 20 53
+75 70 65 72 63 68 61 72 67 65 64 20 43 6F 6E 76
+65 72 74 69 62 6C 65 07 00 00 38 35 2D 32 35 37
+39 15 00 00 56 57 20 42 65 65 74 6C 65 20 43 6F
+6E 76 65 72 74 69 62 6C 65 04 00 00 37 34 33 38
+10 00 00 42 4D 57 20 5A 2D 31 20 52 6F 61 64 73
+74 65 72 04 00 00 36 31 34 38 0B 00 00 44 69 61
+62 6C 6F 20 41 65 72 6F 0B 00 00 55 6E 69 6F 6E
+20 4D 6F 64 65 6C 2B 00 00 50 65 74 65 20 42 72
+6F 63 6B 27 73 20 53 43 43 41 20 43 68 61 6D 70
+69 6F 6E 20 42 52 45 2F 44 61 74 73 75 6E 20 32
+34 30 2D 5A 05 00 00 32 34 31 32 39 0D 00 00 4A
+61 67 75 61 72 20 58 4A 20 32 32 30 05 00 00 30
+33 31 30 31 13 00 00 53 70 69 72 69 74 20 6F 66
+20 53 74 2E 20 4C 6F 75 69 73 05 00 00 30 36 31
+37 31 15 00 00 4F 72 69 6F 6E 20 32 30 30 31 20
+53 70 61 63 65 63 72 61 66 74 04 00 00 38 37 36
+36 05 00 00 31 2F 36 35 30 18 00 00 53 74 61 72
+20 54 72 65 6B 20 55 2E 53 2E 53 2E 20 52 65 6C
+69 61 6E 74 07 00 00 38 35 2D 31 38 33 35 15 00
+00 4E 41 53 41 2F 4D 63 44 6F 6E 6E 65 6C 6C 20
+47 65 6D 69 6E 69 04 00 00 31 39 39 37 24 00 00
+43 68 61 6E 67 20 5A 68 65 6E 67 20 32 20 28 43
+5A 2D 32 45 29 20 4C 61 75 6E 63 68 20 56 65 68
+69 63 6C 65 05 00 00 31 31 32 31 30 04 00 00 31
+2F 32 30 13 00 00 4D 61 6B 6F 20 53 68 61 72 6B
+20 53 68 6F 77 20 43 61 72 08 00 00 44 72 61 67
+73 74 65 72 08 00 00 4C 6F 77 72 69 64 65 72 04
+00 00 36 30 36 36 2F 00 00 57 69 6C 64 20 57 69
+6C 6C 69 65 20 42 6F 72 73 63 68 20 22 57 69 6E
+67 65 64 20 45 78 70 72 65 73 73 22 20 41 6C 74
+65 72 65 64 20 52 6F 64 04 00 00 36 31 38 32 0F
+00 00 31 39 33 33 20 57 69 6C 6C 79 73 20 56 61
+6E 07 00 00 38 35 2D 30 35 34 30 34 00 00 49 6E
+61 75 67 75 72 61 6C 20 4D 41 54 43 4F 20 54 6F
+6F 6C 73 20 53 75 70 65 72 6E 61 74 69 6F 6E 61
+6C 73 20 4E 69 74 72 6F 20 46 75 6E 6E 79 20 43
+61 72 04 00 00 36 33 35 35 1E 00 00 31 39 35 37
+20 43 68 65 76 72 6F 6C 65 74 20 43 6F 72 76 65
+74 74 65 20 47 61 73 73 65 72 07 00 00 38 35 2D
+37 36 37 35 04 00 00 50 43 36 31 2A 00 00 47 72
+65 65 6E 20 48 6F 72 6E 65 74 20 46 6F 72 64 20
+22 54 22 20 53 68 6F 77 20 61 6E 64 20 47 6F 20
+52 6F 61 64 73 74 65 72 04 00 00 38 32 31 35 18
+00 00 31 39 34 30 20 46 6F 72 64 20 53 65 64 61
+6E 20 44 65 6C 69 76 65 72 79 07 00 00 38 35 2D
+37 36 32 38 16 00 00 33 37 20 46 6F 72 64 20 50
+61 6E 65 6C 20 44 65 6C 69 76 65 72 79 04 00 00
+31 32 39 34 10 00 00 47 79 70 73 79 20 44 75 6E
+65 20 42 75 67 67 79 06 00 00 48 2D 31 32 33 31
+23 00 00 43 68 72 79 73 6C 65 72 20 4E 65 77 20
+59 6F 72 6B 65 72 20 43 75 73 74 6F 6D 69 7A 69
+6E 67 20 4B 69 74 05 00 00 33 30 30 38 31 0E 00
+00 36 32 20 54 68 75 6E 64 65 72 62 69 72 64 04
+00 00 36 38 39 39 11 00 00 31 39 33 32 20 46 6F
+72 64 20 50 68 61 65 74 6F 6E 05 00 00 33 30 32
+37 30 0D 00 00 31 39 36 38 20 50 6C 79 6D 6F 75
+74 68 04 00 00 38 38 34 32 17 00 00 47 72 75 6D
+6D 61 6E 20 46 37 46 2D 33 4E 20 54 69 67 65 72
+63 61 74 04 00 00 48 32 34 34 14 00 00 4D 61 72
+74 69 6E 20 50 36 4D 20 53 65 61 6D 61 73 74 65
+72 04 00 00 35 35 30 30 0E 00 00 42 2D 32 35 48
+20 4D 69 74 63 68 65 6C 6C 04 00 00 33 34 30 32
+0D 00 00 50 2D 35 31 41 20 4D 75 73 74 61 6E 67
+04 00 00 36 34 32 31 3E 00 00 44 61 6D 62 75 73
+74 65 72 20 47 72 61 6E 64 20 53 6C 61 6D 20 42
+6F 6D 62 65 72 20 4C 61 6E 63 61 73 74 65 72 20
+42 49 20 53 70 65 63 69 61 6C 20 32 32 30 30 30
+6C 62 2E 20 42 6F 6D 62 05 00 00 31 34 34 34 33
+1E 00 00 4C 6F 63 6B 68 65 65 64 20 53 75 70 65
+72 2D 47 20 43 6F 6E 73 74 65 6C 6C 61 74 69 6F
+6E 04 00 00 35 36 31 30 13 00 00 57 69 6C 6C 69
+61 6D 73 20 42 72 6F 73 2E 20 49 6E 63 2E 07 00
+00 34 38 2D 33 31 39 31 10 00 00 43 6F 72 62 65
+6E 20 53 75 70 65 72 2D 41 63 65 05 00 00 30 35
+30 30 32 10 00 00 52 65 74 72 69 65 76 65 72 20
+52 6F 63 6B 65 74 03 00 00 43 61 72 04 00 00 38
+35 38 38 1D 00 00 50 6C 79 6D 6F 75 74 68 20 50
+72 6F 77 6C 65 72 20 77 69 74 68 20 54 72 61 69
+6C 65 72 04 00 00 35 30 30 31 14 00 00 43 6F 72
+76 65 74 74 65 20 47 72 61 6E 64 20 53 70 6F 72
+74 04 00 00 37 31 30 38 1D 00 00 43 6F 72 76 65
+74 74 65 20 49 6E 64 79 20 22 44 72 65 61 6D 20
+4D 61 63 68 69 6E 65 22 04 00 00 38 30 35 39 0C
+00 00 54 68 65 20 4D 75 6E 73 74 65 72 73 20 00
+00 42 6C 75 65 70 72 69 6E 74 65 72 3B 20 4D 75
+6E 73 74 65 72 73 20 4B 6F 61 63 68 20 6F 6E 6C
+79 07 00 00 38 35 2D 34 31 36 36 05 00 00 43 6F
+75 6E 74 3C 00 00 77 2F 43 75 74 74 69 6E 67 20
+45 64 67 65 20 43 45 43 34 38 30 38 36 20 48 65
+31 31 31 5A 20 22 5A 77 69 6C 6C 69 6E 67 22 20
+6B 69 74 2C 20 73 6B 69 6C 6C 20 6C 65 76 65 6C
+20 33 07 00 00 38 35 2D 37 36 36 36 23 00 00 43
+75 73 74 6F 6D 20 53 69 6C 76 65 72 61 64 6F 20
+61 6E 64 20 57 61 76 65 72 69 64 65 72 20 42 6F
+61 74 07 00 00 38 35 2D 36 38 35 38 16 00 00 53
+6E 61 6B 65 20 26 20 4D 6F 6E 67 6F 6F 73 65 20
+43 6F 6D 62 6F 07 00 00 38 35 2D 34 31 35 39 24
+00 00 4A 6F 65 20 41 6D 61 74 6F 20 53 75 70 65
+72 6D 61 6E 20 54 6F 70 20 46 75 65 6C 20 44 72
+61 67 73 74 65 72 04 00 00 37 35 34 31 0D 00 00
+53 6B 69 6C 6C 20 6C 65 76 65 6C 20 35 09 00 00
+48 38 32 35 2D 31 30 44 30 28 00 00 43 6F 63 61
+20 43 6F 6C 61 20 46 6F 72 64 20 4C 6F 75 69 73
+76 69 6C 6C 65 20 44 65 6C 69 76 65 72 79 20 54
+72 75 63 6B 07 00 00 38 35 2D 32 31 35 36 04 00
+00 32 39 35 34 0B 00 00 50 6F 72 73 63 68 65 20
+39 30 34 04 00 00 32 39 33 35 25 00 00 4C 61 6D
+62 6F 72 67 68 69 6E 69 20 43 6F 75 6E 74 61 63
+68 20 32 35 74 68 20 41 6E 6E 69 76 65 72 73 61
+72 79 07 00 00 38 35 2D 37 36 31 36 1F 00 00 41
+6D 65 72 69 63 61 6E 20 49 6E 74 65 72 6E 61 74
+69 6F 6E 61 6C 20 44 72 61 67 73 74 65 72 07 00
+00 38 35 2D 35 32 34 31 0D 00 00 50 2D 35 31 44
+20 4D 75 73 74 61 6E 67 07 00 00 38 35 2D 35 37
+31 30 11 00 00 52 42 2D 33 36 48 20 50 65 61 63
+65 6D 61 6B 65 72 05 00 00 30 35 31 30 34 14 00
+00 52 65 70 75 62 6C 69 63 20 52 43 2E 33 20 53
+65 61 62 65 65 05 00 00 50 41 31 35 32 05 00 00
+36 31 30 36 36 25 00 00 44 65 48 61 76 69 6C 6C
+61 6E 64 20 4D 6F 73 71 75 69 74 6F 20 42 20 4D
+6B 2E 49 56 2F 50 52 20 4D 6B 2E 49 56 07 00 00
+38 35 2D 37 35 34 36 10 00 00 50 2D 36 31 20 42
+6C 61 63 6B 20 57 69 64 6F 77 07 00 00 38 35 2D
+36 36 35 32 25 00 00 42 2D 31 37 46 20 46 6C 79
+69 6E 67 20 46 6F 72 74 72 65 73 73 20 22 4D 65
+6D 70 68 69 73 20 42 65 6C 6C 65 22 04 00 00 37
+35 30 30 0D 00 00 47 61 74 65 73 20 4C 65 61 72
+6A 65 74 03 00 00 35 31 39 15 00 00 47 72 75 6D
+6D 61 6E 20 46 38 46 2D 32 20 42 65 61 72 63 61
+74 04 00 00 37 35 32 33 12 00 00 46 2D 31 30 34
+43 20 53 74 61 72 66 69 67 68 74 65 72 05 00 00
+36 31 30 37 30 15 00 00 56 6F 75 67 68 74 20 46
+34 55 2D 31 41 20 43 6F 72 73 61 69 72 07 00 00
+38 35 2D 37 36 36 34 19 00 00 42 61 6C 64 77 69
+6E 2D 4D 6F 74 69 6F 6E 20 44 72 61 67 20 43 6F
+62 72 61 04 00 00 38 34 35 35 14 00 00 35 37 20
+43 68 65 76 72 6F 6C 65 74 20 42 65 6C 20 41 69
+72 16 00 00 50 72 6F 53 68 6F 70 2C 20 73 6B 69
+6C 6C 20 6C 65 76 65 6C 20 33 05 00 00 33 30 30
+35 32 0D 00 00 34 31 20 46 6F 72 64 20 57 6F 6F
+64 79 07 00 00 38 35 2D 32 35 35 37 19 00 00 36
+30 20 43 68 65 76 79 20 48 61 72 64 74 6F 70 20
+4C 6F 77 72 69 64 65 72 07 00 00 38 35 2D 37 36
+33 38 09 00 00 41 65 72 6F 76 65 74 74 65 07 00
+00 38 35 2D 30 30 39 34 1B 00 00 4C 69 27 6C 20
+43 6F 66 66 69 6E 20 43 75 73 74 6F 6D 20 53 68
+6F 77 20 52 6F 64 04 00 00 38 32 39 30 0A 00 00
+53 27 43 6F 6F 6C 20 42 75 73 07 00 00 38 35 2D
+32 35 39 37 12 00 00 53 74 72 65 65 74 20 46 69
+67 68 74 65 72 20 54 77 6F 04 00 00 37 36 30 39
+12 00 00 54 68 61 6D 65 73 20 50 61 6E 65 6C 20
+54 72 75 63 6B 07 00 00 38 35 2D 37 36 30 36 15
+00 00 44 61 6E 20 46 69 6E 6B 27 73 20 53 70 65
+65 64 77 61 67 6F 6E 05 00 00 30 35 35 30 35 1A
+00 00 4D 61 72 74 69 6E 20 4D 2D 31 33 30 20 43
+68 69 6E 61 20 43 6C 69 70 70 65 72 07 00 00 38
+35 2D 30 30 31 35 0E 00 00 46 6F 72 64 20 54 72
+69 2D 4D 6F 74 6F 72 04 00 00 50 41 33 30 1A 00
+00 57 72 69 67 68 74 20 42 72 6F 74 68 65 72 73
+20 4B 69 74 74 79 20 48 61 77 6B 07 00 00 38 35
+2D 35 30 38 31 13 00 00 46 69 72 73 74 20 4C 75
+6E 61 72 20 4C 61 6E 64 69 6E 67 07 00 00 38 35
+2D 35 38 33 39 18 00 00 4D 65 73 73 65 72 73 63
+68 6D 69 74 74 20 42 66 20 31 31 30 20 47 2D 32
+04 00 00 43 48 34 31 04 00 00 4A 30 30 34 05 00
+00 4A 54 31 32 33 04 00 00 4A 54 32 32 04 00 00
+4A 54 37 31 04 00 00 53 50 36 33 04 00 00 42 54
+31 36 0C 00 00 4F 56 2D 31 42 20 4D 6F 68 61 77
+6B 03 00 00 30 36 38 0B 00 00 56 2D 32 32 20 4F
+73 70 72 65 79 04 00 00 38 36 31 35 13 00 00 58
+2F 59 42 2D 33 35 20 46 6C 79 69 6E 67 20 57 69
+6E 67 05 00 00 31 31 32 30 38 1B 00 00 31 39 33
+33 20 43 61 64 69 6C 6C 61 63 20 56 2D 31 36 20
+54 6F 77 6E 20 43 61 72 04 00 00 36 36 31 38 27
+00 00 53 74 61 72 20 54 72 65 6B 20 33 20 50 69
+65 63 65 20 55 2E 53 2E 53 2E 20 45 6E 74 65 72
+70 72 69 73 65 20 53 65 74 12 00 00 4D 69 73 73
+69 6E 67 20 54 56 20 76 65 72 73 69 6F 6E 04 00
+00 38 39 31 35 0E 00 00 53 74 61 72 20 44 65 73
+74 72 6F 79 65 72 04 00 00 38 31 39 33 0A 00 00
+44 65 61 74 68 20 53 74 61 72 08 00 00 53 6E 61
+70 54 69 74 65 07 00 00 38 35 2D 33 36 32 31 07
+00 00 38 35 2D 33 36 32 32 17 00 00 42 61 62 79
+6C 6F 6E 20 35 20 53 70 61 63 65 20 53 74 61 74
+69 6F 6E 04 00 00 36 38 35 38 1F 00 00 53 74 61
+72 20 54 72 65 6B 20 33 20 50 69 65 63 65 20 41
+64 76 65 72 73 61 72 79 20 53 65 74 04 00 00 38
+37 36 32 06 00 00 31 2F 31 30 30 30 29 00 00 53
+74 61 72 20 54 72 65 6B 20 47 65 6E 65 72 61 74
+69 6F 6E 73 20 55 2E 53 2E 53 2E 20 45 6E 74 65
+72 70 72 69 73 65 20 42 04 00 00 38 38 38 33 03
+00 00 31 2F 34 05 00 00 4F 74 68 65 72 12 00 00
+56 69 73 69 62 6C 65 20 56 2D 38 20 45 6E 67 69
+6E 65 04 00 00 37 31 32 30 1C 00 00 31 39 36 39
+20 50 6F 6E 74 69 61 63 20 47 54 4F 20 22 54 68
+65 20 4A 75 64 67 65 22 09 00 00 31 2F 32 34 2D
+31 2F 32 35 05 00 00 31 2F 31 33 30 05 00 00 31
+2F 35 37 30 05 00 00 54 6F 20 64 6F 33 00 00 47
+75 73 20 47 72 69 73 73 6F 6D 20 4D 65 6D 6F 72
+69 61 6C 20 43 6F 6D 62 6F 20 77 2F 54 77 6F 20
+43 6F 6C 6C 65 63 74 6F 72 73 20 50 61 74 63 68
+65 73 09 00 00 46 69 72 65 20 49 72 6F 6E 0C 00
+00 77 2F 64 65 74 61 69 6C 20 73 65 74 2C 00 00
+77 2F 64 65 74 61 69 6C 20 73 65 74 20 61 6E 64
+20 69 6E 74 65 72 69 6F 72 20 73 65 74 2C 20 72
+65 73 69 6E 20 65 6E 67 69 6E 65 73 03 00 00 49
+43 4D 0E 00 00 53 70 69 74 66 69 72 65 20 4D 6B
+2E 49 58 1A 00 00 4D 65 73 73 65 72 73 63 68 6D
+69 74 74 20 4D 65 20 34 31 30 42 2D 32 2F 55 34
+0A 00 00 4D 6F 64 65 6C 63 72 61 66 74 12 00 00
+46 2D 38 32 42 20 54 77 69 6E 20 4D 75 73 74 61
+6E 67 1F 00 00 31 39 35 33 20 53 74 75 64 65 62
+61 6B 65 72 20 53 74 61 72 6C 69 6E 65 72 20 43
+6F 75 70 65 04 00 00 32 34 33 36 0E 00 00 42 75
+67 61 74 74 69 20 45 42 20 31 31 30 2D 00 00 53
+74 61 72 20 54 72 65 6B 20 4B 6C 69 6E 67 6F 6E
+20 42 69 72 64 20 6F 66 20 50 72 65 79 20 46 6C
+69 67 68 74 20 44 69 73 70 6C 61 79 16 00 00 50
+6F 72 73 63 68 65 20 39 31 31 20 53 6C 61 6E 74
+20 4E 6F 73 65 05 00 00 36 31 30 37 33 25 00 00
+44 6F 75 67 6C 61 73 20 41 2D 31 4A 20 53 6B 79
+72 61 69 64 65 72 20 55 2E 53 2E 20 41 69 72 20
+46 6F 72 63 65 04 00 00 36 33 33 39 04 00 00 36
+39 35 35 04 00 00 37 35 33 30 06 00 00 34 38 2D
+30 32 30 05 00 00 31 2F 34 35 30 0F 00 00 55 2E
+53 2E 53 2E 20 4D 69 73 73 6F 75 72 69 05 00 00
+36 31 30 35 37 15 00 00 48 65 69 6E 6B 65 6C 20
+48 65 32 31 39 20 41 2D 37 20 55 48 55 05 00 00
+36 31 30 34 31 05 00 00 31 31 36 32 34 32 00 00
+43 6F 6E 73 6F 6C 69 64 61 74 65 64 20 42 2D 32
+34 4A 20 4C 69 62 65 72 61 74 6F 72 20 54 68 65
+20 44 72 61 67 6F 6E 20 26 20 48 69 73 20 54 61
+69
diff --git a/src/testcases/org/apache/poi/hssf/data/duprich1.xls b/src/testcases/org/apache/poi/hssf/data/duprich1.xls
new file mode 100644
index 0000000000..3fddbedd27
--- /dev/null
+++ b/src/testcases/org/apache/poi/hssf/data/duprich1.xls
Binary files differ
diff --git a/src/testcases/org/apache/poi/hssf/data/duprich2.xls b/src/testcases/org/apache/poi/hssf/data/duprich2.xls
new file mode 100644
index 0000000000..57af63b3d4
--- /dev/null
+++ b/src/testcases/org/apache/poi/hssf/data/duprich2.xls
Binary files differ
diff --git a/src/testcases/org/apache/poi/hssf/data/evencontinuation.txt b/src/testcases/org/apache/poi/hssf/data/evencontinuation.txt
new file mode 100644
index 0000000000..4740b27472
--- /dev/null
+++ b/src/testcases/org/apache/poi/hssf/data/evencontinuation.txt
@@ -0,0 +1,16 @@
+14 00 # String length 0x14=20
+01 # Option flag, 16bit
+# String: At a dinner party or
+41 00 74 00 20 00 61 00 20 00
+64 00 69 00 6E 00 6E 00 65 00
+72 00 20 00 70 00 61 00 72 00
+74 00 79 00 20 00 6F 00 72 00
+
+# Continuation record (new string on the boundry)
+11 00 # String length 0x11=17
+00 # Option flag, 8bit
+# String: At a dinner party
+41 74 20 61 20
+64 69 6E 6E 65
+72 20 70 61 72
+74 79
diff --git a/src/testcases/org/apache/poi/hssf/data/richtextdata.txt b/src/testcases/org/apache/poi/hssf/data/richtextdata.txt
new file mode 100644
index 0000000000..a345595831
--- /dev/null
+++ b/src/testcases/org/apache/poi/hssf/data/richtextdata.txt
@@ -0,0 +1,21 @@
+1D 00 # String length 0x1b=29
+09 # Option flag, rich text + 16bit
+02 00 # Formatting runs
+# String: At a dinner party or
+41 00 74 00 20 00 61 00 20 00
+64 00 69 00 6E 00 6E 00 65 00
+72 00 20 00 70 00 61 00 72 00
+74 00 79 00 20 00 6F 00 72 00
+
+# Continuation record
+00 # option flag
+
+# string:at at at
+41 74 20
+41 74 20
+41 74 20
+
+00 00 # Formatting run 1, first formated char at 0
+00 00 # Formatting run 1, Index to font record
+02 00 # Formatting run 2, first formated char at 2
+00 00 # Formatting run 2, Index to font record
diff --git a/src/testcases/org/apache/poi/hssf/data/stringacross2continuations.txt b/src/testcases/org/apache/poi/hssf/data/stringacross2continuations.txt
new file mode 100644
index 0000000000..c9bc332e56
--- /dev/null
+++ b/src/testcases/org/apache/poi/hssf/data/stringacross2continuations.txt
@@ -0,0 +1,7 @@
+14 00 # String length 0x14=20
+01 # Option flag, 16bit
+# String: At a dinner party or
+41 00 74 00 20 00 61 00 20 00
+64 00 69 00 6E 00 6E 00 65 00
+72 00 20 00 70 00 61 00 72 00
+74 00 79 00 20 00 6F 00 72 00
diff --git a/src/testcases/org/apache/poi/hssf/data/stringacross2continuationsCR1.txt b/src/testcases/org/apache/poi/hssf/data/stringacross2continuationsCR1.txt
new file mode 100644
index 0000000000..821142adec
--- /dev/null
+++ b/src/testcases/org/apache/poi/hssf/data/stringacross2continuationsCR1.txt
@@ -0,0 +1,9 @@
+
+# Continuation record
+22 00 # String length 0x11=17
+00 # Option flag, 8bit
+# String: At a dinner party
+41 74 20 61 20
+64 69 6E 6E 65
+72 20 70 61 72
+74 79
diff --git a/src/testcases/org/apache/poi/hssf/data/stringacross2continuationsCR2.txt b/src/testcases/org/apache/poi/hssf/data/stringacross2continuationsCR2.txt
new file mode 100644
index 0000000000..f4eb4c3c3c
--- /dev/null
+++ b/src/testcases/org/apache/poi/hssf/data/stringacross2continuationsCR2.txt
@@ -0,0 +1,7 @@
+# Continuation record
+00 # option flag
+# String: At a dinner party
+41 74 20 61 20
+64 69 6E 6E 65
+72 20 70 61 72
+74 79
diff --git a/src/testcases/org/apache/poi/hssf/record/TestSSTRecord.java b/src/testcases/org/apache/poi/hssf/record/TestSSTRecord.java
index 56e6fec764..b574a34263 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestSSTRecord.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestSSTRecord.java
@@ -1,4 +1,3 @@
-
/* ====================================================================
* The Apache Software License, Version 1.1
*
@@ -55,24 +54,29 @@
package org.apache.poi.hssf.record;
-import org.apache.poi.util.*;
-
-import junit.framework.*;
+import junit.framework.TestCase;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.util.BinaryTree;
+import org.apache.poi.util.HexRead;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianConsts;
import java.io.*;
-
-import java.util.*;
+import java.util.Arrays;
+import java.util.Iterator;
/**
* @author Marc Johnson (mjohnson at apache dot org)
+ * @author Glen Stampoultzis (glens at apache.org)
*/
public class TestSSTRecord
- extends TestCase
+ extends TestCase
{
- private String _test_file_path;
+ private String _test_file_path;
private static final String _test_file_path_property =
- "HSSF.testdata.path";
+ "HSSF.testdata.path";
/**
* Creates new TestSSTRecord
@@ -80,10 +84,10 @@ public class TestSSTRecord
* @param name
*/
- public TestSSTRecord(String name)
+ public TestSSTRecord( String name )
{
- super(name);
- _test_file_path = System.getProperty(_test_file_path_property);
+ super( name );
+ _test_file_path = System.getProperty( _test_file_path_property );
}
/**
@@ -93,118 +97,119 @@ public class TestSSTRecord
*/
public void testProcessContinueRecord()
- throws IOException
+ throws IOException
{
- byte[] testdata = readTestData("BigSSTRecord");
- byte[] input = new byte[ testdata.length - 4 ];
-
- System.arraycopy(testdata, 4, input, 0, input.length);
- SSTRecord record =
- new SSTRecord(LittleEndian.getShort(testdata, 0),
- LittleEndian.getShort(testdata, 2), input);
- byte[] continueRecord = readTestData("BigSSTRecordCR");
-
- input = new byte[ continueRecord.length - 4 ];
- System.arraycopy(continueRecord, 4, input, 0, input.length);
- record.processContinueRecord(input);
- assertEquals(1464, record.getNumStrings());
- assertEquals(688, record.getNumUniqueStrings());
- assertEquals(688, record.countStrings());
+ byte[] testdata = HexRead.readTestData( _test_file_path + File.separator + "BigSSTRecord" );
+ byte[] input = new byte[testdata.length - 4];
+
+ System.arraycopy( testdata, 4, input, 0, input.length );
+ SSTRecord record =
+ new SSTRecord( LittleEndian.getShort( testdata, 0 ),
+ LittleEndian.getShort( testdata, 2 ), input );
+ byte[] continueRecord = HexRead.readTestData( _test_file_path + File.separator + "BigSSTRecordCR" );
+
+ input = new byte[continueRecord.length - 4];
+ System.arraycopy( continueRecord, 4, input, 0, input.length );
+ record.processContinueRecord( input );
+ assertEquals( 1464, record.getNumStrings() );
+ assertEquals( 688, record.getNumUniqueStrings() );
+ assertEquals( 688, record.countStrings() );
byte[] ser_output = record.serialize();
- int offset = 0;
- short type = LittleEndian.getShort(ser_output, offset);
+ int offset = 0;
+ short type = LittleEndian.getShort( ser_output, offset );
offset += LittleEndianConsts.SHORT_SIZE;
- short length = LittleEndian.getShort(ser_output, offset);
+ short length = LittleEndian.getShort( ser_output, offset );
offset += LittleEndianConsts.SHORT_SIZE;
- byte[] recordData = new byte[ length ];
+ byte[] recordData = new byte[length];
- System.arraycopy(ser_output, offset, recordData, 0, length);
+ System.arraycopy( ser_output, offset, recordData, 0, length );
offset += length;
- SSTRecord testRecord = new SSTRecord(type, length, recordData);
+ SSTRecord testRecord = new SSTRecord( type, length, recordData );
- assertEquals(ContinueRecord.sid,
- LittleEndian.getShort(ser_output, offset));
+ assertEquals( ContinueRecord.sid,
+ LittleEndian.getShort( ser_output, offset ) );
offset += LittleEndianConsts.SHORT_SIZE;
- length = LittleEndian.getShort(ser_output, offset);
+ length = LittleEndian.getShort( ser_output, offset );
offset += LittleEndianConsts.SHORT_SIZE;
- byte[] cr = new byte[ length ];
+ byte[] cr = new byte[length];
- System.arraycopy(ser_output, offset, cr, 0, length);
+ System.arraycopy( ser_output, offset, cr, 0, length );
offset += length;
- assertEquals(offset, ser_output.length);
- testRecord.processContinueRecord(cr);
- assertEquals(record, testRecord);
+ assertEquals( offset, ser_output.length );
+ testRecord.processContinueRecord( cr );
+ assertEquals( record, testRecord );
// testing based on new bug report
- testdata = readTestData("BigSSTRecord2");
- input = new byte[ testdata.length - 4 ];
- System.arraycopy(testdata, 4, input, 0, input.length);
- record = new SSTRecord(LittleEndian.getShort(testdata, 0),
- LittleEndian.getShort(testdata, 2), input);
- byte[] continueRecord1 = readTestData("BigSSTRecord2CR1");
-
- input = new byte[ continueRecord1.length - 4 ];
- System.arraycopy(continueRecord1, 4, input, 0, input.length);
- record.processContinueRecord(input);
- byte[] continueRecord2 = readTestData("BigSSTRecord2CR2");
-
- input = new byte[ continueRecord2.length - 4 ];
- System.arraycopy(continueRecord2, 4, input, 0, input.length);
- record.processContinueRecord(input);
- byte[] continueRecord3 = readTestData("BigSSTRecord2CR3");
-
- input = new byte[ continueRecord3.length - 4 ];
- System.arraycopy(continueRecord3, 4, input, 0, input.length);
- record.processContinueRecord(input);
- byte[] continueRecord4 = readTestData("BigSSTRecord2CR4");
-
- input = new byte[ continueRecord4.length - 4 ];
- System.arraycopy(continueRecord4, 4, input, 0, input.length);
- record.processContinueRecord(input);
- byte[] continueRecord5 = readTestData("BigSSTRecord2CR5");
-
- input = new byte[ continueRecord5.length - 4 ];
- System.arraycopy(continueRecord5, 4, input, 0, input.length);
- record.processContinueRecord(input);
- byte[] continueRecord6 = readTestData("BigSSTRecord2CR6");
-
- input = new byte[ continueRecord6.length - 4 ];
- System.arraycopy(continueRecord6, 4, input, 0, input.length);
- record.processContinueRecord(input);
- byte[] continueRecord7 = readTestData("BigSSTRecord2CR7");
-
- input = new byte[ continueRecord7.length - 4 ];
- System.arraycopy(continueRecord7, 4, input, 0, input.length);
- record.processContinueRecord(input);
- assertEquals(158642, record.getNumStrings());
- assertEquals(5249, record.getNumUniqueStrings());
- assertEquals(5249, record.countStrings());
+ testdata = HexRead.readTestData( _test_file_path + File.separator + "BigSSTRecord2" );
+ input = new byte[testdata.length - 4];
+ System.arraycopy( testdata, 4, input, 0, input.length );
+ record = new SSTRecord( LittleEndian.getShort( testdata, 0 ),
+ LittleEndian.getShort( testdata, 2 ), input );
+ byte[] continueRecord1 = HexRead.readTestData( _test_file_path + File.separator + "BigSSTRecord2CR1" );
+
+ input = new byte[continueRecord1.length - 4];
+ System.arraycopy( continueRecord1, 4, input, 0, input.length );
+ record.processContinueRecord( input );
+ byte[] continueRecord2 = HexRead.readTestData( _test_file_path + File.separator + "BigSSTRecord2CR2" );
+
+ input = new byte[continueRecord2.length - 4];
+ System.arraycopy( continueRecord2, 4, input, 0, input.length );
+ record.processContinueRecord( input );
+ byte[] continueRecord3 = HexRead.readTestData( _test_file_path + File.separator + "BigSSTRecord2CR3" );
+
+ input = new byte[continueRecord3.length - 4];
+ System.arraycopy( continueRecord3, 4, input, 0, input.length );
+ record.processContinueRecord( input );
+ byte[] continueRecord4 = HexRead.readTestData( _test_file_path + File.separator + "BigSSTRecord2CR4" );
+
+ input = new byte[continueRecord4.length - 4];
+ System.arraycopy( continueRecord4, 4, input, 0, input.length );
+ record.processContinueRecord( input );
+ byte[] continueRecord5 = HexRead.readTestData( _test_file_path + File.separator + "BigSSTRecord2CR5" );
+
+ input = new byte[continueRecord5.length - 4];
+ System.arraycopy( continueRecord5, 4, input, 0, input.length );
+ record.processContinueRecord( input );
+ byte[] continueRecord6 = HexRead.readTestData( _test_file_path + File.separator + "BigSSTRecord2CR6" );
+
+ input = new byte[continueRecord6.length - 4];
+ System.arraycopy( continueRecord6, 4, input, 0, input.length );
+ record.processContinueRecord( input );
+ byte[] continueRecord7 = HexRead.readTestData( _test_file_path + File.separator + "BigSSTRecord2CR7" );
+
+ input = new byte[continueRecord7.length - 4];
+ System.arraycopy( continueRecord7, 4, input, 0, input.length );
+ record.processContinueRecord( input );
+ assertEquals( 158642, record.getNumStrings() );
+ assertEquals( 5249, record.getNumUniqueStrings() );
+ assertEquals( 5249, record.countStrings() );
ser_output = record.serialize();
- offset = 0;
- type = LittleEndian.getShort(ser_output, offset);
- offset += LittleEndianConsts.SHORT_SIZE;
- length = LittleEndian.getShort(ser_output, offset);
- offset += LittleEndianConsts.SHORT_SIZE;
- recordData = new byte[ length ];
- System.arraycopy(ser_output, offset, recordData, 0, length);
- offset += length;
- testRecord = new SSTRecord(type, length, recordData);
- for (int count = 0; count < 7; count++)
+ offset = 0;
+ type = LittleEndian.getShort( ser_output, offset );
+ offset += LittleEndianConsts.SHORT_SIZE;
+ length = LittleEndian.getShort( ser_output, offset );
+ offset += LittleEndianConsts.SHORT_SIZE;
+ recordData = new byte[length];
+ System.arraycopy( ser_output, offset, recordData, 0, length );
+ offset += length;
+ testRecord = new SSTRecord( type, length, recordData );
+ for ( int count = 0; count < 7; count++ )
{
- assertEquals(ContinueRecord.sid,
- LittleEndian.getShort(ser_output, offset));
+ assertEquals( ContinueRecord.sid,
+ LittleEndian.getShort( ser_output, offset ) );
offset += LittleEndianConsts.SHORT_SIZE;
- length = LittleEndian.getShort(ser_output, offset);
+ length = LittleEndian.getShort( ser_output, offset );
offset += LittleEndianConsts.SHORT_SIZE;
- cr = new byte[ length ];
- System.arraycopy(ser_output, offset, cr, 0, length);
- testRecord.processContinueRecord(cr);
+ cr = new byte[length];
+ System.arraycopy( ser_output, offset, cr, 0, length );
+ testRecord.processContinueRecord( cr );
offset += length;
}
- assertEquals(offset, ser_output.length);
- assertEquals(record, testRecord);
+ assertEquals( offset, ser_output.length );
+ assertEquals( record, testRecord );
+ assertEquals( record.countStrings(), testRecord.countStrings() );
}
/**
@@ -214,23 +219,23 @@ public class TestSSTRecord
*/
public void testHugeStrings()
- throws IOException
+ throws IOException
{
- SSTRecord record = new SSTRecord();
- byte[][] bstrings =
- {
- new byte[ 9000 ], new byte[ 7433 ], new byte[ 9002 ],
- new byte[ 16998 ]
- };
- String[] strings = new String[ bstrings.length ];
- int total_length = 0;
-
- for (int k = 0; k < bstrings.length; k++)
+ SSTRecord record = new SSTRecord();
+ byte[][] bstrings =
+ {
+ new byte[9000], new byte[7433], new byte[9002],
+ new byte[16998]
+ };
+ String[] strings = new String[bstrings.length];
+ int total_length = 0;
+
+ for ( int k = 0; k < bstrings.length; k++ )
{
- Arrays.fill(bstrings[ k ], ( byte ) ('a' + k));
- strings[ k ] = new String(bstrings[ k ]);
- record.addString(strings[ k ]);
- total_length += 3 + bstrings[ k ].length;
+ Arrays.fill( bstrings[k], (byte) ( 'a' + k ) );
+ strings[k] = new String( bstrings[k] );
+ record.addString( strings[k] );
+ total_length += 3 + bstrings[k].length;
}
// add overhead of SST record
@@ -240,88 +245,88 @@ public class TestSSTRecord
total_length += 4;
// add overhead of six records
- total_length += (6 * 4);
- byte[] content = new byte[ record.getRecordSize() ];
+ total_length += ( 6 * 4 );
+ byte[] content = new byte[record.getRecordSize()];
- record.serialize(0, content);
- assertEquals(total_length, content.length);
- for (int index = 0; index != content.length; )
+ record.serialize( 0, content );
+ assertEquals( total_length, content.length );
+ for ( int index = 0; index != content.length; )
{
- short record_type = LittleEndian.getShort(content, index);
+ short record_type = LittleEndian.getShort( content, index );
index += LittleEndianConsts.SHORT_SIZE;
- short record_length = LittleEndian.getShort(content, index);
+ short record_length = LittleEndian.getShort( content, index );
index += LittleEndianConsts.SHORT_SIZE;
- byte[] data = new byte[ record_length ];
+ byte[] data = new byte[record_length];
- System.arraycopy(content, index, data, 0, record_length);
+ System.arraycopy( content, index, data, 0, record_length );
index += record_length;
- if (record_type == SSTRecord.sid)
+ if ( record_type == SSTRecord.sid )
{
- record = new SSTRecord(record_type, record_length, data);
+ record = new SSTRecord( record_type, record_length, data );
}
else
{
- record.processContinueRecord(data);
+ record.processContinueRecord( data );
}
}
- assertEquals(strings.length, record.getNumStrings());
- assertEquals(strings.length, record.getNumUniqueStrings());
- assertEquals(strings.length, record.countStrings());
- for (int k = 0; k < strings.length; k++)
+ assertEquals( strings.length, record.getNumStrings() );
+ assertEquals( strings.length, record.getNumUniqueStrings() );
+ assertEquals( strings.length, record.countStrings() );
+ for ( int k = 0; k < strings.length; k++ )
{
- assertEquals(strings[ k ], record.getString(k));
+ assertEquals( strings[k], record.getString( k ) );
}
- record = new SSTRecord();
- bstrings[ 1 ] = new byte[ bstrings[ 1 ].length - 1 ];
- for (int k = 0; k < bstrings.length; k++)
+ record = new SSTRecord();
+ bstrings[1] = new byte[bstrings[1].length - 1];
+ for ( int k = 0; k < bstrings.length; k++ )
{
- if ((bstrings[ k ].length % 2) == 1)
+ if ( ( bstrings[k].length % 2 ) == 1 )
{
- Arrays.fill(bstrings[ k ], ( byte ) ('a' + k));
- strings[ k ] = new String(bstrings[ k ]);
+ Arrays.fill( bstrings[k], (byte) ( 'a' + k ) );
+ strings[k] = new String( bstrings[k] );
}
else
{
- char[] data = new char[ bstrings[ k ].length / 2 ];
+ char[] data = new char[bstrings[k].length / 2];
- Arrays.fill(data, ( char ) ('\u2122' + k));
- strings[ k ] = new String(data);
+ Arrays.fill( data, (char) ( '\u2122' + k ) );
+ strings[k] = new String( data );
}
- record.addString(strings[ k ]);
+ record.addString( strings[k] );
}
- content = new byte[ record.getRecordSize() ];
- record.serialize(0, content);
+ content = new byte[record.getRecordSize()];
+ record.serialize( 0, content );
total_length--;
- assertEquals(total_length, content.length);
- for (int index = 0; index != content.length; )
+ assertEquals( total_length, content.length );
+ for ( int index = 0; index != content.length; )
{
- short record_type = LittleEndian.getShort(content, index);
+ short record_type = LittleEndian.getShort( content, index );
index += LittleEndianConsts.SHORT_SIZE;
- short record_length = LittleEndian.getShort(content, index);
+ short record_length = LittleEndian.getShort( content, index );
index += LittleEndianConsts.SHORT_SIZE;
- byte[] data = new byte[ record_length ];
+ byte[] data = new byte[record_length];
- System.arraycopy(content, index, data, 0, record_length);
+ System.arraycopy( content, index, data, 0, record_length );
index += record_length;
- if (record_type == SSTRecord.sid)
+ if ( record_type == SSTRecord.sid )
{
- record = new SSTRecord(record_type, record_length, data);
+ record = new SSTRecord( record_type, record_length, data );
}
else
{
- record.processContinueRecord(data);
+ record.processContinueRecord( data );
}
}
- assertEquals(strings.length, record.getNumStrings());
- assertEquals(strings.length, record.getNumUniqueStrings());
- assertEquals(strings.length, record.countStrings());
- for (int k = 0; k < strings.length; k++)
+ assertEquals( strings.length, record.getNumStrings() );
+ assertEquals( strings.length, record.getNumUniqueStrings() );
+ assertEquals( strings.length, record.countStrings() );
+ for ( int k = 0; k < strings.length; k++ )
{
- assertEquals(strings[ k ], record.getString(k));
+ assertEquals( strings[k], record.getString( k ) );
}
}
@@ -330,9 +335,8 @@ public class TestSSTRecord
*
* @exception IOException
*/
-
public void testSSTRecordBug()
- throws IOException
+ throws IOException
{
// create an SSTRecord and write a certain pattern of strings
@@ -342,68 +346,67 @@ public class TestSSTRecord
// the record will start with two integers, then this string
// ... that will eat up 16 of the 8224 bytes that the record
// can hold
- record.addString("Hello");
+ record.addString( "Hello" );
// now we have an additional 8208 bytes, which is an exact
// multiple of 16 bytes
long testvalue = 1000000000000L;
- for (int k = 0; k < 2000; k++)
+ for ( int k = 0; k < 2000; k++ )
{
- record.addString(String.valueOf(testvalue++));
+ record.addString( String.valueOf( testvalue++ ) );
}
- byte[] content = new byte[ record.getRecordSize() ];
+ byte[] content = new byte[record.getRecordSize()];
- record.serialize(0, content);
- assertEquals(( byte ) 13, content[ 4 + 8228 ]);
- assertEquals(( byte ) 13, content[ 4 + 8228 * 2 ]);
- assertEquals(( byte ) 13, content[ 4 + 8228 * 3 ]);
+ record.serialize( 0, content );
+ assertEquals( (byte) 13, content[4 + 8228] );
+ assertEquals( (byte) 13, content[4 + 8228 * 2] );
+ assertEquals( (byte) 13, content[4 + 8228 * 3] );
}
/**
* test simple addString
*/
-
public void testSimpleAddString()
{
SSTRecord record = new SSTRecord();
- String s1 = "Hello world";
+ String s1 = "Hello world";
// \u2122 is the encoding of the trademark symbol ...
- String s2 = "Hello world\u2122";
-
- assertEquals(0, record.addString(s1));
- assertEquals(s1, record.getString(0));
- assertEquals(1, record.countStrings());
- assertEquals(1, record.getNumStrings());
- assertEquals(1, record.getNumUniqueStrings());
- assertEquals(0, record.addString(s1));
- assertEquals(s1, record.getString(0));
- assertEquals(1, record.countStrings());
- assertEquals(2, record.getNumStrings());
- assertEquals(1, record.getNumUniqueStrings());
- assertEquals(1, record.addString(s2));
- assertEquals(s2, record.getString(1));
- assertEquals(2, record.countStrings());
- assertEquals(3, record.getNumStrings());
- assertEquals(2, record.getNumUniqueStrings());
+ String s2 = "Hello world\u2122";
+
+ assertEquals( 0, record.addString( s1 ) );
+ assertEquals( s1, record.getString( 0 ) );
+ assertEquals( 1, record.countStrings() );
+ assertEquals( 1, record.getNumStrings() );
+ assertEquals( 1, record.getNumUniqueStrings() );
+ assertEquals( 0, record.addString( s1 ) );
+ assertEquals( s1, record.getString( 0 ) );
+ assertEquals( 1, record.countStrings() );
+ assertEquals( 2, record.getNumStrings() );
+ assertEquals( 1, record.getNumUniqueStrings() );
+ assertEquals( 1, record.addString( s2 ) );
+ assertEquals( s2, record.getString( 1 ) );
+ assertEquals( 2, record.countStrings() );
+ assertEquals( 3, record.getNumStrings() );
+ assertEquals( 2, record.getNumUniqueStrings() );
Iterator iter = record.getStrings();
- while (iter.hasNext())
+ while ( iter.hasNext() )
{
- UnicodeString ucs = ( UnicodeString ) iter.next();
+ UnicodeString ucs = (UnicodeString) iter.next();
- if (ucs.getString().equals(s1))
+ if ( ucs.getString().equals( s1 ) )
{
- assertEquals(( byte ) 0, ucs.getOptionFlags());
+ assertEquals( (byte) 0, ucs.getOptionFlags() );
}
- else if (ucs.getString().equals(s2))
+ else if ( ucs.getString().equals( s2 ) )
{
- assertEquals(( byte ) 1, ucs.getOptionFlags());
+ assertEquals( (byte) 1, ucs.getOptionFlags() );
}
else
{
- fail("cannot match string: " + ucs.getString());
+ fail( "cannot match string: " + ucs.getString() );
}
}
}
@@ -415,25 +418,25 @@ public class TestSSTRecord
*/
public void testReaderConstructor()
- throws IOException
+ throws IOException
{
- byte[] testdata = readTestData("BigSSTRecord");
- byte[] input = new byte[ testdata.length - 4 ];
-
- System.arraycopy(testdata, 4, input, 0, input.length);
- SSTRecord record = new SSTRecord(LittleEndian.getShort(testdata, 0),
- LittleEndian.getShort(testdata, 2),
- input);
-
- assertEquals(1464, record.getNumStrings());
- assertEquals(688, record.getNumUniqueStrings());
- assertEquals(492, record.countStrings());
- assertEquals(1, record.getExpectedChars());
- assertEquals("Consolidated B-24J Liberator The Dragon & His Tai",
- record.getUnfinishedString());
- assertEquals(52, record.getTotalLength());
- assertEquals(3, record.getStringDataOffset());
- assertTrue(!record.isWideChar());
+ byte[] testdata = HexRead.readTestData( _test_file_path + File.separator + "BigSSTRecord" );
+ byte[] input = new byte[testdata.length - 4];
+
+ System.arraycopy( testdata, 4, input, 0, input.length );
+ SSTRecord record = new SSTRecord( LittleEndian.getShort( testdata, 0 ),
+ LittleEndian.getShort( testdata, 2 ),
+ input );
+
+ assertEquals( 1464, record.getNumStrings() );
+ assertEquals( 688, record.getNumUniqueStrings() );
+ assertEquals( 492, record.countStrings() );
+ assertEquals( 1, record.getDeserializer().getContinuationExpectedChars() );
+ assertEquals( "Consolidated B-24J Liberator The Dragon & His Tai",
+ record.getDeserializer().getUnfinishedString() );
+// assertEquals( 52, record.getDeserializer().getTotalLength() );
+// assertEquals( 3, record.getDeserializer().getStringDataOffset() );
+ assertTrue( !record.getDeserializer().isWideChar() );
}
/**
@@ -444,26 +447,26 @@ public class TestSSTRecord
{
SSTRecord record = new SSTRecord();
- assertEquals(0, record.getNumStrings());
- assertEquals(0, record.getNumUniqueStrings());
- assertEquals(0, record.countStrings());
- assertEquals(0, record.getExpectedChars());
- assertEquals("", record.getUnfinishedString());
- assertEquals(0, record.getTotalLength());
- assertEquals(0, record.getStringDataOffset());
- assertTrue(!record.isWideChar());
- byte[] output = record.serialize();
+ assertEquals( 0, record.getNumStrings() );
+ assertEquals( 0, record.getNumUniqueStrings() );
+ assertEquals( 0, record.countStrings() );
+ assertEquals( 0, record.getDeserializer().getContinuationExpectedChars() );
+ assertEquals( "", record.getDeserializer().getUnfinishedString() );
+// assertEquals( 0, record.getDeserializer().getTotalLength() );
+// assertEquals( 0, record.getDeserializer().getStringDataOffset() );
+ assertTrue( !record.getDeserializer().isWideChar() );
+ byte[] output = record.serialize();
byte[] expected =
+ {
+ (byte) record.getSid(), (byte) ( record.getSid() >> 8 ),
+ (byte) 8, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+ (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0
+ };
+
+ assertEquals( expected.length, output.length );
+ for ( int k = 0; k < expected.length; k++ )
{
- ( byte ) record.getSid(), ( byte ) (record.getSid() >> 8),
- ( byte ) 8, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
- ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0
- };
-
- assertEquals(expected.length, output.length);
- for (int k = 0; k < expected.length; k++)
- {
- assertEquals(String.valueOf(k), expected[ k ], output[ k ]);
+ assertEquals( String.valueOf( k ), expected[k], output[k] );
}
}
@@ -473,102 +476,99 @@ public class TestSSTRecord
* @param ignored_args
*/
- public static void main(String [] ignored_args)
+ public static void main( String[] ignored_args )
{
- System.out.println("Testing hssf.record.SSTRecord functionality");
- junit.textui.TestRunner.run(TestSSTRecord.class);
+ System.out.println( "Testing hssf.record.SSTRecord functionality" );
+ junit.textui.TestRunner.run( TestSSTRecord.class );
}
- private byte [] readTestData(String filename)
- throws IOException
+ /**
+ * Tests that workbooks with rich text that duplicates a non rich text cell can be read and written.
+ */
+ public void testReadWriteDuplicatedRichText1()
+ throws Exception
{
- File file = new File(_test_file_path
- + File.separator
- + filename);
- FileInputStream stream = new FileInputStream(file);
- int characterCount = 0;
- byte b = ( byte ) 0;
- List bytes = new ArrayList();
- boolean done = false;
-
- while (!done)
- {
- int count = stream.read();
+ File file = new File( _test_file_path + File.separator + "duprich1.xls" );
+ InputStream stream = new FileInputStream( file );
+ HSSFWorkbook wb = new HSSFWorkbook( stream );
+ stream.close();
+ HSSFSheet sheet = wb.getSheetAt( 1 );
+ assertEquals( "01/05 (Wed) ", sheet.getRow( 0 ).getCell( (short) 8 ).getStringCellValue() );
+ assertEquals( "01/05 (Wed)", sheet.getRow( 1 ).getCell( (short) 8 ).getStringCellValue() );
+
+ file = File.createTempFile( "testout", "xls" );
+ FileOutputStream outStream = new FileOutputStream( file );
+ wb.write( outStream );
+ outStream.close();
+ file.delete();
+
+ // test the second file.
+ file = new File( _test_file_path + File.separator + "duprich2.xls" );
+ stream = new FileInputStream( file );
+ wb = new HSSFWorkbook( stream );
+ stream.close();
+ sheet = wb.getSheetAt( 0 );
+ int row = 0;
+ assertEquals( "Testing ", sheet.getRow( row++ ).getCell( (short) 0 ).getStringCellValue() );
+ assertEquals( "rich", sheet.getRow( row++ ).getCell( (short) 0 ).getStringCellValue() );
+ assertEquals( "text", sheet.getRow( row++ ).getCell( (short) 0 ).getStringCellValue() );
+ assertEquals( "strings", sheet.getRow( row++ ).getCell( (short) 0 ).getStringCellValue() );
+ assertEquals( "Testing ", sheet.getRow( row++ ).getCell( (short) 0 ).getStringCellValue() );
+ assertEquals( "Testing", sheet.getRow( row++ ).getCell( (short) 0 ).getStringCellValue() );
+
+// file = new File("/tryme.xls");
+ file = File.createTempFile( "testout", ".xls" );
+ outStream = new FileOutputStream( file );
+ wb.write( outStream );
+ outStream.close();
+ file.delete();
+ }
- switch (count)
- {
+ public void testSpanRichTextToPlainText()
+ throws Exception
+ {
+ byte[] bytes = HexRead.readTestData( _test_file_path + File.separator + "richtextdata.txt" );
+ BinaryTree strings = new BinaryTree();
+ SSTDeserializer deserializer = new SSTDeserializer( strings );
+ deserializer.manufactureStrings( bytes, 0, (short) 45 );
+ byte[] continueBytes = new byte[bytes.length - 45];
+ System.arraycopy( bytes, 45, continueBytes, 0, bytes.length - 45 );
+ deserializer.processContinueRecord( continueBytes );
+// System.out.println( "strings.getKeyForValue(new Integer(0)) = " + strings.get( new Integer( 0 ) ) );
+
+ assertEquals( "At a dinner party orAt At At ", strings.get( new Integer( 0 ) ) + "" );
+ }
- case '0' :
- case '1' :
- case '2' :
- case '3' :
- case '4' :
- case '5' :
- case '6' :
- case '7' :
- case '8' :
- case '9' :
- b <<= 4;
- b += ( byte ) (count - '0');
- characterCount++;
- if (characterCount == 2)
- {
- bytes.add(new Byte(b));
- characterCount = 0;
- b = ( byte ) 0;
- }
- break;
-
- case 'A' :
- case 'B' :
- case 'C' :
- case 'D' :
- case 'E' :
- case 'F' :
- b <<= 4;
- b += ( byte ) (count + 10 - 'A');
- characterCount++;
- if (characterCount == 2)
- {
- bytes.add(new Byte(b));
- characterCount = 0;
- b = ( byte ) 0;
- }
- break;
-
- case 'a' :
- case 'b' :
- case 'c' :
- case 'd' :
- case 'e' :
- case 'f' :
- b <<= 4;
- b += ( byte ) (count + 10 - 'a');
- characterCount++;
- if (characterCount == 2)
- {
- bytes.add(new Byte(b));
- characterCount = 0;
- b = ( byte ) 0;
- }
- break;
-
- case -1 :
- done = true;
- break;
-
- default :
- break;
- }
- }
- stream.close();
- Byte[] polished = ( Byte [] ) bytes.toArray(new Byte[ 0 ]);
- byte[] rval = new byte[ polished.length ];
+ public void testContinuationWithNoOverlap()
+ throws Exception
+ {
+ byte[] bytes = HexRead.readTestData( _test_file_path + File.separator + "evencontinuation.txt" );
+ BinaryTree strings = new BinaryTree();
+ SSTDeserializer deserializer = new SSTDeserializer( strings );
+ deserializer.manufactureStrings( bytes, 0, (short) 43 );
+ byte[] continueBytes = new byte[bytes.length - 43];
+ System.arraycopy( bytes, 43, continueBytes, 0, bytes.length - 43 );
+ deserializer.processContinueRecord( continueBytes );
+
+ assertEquals( "At a dinner party or", strings.get( new Integer( 0 ) ) + "" );
+ assertEquals( "At a dinner party", strings.get( new Integer( 1 ) ) + "" );
+
+ }
+
+ public void testStringAcross2Continuations()
+ throws Exception
+ {
+ byte[] bytes = HexRead.readTestData( _test_file_path + File.separator + "stringacross2continuations.txt" );
+ BinaryTree strings = new BinaryTree();
+ SSTDeserializer deserializer = new SSTDeserializer( strings );
+ deserializer.manufactureStrings( bytes, 0, (short) 43 );
+ bytes = HexRead.readTestData( _test_file_path + File.separator + "stringacross2continuationsCR1.txt" );
+ deserializer.processContinueRecord( bytes );
+ bytes = HexRead.readTestData( _test_file_path + File.separator + "stringacross2continuationsCR2.txt" );
+ deserializer.processContinueRecord( bytes );
+
+ assertEquals( "At a dinner party or", strings.get( new Integer( 0 ) ) + "" );
+ assertEquals( "At a dinner partyAt a dinner party", strings.get( new Integer( 1 ) ) + "" );
- for (int j = 0; j < polished.length; j++)
- {
- rval[ j ] = polished[ j ].byteValue();
- }
- return rval;
}
}
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFRow.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFRow.java
index f8c584839a..3c7fb51636 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFRow.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFRow.java
@@ -55,7 +55,10 @@
package org.apache.poi.hssf.usermodel;
import junit.framework.TestCase;
-import org.apache.poi.hssf.record.RowRecord;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
/**
* Test HSSFRow is okay.
@@ -87,33 +90,47 @@ public class TestHSSFRow
assertEquals(1, row.getFirstCellNum());
assertEquals(2, row.getLastCellNum());
- RowRecord rowRecord = new RowRecord();
- rowRecord.setFirstCol((short) 2);
- rowRecord.setLastCol((short) 5);
- row = new HSSFRow(workbook.getWorkbook(), sheet.getSheet(), rowRecord);
- assertEquals(2, row.getFirstCellNum());
- assertEquals(5, row.getLastCellNum());
}
public void testRemoveCell()
+ throws Exception
{
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet();
HSSFRow row = sheet.createRow((short) 0);
assertEquals(-1, row.getLastCellNum());
assertEquals(-1, row.getFirstCellNum());
- row.createCell((short)1);
+ row.createCell((short) 1);
assertEquals(1, row.getLastCellNum());
assertEquals(1, row.getFirstCellNum());
- row.createCell((short)3);
+ row.createCell((short) 3);
assertEquals(3, row.getLastCellNum());
assertEquals(1, row.getFirstCellNum());
- row.removeCell(row.getCell((short)3));
+ row.removeCell(row.getCell((short) 3));
assertEquals(1, row.getLastCellNum());
assertEquals(1, row.getFirstCellNum());
- row.removeCell(row.getCell((short)1));
+ row.removeCell(row.getCell((short) 1));
assertEquals(-1, row.getLastCellNum());
assertEquals(-1, row.getFirstCellNum());
+ // check the row record actually writes it out as 0's
+ byte[] data = new byte[100];
+ row.getRowRecord().serialize(0, data);
+ assertEquals(0, data[6]);
+ assertEquals(0, data[8]);
+
+ File file = File.createTempFile("XXX", "XLS");
+ FileOutputStream stream = new FileOutputStream(file);
+ workbook.write(stream);
+ stream.close();
+ FileInputStream inputStream = new FileInputStream(file);
+ workbook = new HSSFWorkbook(inputStream);
+ sheet = workbook.getSheetAt(0);
+ stream.close();
+ file.delete();
+ assertEquals(-1, sheet.getRow((short) 0).getLastCellNum());
+ assertEquals(-1, sheet.getRow((short) 0).getFirstCellNum());
+
+
}
}
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java
index 4868aee042..ddaedd922e 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java
@@ -58,7 +58,6 @@ import junit.framework.TestCase;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.record.VCenterRecord;
import org.apache.poi.hssf.record.WSBoolRecord;
-import org.apache.poi.hssf.dev.BiffViewer;
import java.io.File;
import java.io.FileInputStream;
@@ -190,7 +189,14 @@ public class TestHSSFSheet
tempFile.delete();
assertNotNull(row);
assertEquals(2, row.getPhysicalNumberOfCells());
+ }
-
+ public void testRemoveRow()
+ {
+ HSSFWorkbook workbook = new HSSFWorkbook();
+ HSSFSheet sheet = workbook.createSheet("Test boolean");
+ HSSFRow row = sheet.createRow((short) 2);
+ sheet.removeRow(row);
}
+
}
diff --git a/src/testcases/org/apache/poi/util/TestLittleEndian.java b/src/testcases/org/apache/poi/util/TestLittleEndian.java
index 1f2780d897..f9f2df2382 100644
--- a/src/testcases/org/apache/poi/util/TestLittleEndian.java
+++ b/src/testcases/org/apache/poi/util/TestLittleEndian.java
@@ -437,6 +437,12 @@ public class TestLittleEndian
return result;
}
+ public void testUnsignedShort()
+ throws Exception
+ {
+ assertEquals(0xffff, LittleEndian.getUShort(new byte[] { (byte)0xff, (byte)0xff }, 0));
+ }
+
/**
* main method to run the unit tests
*
diff --git a/src/testcases/org/apache/poi/util/TestPOILogFactory.java b/src/testcases/org/apache/poi/util/TestPOILogFactory.java
index 82aef5d5c1..2e27e6a9ba 100644
--- a/src/testcases/org/apache/poi/util/TestPOILogFactory.java
+++ b/src/testcases/org/apache/poi/util/TestPOILogFactory.java
@@ -1,4 +1,3 @@
-
/* ====================================================================
* The Apache Software License, Version 1.1
*
@@ -55,11 +54,9 @@
package org.apache.poi.util;
-import org.apache.log4j.Category;
-
-import junit.framework.*;
+import junit.framework.TestCase;
-import java.io.*;
+import java.io.IOException;
/**
* @author Marc Johnson (mjohnson at apache dot org)
@@ -68,7 +65,7 @@ import java.io.*;
*/
public class TestPOILogFactory
- extends TestCase
+ extends TestCase
{
/**
* Creates new TestPOILogFactory
@@ -76,9 +73,9 @@ public class TestPOILogFactory
* @param name
*/
- public TestPOILogFactory(String name)
+ public TestPOILogFactory( String name )
{
- super(name);
+ super( name );
}
/**
@@ -88,26 +85,26 @@ public class TestPOILogFactory
*/
public void testLog()
- throws IOException
+ throws IOException
{
//NKB Testing only that logging classes use gives no exception
// Since logging can be disabled, no checking of logging
// output is done.
-
- POILogger l1 = POILogFactory.getLogger("org.apache.poi.hssf.test");
- POILogger l2 = POILogFactory.getLogger("org.apache.poi.hdf.test");
- l1.log(POILogger.FATAL, "testing cat org.apache.poi.hssf.*:FATAL");
- l1.log(POILogger.ERROR, "testing cat org.apache.poi.hssf.*:ERROR");
- l1.log(POILogger.WARN, "testing cat org.apache.poi.hssf.*:WARN");
- l1.log(POILogger.INFO, "testing cat org.apache.poi.hssf.*:INFO");
- l1.log(POILogger.DEBUG, "testing cat org.apache.poi.hssf.*:DEBUG");
+ POILogger l1 = POILogFactory.getLogger( "org.apache.poi.hssf.test" );
+ POILogger l2 = POILogFactory.getLogger( "org.apache.poi.hdf.test" );
+
+ l1.log( POILogger.FATAL, "testing cat org.apache.poi.hssf.*:FATAL" );
+ l1.log( POILogger.ERROR, "testing cat org.apache.poi.hssf.*:ERROR" );
+ l1.log( POILogger.WARN, "testing cat org.apache.poi.hssf.*:WARN" );
+ l1.log( POILogger.INFO, "testing cat org.apache.poi.hssf.*:INFO" );
+ l1.log( POILogger.DEBUG, "testing cat org.apache.poi.hssf.*:DEBUG" );
- l2.log(POILogger.FATAL, "testing cat org.apache.poi.hdf.*:FATAL");
- l2.log(POILogger.ERROR, "testing cat org.apache.poi.hdf.*:ERROR");
- l2.log(POILogger.WARN, "testing cat org.apache.poi.hdf.*:WARN");
- l2.log(POILogger.INFO, "testing cat org.apache.poi.hdf.*:INFO");
- l2.log(POILogger.DEBUG, "testing cat org.apache.poi.hdf.*:DEBUG");
+ l2.log( POILogger.FATAL, "testing cat org.apache.poi.hdf.*:FATAL" );
+ l2.log( POILogger.ERROR, "testing cat org.apache.poi.hdf.*:ERROR" );
+ l2.log( POILogger.WARN, "testing cat org.apache.poi.hdf.*:WARN" );
+ l2.log( POILogger.INFO, "testing cat org.apache.poi.hdf.*:INFO" );
+ l2.log( POILogger.DEBUG, "testing cat org.apache.poi.hdf.*:DEBUG" );
}
@@ -117,9 +114,9 @@ public class TestPOILogFactory
* @param ignored_args
*/
- public static void main(String [] ignored_args)
+ public static void main( String[] ignored_args )
{
- System.out.println("Testing basic util.POILogFactory functionality");
- junit.textui.TestRunner.run(TestPOILogFactory.class);
+ System.out.println( "Testing basic util.POILogFactory functionality" );
+ junit.textui.TestRunner.run( TestPOILogFactory.class );
}
}
diff --git a/src/testcases/org/apache/poi/util/TestPOILogger.java b/src/testcases/org/apache/poi/util/TestPOILogger.java
index 62b47a24a4..46248b5e21 100644
--- a/src/testcases/org/apache/poi/util/TestPOILogger.java
+++ b/src/testcases/org/apache/poi/util/TestPOILogger.java
@@ -1,4 +1,3 @@
-
/* ====================================================================
* The Apache Software License, Version 1.1
*
@@ -57,19 +56,16 @@ package org.apache.poi.util;
import junit.framework.TestCase;
-import java.io.File;
-import java.io.FileInputStream;
-
/**
* Tests the log class.
*
* @author Glen Stampoultzis (glens at apache.org)
* @author Marc Johnson (mjohnson at apache dot org)
- * @author Nicola Ken Barozzi (nicolaken at apache.org)
+ * @author Nicola Ken Barozzi (nicolaken at apache.org)
*/
public class TestPOILogger
- extends TestCase
+ extends TestCase
{
/**
* Constructor TestPOILogger
@@ -79,23 +75,9 @@ public class TestPOILogger
*
*/
- public TestPOILogger(String s)
- {
- super(s);
- }
-
- /**
- * Method setUp
- *
- *
- * @exception Exception
- *
- */
-
- protected void setUp()
- throws Exception
+ public TestPOILogger( String s )
{
- super.setUp();
+ super( s );
}
/**
@@ -103,29 +85,20 @@ public class TestPOILogger
*
* @exception Exception
*/
-
public void testVariousLogTypes()
- throws Exception
+ throws Exception
{
//NKB Testing only that logging classes use gives no exception
// Since logging can be disabled, no checking of logging
// output is done.
-
- POILogger log = POILogFactory.getLogger("foo");
- log.log(POILogger.WARN, "Test = ", new Integer(1));
- log.logFormatted(POILogger.ERROR, "Test param 1 = %, param 2 = %",
- "2", new Integer(3));
- log.logFormatted(POILogger.ERROR, "Test param 1 = %, param 2 = %",
- new int[]
- {
- 4, 5
- });
- log.logFormatted(POILogger.ERROR,
- "Test param 1 = %1.1, param 2 = %0.1", new double[]
- {
- 4, 5.23
- });
+ POILogger log = POILogFactory.getLogger( "foo" );
+
+ log.log( POILogger.WARN, "Test = ", new Integer( 1 ) );
+ log.logFormatted( POILogger.ERROR, "Test param 1 = %, param 2 = %", "2", new Integer( 3 ) );
+ log.logFormatted( POILogger.ERROR, "Test param 1 = %, param 2 = %", new int[]{4, 5} );
+ log.logFormatted( POILogger.ERROR,
+ "Test param 1 = %1.1, param 2 = %0.1", new double[]{4, 5.23} );
}
}