00001 #include <qpro/common.h>
00002
00003 #include <string.h>
00004
00005 #include <iostream>
00006
00007 #include <qpro/record.h>
00008 #include <qpro/formula.h>
00009
00010
00011
00012 #include <iomanip>
00013 #include <strstream>
00014
00015 void
00016 Charout(ostream& pOut, unsigned char pChar)
00017 {
00018 pOut << ( (pChar<32) || (pChar>126) ? '.' : (char)pChar);
00019 }
00020
00021 void
00022 Hexout(ostream& pOut, unsigned char pChar)
00023 {
00024 pOut << setiosflags(ios::uppercase)
00025 << setfill('0')
00026 << setw(2)
00027 << hex
00028 << (int)pChar
00029 << dec;
00030 }
00031
00032 int
00033 Hexout(char* pChar, int pLen)
00034 {
00035 std::ostrstream* lOStr = new std::ostrstream;
00036
00037 while( pLen )
00038 {
00039 int lIdx = 0;
00040
00041 for( lIdx=0; lIdx < 16; ++lIdx )
00042 {
00043 if( pLen )
00044 {
00045 Hexout(cerr, *pChar);
00046 cerr << (lIdx==8 ? "-" : " ");
00047 Charout(*lOStr, (unsigned char)*pChar);
00048 ++pChar;
00049 --pLen;
00050 }
00051 else
00052 {
00053 cerr << " ";
00054 }
00055 }
00056
00057 cerr << lOStr->rdbuf() << endl;
00058
00059 delete lOStr;
00060 lOStr = new std::ostrstream;
00061 }
00062
00063 delete lOStr;
00064 lOStr = 0;
00065
00066 return 0;
00067 }
00068
00069
00070
00071 QpRec::QpRec(QpRecType pType)
00072 : cType( pType )
00073 {
00074 }
00075
00076 QpRec::~QpRec()
00077 {
00078 }
00079
00080 QP_INT16
00081 QpRec::type()
00082 {
00083 return cType;
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 QpRecCell::QpRecCell(QpRecType pType)
00118 : QpRec(pType)
00119 , cAttributes(0)
00120 , cColumn(0)
00121 , cPage(0)
00122 , cRow(0)
00123 , cCellRef(0)
00124 {
00125 }
00126
00127 QpRecCell::~QpRecCell()
00128 {
00129 delete [] cCellRef;
00130 cCellRef = 0;
00131 }
00132
00133
00134 void
00135 QpRecCell::attributes(QP_INT16 pAttributes)
00136 {
00137 cAttributes = pAttributes;
00138 }
00139
00140 QP_INT16
00141 QpRecCell::attributes()
00142 {
00143 return cAttributes;
00144 }
00145
00146 void
00147 QpRecCell::column(QP_UINT8 pColumn)
00148 {
00149 cColumn = pColumn;
00150 }
00151
00152 QP_UINT8
00153 QpRecCell::column()
00154 {
00155 return cColumn;
00156 }
00157
00158 void
00159 QpRecCell::row(QP_INT16 pRow)
00160 {
00161 cRow = pRow;
00162 }
00163
00164 QP_INT16
00165 QpRecCell::row()
00166 {
00167 return cRow;
00168 }
00169
00170 int
00171 QpRecCell::loadCellInfo(QpIStream& pIn)
00172 {
00173 pIn >> cColumn >> cPage >> cRow >> cAttributes;
00174
00175 QP_DEBUG(" col " << (unsigned)cColumn << ", Page " << (unsigned)cPage
00176 << ", Row " << cRow << ", Ref "
00177 <<
00178 ", Attr " << cAttributes
00179 );
00180
00181 return 6;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00192
00193
00194
00195
00196
00197
00198 void
00199 QpRecCell::cellRef(char* pText, QpTableNames& pTable, QP_INT16 , QP_UINT8 pPage, QP_UINT8 pColumn, QP_INT16 pRow)
00200 {
00201
00202
00203 std::strstream lOut(pText, 20, ios::out);
00204 int lPageRelative = pRow & 0x8000;
00205 int lColRelative = pRow & 0x4000;
00206 int lRowRelative = pRow & 0x2000;
00207 QP_UINT8 lCol = (lColRelative ? cColumn + pColumn : pColumn);
00208
00209
00210 QP_INT16 lRow = (lRowRelative ? cRow + (pRow & 0x1000 ? pRow | 0xE000 : pRow & 0x1FFF)
00211 : pRow & 0x1FFF
00212 );
00213
00214
00215
00216 if( lPageRelative && (pPage == 0) )
00217 {
00218
00219 }
00220 else
00221 if( pPage != cPage )
00222 {
00223
00224
00225 QP_UINT8 lPage = ( lPageRelative ? pPage + cPage : pPage );
00226
00227 QP_DEBUG("pTable.name((unsigned)lPage) = " << pTable.name((unsigned)lPage) << endl);
00228
00229 lOut << pTable.name((unsigned)lPage) << '!';
00230 }
00231
00232 if( !lColRelative )
00233 {
00234 lOut << '$';
00235 }
00236 if( lCol < 26 )
00237 {
00238 lOut << (char)('A' + lCol);
00239 }
00240 else
00241 {
00242 lOut << (char)('A' -1 + lCol / 26)
00243 << (char)('A' + lCol % 26);
00244 }
00245
00246 if( !lRowRelative )
00247 {
00248 lOut << '$';
00249 }
00250
00251 lOut << (lRow & 0x1FFF) +1 << ends;
00252 }
00253
00254 void
00255 QpRecCell::cellRef(char* pText, QpTableNames& pTable, QpIStream& pFormulaRef)
00256 {
00257 QP_INT16 lNoteBook;
00258 pFormulaRef >> lNoteBook;
00259
00260
00261
00262 if( lNoteBook & 0x1000 )
00263 {
00264 QP_UINT8 lFirstColumn;
00265 QP_UINT8 lFirstPage;
00266 QP_INT16 lFirstRow;
00267 QP_UINT8 lLastColumn;
00268 QP_UINT8 lLastPage;
00269 QP_INT16 lLastRow;
00270
00271 pFormulaRef >> lFirstColumn
00272 >> lFirstPage
00273 >> lFirstRow
00274 >> lLastColumn
00275 >> lLastPage
00276 >> lLastRow;
00277
00278 QP_DEBUG("BlockRef: NoteBook " << lNoteBook
00279 << ", 1st col " << lFirstColumn
00280 << ", 1st page " << (unsigned)lFirstPage
00281 << ", 1st row " << lFirstRow
00282 << ", last col " << lLastColumn
00283 << ", last page " << (unsigned)lLastPage
00284 << ", last row " << lLastRow
00285 << endl
00286 );
00287
00288 cellRef( pText, pTable, lNoteBook, lFirstPage, lFirstColumn, lFirstRow );
00289
00290 strcat( pText, ":" );
00291 cellRef( &pText[strlen(pText)], pTable, lNoteBook, lLastPage, lLastColumn, lLastRow );
00292 }
00293 else
00294 {
00295 QP_UINT8 lColumn;
00296 QP_UINT8 lPage;
00297 QP_INT16 lRow;
00298
00299 pFormulaRef >> lColumn >> lPage >> lRow;
00300
00301 QP_DEBUG("FormulaRef: NoteBook " << lNoteBook << ", Col " << (unsigned)lColumn
00302 << ", Page " << (unsigned)lPage << ", Row " << lRow << endl
00303 );
00304
00305
00306
00307 cellRef( pText, pTable, lNoteBook, lPage, lColumn, lRow );
00308 }
00309 }
00310
00311
00312
00313 QpRecBof::QpRecBof(QP_INT16, QpIStream& pIn)
00314 : QpRec( QpBof )
00315 {
00316 pIn >> cFileFormat;
00317
00318 QP_DEBUG("BOF fileformat=" << cFileFormat << endl);
00319 }
00320
00321 QpRecBof::~QpRecBof()
00322 {
00323 }
00324
00325
00326
00327 QpRecEof::QpRecEof(QP_INT16, QpIStream&)
00328 : QpRec( QpEof )
00329 {
00330 QP_DEBUG("EOF" << endl);
00331 }
00332
00333 QpRecEof::~QpRecEof()
00334 {
00335 }
00336
00337
00338
00339
00340 QpRecRecalcMode::QpRecRecalcMode(QP_INT16, QpIStream& pIn)
00341 : QpRec( QpRecalcMode )
00342 {
00343 QP_INT8 lMode;
00344
00345 pIn >> lMode;
00346
00347 cMode = (MODE)(unsigned char) lMode;
00348
00349 QP_DEBUG("Recalc Mode = "
00350 << (int)lMode << ( cMode == Manual ? " (Manual)"
00351 : cMode == Background ? " (Background)"
00352 : cMode == Automatic ? " (Automatic)"
00353 : " (Unknown)"
00354 )
00355 << endl
00356 );
00357 }
00358
00359 QpRecRecalcMode::~QpRecRecalcMode()
00360 {
00361 }
00362
00363
00364 void
00365 QpRecRecalcMode::mode(MODE pMode)
00366 {
00367 cMode = pMode;
00368 }
00369
00370 QpRecRecalcMode::MODE
00371 QpRecRecalcMode::mode()
00372 {
00373 return cMode;
00374 }
00375
00376
00377
00378
00379 QpRecRecalcOrder::QpRecRecalcOrder(QP_INT16, QpIStream& pIn)
00380 : QpRec( QpRecalcOrder )
00381 {
00382 QP_INT8 lOrder;
00383
00384 pIn >> lOrder;
00385
00386 cOrder = (ORDER)(unsigned char) lOrder;
00387
00388 QP_DEBUG("Recalc Order = "
00389 << (int)lOrder << ( cOrder == Natural ? " (Natural)"
00390 : cOrder == Column ? " (Column)"
00391 : cOrder == Row ? " (Row)"
00392 : " (Unknown)"
00393 )
00394 << endl
00395 );
00396 }
00397
00398 QpRecRecalcOrder::~QpRecRecalcOrder()
00399 {
00400 }
00401
00402
00403 void
00404 QpRecRecalcOrder::order(ORDER pOrder)
00405 {
00406 cOrder = pOrder;
00407 }
00408
00409 QpRecRecalcOrder::ORDER
00410 QpRecRecalcOrder::order()
00411 {
00412 return cOrder;
00413 }
00414
00415
00416
00417
00418 QpRecEmptyCell::QpRecEmptyCell(QP_INT16, QpIStream& pIn)
00419 : QpRecCell( QpEmptyCell )
00420 {
00421 QP_DEBUG("Empty Cell - ");
00422
00423 loadCellInfo(pIn);
00424
00425 QP_DEBUG(endl);
00426 }
00427
00428 QpRecEmptyCell::~QpRecEmptyCell()
00429 {
00430 }
00431
00432
00433
00434
00435 QpRecIntegerCell::QpRecIntegerCell(QP_INT16, QpIStream& pIn)
00436 : QpRecCell( QpIntegerCell )
00437 {
00438 QP_DEBUG("Integer Cell - ");
00439
00440 loadCellInfo(pIn);
00441
00442 pIn >> cInt;
00443
00444 QP_DEBUG(", Int " << cInt << endl);
00445 }
00446
00447 QpRecIntegerCell::~QpRecIntegerCell()
00448 {
00449 }
00450
00451 QP_INT16
00452 QpRecIntegerCell::integer()
00453 {
00454 return cInt;
00455 }
00456
00457
00458
00459 QpRecFloatingPointCell::QpRecFloatingPointCell(QP_INT16, QpIStream& pIn)
00460 : QpRecCell( QpFloatingPointCell )
00461 {
00462 QP_DEBUG("Float Cell - ");
00463
00464 loadCellInfo(pIn);
00465
00466 pIn >> cValue;
00467
00468 QP_DEBUG(", Value " << cValue << endl);
00469 }
00470
00471 QpRecFloatingPointCell::~QpRecFloatingPointCell()
00472 {
00473 }
00474
00475 QP_INT64
00476 QpRecFloatingPointCell::value()
00477 {
00478 return cValue;
00479 }
00480
00481
00482
00483 QpRecLabelCell::QpRecLabelCell(QP_INT16 pLen, QpIStream& pIn)
00484 : QpRecCell( QpLabelCell )
00485 {
00486 QP_DEBUG("Label Cell - ");
00487 int lLabelLen = pLen - loadCellInfo(pIn) - 1;
00488
00489 pIn >> cLabelPrefix;
00490
00491 cLabel = new char[lLabelLen];
00492
00493 pIn.read( cLabel, lLabelLen );
00494
00495 QP_DEBUG(", Prefix " << cLabelPrefix << ", Label " << cLabel << endl);
00496 }
00497
00498 QpRecLabelCell::~QpRecLabelCell()
00499 {
00500 delete [] cLabel;
00501 cLabel = 0;
00502 }
00503
00504 char
00505 QpRecLabelCell::labelPrefix()
00506 {
00507 return cLabelPrefix;
00508 }
00509
00510 const char*
00511 QpRecLabelCell::label()
00512 {
00513 return cLabel;
00514 }
00515
00516
00517
00518 QpRecFormulaCell::QpRecFormulaCell(QP_INT16 pLen, QpIStream& pIn)
00519 : QpRecCell( QpFormulaCell )
00520 , cFormula(0)
00521 {
00522 QP_DEBUG("Formula Cell - ");
00523
00524 int lFormulaLen = pLen - loadCellInfo(pIn);
00525
00526 pIn >> cLastValue;
00527 lFormulaLen -= 8;
00528
00529 pIn >> cState;
00530 lFormulaLen -= 2;
00531
00532 pIn >> cLen;
00533 lFormulaLen -= 2;
00534
00535 pIn >> cCellRef;
00536 lFormulaLen -= 2;
00537
00538 cFormula = new char[lFormulaLen];
00539
00540 pIn.read( cFormula, lFormulaLen );
00541
00542 QP_DEBUG(", LastValue " << cLastValue << ", State " << cState << endl);
00543 QP_DEBUG(" FormulaLen " << cLen << ", CellRef " << cCellRef << ", Formula" << endl);
00544 #ifdef QP_TRACE
00545 Hexout( cFormula, lFormulaLen );
00546 #endif
00547 QP_DEBUG(endl);
00548 }
00549
00550 QpRecFormulaCell::~QpRecFormulaCell()
00551 {
00552 delete [] cFormula;
00553 cFormula = 0;
00554 }
00555
00556 const char*
00557 QpRecFormulaCell::formula()
00558 {
00559 return cFormula;
00560 }
00561
00562 QP_INT16
00563 QpRecFormulaCell::formulaLen()
00564 {
00565 return cLen;
00566 }
00567
00568 QP_INT16
00569 QpRecFormulaCell::formulaReferences()
00570 {
00571 return cCellRef;
00572 }
00573
00574
00575
00576 QpRecUnknown::QpRecUnknown(QP_INT16 , QP_INT16 pLen, QpIStream& pIn)
00577 : QpRec( QpUnknown )
00578 {
00579 QP_DEBUG("Unknown Type " << pType << ", len " << pLen << endl);
00580
00581 if( pLen > 0 )
00582 {
00583 char* lBuf = new char[pLen];
00584
00585 pIn.read(lBuf, pLen);
00586
00587 delete [] lBuf;
00588 lBuf = 0;
00589 }
00590 }
00591
00592 QpRecUnknown::~QpRecUnknown()
00593 {
00594 }
00595
00596
00597
00598 QpRecBop::QpRecBop(QP_INT16, QpIStream& pIn)
00599 : QpRec( QpBop )
00600 {
00601 pIn >> cPageIndex;
00602 QP_DEBUG("BOP: " << (unsigned)cPageIndex << endl);
00603 }
00604
00605 QpRecBop::~QpRecBop()
00606 {
00607 }
00608
00609
00610 QP_UINT8
00611 QpRecBop::pageIndex()
00612 {
00613 return cPageIndex;
00614 }
00615
00616
00617
00618
00619 QpRecPageName::QpRecPageName(QP_INT16, QpIStream& pIn)
00620 : QpRec( QpPageName )
00621 {
00622 pIn >> cPageName;
00623
00624 QP_DEBUG("Page Name: " << cPageName << endl);
00625 }
00626
00627 QpRecPageName::~QpRecPageName()
00628 {
00629 }
00630
00631 const char*
00632 QpRecPageName::pageName()
00633 {
00634 return cPageName;
00635 }
00636
00637
00638 QpRecPassword::QpRecPassword(QP_INT16 pLen, QpIStream& pIn)
00639 : QpRec( QpPassword )
00640 {
00641 QP_DEBUG("Password len = " << pLen << endl);
00642
00643 cPassword = new QP_UINT8[pLen];
00644
00645 pIn.read( (char*)cPassword, pLen );
00646
00647 QP_DEBUG("Password(Hex) = ");
00648 #ifdef QP_TRACE
00649 Hexout( (char*)cPassword, pLen );
00650 #endif
00651 QP_DEBUG(endl);
00652 }
00653
00654 QpRecPassword::~QpRecPassword()
00655 {
00656 delete [] cPassword;
00657 cPassword = 0;
00658 }
00659
00660 const QP_UINT8*
00661 QpRecPassword::password()
00662 {
00663 return cPassword;
00664 }
00665