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.hssf.record;
019:
020: import org.apache.poi.util.LittleEndian;
021: import org.apache.poi.util.StringUtil;
022:
023: /**
024: * Title: Footer Record <P>
025: * Description: Specifies the footer for a sheet<P>
026: * REFERENCE: PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
027: * @author Andrew C. Oliver (acoliver at apache dot org)
028: * @author Shawn Laubach (slaubach at apache dot org) Modified 3/14/02
029: * @author Jason Height (jheight at chariot dot net dot au)
030: * @version 2.0-pre
031: */
032:
033: public class FooterRecord extends Record {
034: public final static short sid = 0x15;
035: private byte field_1_footer_len;
036: private byte field_2_reserved;
037: private byte field_3_unicode_flag;
038: private String field_4_footer;
039:
040: public FooterRecord() {
041: }
042:
043: /**
044: * Constructs a FooterRecord record and sets its fields appropriately.
045: * @param in the RecordInputstream to read the record from
046: */
047:
048: public FooterRecord(RecordInputStream in) {
049: super (in);
050: }
051:
052: protected void validateSid(short id) {
053: if (id != sid) {
054: throw new RecordFormatException("NOT A FooterRECORD");
055: }
056: }
057:
058: protected void fillFields(RecordInputStream in) {
059: if (in.remaining() > 0) {
060: field_1_footer_len = in.readByte();
061: /** These two fields are a bit odd. They are not documented*/
062: field_2_reserved = in.readByte();
063: field_3_unicode_flag = in.readByte(); // unicode
064:
065: if (isMultibyte()) {
066: field_4_footer = in.readUnicodeLEString(LittleEndian
067: .ubyteToInt(field_1_footer_len));
068: } else {
069: field_4_footer = in.readCompressedUnicode(LittleEndian
070: .ubyteToInt(field_1_footer_len));
071: }
072: }
073: }
074:
075: /**
076: * see the unicode flag
077: *
078: * @return boolean flag
079: * true:footer string has at least one multibyte character
080: */
081: public boolean isMultibyte() {
082: return ((field_3_unicode_flag & 0xFF) == 1);
083: }
084:
085: /**
086: * set the length of the footer string
087: *
088: * @param len length of the footer string
089: * @see #setFooter(String)
090: */
091:
092: public void setFooterLength(byte len) {
093: field_1_footer_len = len;
094: }
095:
096: /**
097: * set the footer string
098: *
099: * @param footer string to display
100: * @see #setFooterLength(byte)
101: */
102:
103: public void setFooter(String footer) {
104: field_4_footer = footer;
105: field_3_unicode_flag = (byte) (StringUtil
106: .hasMultibyte(field_4_footer) ? 1 : 0);
107: }
108:
109: /**
110: * get the length of the footer string
111: *
112: * @return length of the footer string
113: * @see #getFooter()
114: */
115:
116: public short getFooterLength() {
117: return (short) (0xFF & field_1_footer_len); // [Shawn] Fixed needing unsigned byte
118: }
119:
120: /**
121: * get the footer string
122: *
123: * @return footer string to display
124: * @see #getFooterLength()
125: */
126:
127: public String getFooter() {
128: return field_4_footer;
129: }
130:
131: public String toString() {
132: StringBuffer buffer = new StringBuffer();
133:
134: buffer.append("[FOOTER]\n");
135: buffer.append(" .footerlen = ").append(
136: Integer.toHexString(getFooterLength())).append("\n");
137: buffer.append(" .footer = ").append(getFooter())
138: .append("\n");
139: buffer.append("[/FOOTER]\n");
140: return buffer.toString();
141: }
142:
143: public int serialize(int offset, byte[] data) {
144: int len = 4;
145:
146: if (getFooterLength() > 0) {
147: len += 3; // [Shawn] Fixed for two null bytes in the length
148: }
149: short bytelen = (short) (isMultibyte() ? getFooterLength() * 2
150: : getFooterLength());
151: LittleEndian.putShort(data, 0 + offset, sid);
152: LittleEndian.putShort(data, 2 + offset,
153: (short) ((len - 4) + bytelen));
154: if (getFooterLength() > 0) {
155: data[4 + offset] = (byte) getFooterLength();
156: data[6 + offset] = field_3_unicode_flag;
157: if (isMultibyte()) {
158: StringUtil.putUnicodeLE(getFooter(), data, 7 + offset);
159: } else {
160: StringUtil.putCompressedUnicode(getFooter(), data,
161: 7 + offset); // [Shawn] Place the string in the correct offset
162: }
163: }
164: return getRecordSize();
165: }
166:
167: public int getRecordSize() {
168: int retval = 4;
169:
170: if (getFooterLength() > 0) {
171: retval += 3; // [Shawn] Fixed for two null bytes in the length
172: }
173: return (isMultibyte() ? (retval + getFooterLength() * 2)
174: : (retval + getFooterLength()));
175: }
176:
177: public short getSid() {
178: return sid;
179: }
180:
181: public Object clone() {
182: FooterRecord rec = new FooterRecord();
183: rec.field_1_footer_len = field_1_footer_len;
184: rec.field_2_reserved = field_2_reserved;
185: rec.field_3_unicode_flag = field_3_unicode_flag;
186: rec.field_4_footer = field_4_footer;
187: return rec;
188: }
189: }
|