filters

record.cpp
1#include <qpro/common.h>
2
3#include <string.h>
4
5#include <iostream>
6
7#include <qpro/record.h>
8#include <qpro/formula.h>
9
10// -----------------------------------------------------------------------
11
12#include <iomanip>
13#include <sstream>
14
15void
16Charout(ostream& pOut, unsigned char pChar)
17{
18 pOut << ( (pChar<32) || (pChar>126) ? '.' : (char)pChar);
19}
20
21void
22Hexout(ostream& pOut, unsigned char pChar)
23{
24 pOut << setiosflags(ios::uppercase)
25 << setfill('0')
26 << setw(2)
27 << hex
28 << (int)pChar
29 << dec;
30}
31
32int
33Hexout(char* pChar, int pLen)
34{
35 std::ostringstream* lOStr = new std::ostringstream;
36
37 while( pLen )
38 {
39 int lIdx = 0;
40
41 for( lIdx=0; lIdx < 16; ++lIdx )
42 {
43 if( pLen )
44 {
45 Hexout(cerr, *pChar);
46 cerr << (lIdx==8 ? "-" : " ");
47 Charout(*lOStr, (unsigned char)*pChar);
48 ++pChar;
49 --pLen;
50 }
51 else
52 {
53 cerr << " ";
54 }
55 }
56
57 cerr << lOStr->rdbuf() << endl;
58
59 delete lOStr;
60 lOStr = new std::ostringstream;
61 }
62
63 delete lOStr;
64 lOStr = 0;
65
66 return 0;
67}
68
69// -----------------------------------------------------------------------
70
71QpRec::QpRec(QpRecType pType)
72 : cType( pType )
73{
74}
75
76QpRec::~QpRec()
77{
78}
79
80TQP_INT16
81QpRec::type()
82{
83 return cType;
84}
85
86// -----------------------------------------------------------------------
87//
88//
89//QpCellRef::QpCellRef(QpIStream& pIn)
90//{
91// pIn >> cNoteBook >> cColumn >> cPage >> cRow;
92//
93//TQP_DEBUG("CellRef: NoteBook" << cNoteBook << ", col "
94// << cColumn << ", Page " << (int)cPage << ", Row "
95// << cRow << endl
96// );
97//}
98//
99//QpCellRef::~QpCellRef()
100//{
101//}
102//
103//TQP_UINT8
104//QpCellRef::column()
105//{
106// return cColumn;
107//}
108//
109//TQP_INT16
110//QpCellRef::row()
111//{
112// return cRow;
113//}
114//
115// -----------------------------------------------------------------------
116
117QpRecCell::QpRecCell(QpRecType pType)
118 : QpRec(pType)
119 , cAttributes(0)
120 , cColumn(0)
121 , cPage(0)
122 , cRow(0)
123 , cCellRef(0)
124{
125}
126
127QpRecCell::~QpRecCell()
128{
129 delete [] cCellRef;
130 cCellRef = 0;
131}
132
133
134void
135QpRecCell::attributes(TQP_INT16 pAttributes)
136{
137 cAttributes = pAttributes;
138}
139
140TQP_INT16
141QpRecCell::attributes()
142{
143 return cAttributes;
144}
145
146void
147QpRecCell::column(TQP_UINT8 pColumn)
148{
149 cColumn = pColumn;
150}
151
152TQP_UINT8
153QpRecCell::column()
154{
155 return cColumn;
156}
157
158void
159QpRecCell::row(TQP_INT16 pRow)
160{
161 cRow = pRow;
162}
163
164TQP_INT16
165QpRecCell::row()
166{
167 return cRow;
168}
169
170int
171QpRecCell::loadCellInfo(QpIStream& pIn)
172{
173 pIn >> cColumn >> cPage >> cRow >> cAttributes;
174
175 TQP_DEBUG(" col " << (unsigned)cColumn << ", Page " << (unsigned)cPage
176 << ", Row " << cRow << ", Ref "
177 << /*???cellRef()
178 <<*/ ", Attr " << cAttributes
179 );
180
181 return 6; // number of bytes consumed
182}
183
184//const char*
185//QpRecCell::cellRef()
186//{
187// if( cCellRef == 0 )
188// {
189// cCellRef = new char[20]; // hardcoded len???
190//
192// cellRef( cCellRef, 0, 0, cColumn, cRow ); //hardcoded page no. ?????
193// }
194//
195// return cCellRef;
196//
197
198void
199QpRecCell::cellRef(char* pText, QpTableNames& pTable, TQP_INT16 /*pNoteBook*/, TQP_UINT8 pPage, TQP_UINT8 pColumn, TQP_INT16 pRow)
200{
201//??? cope with relative/absolute references
202
203 std::stringstream lOut(pText, ios::out);
204 int lPageRelative = pRow & 0x8000;
205 int lColRelative = pRow & 0x4000;
206 int lRowRelative = pRow & 0x2000;
207 TQP_UINT8 lCol = (lColRelative ? cColumn + pColumn : pColumn);
208
209 // Sign bit for row is in bit 0x1000, so either set all top bits or lose all top bits
210 TQP_INT16 lRow = (lRowRelative ? cRow + (pRow & 0x1000 ? pRow | 0xE000 : pRow & 0x1FFF)
211 : pRow & 0x1FFF
212 );
213
214 // Are we referencing a different page ?
215
216 if( lPageRelative && (pPage == 0) )
217 {
218 // no - page is zero relative to this one
219 }
220 else
221 if( pPage != cPage )
222 {
223 // yes - not relative & page is a different one
224
225 TQP_UINT8 lPage = ( lPageRelative ? pPage + cPage : pPage );
226
227 TQP_DEBUG("pTable.name((unsigned)lPage) = " << pTable.name((unsigned)lPage) << endl);
228
229 lOut << pTable.name((unsigned)lPage) << '!'; // is '!' compat with TQPRO???
230 }
231
232 if( !lColRelative )
233 {
234 lOut << '$';
235 }
236 if( lCol < 26 )
237 {
238 lOut << (char)('A' + lCol);
239 }
240 else
241 {
242 lOut << (char)('A' -1 + lCol / 26)
243 << (char)('A' + lCol % 26);
244 }
245
246 if( !lRowRelative )
247 {
248 lOut << '$';
249 }
250
251 lOut << (lRow & 0x1FFF) +1 << ends;
252}
253
254void
255QpRecCell::cellRef(char* pText, QpTableNames& pTable, QpIStream& pFormulaRef)
256{
257 TQP_INT16 lNoteBook;
258 pFormulaRef >> lNoteBook;
259
260 // block references (eg. A1..A9) have bit 0x1000 set
261
262 if( lNoteBook & 0x1000 )
263 {
264 TQP_UINT8 lFirstColumn;
265 TQP_UINT8 lFirstPage;
266 TQP_INT16 lFirstRow;
267 TQP_UINT8 lLastColumn;
268 TQP_UINT8 lLastPage;
269 TQP_INT16 lLastRow;
270
271 pFormulaRef >> lFirstColumn
272 >> lFirstPage
273 >> lFirstRow
274 >> lLastColumn
275 >> lLastPage
276 >> lLastRow;
277
278 TQP_DEBUG("BlockRef: NoteBook " << lNoteBook
279 << ", 1st col " << lFirstColumn
280 << ", 1st page " << (unsigned)lFirstPage
281 << ", 1st row " << lFirstRow
282 << ", last col " << lLastColumn
283 << ", last page " << (unsigned)lLastPage
284 << ", last row " << lLastRow
285 << endl
286 );
287// ??? next few lines shouldn't just add rows together
288 cellRef( pText, pTable, lNoteBook, lFirstPage, lFirstColumn, lFirstRow );
289// ?? temp next line strcat( pText, ".." );
290 strcat( pText, ":" );
291 cellRef( &pText[strlen(pText)], pTable, lNoteBook, lLastPage, lLastColumn, lLastRow );
292 }
293 else
294 {
295 TQP_UINT8 lColumn;
296 TQP_UINT8 lPage;
297 TQP_INT16 lRow;
298
299 pFormulaRef >> lColumn >> lPage >> lRow;
300
301 TQP_DEBUG("FormulaRef: NoteBook " << lNoteBook << ", Col " << (unsigned)lColumn
302 << ", Page " << (unsigned)lPage << ", Row " << lRow << endl
303 );
304
305// ??? sort out what to do about lNotebook
306// ??? next few lines shouldn't just add rows together
307 cellRef( pText, pTable, lNoteBook, lPage, lColumn, lRow );
308 }
309}
310
311// -----------------------------------------------------------------------
312
313QpRecBof::QpRecBof(TQP_INT16, QpIStream& pIn)
314 : QpRec( QpBof )
315{
316 pIn >> cFileFormat;
317
318 TQP_DEBUG("BOF fileformat=" << cFileFormat << endl);
319}
320
321QpRecBof::~QpRecBof()
322{
323}
324
325// -----------------------------------------------------------------------
326
327QpRecEof::QpRecEof(TQP_INT16, QpIStream&)
328 : QpRec( QpEof )
329{
330 TQP_DEBUG("EOF" << endl);
331}
332
333QpRecEof::~QpRecEof()
334{
335}
336
337
338// -----------------------------------------------------------------------
339
340QpRecRecalcMode::QpRecRecalcMode(TQP_INT16, QpIStream& pIn)
341 : QpRec( QpRecalcMode )
342{
343 TQP_INT8 lMode;
344
345 pIn >> lMode;
346
347 cMode = (MODE)(unsigned char) lMode;
348
349 TQP_DEBUG("Recalc Mode = "
350 << (int)lMode << ( cMode == Manual ? " (Manual)"
351 : cMode == Background ? " (Background)"
352 : cMode == Automatic ? " (Automatic)"
353 : " (Unknown)"
354 )
355 << endl
356 );
357}
358
359QpRecRecalcMode::~QpRecRecalcMode()
360{
361}
362
363
364void
365QpRecRecalcMode::mode(MODE pMode)
366{
367 cMode = pMode;
368}
369
370QpRecRecalcMode::MODE
371QpRecRecalcMode::mode()
372{
373 return cMode;
374}
375
376
377// -----------------------------------------------------------------------
378
379QpRecRecalcOrder::QpRecRecalcOrder(TQP_INT16, QpIStream& pIn)
380 : QpRec( QpRecalcOrder )
381{
382 TQP_INT8 lOrder;
383
384 pIn >> lOrder;
385
386 cOrder = (ORDER)(unsigned char) lOrder;
387
388 TQP_DEBUG("Recalc Order = "
389 << (int)lOrder << ( cOrder == Natural ? " (Natural)"
390 : cOrder == Column ? " (Column)"
391 : cOrder == Row ? " (Row)"
392 : " (Unknown)"
393 )
394 << endl
395 );
396}
397
398QpRecRecalcOrder::~QpRecRecalcOrder()
399{
400}
401
402
403void
404QpRecRecalcOrder::order(ORDER pOrder)
405{
406 cOrder = pOrder;
407}
408
409QpRecRecalcOrder::ORDER
410QpRecRecalcOrder::order()
411{
412 return cOrder;
413}
414
415
416// -----------------------------------------------------------------------
417
418QpRecEmptyCell::QpRecEmptyCell(TQP_INT16, QpIStream& pIn)
419 : QpRecCell( QpEmptyCell )
420{
421 TQP_DEBUG("Empty Cell - ");
422
423 loadCellInfo(pIn);
424
425 TQP_DEBUG(endl);
426}
427
428QpRecEmptyCell::~QpRecEmptyCell()
429{
430}
431
432
433// -----------------------------------------------------------------------
434
435QpRecIntegerCell::QpRecIntegerCell(TQP_INT16, QpIStream& pIn)
436 : QpRecCell( QpIntegerCell )
437{
438 TQP_DEBUG("Integer Cell - ");
439
440 loadCellInfo(pIn);
441
442 pIn >> cInt;
443
444 TQP_DEBUG(", Int " << cInt << endl);
445}
446
447QpRecIntegerCell::~QpRecIntegerCell()
448{
449}
450
451TQP_INT16
452QpRecIntegerCell::integer()
453{
454 return cInt;
455}
456
457// -----------------------------------------------------------------------
458
459QpRecFloatingPointCell::QpRecFloatingPointCell(TQP_INT16, QpIStream& pIn)
460 : QpRecCell( QpFloatingPointCell )
461{
462 TQP_DEBUG("Float Cell - ");
463
464 loadCellInfo(pIn);
465
466 pIn >> cValue;
467
468 TQP_DEBUG(", Value " << cValue << endl);
469}
470
471QpRecFloatingPointCell::~QpRecFloatingPointCell()
472{
473}
474
475TQP_INT64
476QpRecFloatingPointCell::value()
477{
478 return cValue;
479}
480
481// -----------------------------------------------------------------------
482
483QpRecLabelCell::QpRecLabelCell(TQP_INT16 pLen, QpIStream& pIn)
484 : QpRecCell( QpLabelCell )
485{
486 TQP_DEBUG("Label Cell - ");
487 int lLabelLen = pLen - loadCellInfo(pIn) - 1;
488
489 pIn >> cLabelPrefix;
490
491 cLabel = new char[lLabelLen];
492
493 pIn.read( cLabel, lLabelLen );
494
495 TQP_DEBUG(", Prefix " << cLabelPrefix << ", Label " << cLabel << endl);
496}
497
498QpRecLabelCell::~QpRecLabelCell()
499{
500 delete [] cLabel;
501 cLabel = 0;
502}
503
504char
505QpRecLabelCell::labelPrefix()
506{
507 return cLabelPrefix;
508}
509
510const char*
511QpRecLabelCell::label()
512{
513 return cLabel;
514}
515
516// -----------------------------------------------------------------------
517
518QpRecFormulaCell::QpRecFormulaCell(TQP_INT16 pLen, QpIStream& pIn)
519 : QpRecCell( QpFormulaCell )
520 , cFormula(0)
521{
522 TQP_DEBUG("Formula Cell - ");
523
524 int lFormulaLen = pLen - loadCellInfo(pIn);
525
526 pIn >> cLastValue;
527 lFormulaLen -= 8;
528
529 pIn >> cState;
530 lFormulaLen -= 2;
531
532 pIn >> cLen;
533 lFormulaLen -= 2;
534
535 pIn >> cCellRef;
536 lFormulaLen -= 2;
537
538 cFormula = new char[lFormulaLen];
539
540 pIn.read( cFormula, lFormulaLen );
541
542 TQP_DEBUG(", LastValue " << cLastValue << ", State " << cState << endl);
543 TQP_DEBUG(" FormulaLen " << cLen << ", CellRef " << cCellRef << ", Formula" << endl);
544#ifdef TQP_TRACE
545 Hexout( cFormula, lFormulaLen );
546#endif
547 TQP_DEBUG(endl);
548}
549
550QpRecFormulaCell::~QpRecFormulaCell()
551{
552 delete [] cFormula;
553 cFormula = 0;
554}
555
556const char*
557QpRecFormulaCell::formula()
558{
559 return cFormula;
560}
561
562TQP_INT16
563QpRecFormulaCell::formulaLen()
564{
565 return cLen;
566}
567
568TQP_INT16
569QpRecFormulaCell::formulaReferences()
570{
571 return cCellRef;
572}
573
574// -----------------------------------------------------------------------
575
576QpRecUnknown::QpRecUnknown(TQP_INT16 /*pType*/, TQP_INT16 pLen, QpIStream& pIn)
577 : QpRec( QpUnknown )
578{
579 TQP_DEBUG("Unknown Type " << pType << ", len " << pLen << endl);
580
581 if( pLen > 0 )
582 {
583 char* lBuf = new char[pLen];
584
585 pIn.read(lBuf, pLen);
586
587 delete [] lBuf;
588 lBuf = 0;
589 }
590}
591
592QpRecUnknown::~QpRecUnknown()
593{
594}
595
596// -----------------------------------------------------------------------
597
598QpRecBop::QpRecBop(TQP_INT16, QpIStream& pIn)
599 : QpRec( QpBop )
600{
601 pIn >> cPageIndex;
602 TQP_DEBUG("BOP: " << (unsigned)cPageIndex << endl);
603}
604
605QpRecBop::~QpRecBop()
606{
607}
608
609
610TQP_UINT8
611QpRecBop::pageIndex()
612{
613 return cPageIndex;
614}
615
616
617// -----------------------------------------------------------------------
618
619QpRecPageName::QpRecPageName(TQP_INT16, QpIStream& pIn)
620 : QpRec( QpPageName )
621{
622 pIn >> cPageName;
623
624 TQP_DEBUG("Page Name: " << cPageName << endl);
625}
626
627QpRecPageName::~QpRecPageName()
628{
629}
630
631const char*
632QpRecPageName::pageName()
633{
634 return cPageName;
635}
636// -----------------------------------------------------------------------
637
638QpRecPassword::QpRecPassword(TQP_INT16 pLen, QpIStream& pIn)
639 : QpRec( QpPassword )
640{
641 TQP_DEBUG("Password len = " << pLen << endl);
642
643 cPassword = new TQP_UINT8[pLen];
644
645 pIn.read( (char*)cPassword, pLen );
646
647 TQP_DEBUG("Password(Hex) = ");
648#ifdef TQP_TRACE
649 Hexout( (char*)cPassword, pLen );
650#endif
651 TQP_DEBUG(endl);
652}
653
654QpRecPassword::~QpRecPassword()
655{
656 delete [] cPassword;
657 cPassword = 0;
658}
659
660const TQP_UINT8*
661QpRecPassword::password()
662{
663 return cPassword;
664}
665
This class hold a column.
Definition column.h:38
This class hold a row.
Definition row.h:38