📄 unicodestring.java
字号:
if (isRichText() && (field_4_format_runs != null)) { int count = field_4_format_runs.size(); //This will ensure that a run does not split a continue for (int i=0;i<count;i++) { pos = writeContinueIfRequired(stats, 4, pos, data); FormatRun r = (FormatRun)field_4_format_runs.get(i); LittleEndian.putShort(data, pos, r.character); pos += 2; LittleEndian.putShort(data, pos, r.fontIndex); pos += 2; //Each run count is four bytes stats.recordSize += 4; stats.remainingSize -=4; } } if (isExtendedText() && (field_5_ext_rst != null)) { //Ok ExtRst is actually not documented, so i am going to hope //that we can actually continue on byte boundaries int ammountThatCantFit = field_5_ext_rst.length - stats.remainingSize; int extPos = 0; if (ammountThatCantFit > 0) { while (ammountThatCantFit > 0) { //So for this record we have already written int ammountWritten = Math.min(stats.remainingSize, ammountThatCantFit); System.arraycopy(field_5_ext_rst, extPos, data, pos, ammountWritten); pos += ammountWritten; extPos += ammountWritten; stats.recordSize += ammountWritten; stats.remainingSize -= ammountWritten; //Ok lets subtract what we can write ammountThatCantFit -= ammountWritten; if (ammountThatCantFit > 0) { pos = writeContinueIfRequired(stats, 1, pos, data); } } } else { //We can fit wholey in what remains. System.arraycopy(field_5_ext_rst, 0, data, pos, field_5_ext_rst.length); pos += field_5_ext_rst.length; stats.remainingSize -= field_5_ext_rst.length; stats.recordSize += field_5_ext_rst.length; } } return pos - offset; } public void setCompressedUnicode() { field_2_optionflags = highByte.setByte(field_2_optionflags); } public void setUncompressedUnicode() { field_2_optionflags = highByte.clearByte(field_2_optionflags); } private boolean isUncompressedUnicode() { return highByte.isSet(getOptionFlags()); } /** Returns the size of this record, given the ammount of record space * remaining, it will also include the size of writing a continue record. */ public static class UnicodeRecordStats { public int recordSize; public int remainingSize = SSTRecord.MAX_RECORD_SIZE; public int lastLengthPos = -1; } public void getRecordSize(UnicodeRecordStats stats) { //Basic string overhead if (stats.remainingSize < 3) { //Needs a continue stats.recordSize += 4; stats.remainingSize = SSTRecord.MAX_RECORD_SIZE-4; } stats.recordSize += 3; stats.remainingSize-= 3; //Read the number of rich runs if rich text. if ( isRichText() ) { //Run count if (stats.remainingSize < 2) { //Needs a continue //Reset the available space. stats.remainingSize = SSTRecord.MAX_RECORD_SIZE-4; //continue record overhead stats.recordSize+=4; } stats.recordSize += 2; stats.remainingSize -=2; } //Read the size of extended data if present. if ( isExtendedText() ) { //Needs a continue //extension length if (stats.remainingSize < 4) { //Reset the available space. stats.remainingSize = SSTRecord.MAX_RECORD_SIZE-4; //continue record overhead stats.recordSize+=4; } stats.recordSize += 4; stats.remainingSize -=4; } int charsize = isUncompressedUnicode() ? 2 : 1; int strSize = (getString().length() * charsize); //Check to see if the offset occurs mid string, if so then we need to add //the byte to start with that represents the first byte of the continue record. if (strSize > stats.remainingSize) { //Ok the offset occurs half way through the string, that means that //we need an extra byte after the continue record ie we didnt finish //writing out the string the 1st time through //But hang on, how many continue records did we span? What if this is //a REALLY long string. We need to work this all out. int ammountThatCantFit = strSize; while (ammountThatCantFit > 0) { int ammountWritten = Math.min(stats.remainingSize, ammountThatCantFit); //Make sure that the ammount that cant fit takes into account //whether we are writing double byte unicode if (isUncompressedUnicode()) { //We have the '-1' here because whether this is the first record or //subsequent continue records, there is always the case that the //number of bytes in a string on doube byte boundaries is actually odd. if ( ( (ammountWritten) % 2) == 1) ammountWritten--; } stats.recordSize += ammountWritten; stats.remainingSize -= ammountWritten; //Ok lets subtract what we can write ammountThatCantFit -= ammountWritten; //Each iteration of this while loop is another continue record, unless //everything now fits. if (ammountThatCantFit > 0) { //Reset the available space. stats.remainingSize = SSTRecord.MAX_RECORD_SIZE-4; //continue record overhead stats.recordSize+=4; //The first byte after a continue mid string is the extra byte to //indicate if this run is compressed or not. stats.recordSize++; stats.remainingSize --; } } } else { //Ok the string fits nicely in the remaining size stats.recordSize += strSize; stats.remainingSize -= strSize; } if (isRichText() && (field_4_format_runs != null)) { int count = field_4_format_runs.size(); //This will ensure that a run does not split a continue for (int i=0;i<count;i++) { if (stats.remainingSize < 4) { //Reset the available space. stats.remainingSize = SSTRecord.MAX_RECORD_SIZE-4; //continue record overhead stats.recordSize+=4; } //Each run count is four bytes stats.recordSize += 4; stats.remainingSize -=4; } } if (isExtendedText() && (field_5_ext_rst != null)) { //Ok ExtRst is actually not documented, so i am going to hope //that we can actually continue on byte boundaries int ammountThatCantFit = field_5_ext_rst.length - stats.remainingSize; if (ammountThatCantFit > 0) { while (ammountThatCantFit > 0) { //So for this record we have already written int ammountWritten = Math.min(stats.remainingSize, ammountThatCantFit); stats.recordSize += ammountWritten; stats.remainingSize -= ammountWritten; //Ok lets subtract what we can write ammountThatCantFit -= ammountWritten; if (ammountThatCantFit > 0) { //Each iteration of this while loop is another continue record. //Reset the available space. stats.remainingSize = SSTRecord.MAX_RECORD_SIZE-4; //continue record overhead stats.recordSize += 4; } } } else { //We can fit wholey in what remains. stats.remainingSize -= field_5_ext_rst.length; stats.recordSize += field_5_ext_rst.length; } } } public short getSid() { return sid; } public int compareTo(Object obj) { UnicodeString str = ( UnicodeString ) obj; int result = getString().compareTo(str.getString()); //As per the equals method lets do this in stages if (result != 0) return result; //Ok string appears to be equal but now lets compare formatting runs if ((field_4_format_runs == null) && (str.field_4_format_runs == null)) //Strings are equal, and there are no formtting runs. return 0; if ((field_4_format_runs == null) && (str.field_4_format_runs != null)) //Strings are equal, but one or the other has formatting runs return 1; if ((field_4_format_runs != null) && (str.field_4_format_runs == null)) //Strings are equal, but one or the other has formatting runs return -1; //Strings are equal, so now compare formatting runs. int size = field_4_format_runs.size(); if (size != str.field_4_format_runs.size()) return size - str.field_4_format_runs.size(); for (int i=0;i<size;i++) { FormatRun run1 = (FormatRun)field_4_format_runs.get(i); FormatRun run2 = (FormatRun)str.field_4_format_runs.get(i); result = run1.compareTo(run2); if (result != 0) return result; } //Well the format runs are equal as well!, better check the ExtRst data //Which by the way we dont know how to decode! if ((field_5_ext_rst == null) && (str.field_5_ext_rst == null)) return 0; if ((field_5_ext_rst == null) && (str.field_5_ext_rst != null)) return 1; if ((field_5_ext_rst != null) && (str.field_5_ext_rst == null)) return -1; size = field_5_ext_rst.length; if (size != field_5_ext_rst.length) return size - field_5_ext_rst.length; //Check individual bytes! for (int i=0;i<size;i++) { if (field_5_ext_rst[i] != str.field_5_ext_rst[i]) return field_5_ext_rst[i] - str.field_5_ext_rst[i]; } //Phew!! After all of that we have finally worked out that the strings //are identical. return 0; } public boolean isRichText() { return richText.isSet(getOptionFlags()); } public boolean isExtendedText() { return extBit.isSet(getOptionFlags()); } public Object clone() { UnicodeString str = new UnicodeString(); str.field_1_charCount = field_1_charCount; str.field_2_optionflags = field_2_optionflags; str.field_3_string = field_3_string; if (field_4_format_runs != null) { str.field_4_format_runs = new ArrayList(); int size = field_4_format_runs.size(); for (int i = 0; i < size; i++) { FormatRun r = (FormatRun) field_4_format_runs.get(i); str.field_4_format_runs.add(new FormatRun(r.character, r.fontIndex)); } } if (field_5_ext_rst != null) { str.field_5_ext_rst = new byte[field_5_ext_rst.length]; System.arraycopy(field_5_ext_rst, 0, str.field_5_ext_rst, 0, field_5_ext_rst.length); } return str; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -