/** * Serialises out the String. There are special rules about where we can and can't split onto * Continue records. */ public void serialize(ContinuableRecordOutput out) { int numberOfRichTextRuns = 0; int extendedDataSize = 0; if (isRichText() && field_4_format_runs != null) { numberOfRichTextRuns = field_4_format_runs.size(); } if (isExtendedText() && field_5_ext_rst != null) { extendedDataSize = 4 + field_5_ext_rst.getDataSize(); } // Serialise the bulk of the String // The writeString handles tricky continue stuff for us out.writeString(field_3_string, numberOfRichTextRuns, extendedDataSize); if (numberOfRichTextRuns > 0) { // This will ensure that a run does not split a continue for (int i = 0; i < numberOfRichTextRuns; i++) { if (out.getAvailableSpace() < 4) { out.writeContinue(); } FormatRun r = field_4_format_runs.get(i); r.serialize(out); } } if (extendedDataSize > 0) { field_5_ext_rst.serialize(out); } }
/** * return a character representation of the fields of this record * * @return String of output for biffviewer etc. */ public String getDebugInfo() { StringBuffer buffer = new StringBuffer(); buffer.append("[UNICODESTRING]\n"); buffer .append(" .charcount = ") .append(Integer.toHexString(getCharCount())) .append("\n"); buffer .append(" .optionflags = ") .append(Integer.toHexString(getOptionFlags())) .append("\n"); buffer.append(" .string = ").append(getString()).append("\n"); if (field_4_format_runs != null) { for (int i = 0; i < field_4_format_runs.size(); i++) { FormatRun r = field_4_format_runs.get(i); buffer.append(" .format_run" + i + " = ").append(r.toString()).append("\n"); } } if (field_5_ext_rst != null) { buffer.append(" .field_5_ext_rst = ").append("\n"); buffer.append(field_5_ext_rst.toString()).append("\n"); } buffer.append("[/UNICODESTRING]\n"); return buffer.toString(); }
/** * construct a unicode string record and fill its fields, ID is ignored * * @param in the RecordInputstream to read the record from */ public UnicodeString(RecordInputStream in) { field_1_charCount = in.readShort(); field_2_optionflags = in.readByte(); int runCount = 0; int extensionLength = 0; // Read the number of rich runs if rich text. if (isRichText()) { runCount = in.readShort(); } // Read the size of extended data if present. if (isExtendedText()) { extensionLength = in.readInt(); } boolean isCompressed = ((field_2_optionflags & 1) == 0); if (isCompressed) { field_3_string = in.readCompressedUnicode(getCharCount()); } else { field_3_string = in.readUnicodeLEString(getCharCount()); } if (isRichText() && (runCount > 0)) { field_4_format_runs = new ArrayList<FormatRun>(runCount); for (int i = 0; i < runCount; i++) { field_4_format_runs.add(new FormatRun(in)); } } if (isExtendedText() && (extensionLength > 0)) { field_5_ext_rst = new ExtRst(new ContinuableRecordInput(in), extensionLength); if (field_5_ext_rst.getDataSize() + 4 != extensionLength) { System.err.println( "ExtRst was supposed to be " + extensionLength + " bytes long, but seems to actually be " + (field_5_ext_rst.getDataSize() + 4)); } } }
/** * Our handling of equals is inconsistent with compareTo. The trouble is because we don't truely * understand rich text fields yet it's difficult to make a sound comparison. * * @param o The object to compare. * @return true if the object is actually equal. */ public boolean equals(Object o) { if (!(o instanceof UnicodeString)) { return false; } UnicodeString other = (UnicodeString) o; // OK lets do this in stages to return a quickly, first check the actual string boolean eq = ((field_1_charCount == other.field_1_charCount) && (field_2_optionflags == other.field_2_optionflags) && field_3_string.equals(other.field_3_string)); if (!eq) return false; // OK string appears to be equal but now lets compare formatting runs if ((field_4_format_runs == null) && (other.field_4_format_runs == null)) // Strings are equal, and there are not formatting runs. return true; if (((field_4_format_runs == null) && (other.field_4_format_runs != null)) || (field_4_format_runs != null) && (other.field_4_format_runs == null)) // Strings are equal, but one or the other has formatting runs return false; // Strings are equal, so now compare formatting runs. int size = field_4_format_runs.size(); if (size != other.field_4_format_runs.size()) return false; for (int i = 0; i < size; i++) { FormatRun run1 = field_4_format_runs.get(i); FormatRun run2 = other.field_4_format_runs.get(i); if (!run1.equals(run2)) return false; } // Well the format runs are equal as well!, better check the ExtRst data if (field_5_ext_rst == null && other.field_5_ext_rst == null) { // Good } else if (field_5_ext_rst != null && other.field_5_ext_rst != null) { int extCmp = field_5_ext_rst.compareTo(other.field_5_ext_rst); if (extCmp == 0) { // Good } else { return false; } } else { return false; } // Phew!! After all of that we have finally worked out that the strings // are identical. return true; }
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<FormatRun>(); for (FormatRun r : field_4_format_runs) { str.field_4_format_runs.add(new FormatRun(r._character, r._fontIndex)); } } if (field_5_ext_rst != null) { str.field_5_ext_rst = field_5_ext_rst.clone(); } return str; }
protected ExtRst clone() { ExtRst ext = new ExtRst(); ext.reserved = reserved; ext.formattingFontIndex = formattingFontIndex; ext.formattingOptions = formattingOptions; ext.numberOfRuns = numberOfRuns; ext.phoneticText = phoneticText; ext.phRuns = new PhRun[phRuns.length]; for (int i = 0; i < ext.phRuns.length; i++) { ext.phRuns[i] = new PhRun( phRuns[i].phoneticTextFirstCharacterOffset, phRuns[i].realTextFirstCharacterOffset, phRuns[i].realTextLength); } return ext; }
public int compareTo(UnicodeString str) { 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 formatting 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 = field_4_format_runs.get(i); FormatRun run2 = 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 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; result = field_5_ext_rst.compareTo(str.field_5_ext_rst); if (result != 0) return result; // Phew!! After all of that we have finally worked out that the strings // are identical. return 0; }