001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi.ddf;
019:
020: import org.apache.poi.hssf.record.RecordFormatException;
021: import org.apache.poi.util.HexDump;
022: import org.apache.poi.util.LittleEndian;
023:
024: /**
025: * Holds data from the parent application. Most commonly used to store
026: * text in the format of the parent application, rather than in
027: * Escher format. We don't attempt to understand the contents, since
028: * they will be in the parent's format, not Escher format.
029: *
030: * @author Glen Stampoultzis (glens at apache.org)
031: * @author Nick Burch (nick at torchbox dot com)
032: */
033: public class EscherTextboxRecord extends EscherRecord {
034: public static final short RECORD_ID = (short) 0xF00D;
035: public static final String RECORD_DESCRIPTION = "msofbtClientTextbox";
036:
037: private static final byte[] NO_BYTES = new byte[0];
038:
039: /** The data for this record not including the the 8 byte header */
040: private byte[] thedata = NO_BYTES;
041:
042: public EscherTextboxRecord() {
043: }
044:
045: /**
046: * This method deserializes the record from a byte array.
047: *
048: * @param data The byte array containing the escher record information
049: * @param offset The starting offset into <code>data</code>.
050: * @param recordFactory May be null since this is not a container record.
051: * @return The number of bytes read from the byte array.
052: */
053: public int fillFields(byte[] data, int offset,
054: EscherRecordFactory recordFactory) {
055: int bytesRemaining = readHeader(data, offset);
056:
057: // Save the data, ready for the calling code to do something
058: // useful with it
059: thedata = new byte[bytesRemaining];
060: System.arraycopy(data, offset + 8, thedata, 0, bytesRemaining);
061: return bytesRemaining + 8;
062: }
063:
064: /**
065: * Writes this record and any contained records to the supplied byte
066: * array.
067: *
068: * @return the number of bytes written.
069: */
070: public int serialize(int offset, byte[] data,
071: EscherSerializationListener listener) {
072: listener.beforeRecordSerialize(offset, getRecordId(), this );
073:
074: LittleEndian.putShort(data, offset, getOptions());
075: LittleEndian.putShort(data, offset + 2, getRecordId());
076: int remainingBytes = thedata.length;
077: LittleEndian.putInt(data, offset + 4, remainingBytes);
078: System.arraycopy(thedata, 0, data, offset + 8, thedata.length);
079: int pos = offset + 8 + thedata.length;
080:
081: listener.afterRecordSerialize(pos, getRecordId(), pos - offset,
082: this );
083: int size = pos - offset;
084: if (size != getRecordSize())
085: throw new RecordFormatException(size
086: + " bytes written but getRecordSize() reports "
087: + getRecordSize());
088: return size;
089: }
090:
091: /**
092: * Returns any extra data associated with this record. In practice excel
093: * does not seem to put anything here, but with PowerPoint this will
094: * contain the bytes that make up a TextHeaderAtom followed by a
095: * TextBytesAtom/TextCharsAtom
096: */
097: public byte[] getData() {
098: return thedata;
099: }
100:
101: /**
102: * Sets the extra data (in the parent application's format) to be
103: * contained by the record. Used when the parent application changes
104: * the contents.
105: */
106: public void setData(byte[] b, int start, int length) {
107: thedata = new byte[length];
108: System.arraycopy(b, start, thedata, 0, length);
109: }
110:
111: public void setData(byte[] b) {
112: setData(b, 0, b.length);
113: }
114:
115: /**
116: * Returns the number of bytes that are required to serialize this record.
117: *
118: * @return Number of bytes
119: */
120: public int getRecordSize() {
121: return 8 + thedata.length;
122: }
123:
124: public Object clone() {
125: // shallow clone
126: return super .clone();
127: }
128:
129: /**
130: * The short name for this record
131: */
132: public String getRecordName() {
133: return "ClientTextbox";
134: }
135:
136: public String toString() {
137: String nl = System.getProperty("line.separator");
138:
139: String theDumpHex = "";
140: try {
141: if (thedata.length != 0) {
142: theDumpHex = " Extra Data:" + nl;
143: theDumpHex += HexDump.dump(thedata, 0, 0);
144: }
145: } catch (Exception e) {
146: theDumpHex = "Error!!";
147: }
148:
149: return getClass().getName() + ":" + nl + " isContainer: "
150: + isContainerRecord() + nl + " options: 0x"
151: + HexDump.toHex(getOptions()) + nl + " recordId: 0x"
152: + HexDump.toHex(getRecordId()) + nl + " numchildren: "
153: + getChildRecords().size() + nl + theDumpHex;
154: }
155:
156: }
|