protected int getDataSize() { if (!isExternalReferences()) { return SMALL_RECORD_SIZE; } int sum = 2; // u16 number of sheets sum += StringUtil.getEncodedSize(field_2_encoded_url); for (int i = 0; i < field_3_sheet_names.length; i++) { sum += StringUtil.getEncodedSize(field_3_sheet_names[i]); } return sum; }
public void serialize(LittleEndianOutput out) { out.writeShort(field_1_number_of_sheets); if (isExternalReferences()) { StringUtil.writeUnicodeString(out, field_2_encoded_url); for (int i = 0; i < field_3_sheet_names.length; i++) { StringUtil.writeUnicodeString(out, field_3_sheet_names[i]); } } else { int field2val = _isAddInFunctions ? TAG_ADD_IN_FUNCTIONS : TAG_INTERNAL_REFERENCES; out.writeShort(field2val); } }
@Override protected int getDataSize() { if (_name == null) { return BASE_SIZE; } return BASE_SIZE + 1 // unicode flag + _name.length() * (StringUtil.hasMultibyte(_name) ? 2 : 1); }
public void serialize(LittleEndianOutput out) { _range.serialize(out); _guid.serialize(out); out.writeInt(0x00000002); // TODO const out.writeInt(_linkOpts); if ((_linkOpts & HLINK_LABEL) != 0) { out.writeInt(_label.length()); StringUtil.putUnicodeLE(_label, out); } if ((_linkOpts & HLINK_TARGET_FRAME) != 0) { out.writeInt(_targetFrame.length()); StringUtil.putUnicodeLE(_targetFrame, out); } if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) != 0) { out.writeInt(_address.length()); StringUtil.putUnicodeLE(_address, out); } if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) == 0) { _moniker.serialize(out); if (URL_MONIKER.equals(_moniker)) { if (_uninterpretedTail == null) { out.writeInt(_address.length() * 2); StringUtil.putUnicodeLE(_address, out); } else { out.writeInt(_address.length() * 2 + TAIL_SIZE); StringUtil.putUnicodeLE(_address, out); writeTail(_uninterpretedTail, out); } } else if (FILE_MONIKER.equals(_moniker)) { out.writeShort(_fileOpts); out.writeInt(_shortFilename.length()); StringUtil.putCompressedUnicode(_shortFilename, out); writeTail(_uninterpretedTail, out); if (_address == null) { out.writeInt(0); } else { int addrLen = _address.length() * 2; out.writeInt(addrLen + 6); out.writeInt(addrLen); out.writeShort(0x0003); // TODO const StringUtil.putUnicodeLE(_address, out); } } } if ((_linkOpts & HLINK_PLACE) != 0) { out.writeInt(_textMark.length()); StringUtil.putUnicodeLE(_textMark, out); } }
static void write(Sttb sttb, HWPFOutputStream tableStream) throws IOException { final int headerSize = sttb.cDataLength == 2 ? 6 : 8; byte[] header = new byte[headerSize]; LittleEndian.putShort(header, 0, (short) 0xffff); if (sttb.data == null || sttb.data.length == 0) { if (sttb.cDataLength == 4) { LittleEndian.putInt(header, 2, 0); LittleEndian.putUShort(header, 6, sttb.cbExtra); tableStream.write(header); return; } LittleEndian.putUShort(header, 2, 0); LittleEndian.putUShort(header, 4, sttb.cbExtra); tableStream.write(header); return; } if (sttb.cDataLength == 4) { LittleEndian.putInt(header, 2, sttb.data.length); LittleEndian.putUShort(header, 6, sttb.cbExtra); tableStream.write(header); } else { LittleEndian.putUShort(header, 2, sttb.data.length); LittleEndian.putUShort(header, 4, sttb.cbExtra); tableStream.write(header); } for (int i = 0; i < sttb.data.length; i++) { String entry = sttb.data[i]; if (entry == null) { // is it correct? tableStream.write(new byte[] {-1, 0}); continue; } byte[] buf = new byte[entry.length() * 2 + sttb.cbExtra + 2]; LittleEndian.putShort(buf, 0, (short) entry.length()); StringUtil.putUnicodeLE(entry, buf, 2); if (sttb.extraData != null && i < sttb.extraData.length && sttb.extraData[i] != null) System.arraycopy( sttb.extraData[i], 0, buf, entry.length() * 2, Math.min(sttb.extraData[i].length, sttb.cbExtra)); tableStream.write(buf); } }
@Override protected void serialize(LittleEndianOutput out) { out.writeShort(_sxaxis); out.writeShort(_cSub); out.writeShort(_grbitSub); out.writeShort(_cItm); if (_name != null) { StringUtil.writeUnicodeString(out, _name); } else { out.writeShort(STRING_NOT_PRESENT_LEN); } }
static Sttb read(int cDataLength, byte[] buffer, int startOffset) { short ffff = LittleEndian.getShort(buffer, startOffset); int offset = startOffset + 2; if (ffff != (short) 0xffff) { // Non-extended character Pascal strings throw new UnsupportedOperationException( "Non-extended character Pascal strings are not supported right now. " + "Please, contact POI developers for update."); } // strings are extended character strings int cData = cDataLength == 2 ? LittleEndian.getUShort(buffer, offset) : LittleEndian.getInt(buffer, offset); offset += cDataLength; Sttb sttb = new Sttb(); sttb.cDataLength = cDataLength; sttb.cbExtra = LittleEndian.getUShort(buffer, offset); offset += 2; sttb.data = new String[cData]; sttb.extraData = new byte[cData][]; for (int i = 0; i < cData; i++) { int cchData = LittleEndian.getShort(buffer, offset); offset += 2; if (cchData < 0) continue; sttb.data[i] = StringUtil.getFromUnicodeLE(buffer, offset, cchData); offset += cchData * 2; sttb.extraData[i] = LittleEndian.getByteArray(buffer, offset, sttb.cbExtra); offset += sttb.cbExtra; } return sttb; }
public MAPIStringAttribute(MAPIProperty property, int type, byte[] data) { super(property, type, data); String tmpData = null; if (type == Types.ASCII_STRING) { try { tmpData = new String(data, CODEPAGE); } catch (UnsupportedEncodingException e) { throw new RuntimeException("JVM Broken - core encoding " + CODEPAGE + " missing"); } } else if (type == Types.UNICODE_STRING) { tmpData = StringUtil.getFromUnicodeLE(data); } else { throw new IllegalArgumentException("Not a string type " + type); } // Strip off the null terminator if present if (tmpData.endsWith("\0")) { tmpData = tmpData.substring(0, tmpData.length() - 1); } this.data = tmpData; }
protected void serialize(ContinuableRecordOutput out) { int dataSize = getDataSize(); out.writeContinueIfRequired(8); out.writeShort(reserved); out.writeShort(dataSize); out.writeShort(formattingFontIndex); out.writeShort(formattingOptions); out.writeContinueIfRequired(6); out.writeShort(numberOfRuns); out.writeShort(phoneticText.length()); out.writeShort(phoneticText.length()); out.writeContinueIfRequired(phoneticText.length() * 2); StringUtil.putUnicodeLE(phoneticText, out); for (int i = 0; i < phRuns.length; i++) { phRuns[i].serialize(out); } out.write(extraData); }
public EmbeddedObjectRefSubRecord(LittleEndianInput in, int size) { // Much guess-work going on here due to lack of any documentation. // See similar source code in OOO: // http://svn.services.openoffice.org/ooo/trunk/sc/source/filter/excel/xiescher.cxx // 1223 void XclImpOleObj::ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nRecSize ) int streamIdOffset = in.readShort(); // OOO calls this 'nFmlaLen' int remaining = size - LittleEndian.SHORT_SIZE; int dataLenAfterFormula = remaining - streamIdOffset; int formulaSize = in.readUShort(); remaining -= LittleEndian.SHORT_SIZE; field_1_unknown_int = in.readInt(); remaining -= LittleEndian.INT_SIZE; byte[] formulaRawBytes = readRawData(in, formulaSize); remaining -= formulaSize; field_2_refPtg = readRefPtg(formulaRawBytes); if (field_2_refPtg == null) { // common case // field_2_n16 seems to be 5 here // The formula almost looks like tTbl but the row/column values seem like garbage. field_2_unknownFormulaData = formulaRawBytes; } else { field_2_unknownFormulaData = null; } int stringByteCount; if (remaining >= dataLenAfterFormula + 3) { int tag = in.readByte(); stringByteCount = LittleEndian.BYTE_SIZE; if (tag != 0x03) { throw new RecordFormatException("Expected byte 0x03 here"); } int nChars = in.readUShort(); stringByteCount += LittleEndian.SHORT_SIZE; if (nChars > 0) { // OOO: the 4th way Xcl stores a unicode string: not even a Grbit byte present if length 0 field_3_unicode_flag = (in.readByte() & 0x01) != 0; stringByteCount += LittleEndian.BYTE_SIZE; if (field_3_unicode_flag) { field_4_ole_classname = StringUtil.readUnicodeLE(in, nChars); stringByteCount += nChars * 2; } else { field_4_ole_classname = StringUtil.readCompressedUnicode(in, nChars); stringByteCount += nChars; } } else { field_4_ole_classname = ""; } } else { field_4_ole_classname = null; stringByteCount = 0; } remaining -= stringByteCount; // Pad to next 2-byte boundary if (((stringByteCount + formulaSize) % 2) != 0) { int b = in.readByte(); remaining -= LittleEndian.BYTE_SIZE; if (field_2_refPtg != null && field_4_ole_classname == null) { field_4_unknownByte = Byte.valueOf((byte) b); } } int nUnexpectedPadding = remaining - dataLenAfterFormula; if (nUnexpectedPadding > 0) { logger.log( POILogger.ERROR, "Discarding " + nUnexpectedPadding + " unexpected padding bytes "); readRawData(in, nUnexpectedPadding); remaining -= nUnexpectedPadding; } // Fetch the stream ID if (dataLenAfterFormula >= 4) { field_5_stream_id = Integer.valueOf(in.readInt()); remaining -= LittleEndian.INT_SIZE; } else { field_5_stream_id = null; } field_6_unknown = readRawData(in, remaining); }
public void serialize(LittleEndianOutput out) { int formulaSize = field_2_refPtg == null ? field_2_unknownFormulaData.length : field_2_refPtg.getSize(); int idOffset = getStreamIDOffset(formulaSize); int dataSize = getDataSize(idOffset); out.writeShort(sid); out.writeShort(dataSize); out.writeShort(idOffset); out.writeShort(formulaSize); out.writeInt(field_1_unknown_int); int pos = 12; if (field_2_refPtg == null) { out.write(field_2_unknownFormulaData); } else { field_2_refPtg.write(out); } pos += formulaSize; int stringLen; if (field_4_ole_classname == null) { // don't write 0x03, stringLen, flag, text stringLen = 0; } else { out.writeByte(0x03); pos += 1; stringLen = field_4_ole_classname.length(); out.writeShort(stringLen); pos += 2; if (stringLen > 0) { out.writeByte(field_3_unicode_flag ? 0x01 : 0x00); pos += 1; if (field_3_unicode_flag) { StringUtil.putUnicodeLE(field_4_ole_classname, out); pos += stringLen * 2; } else { StringUtil.putCompressedUnicode(field_4_ole_classname, out); pos += stringLen; } } } // pad to next 2-byte boundary (requires 0 or 1 bytes) switch (idOffset - (pos - 6)) { // 6 for 3 shorts: sid, dataSize, idOffset case 1: out.writeByte(field_4_unknownByte == null ? 0x00 : field_4_unknownByte.intValue()); pos++; case 0: break; default: throw new IllegalStateException("Bad padding calculation (" + idOffset + ", " + pos + ")"); } if (field_5_stream_id != null) { out.writeInt(field_5_stream_id.intValue()); pos += 4; } out.write(field_6_unknown); }
public HyperlinkRecord(RecordInputStream in) { _range = new CellRangeAddress(in); _guid = new GUID(in); /** * streamVersion (4 bytes): An unsigned integer that specifies the version number of the * serialization implementation used to save this structure. This value MUST equal 2. */ int streamVersion = in.readInt(); if (streamVersion != 0x00000002) { throw new RecordFormatException("Stream Version must be 0x2 but found " + streamVersion); } _linkOpts = in.readInt(); if ((_linkOpts & HLINK_LABEL) != 0) { int label_len = in.readInt(); _label = in.readUnicodeLEString(label_len); } if ((_linkOpts & HLINK_TARGET_FRAME) != 0) { int len = in.readInt(); _targetFrame = in.readUnicodeLEString(len); } if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) != 0) { _moniker = null; int nChars = in.readInt(); _address = in.readUnicodeLEString(nChars); } if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) == 0) { _moniker = new GUID(in); if (URL_MONIKER.equals(_moniker)) { int length = in.readInt(); /** * The value of <code>length<code> be either the byte size of the url field * (including the terminating NULL character) or the byte size of the url field plus 24. * If the value of this field is set to the byte size of the url field, * then the tail bytes fields are not present. */ int remaining = in.remaining(); if (length == remaining) { int nChars = length / 2; _address = in.readUnicodeLEString(nChars); } else { int nChars = (length - TAIL_SIZE) / 2; _address = in.readUnicodeLEString(nChars); /** * TODO: make sense of the remaining bytes According to the spec they consist of: 1. * 16-byte GUID: This field MUST equal {0xF4815879, 0x1D3B, 0x487F, 0xAF, 0x2C, 0x82, * 0x5D, 0xC4, 0x85, 0x27, 0x63} 2. Serial version, this field MUST equal 0 if present. 3. * URI Flags */ _uninterpretedTail = readTail(URL_TAIL, in); } } else if (FILE_MONIKER.equals(_moniker)) { _fileOpts = in.readShort(); int len = in.readInt(); _shortFilename = StringUtil.readCompressedUnicode(in, len); _uninterpretedTail = readTail(FILE_TAIL, in); int size = in.readInt(); if (size > 0) { int charDataSize = in.readInt(); // From the spec: An optional unsigned integer that MUST be 3 if present // but some files has 4 int usKeyValue = in.readUShort(); _address = StringUtil.readUnicodeLE(in, charDataSize / 2); } else { _address = null; } } else if (STD_MONIKER.equals(_moniker)) { _fileOpts = in.readShort(); int len = in.readInt(); byte[] path_bytes = new byte[len]; in.readFully(path_bytes); _address = new String(path_bytes); } } if ((_linkOpts & HLINK_PLACE) != 0) { int len = in.readInt(); _textMark = in.readUnicodeLEString(len); } if (in.remaining() > 0) { logger.log( POILogger.WARN, "Hyperlink data remains: " + in.remaining() + " : " + HexDump.toHex(in.readRemainder())); } }
/** Sets the string represented by this record. */ public void setString(String string) { _text = string; _is16bitUnicode = StringUtil.hasMultibyte(string); }
protected ExtRst(LittleEndianInput in, int expectedLength) { reserved = in.readShort(); // Old style detection (Reserved = 0xFF) if (reserved == -1) { populateEmpty(); return; } // Spot corrupt records if (reserved != 1) { System.err.println( "Warning - ExtRst was has wrong magic marker, expecting 1 but found " + reserved + " - ignoring"); // Grab all the remaining data, and ignore it for (int i = 0; i < expectedLength - 2; i++) { in.readByte(); } // And make us be empty populateEmpty(); return; } // Carry on reading in as normal short stringDataSize = in.readShort(); formattingFontIndex = in.readShort(); formattingOptions = in.readShort(); // RPHSSub numberOfRuns = in.readUShort(); short length1 = in.readShort(); // No really. Someone clearly forgot to read // the docs on their datastructure... short length2 = in.readShort(); // And sometimes they write out garbage :( if (length1 == 0 && length2 > 0) { length2 = 0; } if (length1 != length2) { throw new IllegalStateException( "The two length fields of the Phonetic Text don't agree! " + length1 + " vs " + length2); } phoneticText = StringUtil.readUnicodeLE(in, length1); int runData = stringDataSize - 4 - 6 - (2 * phoneticText.length()); int numRuns = (runData / 6); phRuns = new PhRun[numRuns]; for (int i = 0; i < phRuns.length; i++) { phRuns[i] = new PhRun(in); } int extraDataLength = runData - (numRuns * 6); if (extraDataLength < 0) { System.err.println("Warning - ExtRst overran by " + (0 - extraDataLength) + " bytes"); extraDataLength = 0; } extraData = new byte[extraDataLength]; for (int i = 0; i < extraData.length; i++) { extraData[i] = in.readByte(); } }