KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > poi > hssf > record > RKRecord


1
2 /* ====================================================================
3    Copyright 2002-2004 Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16 ==================================================================== */

17         
18
19 package org.apache.poi.hssf.record;
20
21 import org.apache.poi.util.LittleEndian;
22 import org.apache.poi.hssf.util.RKUtil;
23
24 /**
25  * Title: RK Record
26  * Description: An internal 32 bit number with the two most significant bits
27  * storing the type. This is part of a bizarre scheme to save disk
28  * space and memory (gee look at all the other whole records that
29  * are in the file just "cause"..,far better to waste processor
30  * cycles on this then leave on of those "valuable" records out).<P>
31  * We support this in READ-ONLY mode. HSSF converts these to NUMBER records<P>
32  *
33  *
34  *
35  * REFERENCE: PG 376 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
36  * @author Andrew C. Oliver (acoliver at apache dot org)
37  * @author Jason Height (jheight at chariot dot net dot au)
38  * @version 2.0-pre
39  * @see org.apache.poi.hssf.record.NumberRecord
40  */

41
42 public class RKRecord
43     extends Record
44     implements CellValueRecordInterface
45 {
46     public final static short sid = 0x27e;
47     public final static short RK_IEEE_NUMBER = 0;
48     public final static short RK_IEEE_NUMBER_TIMES_100 = 1;
49     public final static short RK_INTEGER = 2;
50     public final static short RK_INTEGER_TIMES_100 = 3;
51     //private short field_1_row;
52
private int field_1_row;
53     private short field_2_col;
54     private short field_3_xf_index;
55     private int field_4_rk_number;
56
57     public RKRecord()
58     {
59     }
60
61     /**
62      * Constructs a RK record and sets its fields appropriately.
63      *
64      * @param id id must be 0x27e or an exception will be throw upon validation
65      * @param size the size of the data area of the record
66      * @param data data of the record (should not contain sid/len)
67      */

68
69     public RKRecord(short id, short size, byte [] data)
70     {
71         super(id, size, data);
72     }
73
74     /**
75      * Constructs a RK record and sets its fields appropriately.
76      *
77      * @param id id must be 0x27e or an exception will be throw upon validation
78      * @param size the size of the data area of the record
79      * @param data data of the record (should not contain sid/len)
80      * @param offset of the data
81      */

82
83     public RKRecord(short id, short size, byte [] data, int offset)
84     {
85         super(id, size, data, offset);
86     }
87
88     protected void validateSid(short id)
89     {
90         if (id != sid)
91         {
92             throw new RecordFormatException("NOT A valid RK RECORD");
93         }
94     }
95
96     protected void fillFields(byte [] data, short size, int offset)
97     {
98         //field_1_row = LittleEndian.getShort(data, 0 + offset);
99
field_1_row = LittleEndian.getUShort(data, 0 + offset);
100         field_2_col = LittleEndian.getShort(data, 2 + offset);
101         field_3_xf_index = LittleEndian.getShort(data, 4 + offset);
102         field_4_rk_number = LittleEndian.getInt(data, 6 + offset);
103     }
104
105     //public short getRow()
106
public int getRow()
107     {
108         return field_1_row;
109     }
110
111     public short getColumn()
112     {
113         return field_2_col;
114     }
115
116     public short getXFIndex()
117     {
118         return field_3_xf_index;
119     }
120
121     public int getRKField()
122     {
123         return field_4_rk_number;
124     }
125
126     /**
127      * Get the type of the number
128      *
129      * @return one of these values:
130      * <OL START="0">
131      * <LI>RK_IEEE_NUMBER</LI>
132      * <LI>RK_IEEE_NUMBER_TIMES_100</LI>
133      * <LI>RK_INTEGER</LI>
134      * <LI>RK_INTEGER_TIMES_100</LI>
135      * </OL>
136      */

137
138     public short getRKType()
139     {
140         return ( short ) (field_4_rk_number & 3);
141     }
142
143     /**
144      * Extract the value of the number
145      * <P>
146      * The mechanism for determining the value is dependent on the two
147      * low order bits of the raw number. If bit 1 is set, the number
148      * is an integer and can be cast directly as a double, otherwise,
149      * it's apparently the exponent and mantissa of a double (and the
150      * remaining low-order bits of the double's mantissa are 0's).
151      * <P>
152      * If bit 0 is set, the result of the conversion to a double is
153      * divided by 100; otherwise, the value is left alone.
154      * <P>
155      * [insert picture of Screwy Squirrel in full Napoleonic regalia]
156      *
157      * @return the value as a proper double (hey, it <B>could</B>
158      * happen)
159      */

160
161     public double getRKNumber()
162     {
163         return RKUtil.decodeNumber(field_4_rk_number);
164     }
165
166
167     public String JavaDoc toString()
168     {
169         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
170
171         buffer.append("[RK]\n");
172         buffer.append(" .row = ")
173             .append(Integer.toHexString(getRow())).append("\n");
174         buffer.append(" .col = ")
175             .append(Integer.toHexString(getColumn())).append("\n");
176         buffer.append(" .xfindex = ")
177             .append(Integer.toHexString(getXFIndex())).append("\n");
178         buffer.append(" .rknumber = ")
179             .append(Integer.toHexString(getRKField())).append("\n");
180         buffer.append(" .rktype = ")
181             .append(Integer.toHexString(getRKType())).append("\n");
182         buffer.append(" .rknumber = ").append(getRKNumber())
183             .append("\n");
184         buffer.append("[/RK]\n");
185         return buffer.toString();
186     }
187
188 //temporarily just constructs a new number record and returns its value
189
public int serialize(int offset, byte [] data)
190     {
191         NumberRecord rec = new NumberRecord();
192
193         rec.setColumn(getColumn());
194         rec.setRow(getRow());
195         rec.setValue(getRKNumber());
196         rec.setXFIndex(getXFIndex());
197         return rec.serialize(offset, data);
198     }
199
200     /**
201      * Debugging main()
202      * <P>
203      * Normally I'd do this in a junit test, but let's face it -- once
204      * this algorithm has been tested and it works, we are never ever
205      * going to change it. This is driven by the Faceless Enemy's
206      * minions, who dare not change the algorithm out from under us.
207      *
208      * @param ignored_args command line arguments, which we blithely
209      * ignore
210      */

211
212     public static void main(String JavaDoc ignored_args[])
213     {
214         int[] values =
215         {
216             0x3FF00000, 0x405EC001, 0x02F1853A, 0x02F1853B, 0xFCDD699A
217         };
218         double[] rvalues =
219         {
220             1, 1.23, 12345678, 123456.78, -13149594
221         };
222
223         for (int j = 0; j < values.length; j++)
224         {
225             System.out.println("input = " + Integer.toHexString(values[ j ])
226                                + " -> " + rvalues[ j ] + ": "
227                                + RKUtil.decodeNumber(values[ j ]));
228         }
229     }
230
231     public short getSid()
232     {
233         return this.sid;
234     }
235
236     public boolean isBefore(CellValueRecordInterface i)
237     {
238         if (this.getRow() > i.getRow())
239         {
240             return false;
241         }
242         if ((this.getRow() == i.getRow())
243                 && (this.getColumn() > i.getColumn()))
244         {
245             return false;
246         }
247         if ((this.getRow() == i.getRow())
248                 && (this.getColumn() == i.getColumn()))
249         {
250             return false;
251         }
252         return true;
253     }
254
255     public boolean isAfter(CellValueRecordInterface i)
256     {
257         if (this.getRow() < i.getRow())
258         {
259             return false;
260         }
261         if ((this.getRow() == i.getRow())
262                 && (this.getColumn() < i.getColumn()))
263         {
264             return false;
265         }
266         if ((this.getRow() == i.getRow())
267                 && (this.getColumn() == i.getColumn()))
268         {
269             return false;
270         }
271         return true;
272     }
273
274     public boolean isEqual(CellValueRecordInterface i)
275     {
276         return ((this.getRow() == i.getRow())
277                 && (this.getColumn() == i.getColumn()));
278     }
279
280     public boolean isInValueSection()
281     {
282         return true;
283     }
284
285     public boolean isValue()
286     {
287         return true;
288     }
289
290     public void setColumn(short col)
291     {
292     }
293
294     //public void setRow(short row)
295
public void setRow(int row)
296     {
297     }
298
299     /**
300      * NO OP!
301      */

302
303     public void setXFIndex(short xf)
304     {
305     }
306
307     public Object JavaDoc clone() {
308       RKRecord rec = new RKRecord();
309       rec.field_1_row = field_1_row;
310       rec.field_2_col = field_2_col;
311       rec.field_3_xf_index = field_3_xf_index;
312       rec.field_4_rk_number = field_4_rk_number;
313       return rec;
314     }
315 }
316
Popular Tags