📄 sstdeserializer.java
字号:
* contains the same kind of data that the SST record contains, * with the following exceptions: * <P> * <OL> * <LI>The string counts at the beginning of the SST record are * not in the Continue record * <LI>The first string in the Continue record might NOT begin * with a size. If the last string in the previous record is * continued in this record, the size is determined by that * last string in the previous record; the first string will * begin with a flag byte, followed by the remaining bytes (or * words) of the last string from the previous * record. Otherwise, the first string in the record will * begin with a string length * </OL> * * @param record the Continue record's byte data */ public void processContinueRecord( final byte[] record ) { if ( isStringFinished() ) { final int offset = continueSkipBytes; initVars(); manufactureStrings( record, offset); } else { // reset the wide bit because that can change across a continuation. the fact that it's // actually rich text doesn't change across continuations even though the rich text // may on longer be set in the "new" option flag. confusing huh? wideChar = ( record[0] & 1 ) == 1; if ( stringSpansContinuation( record.length - LittleEndianConsts.BYTE_SIZE ) ) { processEntireContinuation( record ); } else { readStringRemainder( record ); } } } /** * Reads the remainder string and any subsequent strings from the continuation record. * * @param record The entire continuation record data. */ private void readStringRemainder( final byte[] record ) { int stringRemainderSizeInBytes = calculateByteCount( charCount-getContinuationCharsRead() ); byte[] unicodeStringData = new byte[SSTRecord.STRING_MINIMAL_OVERHEAD + stringRemainderSizeInBytes]; // write the string length LittleEndian.putShort( unicodeStringData, 0, (short) (charCount-getContinuationCharsRead()) ); // 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, stringRemainderSizeInBytes ); // 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); } /** * 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 ) { int offset = stringRemainderSizeInBytes + runCount * LittleEndianConsts.INT_SIZE + extensionLength; if (stringRemainderSizeInBytes != 0) //If a portion of the string remains then the wideChar options byte is repeated, //so need to skip this. offset += + LittleEndianConsts.BYTE_SIZE; return offset; } private byte createOptionByte( boolean wideChar, boolean richText, boolean farEast ) { return (byte) ( ( wideChar ? 1 : 0 ) + ( farEast ? 4 : 0 ) + ( richText ? 8 : 0 ) ); } /** * If the continued record is so long is spans into the next continue then * simply suck the remaining string data into the existing <code>unfinishedString</code>. * * @param record The data from the continuation record. */ private void processEntireContinuation( final byte[] record ) { // create artificial data to create a UnicodeString int dataLengthInBytes = record.length - LittleEndianConsts.BYTE_SIZE; byte[] unicodeStringData = new byte[record.length + LittleEndianConsts.SHORT_SIZE]; int charsRead = calculateCharCount( dataLengthInBytes ); LittleEndian.putShort( unicodeStringData, (byte) 0, (short) charsRead ); arraycopy( record, 0, unicodeStringData, LittleEndianConsts.SHORT_SIZE, record.length ); UnicodeString ucs = new UnicodeString( UnicodeString.sid, (short) unicodeStringData.length, unicodeStringData, unfinishedString); unfinishedString = ucs.getString(); setContinuationCharsRead( getContinuationCharsRead() + charsRead ); if (getContinuationCharsRead() == charCount) { Integer integer = new Integer( strings.size() ); addToStringTable( strings, integer, ucs ); } } private boolean stringSpansContinuation( int continuationSizeInBytes ) { return calculateByteCount( charCount - getContinuationCharsRead() ) > continuationSizeInBytes; } /** * @return the number of characters we expect in the first * sub-record in a subsequent continuation record */ int getContinuationCharsRead() { return continuationReadChars; } private void setContinuationCharsRead( final int count ) { continuationReadChars = count; } private int calculateByteCount( final int character_count ) { return character_count * ( wideChar ? LittleEndianConsts.SHORT_SIZE : LittleEndianConsts.BYTE_SIZE ); } /** * Copies an array from the specified source array, beginning at the * specified position, to the specified position of the destination array. * A subsequence of array components are copied from the source * array referenced by <code>src</code> to the destination array * referenced by <code>dst</code>. The number of components copied is * equal to the <code>length</code> argument. The components at * positions <code>srcOffset</code> through * <code>srcOffset+length-1</code> in the source array are copied into * positions <code>dstOffset</code> through * <code>dstOffset+length-1</code>, respectively, of the destination * array. * <p> * If the <code>src</code> and <code>dst</code> arguments refer to the * same array object, then the copying is performed as if the * components at positions <code>srcOffset</code> through * <code>srcOffset+length-1</code> were first copied to a temporary * array with <code>length</code> components and then the contents of * the temporary array were copied into positions * <code>dstOffset</code> through <code>dstOffset+length-1</code> of the * destination array. * <p> * If <code>dst</code> is <code>null</code>, then a * <code>NullPointerException</code> is thrown. * <p> * If <code>src</code> is <code>null</code>, then a * <code>NullPointerException</code> is thrown and the destination * array is not modified. * <p> * Otherwise, if any of the following is true, an * <code>ArrayStoreException</code> is thrown and the destination is * not modified: * <ul> * <li>The <code>src</code> argument refers to an object that is not an * array. * <li>The <code>dst</code> argument refers to an object that is not an * array. * <li>The <code>src</code> argument and <code>dst</code> argument refer to * arrays whose component types are different primitive types. * <li>The <code>src</code> argument refers to an array with a primitive * component type and the <code>dst</code> argument refers to an array * with a reference component type. * <li>The <code>src</code> argument refers to an array with a reference * component type and the <code>dst</code> argument refers to an array * with a primitive component type. * </ul> * <p> * Otherwise, if any of the following is true, an * <code>IndexOutOfBoundsException</code> is * thrown and the destination is not modified: * <ul> * <li>The <code>srcOffset</code> argument is negative. * <li>The <code>dstOffset</code> argument is negative. * <li>The <code>length</code> argument is negative. * <li><code>srcOffset+length</code> is greater than * <code>src.length</code>, the length of the source array. * <li><code>dstOffset+length</code> is greater than * <code>dst.length</code>, the length of the destination array. * </ul> * <p> * Otherwise, if any actual component of the source array from * position <code>srcOffset</code> through * <code>srcOffset+length-1</code> cannot be converted to the component * type of the destination array by assignment conversion, an * <code>ArrayStoreException</code> is thrown. In this case, let * <b><i>k</i></b> be the smallest nonnegative integer less than * length such that <code>src[srcOffset+</code><i>k</i><code>]</code> * cannot be converted to the component type of the destination * array; when the exception is thrown, source array components from * positions <code>srcOffset</code> through * <code>srcOffset+</code><i>k</i><code>-1</code> * will already have been copied to destination array positions * <code>dstOffset</code> through * <code>dstOffset+</code><i>k</I><code>-1</code> and no other * positions of the destination array will have been modified. * (Because of the restrictions already itemized, this * paragraph effectively applies only to the situation where both * arrays have component types that are reference types.) * * @param src the source array. * @param src_position start position in the source array. * @param dst the destination array. * @param dst_position pos start position in the destination data. * @param length the number of array elements to be copied. * @exception IndexOutOfBoundsException if copying would cause * access of data outside array bounds. * @exception ArrayStoreException if an element in the <code>src</code> * array could not be stored into the <code>dest</code> array * because of a type mismatch. * @exception NullPointerException if either <code>src</code> or * <code>dst</code> is <code>null</code>. */ private void arraycopy( byte[] src, int src_position, byte[] dst, int dst_position, int length ) { System.arraycopy( src, src_position, dst, dst_position, length ); } /** * @return the unfinished string */ String getUnfinishedString() { return unfinishedString; } /** * @return true if current string uses wide characters */ boolean isWideChar() { return wideChar; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -