1    
2    /* ====================================================================
3     * The Apache Software License, Version 1.1
4     *
5     * Copyright (c) 2002 The Apache Software Foundation.  All rights
6     * reserved.
7     *
8     * Redistribution and use in source and binary forms, with or without
9     * modification, are permitted provided that the following conditions
10    * are met:
11    *
12    * 1. Redistributions of source code must retain the above copyright
13    *    notice, this list of conditions and the following disclaimer.
14    *
15    * 2. Redistributions in binary form must reproduce the above copyright
16    *    notice, this list of conditions and the following disclaimer in
17    *    the documentation and/or other materials provided with the
18    *    distribution.
19    *
20    * 3. The end-user documentation included with the redistribution,
21    *    if any, must include the following acknowledgment:
22    *       "This product includes software developed by the
23    *        Apache Software Foundation (http://www.apache.org/)."
24    *    Alternately, this acknowledgment may appear in the software itself,
25    *    if and wherever such third-party acknowledgments normally appear.
26    *
27    * 4. The names "Apache" and "Apache Software Foundation" and
28    *    "Apache POI" must not be used to endorse or promote products
29    *    derived from this software without prior written permission. For
30    *    written permission, please contact apache@apache.org.
31    *
32    * 5. Products derived from this software may not be called "Apache",
33    *    "Apache POI", nor may "Apache" appear in their name, without
34    *    prior written permission of the Apache Software Foundation.
35    *
36    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47    * SUCH DAMAGE.
48    * ====================================================================
49    *
50    * This software consists of voluntary contributions made by many
51    * individuals on behalf of the Apache Software Foundation.  For more
52    * information on the Apache Software Foundation, please see
53    * <http://www.apache.org/>.
54    */
55   
56   /*
57    * NumberRecord.java
58    *
59    * Created on October 1, 2001, 8:01 PM
60    */
61   package org.apache.poi.hssf.record;
62   
63   import org.apache.poi.util.LittleEndian;
64   import org.apache.poi.hssf.record.Record;
65   
66   /**
67    * Contains a numeric cell value. <P>
68    * REFERENCE:  PG 334 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
69    * @author Andrew C. Oliver (acoliver at apache dot org)
70    * @author Jason Height (jheight at chariot dot net dot au)
71    * @version 2.0-pre
72    */
73   
74   public class NumberRecord
75       extends Record
76       implements CellValueRecordInterface, Comparable
77   {
78       public static final short sid = 0x203;
79       //private short             field_1_row;
80       private int             field_1_row;
81       private short             field_2_col;
82       private short             field_3_xf;
83       private double            field_4_value;
84   
85       /** Creates new NumberRecord */
86       public NumberRecord()
87       {
88       }
89   
90       /**
91        * Constructs a Number record and sets its fields appropriately.
92        *
93        * @param id     id must be 0x203 or an exception will be throw upon validation
94        * @param size  the size of the data area of the record
95        * @param data  data of the record (should not contain sid/len)
96        */
97   
98       public NumberRecord(short id, short size, byte [] data)
99       {
100          super(id, size, data);
101      }
102  
103      /**
104       * Constructs a Number record and sets its fields appropriately.
105       *
106       * @param id     id must be 0x203 or an exception will be throw upon validation
107       * @param size  the size of the data area of the record
108       * @param data  data of the record (should not contain sid/len)
109       * @param offset of the data
110       */
111  
112      public NumberRecord(short id, short size, byte [] data, int offset)
113      {
114          super(id, size, data, offset);
115      }
116  
117      /**
118       * called by the constructor, should set class level fields.  Should throw
119       * runtime exception for bad/icomplete data.
120       *
121       * @param data raw data
122       * @param size size of data
123       */
124  
125      protected void fillFields(byte [] data, short size, int offset)
126      {
127          //field_1_row   = LittleEndian.getShort(data, 0 + offset);
128          field_1_row   = LittleEndian.getUShort(data, 0 + offset);
129          field_2_col   = LittleEndian.getShort(data, 2 + offset);
130          field_3_xf    = LittleEndian.getShort(data, 4 + offset);
131          field_4_value = LittleEndian.getDouble(data, 6 + offset);
132      }
133  
134      //public void setRow(short row)
135      public void setRow(int row)
136      {
137          field_1_row = row;
138      }
139  
140      public void setColumn(short col)
141      {
142          field_2_col = col;
143      }
144  
145      /**
146       * set the index to the ExtendedFormat
147       * @see org.apache.poi.hssf.record.ExtendedFormatRecord
148       * @param xf  index to the XF record
149       */
150  
151      public void setXFIndex(short xf)
152      {
153          field_3_xf = xf;
154      }
155  
156      /**
157       * set the value for the cell
158       *
159       * @param value  double representing the value
160       */
161  
162      public void setValue(double value)
163      {
164          field_4_value = value;
165      }
166  
167      //public short getRow()
168      public int getRow()
169      {
170          return field_1_row;
171      }
172  
173      public short getColumn()
174      {
175          return field_2_col;
176      }
177  
178      /**
179       * get the index to the ExtendedFormat
180       * @see org.apache.poi.hssf.record.ExtendedFormatRecord
181       * @return index to the XF record
182       */
183  
184      public short getXFIndex()
185      {
186          return field_3_xf;
187      }
188  
189      /**
190       * get the value for the cell
191       *
192       * @return double representing the value
193       */
194  
195      public double getValue()
196      {
197          return field_4_value;
198      }
199  
200      public String toString()
201      {
202          StringBuffer buffer = new StringBuffer();
203  
204          buffer.append("[NUMBER]\n");
205          buffer.append("    .row            = ")
206              .append(Integer.toHexString(getRow())).append("\n");
207          buffer.append("    .col            = ")
208              .append(Integer.toHexString(getColumn())).append("\n");
209          buffer.append("    .xfindex        = ")
210              .append(Integer.toHexString(getXFIndex())).append("\n");
211          buffer.append("    .value          = ").append(getValue())
212              .append("\n");
213          buffer.append("[/NUMBER]\n");
214          return buffer.toString();
215      }
216  
217      /**
218       * called by the class that is responsible for writing this sucker.
219       * Subclasses should implement this so that their data is passed back in a
220       * byte array.
221       *
222       * @return byte array containing instance data
223       */
224  
225      public int serialize(int offset, byte [] data)
226      {
227          LittleEndian.putShort(data, 0 + offset, sid);
228          LittleEndian.putShort(data, 2 + offset, ( short ) 14);
229          //LittleEndian.putShort(data, 4 + offset, getRow());
230          LittleEndian.putShort(data, 4 + offset, ( short ) getRow());
231          LittleEndian.putShort(data, 6 + offset, getColumn());
232          LittleEndian.putShort(data, 8 + offset, getXFIndex());
233          LittleEndian.putDouble(data, 10 + offset, getValue());
234          return getRecordSize();
235      }
236  
237      public int getRecordSize()
238      {
239          return 18;
240      }
241  
242      /**
243       * called by constructor, should throw runtime exception in the event of a
244       * record passed with a differing ID.
245       *
246       * @param id alleged id for this record
247       */
248  
249      protected void validateSid(short id)
250      {
251          if (id != sid)
252          {
253              throw new RecordFormatException("NOT A Number RECORD");
254          }
255      }
256  
257      public short getSid()
258      {
259          return this.sid;
260      }
261  
262      public boolean isBefore(CellValueRecordInterface i)
263      {
264          if (this.getRow() > i.getRow())
265          {
266              return false;
267          }
268          if ((this.getRow() == i.getRow())
269                  && (this.getColumn() > i.getColumn()))
270          {
271              return false;
272          }
273          if ((this.getRow() == i.getRow())
274                  && (this.getColumn() == i.getColumn()))
275          {
276              return false;
277          }
278          return true;
279      }
280  
281      public boolean isAfter(CellValueRecordInterface i)
282      {
283          if (this.getRow() < i.getRow())
284          {
285              return false;
286          }
287          if ((this.getRow() == i.getRow())
288                  && (this.getColumn() < i.getColumn()))
289          {
290              return false;
291          }
292          if ((this.getRow() == i.getRow())
293                  && (this.getColumn() == i.getColumn()))
294          {
295              return false;
296          }
297          return true;
298      }
299  
300      public boolean isEqual(CellValueRecordInterface i)
301      {
302          return ((this.getRow() == i.getRow())
303                  && (this.getColumn() == i.getColumn()));
304      }
305  
306      public boolean isInValueSection()
307      {
308          return true;
309      }
310  
311      public boolean isValue()
312      {
313          return true;
314      }
315  
316      public int compareTo(Object obj)
317      {
318          CellValueRecordInterface loc = ( CellValueRecordInterface ) obj;
319  
320          if ((this.getRow() == loc.getRow())
321                  && (this.getColumn() == loc.getColumn()))
322          {
323              return 0;
324          }
325          if (this.getRow() < loc.getRow())
326          {
327              return -1;
328          }
329          if (this.getRow() > loc.getRow())
330          {
331              return 1;
332          }
333          if (this.getColumn() < loc.getColumn())
334          {
335              return -1;
336          }
337          if (this.getColumn() > loc.getColumn())
338          {
339              return 1;
340          }
341          return -1;
342      }
343  
344      public boolean equals(Object obj)
345      {
346          if (!(obj instanceof CellValueRecordInterface))
347          {
348              return false;
349          }
350          CellValueRecordInterface loc = ( CellValueRecordInterface ) obj;
351  
352          if ((this.getRow() == loc.getRow())
353                  && (this.getColumn() == loc.getColumn()))
354          {
355              return true;
356          }
357          return false;
358      }
359  
360      public Object clone() {
361        NumberRecord rec = new NumberRecord();
362        rec.field_1_row = field_1_row;
363        rec.field_2_col = field_2_col;
364        rec.field_3_xf = field_3_xf;
365        rec.field_4_value = field_4_value;
366        return rec;
367      }
368  }
369