1 /
55
56
61 package org.apache.poi.hssf.record;
62
63 import java.util.Stack;
64 import java.util.List;
65
66 import org.apache.poi.util.LittleEndian;
67 import org.apache.poi.hssf.record.formula.*;
68
69
75
76 public class FormulaRecord
77 extends Record
78 implements CellValueRecordInterface, Comparable
79 {
80
81 public static final boolean EXPERIMENTAL_FORMULA_SUPPORT_ENABLED=false;
82
83 public static final short sid =
84 0x06;
85
86 private short field_1_row;
87 private short field_2_column;
88 private short field_3_xf;
89 private double field_4_value;
90 private short field_5_options;
91 private int field_6_zero;
92 private short field_7_expression_len;
93 private Stack field_8_parsed_expr;
94
95 private byte[] all_data;
96
97
98
99
100 public FormulaRecord()
101 {
102 field_8_parsed_expr = new Stack();
103 }
104
105
113
114 public FormulaRecord(short id, short size, byte [] data)
115 {
116 super(id, size, data);
117 }
118
119
128
129 public FormulaRecord(short id, short size, byte [] data, int offset)
130 {
131 super(id, size, data, offset);
132 }
133
134 protected void fillFields(byte [] data, short size, int offset)
135 {
136 if (EXPERIMENTAL_FORMULA_SUPPORT_ENABLED) {
137 field_1_row = LittleEndian.getShort(data, 0 + offset);
138 field_2_column = LittleEndian.getShort(data, 2 + offset);
139 field_3_xf = LittleEndian.getShort(data, 4 + offset);
140 field_4_value = LittleEndian.getDouble(data, 6 + offset);
141 field_5_options = LittleEndian.getShort(data, 14 + offset);
142 field_6_zero = LittleEndian.getInt(data, 16 + offset);
143 field_7_expression_len = LittleEndian.getShort(data, 20 + offset);
144 field_8_parsed_expr = getParsedExpressionTokens(data, size,
145 offset);
146
147 } else {
148 all_data = new byte[size+4];
149 LittleEndian.putShort(all_data,0,sid);
150 LittleEndian.putShort(all_data,2,size);
151 System.arraycopy(data,offset,all_data,4,size);
152 }
153
154 }
155
156 private Stack getParsedExpressionTokens(byte [] data, short size,
157 int offset)
158 {
159 Stack stack = new Stack();
160
169 return stack;
170 }
171
172 public void setRow(short row)
173 {
174 field_1_row = row;
175 }
176
177 public void setColumn(short column)
178 {
179 field_2_column = column;
180 }
181
182 public void setXFIndex(short xf)
183 {
184 field_3_xf = xf;
185 }
186
187
192
193 public void setValue(double value)
194 {
195 field_4_value = value;
196 }
197
198
203
204 public void setOptions(short options)
205 {
206 field_5_options = options;
207 }
208
209
213
214 public void setExpressionLength(short len)
215 {
216 field_7_expression_len = len;
217 }
218
219 public short getRow()
220 {
221 return field_1_row;
222 }
223
224 public short getColumn()
225 {
226 return field_2_column;
227 }
228
229 public short getXFIndex()
230 {
231 return field_3_xf;
232 }
233
234
239
240 public double getValue()
241 {
242 return field_4_value;
243 }
244
245
250
251 public short getOptions()
252 {
253 return field_5_options;
254 }
255
256
260
261 public short getExpressionLength()
262 {
263 return field_7_expression_len;
264 }
265
266
271
272 public void pushExpressionToken(Ptg ptg)
273 {
274 field_8_parsed_expr.push(ptg);
275 }
276
277
282
283 public Ptg popExpressionToken()
284 {
285 return ( Ptg ) field_8_parsed_expr.pop();
286 }
287
288
293
294 public Ptg peekExpressionToken()
295 {
296 return ( Ptg ) field_8_parsed_expr.peek();
297 }
298
299
303
304 public int getNumberOfExpressionTokens()
305 {
306 return field_8_parsed_expr.size();
307 }
308
309
314
315 public List getParsedExpression()
316 {
317 return ( List ) field_8_parsed_expr;
318 }
319
320
326
327 protected void validateSid(short id)
328 {
329 if (id != sid)
330 {
331 throw new RecordFormatException("NOT A FORMULA RECORD");
332 }
333 }
334
335 public short getSid()
336 {
337 return sid;
338 }
339
340
347
348 public int serialize(int offset, byte [] data)
349 {
350 if (EXPERIMENTAL_FORMULA_SUPPORT_ENABLED) {
351 int ptgSize = getTotalPtgSize();
352
353 LittleEndian.putShort(data, 0 + offset, sid);
354 LittleEndian.putShort(data, 2 + offset, ( short ) (24 + ptgSize));
355 LittleEndian.putShort(data, 4 + offset, getRow());
356 LittleEndian.putShort(data, 6 + offset, getColumn());
357 LittleEndian.putShort(data, 8 + offset, getXFIndex());
358 LittleEndian.putDouble(data, 10 + offset, getValue());
359 LittleEndian.putShort(data, 18 + offset, getOptions());
360 LittleEndian.putInt(data, 20 + offset, field_6_zero);
361 LittleEndian.putShort(data, 24 + offset, getExpressionLength());
362 } else {
363 System.arraycopy(all_data,0,data,offset,all_data.length);
364 }
365
366
367 return getRecordSize();
368 }
369
370 public int getRecordSize()
371 {
372 int retval =0;
373
374 if (EXPERIMENTAL_FORMULA_SUPPORT_ENABLED) {
375 retval = getTotalPtgSize() + 28;
376 } else {
377 retval =all_data.length;
378 }
379 return retval;
380
381
382 }
383
384 private int getTotalPtgSize()
385 {
386 List list = getParsedExpression();
387 int retval = 0;
388
389 for (int k = 0; k < list.size(); k++)
390 {
391 Ptg ptg = ( Ptg ) list.get(k);
392
393 retval += ptg.getSize();
394 }
395 return retval;
396 }
397
398 private void serializePtgs(byte [] data, int offset)
399 {
400 int pos = offset;
401
402 for (int k = 0; k < field_8_parsed_expr.size(); k++)
403 {
404 Ptg ptg = ( Ptg ) field_8_parsed_expr.get(k);
405
406 ptg.writeBytes(data, pos);
407 pos += ptg.getSize();
408 }
409 }
410
411 public boolean isBefore(CellValueRecordInterface i)
412 {
413 if (this.getRow() > i.getRow())
414 {
415 return false;
416 }
417 if ((this.getRow() == i.getRow())
418 && (this.getColumn() > i.getColumn()))
419 {
420 return false;
421 }
422 if ((this.getRow() == i.getRow())
423 && (this.getColumn() == i.getColumn()))
424 {
425 return false;
426 }
427 return true;
428 }
429
430 public boolean isAfter(CellValueRecordInterface i)
431 {
432 if (this.getRow() < i.getRow())
433 {
434 return false;
435 }
436 if ((this.getRow() == i.getRow())
437 && (this.getColumn() < i.getColumn()))
438 {
439 return false;
440 }
441 if ((this.getRow() == i.getRow())
442 && (this.getColumn() == i.getColumn()))
443 {
444 return false;
445 }
446 return true;
447 }
448
449 public boolean isEqual(CellValueRecordInterface i)
450 {
451 return ((this.getRow() == i.getRow())
452 && (this.getColumn() == i.getColumn()));
453 }
454
455 public boolean isInValueSection()
456 {
457 return true;
458 }
459
460 public boolean isValue()
461 {
462 return true;
463 }
464
465 public int compareTo(Object obj)
466 {
467 CellValueRecordInterface loc = ( CellValueRecordInterface ) obj;
468
469 if ((this.getRow() == loc.getRow())
470 && (this.getColumn() == loc.getColumn()))
471 {
472 return 0;
473 }
474 if (this.getRow() < loc.getRow())
475 {
476 return -1;
477 }
478 if (this.getRow() > loc.getRow())
479 {
480 return 1;
481 }
482 if (this.getColumn() < loc.getColumn())
483 {
484 return -1;
485 }
486 if (this.getColumn() > loc.getColumn())
487 {
488 return 1;
489 }
490 return -1;
491 }
492
493 public boolean equals(Object obj)
494 {
495 if (!(obj instanceof CellValueRecordInterface))
496 {
497 return false;
498 }
499 CellValueRecordInterface loc = ( CellValueRecordInterface ) obj;
500
501 if ((this.getRow() == loc.getRow())
502 && (this.getColumn() == loc.getColumn()))
503 {
504 return true;
505 }
506 return false;
507 }
508 }
509