From d7672fa259af6af97db24f89b3cd68309b94106d Mon Sep 17 00:00:00 2001 From: Glen Stampoultzis Date: Sun, 9 Jun 2002 12:33:26 +0000 Subject: [PATCH] SST fixed!!! Yay... Will reliably read in spreadsheets that have rich text or extended text. Code is a bit cleaner now but could still use more improvement. If I have the energy I'll look into it. git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/branches/REL_1_5_BRANCH@352663 13f79535-47bb-0310-9956-ffa450edef68 --- module.xml | 4 +- .../poi/hssf/record/SSTDeserializer.java | 572 ++++++--- .../org/apache/poi/hssf/record/SSTRecord.java | 2 +- .../apache/poi/hssf/record/UnicodeString.java | 6 + src/java/org/apache/poi/util/HexDump.java | 40 +- .../org/apache/poi/util/LittleEndian.java | 16 +- .../org/apache/poi/hssf/data/BigSSTRecord | 1032 ++++++++--------- .../apache/poi/hssf/data/evencontinuation.txt | 16 + .../org/apache/poi/hssf/data/richtextdata.txt | 21 + .../hssf/data/stringacross2continuations.txt | 7 + .../data/stringacross2continuationsCR1.txt | 9 + .../data/stringacross2continuationsCR2.txt | 7 + .../apache/poi/hssf/record/TestSSTRecord.java | 227 ++-- 13 files changed, 1113 insertions(+), 846 deletions(-) create mode 100644 src/testcases/org/apache/poi/hssf/data/evencontinuation.txt create mode 100644 src/testcases/org/apache/poi/hssf/data/richtextdata.txt create mode 100644 src/testcases/org/apache/poi/hssf/data/stringacross2continuations.txt create mode 100644 src/testcases/org/apache/poi/hssf/data/stringacross2continuationsCR1.txt create mode 100644 src/testcases/org/apache/poi/hssf/data/stringacross2continuationsCR2.txt diff --git a/module.xml b/module.xml index 93a451d2c..e4bff67a4 100644 --- a/module.xml +++ b/module.xml @@ -68,8 +68,8 @@ + fix ="1" + tag="dev"/> org.apache.poi diff --git a/src/java/org/apache/poi/hssf/record/SSTDeserializer.java b/src/java/org/apache/poi/hssf/record/SSTDeserializer.java index 58b62c316..2e1573e79 100644 --- a/src/java/org/apache/poi/hssf/record/SSTDeserializer.java +++ b/src/java/org/apache/poi/hssf/record/SSTDeserializer.java @@ -1,12 +1,68 @@ +/* ==================================================================== + * 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 + * . + */ + package org.apache.poi.hssf.record; +import org.apache.poi.util.BinaryTree; import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndianConsts; -import org.apache.poi.util.BinaryTree; -import org.apache.poi.util.HexDump; - -import java.io.IOException; +/** + * Handles the task of deserializing a SST string. The two main entry points are + * + * @author Glen Stampoultzis (glens at apache.org) + */ class SSTDeserializer { @@ -15,22 +71,35 @@ class SSTDeserializer 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 the total length of the current string being handled */ - private int totalLengthBytes; - /** this is the offset into a string field of the actual string data */ - private int stringDataOffset; /** 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) + public SSTDeserializer( BinaryTree strings ) { this.strings = strings; - setExpectedChars( 0 ); + initVars(); + } + + private void initVars() + { + runCount = 0; + continuationExpectedChars = 0; unfinishedString = ""; - totalLengthBytes = 0; - stringDataOffset = 0; +// bytesInCurrentSegment = 0; +// stringDataOffset = 0; wideChar = false; + richText = false; + extendedText = false; } /** @@ -38,14 +107,14 @@ class SSTDeserializer * strings may span across multiple continuations. Read the SST record * carefully before beginning to hack. */ - public void manufactureStrings( final byte[] data, final int index, - short size ) + public void manufactureStrings( final byte[] data, final int initialOffset, short dataSize ) { - int offset = index; + initVars(); - while ( offset < size ) + int offset = initialOffset; + while ( ( offset - initialOffset ) < dataSize ) { - int remaining = size - offset; + int remaining = dataSize - offset + initialOffset; if ( ( remaining > 0 ) && ( remaining < LittleEndianConsts.SHORT_SIZE ) ) { @@ -53,90 +122,38 @@ class SSTDeserializer } if ( remaining == LittleEndianConsts.SHORT_SIZE ) { - setExpectedChars( LittleEndian.getUShort( data, offset ) ); + setContinuationExpectedChars( LittleEndian.getUShort( data, offset ) ); unfinishedString = ""; break; } - short charCount = LittleEndian.getShort( data, offset ); - - setupStringParameters( data, offset, charCount ); - if ( remaining < totalLengthBytes ) + charCount = LittleEndian.getUShort( data, offset ); + readStringHeader( data, offset ); + boolean stringContinuesOverContinuation = remaining < totalStringSize(); + if ( stringContinuesOverContinuation ) { - setExpectedChars( calculateCharCount( totalLengthBytes - remaining ) ); - charCount -= getExpectedChars(); - totalLengthBytes = remaining; + int remainingBytes = ( initialOffset + dataSize ) - offset - stringHeaderOverhead(); + setContinuationExpectedChars( charCount - calculateCharCount( remainingBytes ) ); + charCount -= getContinuationExpectedChars(); } else { - setExpectedChars( 0 ); + setContinuationExpectedChars( 0 ); } processString( data, offset, charCount ); - offset += totalLengthBytes; - if ( getExpectedChars() != 0 ) + offset += totalStringSize(); + if ( getContinuationExpectedChars() != 0 ) { break; } } } - - /** - * 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. - * - * @param data - * @param index - * @param char_count - */ - private void setupStringParameters( final byte[] data, final int index, - final int char_count ) - { - byte optionFlag = data[index + LittleEndianConsts.SHORT_SIZE]; - - wideChar = ( optionFlag & 1 ) == 1; - boolean farEast = ( optionFlag & 4 ) == 4; - boolean richText = ( optionFlag & 8 ) == 8; - - totalLengthBytes = SSTRecord.STRING_MINIMAL_OVERHEAD + calculateByteCount( char_count ); - stringDataOffset = SSTRecord.STRING_MINIMAL_OVERHEAD; - if ( richText ) - { - short run_count = LittleEndian.getShort( data, index + stringDataOffset ); - - stringDataOffset += LittleEndianConsts.SHORT_SIZE; - totalLengthBytes += LittleEndianConsts.SHORT_SIZE + ( LittleEndianConsts.INT_SIZE * run_count ); - } - if ( farEast ) - { - int extension_length = LittleEndian.getInt( data, index + stringDataOffset ); - - stringDataOffset += LittleEndianConsts.INT_SIZE; - totalLengthBytes += LittleEndianConsts.INT_SIZE + extension_length; - } - } - - - private void processString( final byte[] data, final int index, - final short char_count ) - { - byte[] stringDataBuffer = new byte[totalLengthBytes]; - int length = SSTRecord.STRING_MINIMAL_OVERHEAD + calculateByteCount( char_count ); - byte[] bstring = new byte[length]; - - System.arraycopy( data, index, stringDataBuffer, 0, stringDataBuffer.length ); - int offset = 0; - - LittleEndian.putShort( bstring, offset, char_count ); - offset += LittleEndianConsts.SHORT_SIZE; - bstring[offset] = stringDataBuffer[offset]; - -// System.out.println( "offset = " + stringDataOffset ); -// System.out.println( "length = " + (bstring.length - STRING_MINIMAL_OVERHEAD) ); -// System.out.println( "src.length = " + str_data.length ); +// private void dump( final byte[] data, int offset, int length ) +// { // try // { -// System.out.println( "----------------------- DUMP -------------------------" ); -// HexDump.dump( stringDataBuffer, (long)stringDataOffset, System.out, 1); +// System.out.println( "------------------- SST DUMP -------------------------" ); +// HexDump.dump( (byte[]) data, offset, System.out, offset, length ); // } // catch ( IOException e ) // { @@ -147,56 +164,116 @@ class SSTDeserializer // catch ( IllegalArgumentException e ) // { // } - System.arraycopy( stringDataBuffer, stringDataOffset, bstring, - SSTRecord.STRING_MINIMAL_OVERHEAD, - bstring.length - SSTRecord.STRING_MINIMAL_OVERHEAD ); - UnicodeString string = new UnicodeString( UnicodeString.sid, - (short) bstring.length, - bstring ); +// } - if ( getExpectedChars() != 0 ) + /** + * 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 ) { - unfinishedString = string.getString(); + runCount = LittleEndian.getShort( data, index + SSTRecord.STRING_MINIMAL_OVERHEAD ); } - else + extensionLength = 0; + if ( extendedText ) + { + extensionLength = LittleEndian.getInt( data, index + SSTRecord.STRING_MINIMAL_OVERHEAD ); + } + + } + + + /** + * 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 do things: 1. Converting rich + * 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.isRichText() ) + string.setOptionFlags( (byte) ( string.getOptionFlags() & ( ~8 ) ) ); + if ( string.isExtendedText() ) + string.setOptionFlags( (byte) ( string.getOptionFlags() & ( ~4 ) ) ); boolean added = false; - while (added == false) + while ( added == false ) { try { strings.put( integer, string ); added = true; } - catch( Exception ignore ) + catch ( Exception ignore ) { string.setString( string.getString() + " " ); } } - } + } private int calculateCharCount( final int byte_count ) { - return byte_count / ( wideChar ? LittleEndianConsts.SHORT_SIZE - : LittleEndianConsts.BYTE_SIZE ); + return byte_count / ( wideChar ? LittleEndianConsts.SHORT_SIZE : LittleEndianConsts.BYTE_SIZE ); } /** @@ -219,81 +296,129 @@ class SSTDeserializer * * @param record the Continue record's byte data */ - public void processContinueRecord( final byte[] record ) { - if ( getExpectedChars() == 0 ) + if ( isStringFinished() ) { - unfinishedString = ""; - totalLengthBytes = 0; - stringDataOffset = 0; - wideChar = false; + initVars(); manufactureStrings( record, 0, (short) record.length ); } else { - int data_length = record.length - LittleEndianConsts.BYTE_SIZE; + // 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 ( calculateByteCount( getExpectedChars() ) > data_length ) + if ( stringSpansContinuation( record.length - LittleEndianConsts.BYTE_SIZE ) ) { - - // 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 ); - - unfinishedString = unfinishedString + ucs.getString(); - setExpectedChars( getExpectedChars() - size ); + processEntireContinuation( record ); } else { - setupStringParameters( record, -LittleEndianConsts.SHORT_SIZE, - getExpectedChars() ); - byte[] str_data = new byte[totalLengthBytes]; - int length = SSTRecord.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, stringDataOffset, bstring, - SSTRecord.STRING_MINIMAL_OVERHEAD, - bstring.length - SSTRecord.STRING_MINIMAL_OVERHEAD ); - - // use special constructor to create the final string - UnicodeString string = - new UnicodeString( UnicodeString.sid, - (short) bstring.length, bstring, - unfinishedString ); - Integer integer = new Integer( strings.size() ); - -// field_3_strings.put( integer, string ); - addToStringTable( strings, integer, string ); - manufactureStrings( record, totalLengthBytes - LittleEndianConsts.SHORT_SIZE, (short) record.length ); + 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 unfinishedString. + * + * @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; } /** @@ -301,12 +426,12 @@ class SSTDeserializer * sub-record in a subsequent continuation record */ - int getExpectedChars() + int getContinuationExpectedChars() { return continuationExpectedChars; } - private void setExpectedChars( final int count ) + private void setContinuationExpectedChars( final int count ) { continuationExpectedChars = count; } @@ -317,37 +442,116 @@ class SSTDeserializer } + /** + * 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 src to the destination array + * referenced by dst. The number of components copied is + * equal to the length argument. The components at + * positions srcOffset through + * srcOffset+length-1 in the source array are copied into + * positions dstOffset through + * dstOffset+length-1, respectively, of the destination + * array. + *

+ * If the src and dst arguments refer to the + * same array object, then the copying is performed as if the + * components at positions srcOffset through + * srcOffset+length-1 were first copied to a temporary + * array with length components and then the contents of + * the temporary array were copied into positions + * dstOffset through dstOffset+length-1 of the + * destination array. + *

+ * If dst is null, then a + * NullPointerException is thrown. + *

+ * If src is null, then a + * NullPointerException is thrown and the destination + * array is not modified. + *

+ * Otherwise, if any of the following is true, an + * ArrayStoreException is thrown and the destination is + * not modified: + *

    + *
  • The src argument refers to an object that is not an + * array. + *
  • The dst argument refers to an object that is not an + * array. + *
  • The src argument and dst argument refer to + * arrays whose component types are different primitive types. + *
  • The src argument refers to an array with a primitive + * component type and the dst argument refers to an array + * with a reference component type. + *
  • The src argument refers to an array with a reference + * component type and the dst argument refers to an array + * with a primitive component type. + *
+ *

+ * Otherwise, if any of the following is true, an + * IndexOutOfBoundsException is + * thrown and the destination is not modified: + *

    + *
  • The srcOffset argument is negative. + *
  • The dstOffset argument is negative. + *
  • The length argument is negative. + *
  • srcOffset+length is greater than + * src.length, the length of the source array. + *
  • dstOffset+length is greater than + * dst.length, the length of the destination array. + *
+ *

+ * Otherwise, if any actual component of the source array from + * position srcOffset through + * srcOffset+length-1 cannot be converted to the component + * type of the destination array by assignment conversion, an + * ArrayStoreException is thrown. In this case, let + * k be the smallest nonnegative integer less than + * length such that src[srcOffset+k] + * cannot be converted to the component type of the destination + * array; when the exception is thrown, source array components from + * positions srcOffset through + * srcOffset+k-1 + * will already have been copied to destination array positions + * dstOffset through + * dstOffset+k-1 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 src + * array could not be stored into the dest array + * because of a type mismatch. + * @exception NullPointerException if either src or + * dst is null. + */ + 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 the total length of the current string - */ - - int getTotalLength() - { - return totalLengthBytes; - } - - /** - * @return offset into current string data - */ - - int getStringDataOffset() - { - return stringDataOffset; - } - /** * @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 6011c8f5d..734a90f6f 100644 --- a/src/java/org/apache/poi/hssf/record/SSTRecord.java +++ b/src/java/org/apache/poi/hssf/record/SSTRecord.java @@ -478,7 +478,7 @@ public class SSTRecord 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, size ); + deserializer.manufactureStrings( data, 8 + offset, (short)(size - 8) ); } diff --git a/src/java/org/apache/poi/hssf/record/UnicodeString.java b/src/java/org/apache/poi/hssf/record/UnicodeString.java index 2d6881525..d56b660d4 100644 --- a/src/java/org/apache/poi/hssf/record/UnicodeString.java +++ b/src/java/org/apache/poi/hssf/record/UnicodeString.java @@ -79,6 +79,7 @@ public class UnicodeString 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() { @@ -364,4 +365,9 @@ public class UnicodeString return rval; } + public boolean isExtendedText() + { + return (getOptionFlags() & EXT_BIT) != 0; + } + } diff --git a/src/java/org/apache/poi/util/HexDump.java b/src/java/org/apache/poi/util/HexDump.java index 4e0cfd35a..49bca34ff 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/LittleEndian.java b/src/java/org/apache/poi/util/LittleEndian.java index 2346a0a27..21b0c69ea 100644 --- a/src/java/org/apache/poi/util/LittleEndian.java +++ b/src/java/org/apache/poi/util/LittleEndian.java @@ -236,13 +236,27 @@ public class LittleEndian * * @exception ArrayIndexOutOfBoundsException may be thrown */ - public static void putShort(final byte[] data, final int offset, final short value) { putNumber(data, offset, value, SHORT_SIZE); } + /** + * 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 * diff --git a/src/testcases/org/apache/poi/hssf/data/BigSSTRecord b/src/testcases/org/apache/poi/hssf/data/BigSSTRecord index 6cebff51b..3dd8f9ebd 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/evencontinuation.txt b/src/testcases/org/apache/poi/hssf/data/evencontinuation.txt new file mode 100644 index 000000000..4740b2747 --- /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 000000000..a34559583 --- /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 000000000..c9bc332e5 --- /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 000000000..821142ade --- /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 000000000..f4eb4c3c3 --- /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 f6963e137..b574a3426 100644 --- a/src/testcases/org/apache/poi/hssf/record/TestSSTRecord.java +++ b/src/testcases/org/apache/poi/hssf/record/TestSSTRecord.java @@ -55,19 +55,20 @@ package org.apache.poi.hssf.record; 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 org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.usermodel.HSSFSheet; import java.io.*; -import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; -import java.util.List; /** * @author Marc Johnson (mjohnson at apache dot org) + * @author Glen Stampoultzis (glens at apache.org) */ public class TestSSTRecord @@ -98,14 +99,14 @@ public class TestSSTRecord public void testProcessContinueRecord() throws IOException { - byte[] testdata = readTestData( "BigSSTRecord" ); + 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 = readTestData( "BigSSTRecordCR" ); + byte[] continueRecord = HexRead.readTestData( _test_file_path + File.separator + "BigSSTRecordCR" ); input = new byte[continueRecord.length - 4]; System.arraycopy( continueRecord, 4, input, 0, input.length ); @@ -141,42 +142,42 @@ public class TestSSTRecord assertEquals( record, testRecord ); // testing based on new bug report - testdata = readTestData( "BigSSTRecord2" ); + 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 = readTestData( "BigSSTRecord2CR1" ); + 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 = readTestData( "BigSSTRecord2CR2" ); + 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 = readTestData( "BigSSTRecord2CR3" ); + 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 = readTestData( "BigSSTRecord2CR4" ); + 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 = readTestData( "BigSSTRecord2CR5" ); + 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 = readTestData( "BigSSTRecord2CR6" ); + 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 = readTestData( "BigSSTRecord2CR7" ); + byte[] continueRecord7 = HexRead.readTestData( _test_file_path + File.separator + "BigSSTRecord2CR7" ); input = new byte[continueRecord7.length - 4]; System.arraycopy( continueRecord7, 4, input, 0, input.length ); @@ -208,6 +209,7 @@ public class TestSSTRecord } assertEquals( offset, ser_output.length ); assertEquals( record, testRecord ); + assertEquals( record.countStrings(), testRecord.countStrings() ); } /** @@ -333,7 +335,6 @@ public class TestSSTRecord * * @exception IOException */ - public void testSSTRecordBug() throws IOException { @@ -366,7 +367,6 @@ public class TestSSTRecord /** * test simple addString */ - public void testSimpleAddString() { SSTRecord record = new SSTRecord(); @@ -420,7 +420,7 @@ public class TestSSTRecord public void testReaderConstructor() throws IOException { - byte[] testdata = readTestData( "BigSSTRecord" ); + 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 ); @@ -431,11 +431,11 @@ public class TestSSTRecord assertEquals( 1464, record.getNumStrings() ); assertEquals( 688, record.getNumUniqueStrings() ); assertEquals( 492, record.countStrings() ); - assertEquals( 1, record.getDeserializer().getExpectedChars() ); + 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() ); +// assertEquals( 52, record.getDeserializer().getTotalLength() ); +// assertEquals( 3, record.getDeserializer().getStringDataOffset() ); assertTrue( !record.getDeserializer().isWideChar() ); } @@ -450,10 +450,10 @@ public class TestSSTRecord assertEquals( 0, record.getNumStrings() ); assertEquals( 0, record.getNumUniqueStrings() ); assertEquals( 0, record.countStrings() ); - assertEquals( 0, record.getDeserializer().getExpectedChars() ); + assertEquals( 0, record.getDeserializer().getContinuationExpectedChars() ); assertEquals( "", record.getDeserializer().getUnfinishedString() ); - assertEquals( 0, record.getDeserializer().getTotalLength() ); - assertEquals( 0, record.getDeserializer().getStringDataOffset() ); +// assertEquals( 0, record.getDeserializer().getTotalLength() ); +// assertEquals( 0, record.getDeserializer().getStringDataOffset() ); assertTrue( !record.getDeserializer().isWideChar() ); byte[] output = record.serialize(); byte[] expected = @@ -482,99 +482,6 @@ public class TestSSTRecord junit.textui.TestRunner.run( TestSSTRecord.class ); } - private byte[] readTestData( String filename ) - throws IOException - { - 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(); - - switch ( count ) - { - - 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; - } - /** * Tests that workbooks with rich text that duplicates a non rich text cell can be read and written. */ @@ -582,38 +489,86 @@ public class TestSSTRecord throws Exception { File file = new File( _test_file_path + File.separator + "duprich1.xls" ); - InputStream stream = new FileInputStream(file); - HSSFWorkbook wb = new HSSFWorkbook(stream); + 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()); + 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); + 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 = new FileInputStream( file ); + wb = new HSSFWorkbook( stream ); stream.close(); - sheet = wb.getSheetAt(0); + 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()); + 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); + file = File.createTempFile( "testout", ".xls" ); + outStream = new FileOutputStream( file ); + wb.write( outStream ); outStream.close(); file.delete(); } + + 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 ) ) + "" ); + } + + 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 ) ) + "" ); + + } }