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:
022: /**
023: * Title: DBCell Record
024: * Description: Used by Excel and other MS apps to quickly find rows in the sheets.<P>
025: * REFERENCE: PG 299/440 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
026: * @author Andrew C. Oliver (acoliver at apache dot org)
027: * @author Jason Height
028: * @version 2.0-pre
029: */
030:
031: public class DBCellRecord extends Record {
032: public final static int BLOCK_SIZE = 32;
033: public final static short sid = 0xd7;
034: private int field_1_row_offset;
035: private short[] field_2_cell_offsets;
036:
037: public DBCellRecord() {
038: }
039:
040: /**
041: * Constructs a DBCellRecord and sets its fields appropriately
042: * @param in the RecordInputstream to read the record from
043: */
044:
045: public DBCellRecord(RecordInputStream in) {
046: super (in);
047: }
048:
049: protected void validateSid(short id) {
050: if (id != sid) {
051: throw new RecordFormatException("NOT A valid DBCell RECORD");
052: }
053: }
054:
055: protected void fillFields(RecordInputStream in) {
056: field_1_row_offset = in.readUShort();
057: int size = in.remaining();
058: field_2_cell_offsets = new short[size / 2];
059:
060: for (int i = 0; i < field_2_cell_offsets.length; i++) {
061: field_2_cell_offsets[i] = in.readShort();
062: }
063: }
064:
065: /**
066: * sets offset from the start of this DBCellRecord to the start of the first cell in
067: * the next DBCell block.
068: *
069: * @param offset offset to the start of the first cell in the next DBCell block
070: */
071:
072: public void setRowOffset(int offset) {
073: field_1_row_offset = offset;
074: }
075:
076: // need short list impl.
077: public void addCellOffset(short offset) {
078: if (field_2_cell_offsets == null) {
079: field_2_cell_offsets = new short[1];
080: } else {
081: short[] temp = new short[field_2_cell_offsets.length + 1];
082:
083: System.arraycopy(field_2_cell_offsets, 0, temp, 0,
084: field_2_cell_offsets.length);
085: field_2_cell_offsets = temp;
086: }
087: field_2_cell_offsets[field_2_cell_offsets.length - 1] = offset;
088: }
089:
090: /**
091: * gets offset from the start of this DBCellRecord to the start of the first cell in
092: * the next DBCell block.
093: *
094: * @return rowoffset to the start of the first cell in the next DBCell block
095: */
096:
097: public int getRowOffset() {
098: return field_1_row_offset;
099: }
100:
101: /**
102: * return the cell offset in the array
103: *
104: * @param index of the cell offset to retrieve
105: * @return celloffset from the celloffset array
106: */
107:
108: public short getCellOffsetAt(int index) {
109: return field_2_cell_offsets[index];
110: }
111:
112: /**
113: * get the number of cell offsets in the celloffset array
114: *
115: * @return number of cell offsets
116: */
117:
118: public int getNumCellOffsets() {
119: return field_2_cell_offsets.length;
120: }
121:
122: public String toString() {
123: StringBuffer buffer = new StringBuffer();
124:
125: buffer.append("[DBCELL]\n");
126: buffer.append(" .rowoffset = ").append(
127: Integer.toHexString(getRowOffset())).append("\n");
128: for (int k = 0; k < getNumCellOffsets(); k++) {
129: buffer.append(" .cell_" + k + " = ").append(
130: Integer.toHexString(getCellOffsetAt(k))).append(
131: "\n");
132: }
133: buffer.append("[/DBCELL]\n");
134: return buffer.toString();
135: }
136:
137: public int serialize(int offset, byte[] data) {
138: if (field_2_cell_offsets == null) {
139: field_2_cell_offsets = new short[0];
140: }
141: LittleEndian.putShort(data, 0 + offset, sid);
142: LittleEndian.putShort(data, 2 + offset,
143: ((short) (4 + (getNumCellOffsets() * 2))));
144: LittleEndian.putInt(data, 4 + offset, getRowOffset());
145: for (int k = 0; k < getNumCellOffsets(); k++) {
146: LittleEndian.putShort(data, 8 + 2 * k + offset,
147: getCellOffsetAt(k));
148: }
149: return getRecordSize();
150: }
151:
152: public int getRecordSize() {
153: return 8 + (getNumCellOffsets() * 2);
154: }
155:
156: /** Returns the size of a DBCellRecord when it needs to reference a certain number of rows*/
157: public static int getRecordSizeForRows(int rows) {
158: return 8 + (rows * 2);
159: }
160:
161: public short getSid() {
162: return sid;
163: }
164:
165: public boolean isInValueSection() {
166: return true;
167: }
168: }
|