xref: /aoo41x/main/oox/source/dump/xlsbdumper.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "oox/dump/xlsbdumper.hxx"
29 
30 #include <com/sun/star/io/XTextInputStream.hpp>
31 #include "oox/core/filterbase.hxx"
32 #include "oox/dump/biffdumper.hxx"
33 #include "oox/dump/oledumper.hxx"
34 #include "oox/dump/pptxdumper.hxx"
35 #include "oox/helper/zipstorage.hxx"
36 #include "oox/ole/olestorage.hxx"
37 #include "oox/xls/biffhelper.hxx"
38 #include "oox/xls/formulabase.hxx"
39 #include "oox/xls/richstring.hxx"
40 
41 #if OOX_INCLUDE_DUMPER
42 
43 namespace oox {
44 namespace dump {
45 namespace xlsb {
46 
47 // ============================================================================
48 
49 using namespace ::com::sun::star::io;
50 using namespace ::com::sun::star::lang;
51 using namespace ::com::sun::star::uno;
52 using namespace ::com::sun::star::util;
53 using namespace ::oox::xls;
54 
55 using ::comphelper::MediaDescriptor;
56 using ::oox::core::FilterBase;
57 using ::rtl::OUString;
58 using ::rtl::OUStringBuffer;
59 
60 // ============================================================================
61 
62 namespace {
63 
64 const sal_uInt8 BIFF12_STRINGFLAG_FONTS         = 0x01;
65 const sal_uInt8 BIFF12_STRINGFLAG_PHONETICS     = 0x02;
66 
67 const sal_uInt16 BIFF12_OLEOBJECT_LINKED        = 0x0001;
68 
69 } // namespace
70 
71 // ============================================================================
72 
73 RecordObjectBase::RecordObjectBase()
74 {
75 }
76 
77 RecordObjectBase::~RecordObjectBase()
78 {
79 }
80 
81 void RecordObjectBase::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
82 {
83     mxBiffStrm.reset( new SequenceInputStream( getRecordDataSequence() ) );
84     SequenceRecordObjectBase::construct( rParent, rxStrm, rSysFileName, mxBiffStrm, "RECORD-NAMES", "SIMPLE-RECORDS" );
85     if( SequenceRecordObjectBase::implIsValid() )
86         mxErrCodes = cfg().getNameList( "ERRORCODES" );
87 }
88 
89 void RecordObjectBase::construct( const RecordObjectBase& rParent )
90 {
91     *this = rParent;
92 }
93 
94 bool RecordObjectBase::implReadRecordHeader( BinaryInputStream& rBaseStrm, sal_Int64& ornRecId, sal_Int64& ornRecSize )
95 {
96     sal_Int32 nRecId = 0, nRecSize = 0;
97     bool bValid = readCompressedInt( rBaseStrm, nRecId ) && (nRecId >= 0) && readCompressedInt( rBaseStrm, nRecSize ) && (nRecSize >= 0);
98     ornRecId = nRecId;
99     ornRecSize = nRecSize;
100     return bValid;
101 }
102 
103 OUString RecordObjectBase::getErrorName( sal_uInt8 nErrCode ) const
104 {
105     return cfg().getName( mxErrCodes, nErrCode );
106 }
107 
108 // ------------------------------------------------------------------------
109 
110 void RecordObjectBase::readAddress( Address& orAddress )
111 {
112     *mxStrm >> orAddress.mnRow >> orAddress.mnCol;
113 }
114 
115 void RecordObjectBase::readRange( Range& orRange )
116 {
117     *mxStrm >> orRange.maFirst.mnRow >> orRange.maLast.mnRow >> orRange.maFirst.mnCol >> orRange.maLast.mnCol;
118 }
119 
120 void RecordObjectBase::readRangeList( RangeList& orRanges )
121 {
122     sal_Int32 nCount;
123     *mxStrm >> nCount;
124     if( nCount >= 0 )
125     {
126         orRanges.resize( getLimitedValue< size_t, sal_Int32 >( nCount, 0, SAL_MAX_UINT16 ) );
127         for( RangeList::iterator aIt = orRanges.begin(), aEnd = orRanges.end(); !mxStrm->isEof() && (aIt != aEnd); ++aIt )
128             readRange( *aIt );
129     }
130     else
131         orRanges.clear();
132 }
133 
134 // ----------------------------------------------------------------------------
135 
136 void RecordObjectBase::writeBooleanItem( const String& rName, sal_uInt8 nBool )
137 {
138     writeDecItem( rName, nBool, "BOOLEAN" );
139 }
140 
141 void RecordObjectBase::writeErrorCodeItem( const String& rName, sal_uInt8 nErrCode )
142 {
143     writeHexItem( rName, nErrCode, mxErrCodes );
144 }
145 
146 void RecordObjectBase::writeFontPortions( const FontPortionModelList& rPortions )
147 {
148     if( !rPortions.empty() )
149     {
150         writeDecItem( "font-count", static_cast< sal_uInt32 >( rPortions.size() ) );
151         IndentGuard aIndGuard( mxOut );
152         TableGuard aTabGuard( mxOut, 14 );
153         for( FontPortionModelList::const_iterator aIt = rPortions.begin(), aEnd = rPortions.end(); aIt != aEnd; ++aIt )
154         {
155             MultiItemsGuard aMultiGuard( mxOut );
156             writeDecItem( "char-pos", aIt->mnPos );
157             writeDecItem( "font-id", aIt->mnFontId, "FONTNAMES" );
158         }
159     }
160 }
161 
162 void RecordObjectBase::writePhoneticPortions( const PhoneticPortionModelList& rPortions )
163 {
164     if( !rPortions.empty() )
165     {
166         writeDecItem( "portion-count", static_cast< sal_uInt32 >( rPortions.size() ) );
167         IndentGuard aIndGuard( mxOut );
168         TableGuard aTabGuard( mxOut, 14, 21 );
169         for( PhoneticPortionModelList::const_iterator aIt = rPortions.begin(), aEnd = rPortions.end(); aIt != aEnd; ++aIt )
170         {
171             MultiItemsGuard aMultiGuard( mxOut );
172             writeDecItem( "char-pos", aIt->mnPos );
173             writeDecItem( "base-text-start", aIt->mnBasePos );
174             writeDecItem( "base-text-length", aIt->mnBaseLen );
175         }
176     }
177 }
178 
179 // ----------------------------------------------------------------------------
180 
181 sal_uInt8 RecordObjectBase::dumpBoolean( const String& rName )
182 {
183     sal_uInt8 nBool;
184     *mxStrm >> nBool;
185     writeBooleanItem( rName( "boolean" ), nBool );
186     return nBool;
187 }
188 
189 sal_uInt8 RecordObjectBase::dumpErrorCode( const String& rName )
190 {
191     sal_uInt8 nErrCode;
192     *mxStrm >> nErrCode;
193     writeErrorCodeItem( rName( "error-code" ), nErrCode );
194     return nErrCode;
195 }
196 
197 OUString RecordObjectBase::dumpString( const String& rName, bool bRich, bool b32BitLen )
198 {
199     sal_uInt8 nFlags = bRich ? dumpHex< sal_uInt8 >( "flags", "STRING-FLAGS" ) : 0;
200 
201     OUString aString = BiffHelper::readString( *mxBiffStrm, b32BitLen );
202     writeStringItem( rName( "text" ), aString );
203 
204     // --- formatting ---
205     if( getFlag( nFlags, BIFF12_STRINGFLAG_FONTS ) )
206     {
207         IndentGuard aIndGuard( mxOut );
208         FontPortionModelList aPortions;
209         aPortions.importPortions( *mxBiffStrm );
210         writeFontPortions( aPortions );
211     }
212 
213     // --- phonetic text ---
214     if( getFlag( nFlags, BIFF12_STRINGFLAG_PHONETICS ) )
215     {
216         IndentGuard aIndGuard( mxOut );
217         dumpString( "phonetic-text" );
218         PhoneticPortionModelList aPortions;
219         aPortions.importPortions( *mxBiffStrm );
220         writePhoneticPortions( aPortions );
221         dumpDec< sal_uInt16 >( "font-id", "FONTNAMES" );
222         dumpHex< sal_uInt16 >( "flags", "PHONETIC-FLAGS" );
223     }
224 
225     return aString;
226 }
227 
228 void RecordObjectBase::dumpColor( const String& rName )
229 {
230     MultiItemsGuard aMultiGuard( mxOut );
231     writeEmptyItem( rName( "color" ) );
232     switch( extractValue< sal_uInt8 >( dumpDec< sal_uInt8 >( "flags", "COLOR-FLAGS" ), 1, 7 ) )
233     {
234         case 0:     dumpUnused( 1 );                                    break;
235         case 1:     dumpDec< sal_uInt8 >( "index", "PALETTE-COLORS" );  break;
236         case 2:     dumpUnused( 1 );                                    break;
237         case 3:     dumpDec< sal_uInt8 >( "theme-id" );                 break;
238         default:    dumpUnknown( 1 );
239     }
240     dumpDec< sal_Int16 >( "tint", "CONV-TINT" );
241     dumpColorABGR();
242 }
243 
244 DateTime RecordObjectBase::dumpPivotDateTime( const String& rName )
245 {
246     DateTime aDateTime;
247     aDateTime.Year = mxStrm->readuInt16();
248     aDateTime.Month = mxStrm->readuInt16();
249     aDateTime.Day = mxStrm->readuInt8();
250     aDateTime.Hours = mxStrm->readuInt8();
251     aDateTime.Minutes = mxStrm->readuInt8();
252     aDateTime.Seconds = mxStrm->readuInt8();
253     writeDateTimeItem( rName, aDateTime );
254     return aDateTime;
255 }
256 
257 sal_Int32 RecordObjectBase::dumpColIndex( const String& rName )
258 {
259     sal_Int32 nCol;
260     *mxStrm >> nCol;
261     writeColIndexItem( rName( "col-idx" ), nCol );
262     return nCol;
263 }
264 
265 sal_Int32 RecordObjectBase::dumpRowIndex( const String& rName )
266 {
267     sal_Int32 nRow;
268     *mxStrm >> nRow;
269     writeRowIndexItem( rName( "row-idx" ), nRow );
270     return nRow;
271 }
272 
273 sal_Int32 RecordObjectBase::dumpColRange( const String& rName )
274 {
275     sal_Int32 nCol1, nCol2;
276     *mxStrm >> nCol1 >> nCol2;
277     writeColRangeItem( rName( "col-range" ), nCol1, nCol2 );
278     return nCol2 - nCol1 + 1;
279 }
280 
281 sal_Int32 RecordObjectBase::dumpRowRange( const String& rName )
282 {
283     sal_Int32 nRow1, nRow2;
284     *mxStrm >> nRow1 >> nRow2;
285     writeRowRangeItem( rName( "row-range" ), nRow1, nRow2 );
286     return nRow2 - nRow1 + 1;
287 }
288 
289 Address RecordObjectBase::dumpAddress( const String& rName )
290 {
291     Address aPos;
292     readAddress( aPos );
293     writeAddressItem( rName( "addr" ), aPos );
294     return aPos;
295 }
296 
297 Range RecordObjectBase::dumpRange( const String& rName )
298 {
299     Range aRange;
300     readRange( aRange );
301     writeRangeItem( rName( "range" ), aRange );
302     return aRange;
303 }
304 
305 void RecordObjectBase::dumpRangeList( const String& rName )
306 {
307     RangeList aRanges;
308     readRangeList( aRanges );
309     writeRangeListItem( rName( "range-list" ), aRanges );
310 }
311 
312 // private --------------------------------------------------------------------
313 
314 bool RecordObjectBase::readCompressedInt( BinaryInputStream& rStrm, sal_Int32& ornValue )
315 {
316     ornValue = 0;
317     sal_uInt8 nByte;
318     rStrm >> nByte;
319     ornValue = nByte & 0x7F;
320     if( (nByte & 0x80) != 0 )
321     {
322         rStrm >> nByte;
323         ornValue |= sal_Int32( nByte & 0x7F ) << 7;
324         if( (nByte & 0x80) != 0 )
325         {
326             rStrm >> nByte;
327             ornValue |= sal_Int32( nByte & 0x7F ) << 14;
328             if( (nByte & 0x80) != 0 )
329             {
330                 rStrm >> nByte;
331                 ornValue |= sal_Int32( nByte & 0x7F ) << 21;
332             }
333         }
334     }
335     return !rStrm.isEof();
336 }
337 
338 // ============================================================================
339 
340 FormulaObject::FormulaObject( const RecordObjectBase& rParent ) :
341     mnSize( 0 )
342 {
343     RecordObjectBase::construct( rParent );
344     constructFmlaObj();
345 }
346 
347 FormulaObject::~FormulaObject()
348 {
349 }
350 
351 void FormulaObject::dumpCellFormula( const String& rName )
352 {
353     dumpFormula( rName, false );
354 }
355 
356 void FormulaObject::dumpNameFormula( const String& rName )
357 {
358     dumpFormula( rName, true );
359 }
360 
361 void FormulaObject::implDump()
362 {
363     {
364         MultiItemsGuard aMultiGuard( mxOut );
365         writeEmptyItem( maName );
366         writeDecItem( "formula-size", mnSize );
367     }
368     if( mnSize < 0 ) return;
369 
370     sal_Int64 nStartPos = mxStrm->tell();
371     sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->size() );
372 
373     bool bValid = mxTokens.get();
374     mxStack.reset( new FormulaStack );
375     maAddData.clear();
376     IndentGuard aIndGuard( mxOut );
377     {
378         TableGuard aTabGuard( mxOut, 8, 18 );
379         while( bValid && (mxStrm->tell() < nEndPos) )
380         {
381             MultiItemsGuard aMultiGuard( mxOut );
382             writeHexItem( EMPTY_STRING, static_cast< sal_uInt16 >( mxStrm->tell() - nStartPos ) );
383             sal_uInt8 nTokenId = dumpHex< sal_uInt8 >( EMPTY_STRING, mxTokens );
384             bValid = mxTokens->hasName( nTokenId );
385             if( bValid )
386             {
387                 sal_uInt8 nTokClass = nTokenId & BIFF_TOKCLASS_MASK;
388                 sal_uInt8 nBaseId = nTokenId & BIFF_TOKID_MASK;
389                 if( nTokClass == BIFF_TOKCLASS_NONE )
390                 {
391                     switch( nBaseId )
392                     {
393                         case BIFF_TOKID_EXP:        dumpExpToken( "EXP" );          break;
394                         case BIFF_TOKID_ADD:        dumpBinaryOpToken( "+" );       break;
395                         case BIFF_TOKID_SUB:        dumpBinaryOpToken( "-" );       break;
396                         case BIFF_TOKID_MUL:        dumpBinaryOpToken( "*" );       break;
397                         case BIFF_TOKID_DIV:        dumpBinaryOpToken( "/" );       break;
398                         case BIFF_TOKID_POWER:      dumpBinaryOpToken( "^" );       break;
399                         case BIFF_TOKID_CONCAT:     dumpBinaryOpToken( "&" );       break;
400                         case BIFF_TOKID_LT:         dumpBinaryOpToken( "<" );       break;
401                         case BIFF_TOKID_LE:         dumpBinaryOpToken( "<=" );      break;
402                         case BIFF_TOKID_EQ:         dumpBinaryOpToken( "=" );       break;
403                         case BIFF_TOKID_GE:         dumpBinaryOpToken( ">=" );      break;
404                         case BIFF_TOKID_GT:         dumpBinaryOpToken( "<" );       break;
405                         case BIFF_TOKID_NE:         dumpBinaryOpToken( "<>" );      break;
406                         case BIFF_TOKID_ISECT:      dumpBinaryOpToken( " " );       break;
407                         case BIFF_TOKID_LIST:       dumpBinaryOpToken( "," );       break;
408                         case BIFF_TOKID_RANGE:      dumpBinaryOpToken( ":" );       break;
409                         case BIFF_TOKID_UPLUS:      dumpUnaryOpToken( "+", "" );    break;
410                         case BIFF_TOKID_UMINUS:     dumpUnaryOpToken( "-", "" );    break;
411                         case BIFF_TOKID_PERCENT:    dumpUnaryOpToken( "", "%" );    break;
412                         case BIFF_TOKID_PAREN:      dumpUnaryOpToken( "(", ")" );   break;
413                         case BIFF_TOKID_MISSARG:    dumpMissArgToken();             break;
414                         case BIFF_TOKID_STR:        dumpStringToken();              break;
415                         case BIFF_TOKID_NLR:        bValid = dumpTableToken();      break;
416                         case BIFF_TOKID_ATTR:       bValid = dumpAttrToken();       break;
417                         case BIFF_TOKID_ERR:        dumpErrorToken();               break;
418                         case BIFF_TOKID_BOOL:       dumpBoolToken();                break;
419                         case BIFF_TOKID_INT:        dumpIntToken();                 break;
420                         case BIFF_TOKID_NUM:        dumpDoubleToken();              break;
421                         default:                    bValid = false;
422                     }
423                 }
424                 else
425                 {
426                     OUString aTokClass = cfg().getName( mxClasses, nTokClass );
427                     switch( nBaseId )
428                     {
429                         case BIFF_TOKID_ARRAY:      dumpArrayToken( aTokClass );                break;
430                         case BIFF_TOKID_FUNC:       dumpFuncToken( aTokClass );                 break;
431                         case BIFF_TOKID_FUNCVAR:    dumpFuncVarToken( aTokClass );              break;
432                         case BIFF_TOKID_NAME:       dumpNameToken( aTokClass );                 break;
433                         case BIFF_TOKID_REF:        dumpRefToken( aTokClass, false );           break;
434                         case BIFF_TOKID_AREA:       dumpAreaToken( aTokClass, false );          break;
435                         case BIFF_TOKID_MEMAREA:    dumpMemAreaToken( aTokClass, true );        break;
436                         case BIFF_TOKID_MEMERR:     dumpMemAreaToken( aTokClass, false );       break;
437                         case BIFF_TOKID_MEMNOMEM:   dumpMemAreaToken( aTokClass, false );       break;
438                         case BIFF_TOKID_MEMFUNC:    dumpMemFuncToken( aTokClass );              break;
439                         case BIFF_TOKID_REFERR:     dumpRefErrToken( aTokClass, false );        break;
440                         case BIFF_TOKID_AREAERR:    dumpRefErrToken( aTokClass, true );         break;
441                         case BIFF_TOKID_REFN:       dumpRefToken( aTokClass, true );            break;
442                         case BIFF_TOKID_AREAN:      dumpAreaToken( aTokClass, true );           break;
443                         case BIFF_TOKID_MEMAREAN:   dumpMemFuncToken( aTokClass );              break;
444                         case BIFF_TOKID_MEMNOMEMN:  dumpMemFuncToken( aTokClass );              break;
445                         case BIFF_TOKID_NAMEX:      dumpNameXToken( aTokClass );                break;
446                         case BIFF_TOKID_REF3D:      dumpRef3dToken( aTokClass, mbNameMode );    break;
447                         case BIFF_TOKID_AREA3D:     dumpArea3dToken( aTokClass, mbNameMode );   break;
448                         case BIFF_TOKID_REFERR3D:   dumpRefErr3dToken( aTokClass, false );      break;
449                         case BIFF_TOKID_AREAERR3D:  dumpRefErr3dToken( aTokClass, true );       break;
450                         default:                    bValid = false;
451                     }
452                 }
453             }
454         }
455     }
456 
457     if( nEndPos == mxStrm->tell() )
458     {
459         dumpAddTokenData();
460         if( mnSize > 0 )
461         {
462             writeInfoItem( "formula", mxStack->getFormulaString() );
463             writeInfoItem( "classes", mxStack->getClassesString() );
464         }
465     }
466     else
467     {
468         dumpBinary( OOX_DUMP_ERRASCII( "formula-error" ), static_cast< sal_Int32 >( nEndPos - mxStrm->tell() ), false );
469         sal_Int32 nAddDataSize = dumpDec< sal_Int32 >( "add-data-size" );
470         dumpBinary( "add-data", nAddDataSize, false );
471     }
472 
473     mnSize = 0;
474 }
475 
476 void FormulaObject::dumpFormula( const String& rName, bool bNameMode )
477 {
478     maName = rName( "formula" );
479     *mxStrm >> mnSize;
480     mbNameMode = bNameMode;
481     dump();
482 }
483 
484 // private --------------------------------------------------------------------
485 
486 void FormulaObject::constructFmlaObj()
487 {
488     if( RecordObjectBase::implIsValid() )
489     {
490         mxFuncProv.reset( new FunctionProvider( FILTER_OOXML, BIFF_UNKNOWN, true ) );
491 
492         Config& rCfg = cfg();
493         mxClasses   = rCfg.getNameList( "TOKENCLASSES" );
494         mxRelFlags  = rCfg.getNameList( "REFRELFLAGS" );
495         mxAttrTypes = rCfg.getNameList( "ATTRTYPES" );
496         mxSpTypes   = rCfg.getNameList( "ATTRSPACETYPES" );
497 
498         // create classified token names
499         mxTokens = rCfg.createNameList< ConstList >( "TOKENS" );
500         mxTokens->includeList( rCfg.getNameList( "BASETOKENS" ) );
501 
502         NameListRef xClassTokens = rCfg.getNameList( "CLASSTOKENS" );
503         if( mxClasses.get() && xClassTokens.get() )
504             for( NameListBase::const_iterator aCIt = mxClasses->begin(), aCEnd = mxClasses->end(); aCIt != aCEnd; ++aCIt )
505                 for( NameListBase::const_iterator aTIt = xClassTokens->begin(), aTEnd = xClassTokens->end(); aTIt != aTEnd; ++aTIt )
506                     mxTokens->setName( aCIt->first | aTIt->first, aTIt->second + aCIt->second );
507 
508         mnColCount = 16384;
509         mnRowCount = 1024 * 1024;
510     }
511 }
512 
513 // ----------------------------------------------------------------------------
514 
515 namespace {
516 
517 OUString lclCreateName( const OUString& rRef, sal_Int32 nNameId )
518 {
519     OUStringBuffer aName( rRef );
520     StringHelper::appendIndexedText( aName, CREATE_OUSTRING( "NAME" ), nNameId );
521     return aName.makeStringAndClear();
522 }
523 
524 } // namespace
525 
526 // ----------------------------------------------------------------------------
527 
528 TokenAddress FormulaObject::createTokenAddress( sal_Int32 nCol, sal_Int32 nRow, bool bRelC, bool bRelR, bool bNameMode ) const
529 {
530     TokenAddress aPos;
531     aPos.mnCol = nCol;
532     if( bRelC && bNameMode && (nCol >= mnColCount / 2) ) aPos.mnCol -= mnColCount;
533     aPos.mbRelCol = bRelC;
534     aPos.mnRow = nRow;
535     if( bRelR && bNameMode && (nRow >= mnRowCount / 2) ) aPos.mnRow -= mnRowCount;
536     aPos.mbRelRow = bRelR;
537     return aPos;
538 }
539 
540 OUString FormulaObject::createRef( const OUString& rData ) const
541 {
542     return maRefPrefix + rData;
543 }
544 
545 OUString FormulaObject::createName( sal_Int32 nNameId ) const
546 {
547     return lclCreateName( maRefPrefix, nNameId );
548 }
549 
550 OUString FormulaObject::createPlaceHolder( size_t nIdx ) const
551 {
552     OUStringBuffer aStr;
553     StringHelper::appendDec( aStr, static_cast< sal_uInt32 >( nIdx ) );
554     StringHelper::enclose( aStr, OOX_DUMP_PLACEHOLDER );
555     return aStr.makeStringAndClear();
556 }
557 
558 OUString FormulaObject::createPlaceHolder() const
559 {
560     return createPlaceHolder( maAddData.size() );
561 }
562 
563 OUString FormulaObject::writeFuncIdItem( sal_uInt16 nFuncId, const FunctionInfo** oppFuncInfo )
564 {
565     ItemGuard aItem( mxOut, "func-id" );
566     writeHexItem( EMPTY_STRING, nFuncId, "FUNCID" );
567     OUStringBuffer aBuffer;
568     const FunctionInfo* pFuncInfo = mxFuncProv->getFuncInfoFromBiff12FuncId( nFuncId );
569     if( pFuncInfo )
570         aBuffer.append( pFuncInfo->maOoxFuncName );
571     else
572     {
573         bool bCmd = getFlag( nFuncId, BIFF_TOK_FUNCVAR_CMD );
574         aBuffer.appendAscii( bCmd ? "CMD" : "FUNC" );
575         StringHelper::appendIndex( aBuffer, nFuncId & BIFF_TOK_FUNCVAR_FUNCIDMASK );
576     }
577     OUString aFuncName = aBuffer.makeStringAndClear();
578     aItem.cont();
579     mxOut->writeChar( OOX_DUMP_STRQUOTE );
580     mxOut->writeString( aFuncName );
581     mxOut->writeChar( OOX_DUMP_STRQUOTE );
582     if( oppFuncInfo ) *oppFuncInfo = pFuncInfo;
583     return aFuncName;
584 }
585 
586 sal_Int32 FormulaObject::dumpTokenCol( const String& rName, bool& rbRelC, bool& rbRelR )
587 {
588     sal_uInt16 nCol = dumpHex< sal_uInt16 >( rName, mxRelFlags );
589     rbRelC = getFlag( nCol, BIFF12_TOK_REF_COLREL );
590     rbRelR = getFlag( nCol, BIFF12_TOK_REF_ROWREL );
591     nCol &= BIFF12_TOK_REF_COLMASK;
592     return nCol;
593 }
594 
595 sal_Int32 FormulaObject::dumpTokenRow( const String& rName )
596 {
597     return dumpDec< sal_Int32 >( rName );
598 }
599 
600 TokenAddress FormulaObject::dumpTokenAddress( bool bNameMode )
601 {
602     bool bRelC = false;
603     bool bRelR = false;
604     sal_Int32 nRow = dumpTokenRow( "row" );
605     sal_Int32 nCol = dumpTokenCol( "col", bRelC, bRelR );
606     return createTokenAddress( nCol, nRow, bRelC, bRelR, bNameMode );
607 }
608 
609 TokenRange FormulaObject::dumpTokenRange( bool bNameMode )
610 {
611     bool bRelC1 = false;
612     bool bRelR1 = false;
613     bool bRelC2 = false;
614     bool bRelR2 = false;
615     sal_Int32 nRow1 = dumpTokenRow( "row1" );
616     sal_Int32 nRow2 = dumpTokenRow( "row2" );
617     sal_Int32 nCol1 = dumpTokenCol( "col1", bRelC1, bRelR1 );
618     sal_Int32 nCol2 = dumpTokenCol( "col2", bRelC2, bRelR2 );
619     TokenRange aRange;
620     aRange.maFirst = createTokenAddress( nCol1, nRow1, bRelC1, bRelR1, bNameMode );
621     aRange.maLast  = createTokenAddress( nCol2, nRow2, bRelC2, bRelR2, bNameMode );
622     return aRange;
623 }
624 
625 sal_Int16 FormulaObject::readTokenRefId()
626 {
627     return dumpDec< sal_Int16 >( "ref-id" );
628 }
629 
630 OUString FormulaObject::dumpTokenRefId()
631 {
632     OUStringBuffer aRef( CREATE_OUSTRING( "REF" ) );
633     StringHelper::appendIndex( aRef, readTokenRefId() );
634     aRef.append( OOX_DUMP_TABSEP );
635     return aRef.makeStringAndClear();
636 }
637 
638 void FormulaObject::dumpIntToken()
639 {
640     dumpDec< sal_uInt16 >( "value" );
641     mxStack->pushOperand( mxOut->getLastItemValue() );
642 }
643 
644 void FormulaObject::dumpDoubleToken()
645 {
646     dumpDec< double >( "value" );
647     mxStack->pushOperand( mxOut->getLastItemValue() );
648 }
649 
650 void FormulaObject::dumpStringToken()
651 {
652     OUStringBuffer aBuffer( dumpString( "value", false, false ) );
653     StringHelper::enclose( aBuffer, OOX_DUMP_FMLASTRQUOTE );
654     mxStack->pushOperand( aBuffer.makeStringAndClear() );
655 }
656 
657 void FormulaObject::dumpBoolToken()
658 {
659     dumpBoolean( "value" );
660     mxStack->pushOperand( mxOut->getLastItemValue() );
661 }
662 
663 void FormulaObject::dumpErrorToken()
664 {
665     dumpErrorCode( "value" );
666     mxStack->pushOperand( mxOut->getLastItemValue() );
667 }
668 
669 void FormulaObject::dumpMissArgToken()
670 {
671     mxStack->pushOperand( OUString( OOX_DUMP_EMPTYVALUE ) );
672 }
673 
674 void FormulaObject::dumpArrayToken( const OUString& rTokClass )
675 {
676     dumpUnused( 14 );
677     mxStack->pushOperand( createPlaceHolder(), rTokClass );
678     maAddData.push_back( ADDDATA_ARRAY );
679 }
680 
681 void FormulaObject::dumpNameToken( const OUString& rTokClass )
682 {
683     sal_Int32 nNameId = dumpDec< sal_Int32 >( "name-id" );
684     mxStack->pushOperand( createName( nNameId ), rTokClass );
685 }
686 
687 void FormulaObject::dumpNameXToken( const OUString& rTokClass )
688 {
689     OUString aRef = dumpTokenRefId();
690     sal_Int32 nNameId = dumpDec< sal_Int32 >( "name-id" );
691     mxStack->pushOperand( lclCreateName( aRef, nNameId ), rTokClass );
692 }
693 
694 void FormulaObject::dumpRefToken( const OUString& rTokClass, bool bNameMode )
695 {
696     TokenAddress aPos = dumpTokenAddress( bNameMode );
697     writeTokenAddressItem( "addr", aPos, bNameMode );
698     mxStack->pushOperand( createRef( mxOut->getLastItemValue() ), rTokClass );
699 }
700 
701 void FormulaObject::dumpAreaToken( const OUString& rTokClass, bool bNameMode )
702 {
703     TokenRange aRange = dumpTokenRange( bNameMode );
704     writeTokenRangeItem( "range", aRange, bNameMode );
705     mxStack->pushOperand( createRef( mxOut->getLastItemValue() ), rTokClass );
706 }
707 
708 void FormulaObject::dumpRefErrToken( const OUString& rTokClass, bool bArea )
709 {
710     dumpUnused( 4 * (bArea ? 2 : 1) );
711     mxStack->pushOperand( createRef( getErrorName( BIFF_ERR_REF ) ), rTokClass );
712 }
713 
714 void FormulaObject::dumpRef3dToken( const OUString& rTokClass, bool bNameMode )
715 {
716     OUString aRef = dumpTokenRefId();
717     TokenAddress aPos = dumpTokenAddress( bNameMode );
718     writeTokenAddress3dItem( "addr", aRef, aPos, bNameMode );
719     mxStack->pushOperand( mxOut->getLastItemValue(), rTokClass );
720 }
721 
722 void FormulaObject::dumpArea3dToken( const OUString& rTokClass, bool bNameMode )
723 {
724     OUString aRef = dumpTokenRefId();
725     TokenRange aRange = dumpTokenRange( bNameMode );
726     writeTokenRange3dItem( "range", aRef, aRange, bNameMode );
727     mxStack->pushOperand( mxOut->getLastItemValue(), rTokClass );
728 }
729 
730 void FormulaObject::dumpRefErr3dToken( const OUString& rTokClass, bool bArea )
731 {
732     OUString aRef = dumpTokenRefId();
733     dumpUnused( 4 * (bArea ? 2 : 1) );
734     mxStack->pushOperand( aRef + getErrorName( BIFF_ERR_REF ), rTokClass );
735 }
736 
737 void FormulaObject::dumpMemFuncToken( const OUString& /*rTokClass*/ )
738 {
739     dumpDec< sal_uInt16 >( "size" );
740 }
741 
742 void FormulaObject::dumpMemAreaToken( const OUString& rTokClass, bool bAddData )
743 {
744     dumpUnused( 4 );
745     dumpMemFuncToken( rTokClass );
746     if( bAddData )
747         maAddData.push_back( ADDDATA_MEMAREA );
748 }
749 
750 void FormulaObject::dumpExpToken( const String& rName )
751 {
752     Address aPos;
753     dumpRowIndex( "base-row" );
754     OUStringBuffer aOp( rName );
755     StringHelper::appendIndex( aOp, createPlaceHolder() + mxOut->getLastItemValue() );
756     mxStack->pushOperand( aOp.makeStringAndClear() );
757     maAddData.push_back( ADDDATA_EXP );
758 }
759 
760 void FormulaObject::dumpUnaryOpToken( const String& rLOp, const String& rROp )
761 {
762     mxStack->pushUnaryOp( rLOp, rROp );
763 }
764 
765 void FormulaObject::dumpBinaryOpToken( const String& rOp )
766 {
767     mxStack->pushBinaryOp( rOp );
768 }
769 
770 void FormulaObject::dumpFuncToken( const OUString& rTokClass )
771 {
772     sal_uInt16 nFuncId;
773     *mxStrm >> nFuncId;
774     const FunctionInfo* pFuncInfo = 0;
775     OUString aFuncName = writeFuncIdItem( nFuncId, &pFuncInfo );
776     if( pFuncInfo && (pFuncInfo->mnMinParamCount == pFuncInfo->mnMaxParamCount) )
777         mxStack->pushFuncOp( aFuncName, rTokClass, pFuncInfo->mnMinParamCount );
778     else
779         mxStack->setError();
780 }
781 
782 void FormulaObject::dumpFuncVarToken( const OUString& rTokClass )
783 {
784     sal_uInt8 nParamCount;
785     sal_uInt16 nFuncId;
786     *mxStrm >> nParamCount >> nFuncId;
787     bool bCmd = getFlag( nFuncId, BIFF_TOK_FUNCVAR_CMD );
788     if( bCmd )
789         writeHexItem( "param-count", nParamCount, "PARAMCOUNT-CMD" );
790     else
791         writeDecItem( "param-count", nParamCount );
792     OUString aFuncName = writeFuncIdItem( nFuncId );
793     if( bCmd && getFlag( nParamCount, BIFF_TOK_FUNCVAR_CMDPROMPT ) )
794     {
795         aFuncName += OUString( OOX_DUMP_CMDPROMPT );
796         nParamCount &= BIFF_TOK_FUNCVAR_COUNTMASK;
797     }
798     mxStack->pushFuncOp( aFuncName, rTokClass, nParamCount );
799 }
800 
801 bool FormulaObject::dumpTableToken()
802 {
803     dumpUnused( 3 );
804     sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "TABLEFLAGS" );
805     sal_uInt16 nTabId = dumpDec< sal_uInt16 >( "table-id" );
806     dumpUnused( 2 );
807     {
808         sal_uInt16 nCol1, nCol2;
809         *mxStrm >> nCol1 >> nCol2;
810         ItemGuard aItem( mxOut, "cols" );
811         mxOut->writeDec( nCol1 );
812         if( nCol1 != nCol2 )
813         {
814             mxOut->writeChar( OOX_DUMP_RANGESEP );
815             mxOut->writeDec( nCol2 );
816         }
817     }
818     OUStringBuffer aColRange;
819     StringHelper::appendIndex( aColRange, mxOut->getLastItemValue() );
820     OUStringBuffer aParams;
821     size_t nParams = 0;
822     if( getFlag( nFlags, BIFF12_TOK_TABLE_ALL ) && ++nParams )
823         StringHelper::appendToken( aParams, CREATE_OUSTRING( "[#All]" ) );
824     if( getFlag( nFlags, BIFF12_TOK_TABLE_HEADERS ) && ++nParams )
825         StringHelper::appendToken( aParams, CREATE_OUSTRING( "[#Headers]" ) );
826     if( getFlag( nFlags, BIFF12_TOK_TABLE_DATA ) && ++nParams )
827         StringHelper::appendToken( aParams, CREATE_OUSTRING( "[#Data]" ) );
828     if( getFlag( nFlags, BIFF12_TOK_TABLE_TOTALS ) && ++nParams )
829         StringHelper::appendToken( aParams, CREATE_OUSTRING( "[#Totals]" ) );
830     if( getFlag( nFlags, BIFF12_TOK_TABLE_THISROW ) && ++nParams )
831         StringHelper::appendToken( aParams, CREATE_OUSTRING( "[#This Row]" ) );
832     if( (getFlag( nFlags, BIFF12_TOK_TABLE_COLUMN ) || getFlag( nFlags, BIFF12_TOK_TABLE_COLRANGE )) && ++nParams )
833         StringHelper::appendToken( aParams, aColRange.makeStringAndClear() );
834     OUStringBuffer aOp;
835     StringHelper::appendIndexedText( aOp, CREATE_OUSTRING( "TABLE" ), nTabId );
836     if( nParams > 1 )
837         StringHelper::appendIndex( aOp, aParams.makeStringAndClear() );
838     else if( nParams == 1 )
839         aOp.append( aParams.makeStringAndClear() );
840     mxStack->pushOperand( aOp.makeStringAndClear() );
841     return true;
842 }
843 
844 bool FormulaObject::dumpAttrToken()
845 {
846     bool bValid = true;
847     sal_uInt8 nType = dumpHex< sal_uInt8 >( "type", mxAttrTypes );
848     switch( nType )
849     {
850         case BIFF_TOK_ATTR_VOLATILE:
851             dumpUnused( 2 );
852         break;
853         case BIFF_TOK_ATTR_IF:
854             dumpDec< sal_uInt16 >( "skip" );
855         break;
856         case BIFF_TOK_ATTR_CHOOSE:
857         {
858             sal_uInt16 nCount = dumpDec< sal_uInt16 >( "choices" );
859             mxOut->resetItemIndex();
860             for( sal_uInt16 nIdx = 0; nIdx < nCount; ++nIdx )
861                 dumpDec< sal_uInt16 >( "#skip" );
862             dumpDec< sal_uInt16 >( "skip-err" );
863         }
864         break;
865         case BIFF_TOK_ATTR_SKIP:
866             dumpDec< sal_uInt16 >( "skip" );
867         break;
868         case BIFF_TOK_ATTR_SUM:
869             dumpUnused( 2 );
870             mxStack->pushFuncOp( CREATE_OUSTRING( "SUM" ), OUString( OOX_DUMP_BASECLASS ), 1 );
871         break;
872         case BIFF_TOK_ATTR_ASSIGN:
873             dumpUnused( 2 );
874         break;
875         case BIFF_TOK_ATTR_SPACE:
876         case BIFF_TOK_ATTR_SPACE | BIFF_TOK_ATTR_VOLATILE:
877             dumpDec< sal_uInt8 >( "char-type", mxSpTypes );
878             dumpDec< sal_uInt8 >( "char-count" );
879         break;
880         case BIFF_TOK_ATTR_IFERROR:
881             dumpDec< sal_uInt16 >( "skip" );
882         break;
883         default:
884             bValid = false;
885     }
886     return bValid;
887 }
888 
889 void FormulaObject::dumpAddTokenData()
890 {
891     mxOut->resetItemIndex();
892     sal_Int32 nAddDataSize = (mxStrm->size() - mxStrm->tell() >= 4) ? dumpDec< sal_Int32 >( "add-data-size" ) : 0;
893     sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nAddDataSize, mxStrm->size() );
894     for( AddDataTypeVec::const_iterator aIt = maAddData.begin(), aEnd = maAddData.end(); (aIt != aEnd) && !mxStrm->isEof() && (mxStrm->tell() < nEndPos); ++aIt )
895     {
896         AddDataType eType = *aIt;
897 
898         {
899             ItemGuard aItem( mxOut, "#add-data" );
900             switch( eType )
901             {
902                 case ADDDATA_EXP:       mxOut->writeAscii( "tExp" );      break;
903                 case ADDDATA_ARRAY:     mxOut->writeAscii( "tArray" );    break;
904                 case ADDDATA_MEMAREA:   mxOut->writeAscii( "tMemArea" );  break;
905             }
906         }
907 
908         size_t nIdx = aIt - maAddData.begin();
909         IndentGuard aIndGuard( mxOut );
910         switch( eType )
911         {
912             case ADDDATA_EXP:       dumpAddDataExp( nIdx );     break;
913             case ADDDATA_ARRAY:     dumpAddDataArray( nIdx );   break;
914             case ADDDATA_MEMAREA:   dumpAddDataMemArea( nIdx ); break;
915             default:;
916         }
917     }
918 }
919 
920 void FormulaObject::dumpAddDataExp( size_t nIdx )
921 {
922     dumpColIndex( "base-col" );
923     mxStack->replaceOnTop( createPlaceHolder( nIdx ), mxOut->getLastItemValue() );
924 }
925 
926 void FormulaObject::dumpAddDataArray( size_t nIdx )
927 {
928     sal_Int32 nCols, nRows;
929     dumpaddDataArrayHeader( nCols, nRows );
930 
931     OUStringBuffer aOp;
932     TableGuard aTabGuard( mxOut, 17 );
933     for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
934     {
935         OUStringBuffer aArrayLine;
936         for( sal_Int32 nCol = 0; nCol < nCols; ++nCol )
937             StringHelper::appendToken( aArrayLine, dumpaddDataArrayValue(), OOX_DUMP_LISTSEP );
938         StringHelper::appendToken( aOp, aArrayLine.makeStringAndClear(), OOX_DUMP_ARRAYSEP );
939     }
940     StringHelper::enclose( aOp, '{', '}' );
941     mxStack->replaceOnTop( createPlaceHolder( nIdx ), aOp.makeStringAndClear() );
942 }
943 
944 void FormulaObject::dumpAddDataMemArea( size_t /*nIdx*/ )
945 {
946     dumpRangeList();
947 }
948 
949 void FormulaObject::dumpaddDataArrayHeader( sal_Int32& rnCols, sal_Int32& rnRows )
950 {
951     MultiItemsGuard aMultiGuard( mxOut );
952     rnRows = dumpDec< sal_Int32 >( "height" );
953     rnCols = dumpDec< sal_Int32 >( "width" );
954     ItemGuard aItem( mxOut, "size" );
955     mxOut->writeDec( rnCols );
956     mxOut->writeChar( 'x' );
957     mxOut->writeDec( rnRows );
958     aItem.cont();
959     mxOut->writeDec( rnCols * rnRows );
960 }
961 
962 OUString FormulaObject::dumpaddDataArrayValue()
963 {
964     MultiItemsGuard aMultiGuard( mxOut );
965     OUStringBuffer aValue;
966     switch( dumpDec< sal_uInt8 >( "type", "ARRAYVALUE-TYPE" ) )
967     {
968         case BIFF_TOK_ARRAY_DOUBLE:
969             dumpDec< double >( "value" );
970             aValue.append( mxOut->getLastItemValue() );
971         break;
972         case BIFF_TOK_ARRAY_STRING:
973             aValue.append( dumpString( "value", false, false ) );
974             StringHelper::enclose( aValue, OOX_DUMP_STRQUOTE );
975         break;
976         case BIFF_TOK_ARRAY_BOOL:
977             dumpBoolean( "value" );
978             aValue.append( mxOut->getLastItemValue() );
979         break;
980         case BIFF_TOK_ARRAY_ERROR:
981             dumpErrorCode( "value" );
982             aValue.append( mxOut->getLastItemValue() );
983             dumpUnused( 3 );
984         break;
985     }
986     return aValue.makeStringAndClear();
987 }
988 
989 // ============================================================================
990 
991 RecordStreamObject::RecordStreamObject( ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
992 {
993     RecordObjectBase::construct( rParent, rxStrm, rSysFileName );
994     if( RecordObjectBase::implIsValid() )
995         mxFmlaObj.reset( new FormulaObject( *this ) );
996 }
997 
998 bool RecordStreamObject::implIsValid() const
999 {
1000     return isValid( mxFmlaObj ) && RecordObjectBase::implIsValid();
1001 }
1002 
1003 void RecordStreamObject::implDumpRecordBody()
1004 {
1005     switch( getRecId() )
1006     {
1007         case BIFF12_ID_ARRAY:
1008             dumpRange( "array-range" );
1009             dumpHex< sal_uInt8 >( "flags", "ARRAY-FLAGS" );
1010             mxFmlaObj->dumpCellFormula();
1011         break;
1012 
1013         case BIFF12_ID_AUTOFILTER:
1014             dumpRange( "filter-range" );
1015         break;
1016 
1017         case BIFF12_ID_BINARYINDEXBLOCK:
1018             dumpRowRange( "row-range" );
1019             dumpUnknown( 12 );
1020         break;
1021 
1022         case BIFF12_ID_BINARYINDEXROWS:
1023         {
1024             sal_uInt32 nUsedRows = dumpBin< sal_uInt32 >( "used-rows" );
1025             dumpDec< sal_Int64 >( "stream-offset" );
1026             for( ; nUsedRows > 0; nUsedRows >>= 1 )
1027                 if( (nUsedRows & 1) != 0 )
1028                     dumpBin< sal_uInt16 >( "used-columns" );
1029         }
1030         break;
1031 
1032         case BIFF12_ID_BORDER:
1033             dumpHex< sal_uInt8 >( "flags", "BORDER-FLAGS" );
1034             dumpDec< sal_uInt16 >( "top-style", "BORDERSTYLES" );
1035             dumpColor( "top-color" );
1036             dumpDec< sal_uInt16 >( "bottom-style", "BORDERSTYLES" );
1037             dumpColor( "bottom-color" );
1038             dumpDec< sal_uInt16 >( "left-style", "BORDERSTYLES" );
1039             dumpColor( "left-color" );
1040             dumpDec< sal_uInt16 >( "right-style", "BORDERSTYLES" );
1041             dumpColor( "right-color" );
1042             dumpDec< sal_uInt16 >( "diag-style", "BORDERSTYLES" );
1043             dumpColor( "diag-color" );
1044         break;
1045 
1046         case BIFF12_ID_BRK:
1047             dumpDec< sal_Int32 >( "id" );
1048             dumpDec< sal_Int32 >( "min" );
1049             dumpDec< sal_Int32 >( "max" );
1050             dumpDec< sal_Int32 >( "manual-break", "BOOLEAN" );
1051             dumpDec< sal_Int32 >( "pivot-break", "BOOLEAN" );
1052         break;
1053 
1054         case BIFF12_ID_CALCPR:
1055             dumpDec< sal_Int32 >( "calc-id" );
1056             dumpDec< sal_Int32 >( "calc-mode", "CALCPR-CALCMODE" );
1057             dumpDec< sal_Int32 >( "iteration-count" );
1058             dumpDec< double >( "iteration-delta" );
1059             dumpDec< sal_Int32 >( "processor-count" );
1060             dumpHex< sal_uInt16 >( "flags", "CALCPR-FLAGS" );
1061         break;
1062 
1063         case BIFF12_ID_CELL_BLANK:
1064             dumpCellHeader( true );
1065         break;
1066 
1067         case BIFF12_ID_CELL_BOOL:
1068             dumpCellHeader( true );
1069             dumpBoolean();
1070         break;
1071 
1072         case BIFF12_ID_CELL_DOUBLE:
1073             dumpCellHeader( true );
1074             dumpDec< double >( "value" );
1075         break;
1076 
1077         case BIFF12_ID_CELL_ERROR:
1078             dumpCellHeader( true );
1079             dumpErrorCode();
1080         break;
1081 
1082         case BIFF12_ID_CELL_RK:
1083             dumpCellHeader( true );
1084             dumpRk( "value" );
1085         break;
1086 
1087         case BIFF12_ID_CELL_RSTRING:
1088             dumpCellHeader( true );
1089             dumpString( "value", true );
1090         break;
1091 
1092         case BIFF12_ID_CELL_SI:
1093             dumpCellHeader( true );
1094             dumpDec< sal_Int32 >( "string-id" );
1095         break;
1096 
1097         case BIFF12_ID_CELL_STRING:
1098             dumpCellHeader( true );
1099             dumpString( "value" );
1100         break;
1101 
1102         case BIFF12_ID_CELLSTYLE:
1103             dumpDec< sal_Int32 >( "xf-id" );
1104             dumpHex< sal_uInt16 >( "flags", "CELLSTYLE-FLAGS" );
1105             dumpDec< sal_uInt8 >( "builtin-id", "CELLSTYLE-BUILTIN" );
1106             dumpDec< sal_uInt8 >( "outline-level" );
1107             dumpString( "name" );
1108         break;
1109 
1110         case BIFF12_ID_CFCOLOR:
1111             dumpColor();
1112         break;
1113 
1114         case BIFF12_ID_CFRULE:
1115         {
1116             // type/subtype/operator is a mess...
1117             dumpDec< sal_Int32 >( "type", "CFRULE-TYPE" );
1118             sal_Int32 nSubType = dumpDec< sal_Int32 >( "sub-type", "CFRULE-SUBTYPE" );
1119             dumpDec< sal_Int32 >( "dxf-id" );
1120             dumpDec< sal_Int32 >( "priority" );
1121             switch( nSubType )
1122             {
1123                 case 0:     dumpDec< sal_Int32 >( "operator", "CFRULE-CELL-OPERATOR" ); break;
1124                 case 5:     dumpDec< sal_Int32 >( "rank" );                             break;
1125                 case 8:     dumpDec< sal_Int32 >( "operator", "CFRULE-TEXT-OPERATOR" ); break;
1126                 case 15:    dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
1127                 case 16:    dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
1128                 case 17:    dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
1129                 case 18:    dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
1130                 case 19:    dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
1131                 case 20:    dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
1132                 case 21:    dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
1133                 case 22:    dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
1134                 case 23:    dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
1135                 case 24:    dumpDec< sal_Int32 >( "operator", "CFRULE-DATE-OPERATOR" ); break;
1136                 case 25:    dumpDec< sal_Int32 >( "std-dev" );                          break;
1137                 case 26:    dumpDec< sal_Int32 >( "std-dev" );                          break;
1138                 case 29:    dumpDec< sal_Int32 >( "std-dev" );                          break;
1139                 case 30:    dumpDec< sal_Int32 >( "std-dev" );                          break;
1140                 default:    dumpDec< sal_Int32 >( "operator", "CFRULE-OTHER-OPERATOR" );
1141             }
1142             dumpUnknown( 8 );
1143             dumpHex< sal_uInt16 >( "flags", "CFRULE-FLAGS" );
1144             // for no obvious reason the formula sizes occur twice
1145             dumpDec< sal_Int32 >( "formula1-size" );
1146             dumpDec< sal_Int32 >( "formula2-size" );
1147             dumpDec< sal_Int32 >( "formula3-size" );
1148             dumpString( "text" );
1149             if( mxStrm->getRemaining() >= 8 )
1150                 mxFmlaObj->dumpNameFormula( "formula1" );
1151             if( mxStrm->getRemaining() >= 8 )
1152                 mxFmlaObj->dumpNameFormula( "formula2" );
1153             if( mxStrm->getRemaining() >= 8 )
1154                 mxFmlaObj->dumpNameFormula( "formula3" );
1155         }
1156         break;
1157 
1158         case BIFF12_ID_CHARTPAGESETUP:
1159             dumpDec< sal_Int32 >( "paper-size", "PAGESETUP-PAPERSIZE" );
1160             dumpDec< sal_Int32 >( "horizontal-res", "PAGESETUP-DPI" );
1161             dumpDec< sal_Int32 >( "vertical-res", "PAGESETUP-DPI" );
1162             dumpDec< sal_Int32 >( "copies" );
1163             dumpDec< sal_uInt16 >( "first-page" );
1164             dumpHex< sal_uInt16 >( "flags", "CHARTPAGESETUP-FLAGS" );
1165             dumpString( "printer-settings-rel-id" );
1166         break;
1167 
1168         case BIFF12_ID_CHARTPROTECTION:
1169             dumpHex< sal_uInt16 >( "password-hash" );
1170             // no flags field for the boolean flags?!?
1171             dumpDec< sal_Int32 >( "content-locked", "BOOLEAN" );
1172             dumpDec< sal_Int32 >( "objects-locked", "BOOLEAN" );
1173         break;
1174 
1175         case BIFF12_ID_CHARTSHEETPR:
1176             dumpHex< sal_uInt16 >( "flags", "CHARTSHEETPR-FLAGS" );
1177             dumpColor( "tab-color" );
1178             dumpString( "codename" );
1179         break;
1180 
1181         case BIFF12_ID_CHARTSHEETVIEW:
1182             dumpHex< sal_uInt16 >( "flags", "CHARTSHEETVIEW-FLAGS" );
1183             dumpDec< sal_Int32 >( "zoom-scale", "CONV-PERCENT" );
1184             dumpDec< sal_Int32 >( "workbookview-id" );
1185         break;
1186 
1187         case BIFF12_ID_COL:
1188             dumpColRange();
1189             dumpDec< sal_Int32 >( "col-width", "CONV-COLWIDTH" );
1190             dumpDec< sal_Int32 >( "custom-xf-id" );
1191             dumpHex< sal_uInt16 >( "flags", "COL-FLAGS" );
1192         break;
1193 
1194         case BIFF12_ID_COLBREAKS:
1195             dumpDec< sal_Int32 >( "count" );
1196             dumpDec< sal_Int32 >( "manual-count" );
1197         break;
1198 
1199         case BIFF12_ID_COLOR:
1200             dumpColor();
1201         break;
1202 
1203         case BIFF12_ID_COMMENT:
1204             dumpDec< sal_Int32 >( "author-id" );
1205             dumpRange( "ref" );
1206             dumpGuid();
1207         break;
1208 
1209         case BIFF12_ID_COMMENTAUTHOR:
1210             dumpString( "author" );
1211         break;
1212 
1213         case BIFF12_ID_COMMENTTEXT:
1214             dumpString( "text", true );
1215         break;
1216 
1217         case BIFF12_ID_CONDFORMATTING:
1218             dumpDec< sal_Int32 >( "cfrule-count" );
1219             dumpDec< sal_Int32 >( "pivot-table", "BOOLEAN" );
1220             dumpRangeList();
1221         break;
1222 
1223         case BIFF12_ID_CONNECTION:
1224         {
1225             dumpDec< sal_uInt8 >( "refreshed-version" );
1226             dumpDec< sal_uInt8 >( "min-refresh-version" );
1227             dumpDec< sal_uInt8 >( "save-password", "CONNECTION-SAVEPASSWORD" );
1228             dumpUnused( 1 );
1229             dumpDec< sal_uInt16 >( "refresh-interval", "CONNECTION-INTERVAL" );
1230             dumpHex< sal_uInt16 >( "flags", "CONNECTION-FLAGS" );
1231             sal_uInt16 nStrFlags = dumpHex< sal_uInt16 >( "string-flags", "CONNECTION-STRINGFLAGS" );
1232             dumpDec< sal_Int32 >( "data-source-type", "CONNECTION-SOURCETYPE" );
1233             dumpDec< sal_Int32 >( "reconnect-type", "CONNECTION-RECONNECTTYPE" );
1234             dumpDec< sal_Int32 >( "id" );
1235             dumpDec< sal_uInt8 >( "credentials", "CONNECTION-CREDENTIALS" );
1236             if( nStrFlags & 0x0001 ) dumpString( "source-file" );
1237             if( nStrFlags & 0x0002 ) dumpString( "source-conn-file" );
1238             if( nStrFlags & 0x0004 ) dumpString( "description" );
1239             if( nStrFlags & 0x0008 ) dumpString( "name" );
1240             if( nStrFlags & 0x0010 ) dumpString( "sso-id" );
1241         }
1242         break;
1243 
1244         case BIFF12_ID_CONTROL:
1245             dumpDec< sal_Int32 >( "shape-id" );
1246             dumpString( "rel-id" );
1247             dumpString( "name" );
1248         break;
1249 
1250         case BIFF12_ID_CUSTOMFILTER:
1251         {
1252             sal_uInt8 nType = dumpDec< sal_uInt8 >( "data-type", "CUSTOMFILTER-DATATYPE" );
1253             dumpDec< sal_uInt8 >( "operator", "CUSTOMFILTER-OPERATOR" );
1254             switch( nType )
1255             {
1256                 case 4:     dumpDec< double >( "value" );               break;
1257                 case 6:     dumpUnused( 8 ); dumpString( "value" );     break;
1258                 case 8:     dumpBoolean( "value" ); dumpUnused( 7 );    break;
1259                 default:    dumpUnused( 8 );
1260             }
1261         }
1262         break;
1263 
1264         case BIFF12_ID_DATATABLE:
1265             dumpRange( "table-range" );
1266             dumpAddress( "ref1" );
1267             dumpAddress( "ref2" );
1268             dumpHex< sal_uInt8 >( "flags", "DATATABLE-FLAGS" );
1269         break;
1270 
1271         case BIFF12_ID_DATAVALIDATION:
1272             dumpHex< sal_uInt32 >( "flags", "DATAVALIDATION-FLAGS" );
1273             dumpRangeList();
1274             dumpString( "error-title" );
1275             dumpString( "error-message" );
1276             dumpString( "input-title" );
1277             dumpString( "input-message" );
1278             mxFmlaObj->dumpNameFormula( "formula1" );
1279             mxFmlaObj->dumpNameFormula( "formula2" );
1280         break;
1281 
1282         case BIFF12_ID_DATAVALIDATIONS:
1283             dumpHex< sal_uInt16 >( "flags", "DATAVALIDATIONS-FLAGS" );
1284             dumpDec< sal_Int32 >( "input-x" );
1285             dumpDec< sal_Int32 >( "input-y" );
1286             dumpUnused( 4 );
1287             dumpDec< sal_Int32 >( "count" );
1288         break;
1289 
1290         case BIFF12_ID_DDEITEMVALUES:
1291             dumpDec< sal_Int32 >( "rows" );
1292             dumpDec< sal_Int32 >( "columns" );
1293         break;
1294 
1295         case BIFF12_ID_DDEITEM_STRING:
1296             dumpString( "value" );
1297         break;
1298 
1299         case BIFF12_ID_DEFINEDNAME:
1300             dumpHex< sal_uInt32 >( "flags", "DEFINEDNAME-FLAGS" );
1301             dumpChar( "accelerator", RTL_TEXTENCODING_ISO_8859_1 );
1302             dumpDec< sal_Int32 >( "sheet-id", "DEFINEDNAME-SHEETID" );
1303             dumpString( "name" );
1304             mxFmlaObj->dumpNameFormula();
1305             dumpString( "comment" );
1306             if( mxStrm->getRemaining() >= 4 ) dumpString( "menu-text" );
1307             if( mxStrm->getRemaining() >= 4 ) dumpString( "description-text" );
1308             if( mxStrm->getRemaining() >= 4 ) dumpString( "help-text" );
1309             if( mxStrm->getRemaining() >= 4 ) dumpString( "statusbar-text" );
1310         break;
1311 
1312         case BIFF12_ID_DIMENSION:
1313             dumpRange( "used-range" );
1314         break;
1315 
1316         case BIFF12_ID_DISCRETEFILTER:
1317             dumpString( "value" );
1318         break;
1319 
1320         case BIFF12_ID_DISCRETEFILTERS:
1321             dumpBool< sal_Int32 >( "show-blank" );
1322             dumpDec< sal_Int32 >( "calendar-type", "DISCRETEFILTERS-CALTYPE" );
1323         break;
1324 
1325         case BIFF12_ID_DRAWING:
1326             dumpString( "rel-id" );
1327         break;
1328 
1329         case BIFF12_ID_DXF:
1330             dumpHex< sal_uInt32 >( "flags", "DXF-FLAGS" );
1331             for( sal_uInt16 nIndex = 0, nCount = dumpDec< sal_uInt16 >( "subrec-count" ); !mxStrm->isEof() && (nIndex < nCount); ++nIndex )
1332             {
1333                 mxOut->startMultiItems();
1334                 sal_Int64 nStartPos = mxStrm->tell();
1335                 writeEmptyItem( "SUBREC" );
1336                 sal_uInt16 nSubRecId = dumpDec< sal_uInt16 >( "id", "DXF-SUBREC" );
1337                 sal_uInt16 nSubRecSize = dumpDec< sal_uInt16 >( "size" );
1338                 sal_Int64 nEndPos = nStartPos + nSubRecSize;
1339                 mxOut->endMultiItems();
1340                 IndentGuard aIndGuard( mxOut );
1341                 switch( nSubRecId )
1342                 {
1343                     case 0:
1344                         dumpDec< sal_uInt8 >( "pattern", "FILLPATTERNS" );
1345                     break;
1346                     case 1: case 2: case 5:
1347                         dumpColor();
1348                     break;
1349                     case 3:
1350                         dumpGradientHead();
1351                     break;
1352                     case 4:
1353                         dumpDec< sal_uInt16 >( "index" );
1354                         dumpDec< double >( "stop-position" );
1355                         dumpColor( "stop-color" );
1356                     break;
1357                     case 6: case 7: case 8: case 9: case 10: case 11: case 12:
1358                         dumpColor( "color" );
1359                         dumpDec< sal_uInt16 >( "style", "BORDERSTYLES" );
1360                     break;
1361                     case 13: case 14:
1362                         dumpBoolean( "value" );
1363                     break;
1364                     case 15:
1365                         dumpDec< sal_uInt8 >( "alignment", "XF-HORALIGN" );
1366                     break;
1367                     case 16:
1368                         dumpDec< sal_uInt8 >( "alignment", "XF-VERALIGN" );
1369                     break;
1370                     case 17:
1371                         dumpDec< sal_uInt8 >( "rotation", "TEXTROTATION" );
1372                     break;
1373                     case 18:
1374                         dumpDec< sal_uInt16 >( "indent" );
1375                     break;
1376                     case 19:
1377                         dumpDec< sal_uInt8 >( "text-dir", "XF-TEXTDIRECTION" );
1378                     break;
1379                     case 20: case 21: case 22:
1380                         dumpBoolean( "value" );
1381                     break;
1382                     case 24:
1383                         dumpString( "name", false, false );
1384                     break;
1385                     case 25:
1386                         dumpDec< sal_uInt16 >( "weight", "FONT-WEIGHT" );
1387                     break;
1388                     case 26:
1389                         dumpDec< sal_uInt16 >( "underline", "FONT-UNDERLINE" );
1390                     break;
1391                     case 27:
1392                         dumpDec< sal_uInt16 >( "escapement", "FONT-ESCAPEMENT" );
1393                     break;
1394                     case 28: case 29: case 30: case 31: case 32: case 33:
1395                         dumpBoolean( "value" );
1396                     break;
1397                     case 34:
1398                         dumpDec< sal_uInt8 >( "charset", "CHARSET" );
1399                     break;
1400                     case 35:
1401                         dumpDec< sal_uInt8 >( "family", "FONT-FAMILY" );
1402                     break;
1403                     case 36:
1404                         dumpDec< sal_Int32 >( "height", "CONV-TWIP-TO-PT" );
1405                     break;
1406                     case 37:
1407                         dumpDec< sal_uInt8 >( "scheme", "FONT-SCHEME" );
1408                     break;
1409                     case 38:
1410                         dumpString( "numfmt", false, false );
1411                     break;
1412                     case 41:
1413                         dumpDec< sal_uInt16 >( "numfmt-id" );
1414                     break;
1415                     case 42:
1416                         dumpDec< sal_Int16 >( "relative-indent" );
1417                     break;
1418                     case 43: case 44:
1419                         dumpBoolean( "value" );
1420                     break;
1421                 }
1422                 dumpRemainingTo( nEndPos );
1423             }
1424         break;
1425 
1426         case BIFF12_ID_EXTCELL_BOOL:
1427             dumpColIndex();
1428             dumpBoolean();
1429         break;
1430 
1431         case BIFF12_ID_EXTCELL_DOUBLE:
1432             dumpColIndex();
1433             dumpDec< double >( "value" );
1434         break;
1435 
1436         case BIFF12_ID_EXTCELL_ERROR:
1437             dumpColIndex();
1438             dumpErrorCode();
1439         break;
1440 
1441         case BIFF12_ID_EXTCELL_STRING:
1442             dumpColIndex();
1443             dumpString( "value" );
1444         break;
1445 
1446         case BIFF12_ID_EXTERNALBOOK:
1447             switch( dumpDec< sal_uInt16 >( "type", "EXTERNALBOOK-TYPE" ) )
1448             {
1449                 case 0:
1450                     dumpString( "rel-id" );
1451                     dumpDec< sal_Int32 >( "unused" );
1452                 break;
1453                 case 1:
1454                     dumpString( "dde-service" );
1455                     dumpString( "dde-topic" );
1456                 break;
1457                 case 2:
1458                     dumpString( "rel-id" );
1459                     dumpString( "prog-id" );
1460                 break;
1461             }
1462         break;
1463 
1464         case BIFF12_ID_EXTERNALNAME:
1465             dumpString( "name" );
1466         break;
1467 
1468         case BIFF12_ID_EXTERNALNAMEFLAGS:
1469             dumpHex< sal_uInt16 >( "flags", "EXTERNALNAMEFLAGS-FLAGS" );
1470             dumpDec< sal_Int32 >( "sheet-id" );
1471             dumpBoolean( "is-dde-ole" );
1472         break;
1473 
1474         case BIFF12_ID_EXTERNALREF:
1475             dumpString( "rel-id" );
1476         break;
1477 
1478         case BIFF12_ID_EXTERNALSHEETS:
1479         {
1480             sal_Int32 nCount = dumpDec< sal_Int32 >( "ref-count" );
1481             TableGuard aTabGuard( mxOut, 13, 17, 24 );
1482             mxOut->resetItemIndex();
1483             for( sal_Int32 nRefId = 0; !mxStrm->isEof() && (nRefId < nCount); ++nRefId )
1484             {
1485                 MultiItemsGuard aMultiGuard( mxOut );
1486                 writeEmptyItem( "#ref" );
1487                 dumpDec< sal_Int32 >( "extref-id" );
1488                 dumpDec< sal_Int32 >( "first-sheet", "EXTERNALSHEETS-ID" );
1489                 dumpDec< sal_Int32 >( "last-sheet", "EXTERNALSHEETS-ID" );
1490             }
1491         }
1492         break;
1493 
1494         case BIFF12_ID_EXTROW:
1495             dumpRowIndex();
1496         break;
1497 
1498         case BIFF12_ID_EXTSHEETDATA:
1499             dumpDec< sal_Int32 >( "sheet-id" );
1500             dumpHex< sal_uInt8 >( "flags", "EXTSHEETDATA-FLAGS" );
1501         break;
1502 
1503         case BIFF12_ID_EXTSHEETNAMES:
1504             mxOut->resetItemIndex();
1505             for( sal_Int32 nSheet = 0, nCount = dumpDec< sal_Int32 >( "sheet-count" ); !mxStrm->isEof() && (nSheet < nCount); ++nSheet )
1506                 dumpString( "#sheet-name" );
1507         break;
1508 
1509         case BIFF12_ID_FILESHARING:
1510             dumpBool< sal_uInt16 >( "recommend-read-only" );
1511             dumpHex< sal_uInt16 >( "password-hash" );
1512             dumpString( "password-creator" );
1513         break;
1514 
1515         case BIFF12_ID_FILL:
1516             dumpDec< sal_Int32 >( "fill-pattern", "FILLPATTERNS" );
1517             dumpColor( "fg-color" );
1518             dumpColor( "bg-color" );
1519             dumpGradientHead();
1520             mxOut->resetItemIndex();
1521             for( sal_Int32 nStop = 0, nStopCount = dumpDec< sal_Int32 >( "stop-count" ); (nStop < nStopCount) && !mxStrm->isEof(); ++nStop )
1522             {
1523                 writeEmptyItem( "#stop" );
1524                 IndentGuard aIndGuard( mxOut );
1525                 dumpColor( "stop-color" );
1526                 dumpDec< double >( "stop-position" );
1527             }
1528         break;
1529 
1530         case BIFF12_ID_FILEVERSION:
1531             dumpGuid( "codename" );
1532             dumpString( "app-name" );
1533             dumpString( "last-edited" );
1534             dumpString( "lowest-edited" );
1535             dumpString( "build-version" );
1536         break;
1537 
1538         case BIFF12_ID_FILTERCOLUMN:
1539             dumpDec< sal_Int32 >( "column-index" );
1540             dumpHex< sal_uInt16 >( "flags", "FILTERCOLUMN-FLAGS" );
1541         break;
1542 
1543         case BIFF12_ID_FONT:
1544             dumpDec< sal_uInt16 >( "height", "CONV-TWIP-TO-PT" );
1545             dumpHex< sal_uInt16 >( "flags", "FONT-FLAGS" );
1546             dumpDec< sal_uInt16 >( "weight", "FONT-WEIGHT" );
1547             dumpDec< sal_uInt16 >( "escapement", "FONT-ESCAPEMENT" );
1548             dumpDec< sal_uInt8 >( "underline", "FONT-UNDERLINE" );
1549             dumpDec< sal_uInt8 >( "family", "FONT-FAMILY" );
1550             dumpDec< sal_uInt8 >( "charset", "CHARSET" );
1551             dumpUnused( 1 );
1552             dumpColor();
1553             dumpDec< sal_uInt8 >( "scheme", "FONT-SCHEME" );
1554             dumpString( "name" );
1555         break;
1556 
1557         case BIFF12_ID_FORMULA_BOOL:
1558             dumpCellHeader( true );
1559             dumpBoolean();
1560             dumpHex< sal_uInt16 >( "flags", "FORMULA-FLAGS" );
1561             mxFmlaObj->dumpCellFormula();
1562         break;
1563 
1564         case BIFF12_ID_FORMULA_DOUBLE:
1565             dumpCellHeader( true );
1566             dumpDec< double >( "value" );
1567             dumpHex< sal_uInt16 >( "flags", "FORMULA-FLAGS" );
1568             mxFmlaObj->dumpCellFormula();
1569         break;
1570 
1571         case BIFF12_ID_FORMULA_ERROR:
1572             dumpCellHeader( true );
1573             dumpErrorCode();
1574             dumpHex< sal_uInt16 >( "flags", "FORMULA-FLAGS" );
1575             mxFmlaObj->dumpCellFormula();
1576         break;
1577 
1578         case BIFF12_ID_FORMULA_STRING:
1579             dumpCellHeader( true );
1580             dumpString( "value" );
1581             dumpHex< sal_uInt16 >( "flags", "FORMULA-FLAGS" );
1582             mxFmlaObj->dumpCellFormula();
1583         break;
1584 
1585         case BIFF12_ID_FUNCTIONGROUP:
1586             dumpString( "name" );
1587         break;
1588 
1589         case BIFF12_ID_HEADERFOOTER:
1590             dumpHex< sal_uInt16 >( "flags", "HEADERFOOTER-FLAGS" );
1591             dumpString( "odd-header" );
1592             dumpString( "odd-footer" );
1593             dumpString( "even-header" );
1594             dumpString( "even-footer" );
1595             dumpString( "first-header" );
1596             dumpString( "first-footer" );
1597         break;
1598 
1599         case BIFF12_ID_HYPERLINK:
1600             dumpRange();
1601             dumpString( "rel-id" );
1602             dumpString( "location" );
1603             dumpString( "tooltip" );
1604             dumpString( "display" );
1605         break;
1606 
1607         case BIFF12_ID_INPUTCELLS:
1608             dumpAddress( "pos" );
1609             dumpUnused( 8 );
1610             dumpDec< sal_uInt16 >( "numfmt-id" );
1611             dumpString( "value" );
1612         break;
1613 
1614         case BIFF12_ID_LEGACYDRAWING:
1615             dumpString( "rel-id" );
1616         break;
1617 
1618         case BIFF12_ID_MERGECELL:
1619             dumpRange();
1620         break;
1621 
1622         case BIFF12_ID_MULTCELL_BLANK:
1623             dumpCellHeader( false );
1624         break;
1625 
1626         case BIFF12_ID_MULTCELL_BOOL:
1627             dumpCellHeader( false );
1628             dumpBoolean();
1629         break;
1630 
1631         case BIFF12_ID_MULTCELL_DOUBLE:
1632             dumpCellHeader( false );
1633             dumpDec< double >( "value" );
1634         break;
1635 
1636         case BIFF12_ID_MULTCELL_ERROR:
1637             dumpCellHeader( false );
1638             dumpErrorCode();
1639         break;
1640 
1641         case BIFF12_ID_MULTCELL_RK:
1642             dumpCellHeader( false );
1643             dumpRk( "value" );
1644         break;
1645 
1646         case BIFF12_ID_MULTCELL_RSTRING:
1647             dumpCellHeader( false );
1648             dumpString( "value", true );
1649         break;
1650 
1651         case BIFF12_ID_MULTCELL_SI:
1652             dumpCellHeader( false );
1653             dumpDec< sal_Int32 >( "string-id" );
1654         break;
1655 
1656         case BIFF12_ID_MULTCELL_STRING:
1657             dumpCellHeader( false );
1658             dumpString( "value" );
1659         break;
1660 
1661         case BIFF12_ID_NUMFMT:
1662             dumpDec< sal_uInt16 >( "numfmt-id" );
1663             dumpString( "format" );
1664         break;
1665 
1666         case BIFF12_ID_OLEOBJECT:
1667         {
1668             dumpDec< sal_Int32 >( "aspect", "OLEOBJECT-ASPECT" );
1669             dumpDec< sal_Int32 >( "update", "OLEOBJECT-UPDATE" );
1670             dumpDec< sal_Int32 >( "shape-id" );
1671             sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "OLEOBJECT-FLAGS" );
1672             dumpString( "prog-id" );
1673             if( getFlag( nFlags, BIFF12_OLEOBJECT_LINKED ) )
1674                 mxFmlaObj->dumpNameFormula( "link" );
1675             else
1676                 dumpString( "rel-id" );
1677         }
1678         break;
1679 
1680         case BIFF12_ID_OLESIZE:
1681             dumpRange( "visible-range" );
1682         break;
1683 
1684         case BIFF12_ID_PAGEMARGINS:
1685             dumpDec< double >( "left-margin" );
1686             dumpDec< double >( "right-margin" );
1687             dumpDec< double >( "top-margin" );
1688             dumpDec< double >( "bottom-margin" );
1689             dumpDec< double >( "header-margin" );
1690             dumpDec< double >( "footer-margin" );
1691         break;
1692 
1693         case BIFF12_ID_PAGESETUP:
1694             dumpDec< sal_Int32 >( "paper-size", "PAGESETUP-PAPERSIZE" );
1695             dumpDec< sal_Int32 >( "scaling", "CONV-PERCENT" );
1696             dumpDec< sal_Int32 >( "horizontal-res", "PAGESETUP-DPI" );
1697             dumpDec< sal_Int32 >( "vertical-res", "PAGESETUP-DPI" );
1698             dumpDec< sal_Int32 >( "copies" );
1699             dumpDec< sal_Int32 >( "first-page" );
1700             dumpDec< sal_Int32 >( "scale-to-width", "PAGESETUP-SCALETOPAGES" );
1701             dumpDec< sal_Int32 >( "scale-to-height", "PAGESETUP-SCALETOPAGES" );
1702             dumpHex< sal_uInt16 >( "flags", "PAGESETUP-FLAGS" );
1703             dumpString( "printer-settings-rel-id" );
1704         break;
1705 
1706         case BIFF12_ID_PANE:
1707             dumpDec< double >( "x-split-pos" );
1708             dumpDec< double >( "y-split-pos" );
1709             dumpAddress( "second-top-left" );
1710             dumpDec< sal_Int32 >( "active-pane", "PANE-ID" );
1711             dumpHex< sal_uInt8 >( "flags", "PANE-FLAGS" );
1712         break;
1713 
1714         case BIFF12_ID_PCDEFINITION:
1715         {
1716             dumpDec< sal_uInt8 >( "refreshed-version" );
1717             dumpDec< sal_uInt8 >( "min-refresh-version" );
1718             dumpDec< sal_uInt8 >( "created-version" );
1719             dumpHex< sal_uInt8 >( "flags-1", "PCDEFINITION-FLAGS1" );
1720             dumpDec< sal_Int32 >( "missing-items-limit", "PCDEFINITION-MISSINGITEMS" );
1721             dumpDec< double >( "refreshed-date" );
1722             sal_uInt8 nFlags2 = dumpHex< sal_uInt8 >( "flags-2", "PCDEFINITION-FLAGS2" );
1723             dumpDec< sal_Int32 >( "record-count" );
1724             if( nFlags2 & 0x01 ) dumpString( "refreshed-by" );
1725             if( nFlags2 & 0x02 ) dumpString( "rel-id" );
1726         }
1727         break;
1728 
1729         case BIFF12_ID_PCDFIELD:
1730         {
1731             sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "PCDFIELD-FLAGS" );
1732             dumpDec< sal_Int32 >( "numfmt-id" );
1733             dumpDec< sal_Int16 >( "sql-datatype" );
1734             dumpDec< sal_Int32 >( "hierarchy" );
1735             dumpDec< sal_Int32 >( "hierarchy-level" );
1736             sal_Int32 nMappingCount = dumpDec< sal_Int32 >( "property-mapping-count" );
1737             dumpString( "name" );
1738             if( nFlags & 0x0008 ) dumpString( "caption" );
1739             if( nFlags & 0x0100 ) mxFmlaObj->dumpNameFormula( "formula" );
1740             if( nMappingCount > 0 )
1741             {
1742                 sal_Int32 nBytes = dumpDec< sal_Int32 >( "property-mapping-size" );
1743                 dumpArray( "property-mapping-indexes", nBytes );
1744             }
1745             if( nFlags & 0x0200 ) dumpString( "property-name" );
1746         }
1747         break;
1748 
1749         case BIFF12_ID_PCDFIELDGROUP:
1750             dumpDec< sal_Int32 >( "parent-field" );
1751             dumpDec< sal_Int32 >( "base-field" );
1752         break;
1753 
1754         case BIFF12_ID_PCDFRANGEPR:
1755             dumpDec< sal_uInt8 >( "group-by", "PCDFRANGEPR-GROUPBY" );
1756             dumpHex< sal_uInt8 >( "flags", "PCDFRANGEPR-FLAGS" );
1757             dumpDec< double >( "start-value" );
1758             dumpDec< double >( "end-value" );
1759             dumpDec< double >( "interval" );
1760         break;
1761 
1762         case BIFF12_ID_PCDFSHAREDITEMS:
1763         {
1764             sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "PCDFSHAREDITEMS-FLAGS" );
1765             dumpDec< sal_Int32 >( "count" );
1766             if( nFlags & 0x0100 ) dumpDec< double >( "min-value" );
1767             if( nFlags & 0x0100 ) dumpDec< double >( "max-value" );
1768         }
1769         break;
1770 
1771         case BIFF12_ID_PCDSHEETSOURCE:
1772         {
1773             sal_uInt8 nIsDefName = dumpBoolean( "is-def-name" );
1774             dumpBoolean( "is-builtin-def-name" );
1775             sal_uInt8 nFlags = dumpHex< sal_uInt8 >( "flags", "PCDWORKSHEETSOURCE-FLAGS" );
1776             if( nFlags & 0x02 ) dumpString( "sheet-name" );
1777             if( nFlags & 0x01 ) dumpString( "rel-id" );
1778             if( nIsDefName == 0 ) dumpRange(); else dumpString( "def-name" );
1779         }
1780         break;
1781 
1782         case BIFF12_ID_PCDSOURCE:
1783             dumpDec< sal_Int32 >( "source-type", "PCDSOURCE-TYPE" );
1784             dumpDec< sal_Int32 >( "connection-id" );
1785         break;
1786 
1787         case BIFF12_ID_PCITEM_ARRAY:
1788         {
1789             sal_uInt16 nType = dumpDec< sal_uInt16 >( "type", "PCITEM_ARRAY-TYPE" );
1790             sal_Int32 nCount = dumpDec< sal_Int32 >( "count" );
1791             mxOut->resetItemIndex();
1792             for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
1793             {
1794                 switch( nType )
1795                 {
1796                     case 1:     dumpDec< double >( "#value" );  break;
1797                     case 2:     dumpString( "#value" );         break;
1798                     case 16:    dumpErrorCode( "#value" );      break;
1799                     case 32:    dumpPivotDateTime( "#value" );  break;
1800                     default:    nIdx = nCount;
1801                 }
1802             }
1803         }
1804         break;
1805 
1806         case BIFF12_ID_PCITEM_BOOL:
1807             dumpBoolean( "value" );
1808         break;
1809 
1810         case BIFF12_ID_PCITEM_DATE:
1811             dumpPivotDateTime( "value" );
1812         break;
1813 
1814         case BIFF12_ID_PCITEM_DOUBLE:
1815             dumpDec< double >( "value" );
1816             // TODO: server formatting
1817         break;
1818 
1819         case BIFF12_ID_PCITEM_ERROR:
1820             dumpErrorCode( "value" );
1821             // TODO: server formatting
1822         break;
1823 
1824         case BIFF12_ID_PCITEM_INDEX:
1825             dumpDec< sal_Int32 >( "index" );
1826         break;
1827 
1828         case BIFF12_ID_PCITEM_MISSING:
1829             // TODO: server formatting
1830         break;
1831 
1832 
1833         case BIFF12_ID_PCITEM_STRING:
1834             dumpString( "value" );
1835             // TODO: server formatting
1836         break;
1837 
1838         case BIFF12_ID_PCITEMA_BOOL:
1839             dumpBoolean( "value" );
1840             // TODO: additional info
1841         break;
1842 
1843         case BIFF12_ID_PCITEMA_DATE:
1844             dumpPivotDateTime( "value" );
1845             // TODO: additional info
1846         break;
1847 
1848         case BIFF12_ID_PCITEMA_DOUBLE:
1849             dumpDec< double >( "value" );
1850             // TODO: additional info
1851         break;
1852 
1853         case BIFF12_ID_PCITEMA_ERROR:
1854             dumpErrorCode( "value" );
1855             // TODO: additional info
1856         break;
1857 
1858         case BIFF12_ID_PCITEMA_MISSING:
1859             // TODO: additional info
1860         break;
1861 
1862         case BIFF12_ID_PCITEMA_STRING:
1863             dumpString( "value" );
1864             // TODO: additional info
1865         break;
1866 
1867         case BIFF12_ID_PHONETICPR:
1868             dumpDec< sal_uInt16 >( "font-id", "FONTNAMES" );
1869             dumpDec< sal_Int32 >( "type", "PHONETICPR-TYPE" );
1870             dumpDec< sal_Int32 >( "alignment", "PHONETICPR-ALIGNMENT" );
1871         break;
1872 
1873         case BIFF12_ID_PICTURE:
1874             dumpString( "rel-id" );
1875         break;
1876 
1877         case BIFF12_ID_PIVOTAREA:
1878             dumpDec< sal_Int32 >( "field" );
1879             dumpDec< sal_uInt8 >( "type", "PIVOTAREA-TYPE" );
1880             dumpHex< sal_uInt8 >( "flags-1", "PIVOTAREA-FLAGS1" );
1881             dumpHex< sal_uInt16 >( "flags-2", "PIVOTAREA-FLAGS2" );
1882         break;
1883 
1884         case BIFF12_ID_PIVOTCACHE:
1885             dumpDec< sal_Int32 >( "cache-id" );
1886             dumpString( "rel-id" );
1887         break;
1888 
1889         case BIFF12_ID_PTCOLFIELDS:
1890             dumpDec< sal_Int32 >( "count" );
1891             mxOut->resetItemIndex();
1892             while( mxStrm->getRemaining() >= 4 )
1893                 dumpDec< sal_Int32 >( "#field", "PT-FIELDINDEX" );
1894         break;
1895 
1896         case BIFF12_ID_PTDATAFIELD:
1897             dumpDec< sal_Int32 >( "field" );
1898             dumpDec< sal_Int32 >( "subtotal", "PTDATAFIELD-SUBTOTAL" );
1899             dumpDec< sal_Int32 >( "show-data-as", "PTDATAFIELD-SHOWDATAAS" );
1900             dumpDec< sal_Int32 >( "base-field" );
1901             dumpDec< sal_Int32 >( "base-item", "PTDATAFIELD-BASEITEM" );
1902             dumpDec< sal_Int32 >( "number-format" );
1903             if( dumpBool< sal_uInt8 >( "has-name" ) )
1904                 dumpString( "name" );
1905         break;
1906 
1907         case BIFF12_ID_PTDEFINITION:
1908         {
1909             dumpDec< sal_uInt8 >( "created-version" );
1910             dumpHex< sal_uInt8 >( "flags-1", "PTDEFINITION-FLAGS1" );
1911             dumpHex< sal_uInt16 >( "flags-2", "PTDEFINITION-FLAGS2" );
1912             sal_uInt32 nFlags3 = dumpHex< sal_uInt32 >( "flags-3", "PTDEFINITION-FLAGS3" );
1913             sal_uInt32 nFlags4 = dumpHex< sal_uInt32 >( "flags-4", "PTDEFINITION-FLAGS4" );
1914             dumpDec< sal_uInt8 >( "datafield-axis", "PTDEFINITION-DATAFIELD-AXIS" );
1915             dumpDec< sal_uInt8 >( "page-wrap" );
1916             dumpDec< sal_uInt8 >( "refreshed-version" );
1917             dumpDec< sal_uInt8 >( "min-refresh-version" );
1918             dumpDec< sal_Int32 >( "datafield-position", "PTDEFINITION-DATAFIELD-POS" );
1919             dumpDec< sal_Int16 >( "autoformat-id" );
1920             dumpUnused( 2 );
1921             dumpDec< sal_Int32 >( "next-chart-id" );
1922             dumpDec< sal_Int32 >( "cache-id" );
1923             dumpString( "name" );
1924             if( nFlags3 & 0x00080000 ) dumpString( "data-caption" );
1925             if( nFlags3 & 0x00100000 ) dumpString( "grand-total-caption" );
1926             if( (nFlags4 & 0x00000040) == 0 ) dumpString( "error-caption" );
1927             if( (nFlags4 & 0x00000080) == 0 ) dumpString( "missing-caption" );
1928             if( nFlags3 & 0x00200000 ) dumpString( "page-field-style" );
1929             if( nFlags3 & 0x00400000 ) dumpString( "pivot-table-style" );
1930             if( nFlags3 & 0x00800000 ) dumpString( "vacated-style" );
1931             if( nFlags3 & 0x40000000 ) dumpString( "tag" );
1932             if( nFlags4 & 0x00000800 ) dumpString( "col-header-caption" );
1933             if( nFlags4 & 0x00000400 ) dumpString( "row-header-caption" );
1934         }
1935         break;
1936 
1937         case BIFF12_ID_PTFIELD:
1938             dumpHex< sal_uInt32 >( "flags-1", "PTFIELD-FLAGS1" );
1939             dumpDec< sal_Int32 >( "num-fmt" );
1940             dumpHex< sal_uInt32 >( "flags-2", "PTFIELD-FLAGS2" );
1941             dumpDec< sal_Int32 >( "autoshow-items" );
1942             dumpDec< sal_Int32 >( "autoshow-datafield-idx" );
1943         break;
1944 
1945         case BIFF12_ID_PTFILTER:
1946         {
1947             dumpDec< sal_Int32 >( "field" );
1948             dumpDec< sal_Int32 >( "member-prop-field" );
1949             dumpDec< sal_Int32 >( "type", "PTFILTER-TYPE" );
1950             dumpUnused( 4 );
1951             dumpDec< sal_Int32 >( "unique-id" );
1952             dumpDec< sal_Int32 >( "measure-data-field" );
1953             dumpDec< sal_Int32 >( "measure-data-hierarchy" );
1954             sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "PTFILTER-FLAGS" );
1955             if( nFlags & 0x0001 ) dumpString( "name" );
1956             if( nFlags & 0x0002 ) dumpString( "description" );
1957             if( nFlags & 0x0004 ) dumpString( "str-value1" );
1958             if( nFlags & 0x0008 ) dumpString( "str-value2" );
1959         }
1960         break;
1961 
1962         case BIFF12_ID_PTFITEM:
1963         {
1964             dumpDec< sal_uInt8 >( "type", "PTFITEM-TYPE" );
1965             sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "PTFITEM-FLAGS" );
1966             dumpDec< sal_Int32 >( "cache-idx" );
1967             if( nFlags & 0x0010 ) dumpString( "display-name" );
1968         }
1969         break;
1970 
1971         case BIFF12_ID_PTLOCATION:
1972             dumpRange( "location" );
1973             dumpDec< sal_Int32 >( "first-header-row" );
1974             dumpDec< sal_Int32 >( "first-data-row" );
1975             dumpDec< sal_Int32 >( "first-data-col" );
1976             dumpDec< sal_Int32 >( "page-row-count" );
1977             dumpDec< sal_Int32 >( "page-col-count" );
1978         break;
1979 
1980         case BIFF12_ID_PTPAGEFIELD:
1981         {
1982             dumpDec< sal_Int32 >( "field" );
1983             dumpDec< sal_Int32 >( "cache-item", "PTPAGEFIELD-ITEM" );
1984             dumpDec< sal_Int32 >( "olap-hierarchy" );
1985             sal_uInt8 nFlags = dumpHex< sal_uInt8 >( "flags", "PTPAGEFIELD-FLAGS" );
1986             if( nFlags & 0x01 ) dumpString( "unique-name" );
1987             if( nFlags & 0x02 ) dumpString( "olap-caption" );
1988         }
1989         break;
1990 
1991         case BIFF12_ID_PTREFERENCE:
1992             dumpDec< sal_Int32 >( "field", "PT-FIELDINDEX" );
1993             dumpDec< sal_Int32 >( "item-count" );
1994             dumpHex< sal_uInt16 >( "flags-1", "PTREFERENCE-FLAGS1" );
1995             dumpHex< sal_uInt8 >( "flags-2", "PTREFERENCE-FLAGS2" );
1996         break;
1997 
1998         case BIFF12_ID_PTROWFIELDS:
1999             dumpDec< sal_Int32 >( "count" );
2000             mxOut->resetItemIndex();
2001             while( mxStrm->getRemaining() >= 4 )
2002                 dumpDec< sal_Int32 >( "#field", "PT-FIELDINDEX" );
2003         break;
2004 
2005         case BIFF12_ID_QUERYTABLE:
2006             dumpHex< sal_uInt32 >( "flags", "QUERYTABLE-FLAGS" );
2007             dumpDec< sal_uInt16 >( "autoformat-id" );
2008             dumpDec< sal_Int32 >( "connection-id" );
2009             dumpString( "defined-name" );
2010         break;
2011 
2012         case BIFF12_ID_ROW:
2013             dumpRowIndex();
2014             dumpDec< sal_Int32 >( "custom-xf-id" );
2015             dumpDec< sal_uInt16 >( "height", "CONV-TWIP-TO-PT" );
2016             dumpHex< sal_uInt16 >( "flags", "ROW-FLAGS1" );
2017             dumpHex< sal_uInt8 >( "flags", "ROW-FLAGS2" );
2018             mxOut->resetItemIndex();
2019             for( sal_Int32 nSpan = 0, nSpanCount = dumpDec< sal_Int32 >( "row-spans-count" ); !mxStrm->isEof() && (nSpan < nSpanCount); ++nSpan )
2020                 dumpRowRange( "#row-spans" );
2021         break;
2022 
2023         case BIFF12_ID_ROWBREAKS:
2024             dumpDec< sal_Int32 >( "count" );
2025             dumpDec< sal_Int32 >( "manual-count" );
2026         break;
2027 
2028         case BIFF12_ID_SCENARIO:
2029             dumpDec< sal_uInt16 >( "cell-count" );
2030             // two longs instead of flag field
2031             dumpDec< sal_Int32 >( "locked", "BOOLEAN" );
2032             dumpDec< sal_Int32 >( "hidden", "BOOLEAN" );
2033             dumpString( "name" );
2034             dumpString( "comment" );
2035             dumpString( "user" );
2036         break;
2037 
2038         case BIFF12_ID_SCENARIOS:
2039             dumpDec< sal_uInt16 >( "selected" );
2040             dumpDec< sal_uInt16 >( "shown" );
2041             dumpRangeList( "result-cells" );
2042         break;
2043 
2044         case BIFF12_ID_SELECTION:
2045             dumpDec< sal_Int32 >( "pane", "PANE-ID" );
2046             dumpAddress( "active-cell" );
2047             dumpDec< sal_Int32 >( "active-cell-id" );
2048             dumpRangeList( "selection" );
2049         break;
2050 
2051         case BIFF12_ID_SHAREDFMLA:
2052             dumpRange( "formula-range" );
2053             mxFmlaObj->dumpCellFormula();
2054         break;
2055 
2056         case BIFF12_ID_SHEET:
2057             dumpDec< sal_Int32 >( "sheet-state", "SHEET-STATE" );
2058             dumpDec< sal_Int32 >( "sheet-id" );
2059             dumpString( "rel-id" );
2060             dumpString( "sheet-name" );
2061         break;
2062 
2063         case BIFF12_ID_SHEETFORMATPR:
2064             dumpDec< sal_Int32 >( "default-col-width", "CONV-COLWIDTH" );
2065             dumpDec< sal_uInt16 >( "base-col-width" );
2066             dumpDec< sal_uInt16 >( "default-row-height", "CONV-TWIP-TO-PT" );
2067             dumpHex< sal_uInt16 >( "flags", "SHEETFORMATPR-FLAGS" );
2068             dumpDec< sal_uInt8 >( "max-row-outline" );
2069             dumpDec< sal_uInt8 >( "max-col-outline" );
2070         break;
2071 
2072         case BIFF12_ID_SHEETPR:
2073             dumpHex< sal_uInt16 >( "flags1", "SHEETPR-FLAGS1" );
2074             dumpHex< sal_uInt8 >( "flags2", "SHEETPR-FLAGS2" );
2075             dumpColor( "tab-color" );
2076             dumpAddress( "window-anchor" );
2077             dumpString( "codename" );
2078         break;
2079 
2080         case BIFF12_ID_SHEETPROTECTION:
2081             dumpHex< sal_uInt16 >( "password-hash" );
2082             // no flags field for all these boolean flags?!?
2083             dumpDec< sal_Int32 >( "sheet-locked", "BOOLEAN" );
2084             dumpDec< sal_Int32 >( "objects-locked", "BOOLEAN" );
2085             dumpDec< sal_Int32 >( "scenarios-locked", "BOOLEAN" );
2086             dumpDec< sal_Int32 >( "format-cells-locked", "BOOLEAN" );
2087             dumpDec< sal_Int32 >( "format-columns-locked", "BOOLEAN" );
2088             dumpDec< sal_Int32 >( "format-rows-locked", "BOOLEAN" );
2089             dumpDec< sal_Int32 >( "insert-columns-locked", "BOOLEAN" );
2090             dumpDec< sal_Int32 >( "insert-rows-locked", "BOOLEAN" );
2091             dumpDec< sal_Int32 >( "insert-hyperlinks-locked", "BOOLEAN" );
2092             dumpDec< sal_Int32 >( "delete-columns-locked", "BOOLEAN" );
2093             dumpDec< sal_Int32 >( "delete-rows-locked", "BOOLEAN" );
2094             dumpDec< sal_Int32 >( "select-locked-cells-locked", "BOOLEAN" );
2095             dumpDec< sal_Int32 >( "sort-locked", "BOOLEAN" );
2096             dumpDec< sal_Int32 >( "autofilter-locked", "BOOLEAN" );
2097             dumpDec< sal_Int32 >( "pivot-tables-locked", "BOOLEAN" );
2098             dumpDec< sal_Int32 >( "select-unlocked-cells-locked", "BOOLEAN" );
2099         break;
2100 
2101         case BIFF12_ID_SHEETVIEW:
2102             dumpHex< sal_uInt16 >( "flags", "SHEETVIEW-FLAGS" );
2103             dumpDec< sal_Int32 >( "view-type", "SHEETVIEW-TYPE" );
2104             dumpAddress( "top-left" );
2105             dumpDec< sal_Int32 >( "gridcolor-id", "PALETTE-COLORS" );
2106             dumpDec< sal_uInt16 >( "zoom-scale", "CONV-PERCENT" );
2107             dumpDec< sal_uInt16 >( "zoom-scale-normal", "CONV-PERCENT" );
2108             dumpDec< sal_uInt16 >( "zoom-scale-sheet-layout", "CONV-PERCENT" );
2109             dumpDec< sal_uInt16 >( "zoom-scale-page-layout", "CONV-PERCENT" );
2110             dumpDec< sal_Int32 >( "workbookview-id" );
2111         break;
2112 
2113         case BIFF12_ID_SI:
2114             dumpString( "string", true );
2115         break;
2116 
2117         case BIFF12_ID_SST:
2118             dumpDec< sal_Int32 >( "string-cell-count" );
2119             dumpDec< sal_Int32 >( "sst-size" );
2120         break;
2121 
2122         case BIFF12_ID_TABLE:
2123             dumpRange();
2124             dumpDec< sal_Int32 >( "type", "TABLE-TYPE" );
2125             dumpDec< sal_Int32 >( "id" );
2126             dumpDec< sal_Int32 >( "header-rows" );
2127             dumpDec< sal_Int32 >( "totals-rows" );
2128             dumpHex< sal_uInt32 >( "flags", "TABLE-FLAGS" );
2129             dumpDec< sal_Int32 >( "headerrow-dxf-id" );
2130             dumpDec< sal_Int32 >( "data-dxf-id" );
2131             dumpDec< sal_Int32 >( "totalsrow-dxf-id" );
2132             dumpDec< sal_Int32 >( "table-border-dxf-id" );
2133             dumpDec< sal_Int32 >( "headerrow-border-dxf-id" );
2134             dumpDec< sal_Int32 >( "totalsrow-border-dxf-id" );
2135             dumpDec< sal_Int32 >( "connection-id" );
2136             dumpString( "name" );
2137             dumpString( "display-name" );
2138             dumpString( "comment" );
2139             dumpString( "headerrow-cell-style" );
2140             dumpString( "data-cell-style" );
2141             dumpString( "totalsrow-cell-style" );
2142         break;
2143 
2144         case BIFF12_ID_TABLEPART:
2145             dumpString( "rel-id" );
2146         break;
2147 
2148         case BIFF12_ID_TABLESTYLEINFO:
2149             dumpHex< sal_uInt16 >( "flags", "TABLESTYLEINFO-FLAGS" );
2150             dumpString( "style-name" );
2151         break;
2152 
2153         case BIFF12_ID_TOP10FILTER:
2154             dumpHex< sal_uInt8 >( "flags", "TOP10FILTER-FLAGS" );
2155             dumpDec< double >( "value" );
2156             dumpDec< double >( "cell-value" );
2157         break;
2158 
2159         case BIFF12_ID_VOLTYPEMAIN:
2160             dumpString( "first" );
2161         break;
2162 
2163         case BIFF12_ID_VOLTYPESTP:
2164             dumpString( "topic-value" );
2165         break;
2166 
2167         case BIFF12_ID_VOLTYPETR:
2168             dumpAddress( "ref" );
2169             dumpDec< sal_Int32 >( "sheet-id" );
2170         break;
2171 
2172         case BIFF12_ID_WEBPR:
2173         {
2174             dumpHex< sal_uInt32 >( "flags", "WEBPR-FLAGS" );
2175             sal_uInt8 nStrFlags = dumpHex< sal_uInt8 >( "string-flags", "WEBPR-STRINGFLAGS" );
2176             if( nStrFlags & 0x04 ) dumpString( "url" );
2177             if( nStrFlags & 0x01 ) dumpString( "post-method" );
2178             if( nStrFlags & 0x02 ) dumpString( "edit-page" );
2179         }
2180         break;
2181 
2182         case BIFF12_ID_WORKBOOKPR:
2183             dumpHex< sal_uInt32 >( "flags", "WORKBBOKPR-FLAGS" );
2184             dumpDec< sal_Int32 >( "default-theme-version" );
2185             dumpString( "codename" );
2186         break;
2187 
2188         case BIFF12_ID_WORKBOOKVIEW:
2189             dumpDec< sal_Int32 >( "x-window" );
2190             dumpDec< sal_Int32 >( "y-window" );
2191             dumpDec< sal_Int32 >( "win-width" );
2192             dumpDec< sal_Int32 >( "win-height" );
2193             dumpDec< sal_Int32 >( "tabbar-ratio" );
2194             dumpDec< sal_Int32 >( "first-sheet" );
2195             dumpDec< sal_Int32 >( "active-sheet" );
2196             dumpHex< sal_uInt8 >( "flags", "WORKBOOKVIEW-FLAGS" );
2197         break;
2198 
2199         case BIFF12_ID_XF:
2200             dumpDec< sal_uInt16 >( "parent-xf-id" );
2201             dumpDec< sal_uInt16 >( "numfmt-id" );
2202             dumpDec< sal_uInt16 >( "font-id", "FONTNAMES" );
2203             dumpDec< sal_uInt16 >( "fill-id" );
2204             dumpDec< sal_uInt16 >( "border-id" );
2205             dumpHex< sal_uInt32 >( "alignment", "XF-ALIGNMENT" );
2206             dumpHex< sal_uInt16 >( "used-flags", "XF-USEDFLAGS" );
2207         break;
2208     }
2209 }
2210 
2211 void RecordStreamObject::dumpGradientHead()
2212 {
2213     dumpDec< sal_Int32 >( "gradient-type", "FILL-GRADIENTTYPE" );
2214     dumpDec< double >( "linear-angle" );
2215     dumpDec< double >( "pos-left" );
2216     dumpDec< double >( "pos-right" );
2217     dumpDec< double >( "pos-top" );
2218     dumpDec< double >( "pos-bottom" );
2219 }
2220 
2221 void RecordStreamObject::dumpCellHeader( bool bWithColumn )
2222 {
2223     if( bWithColumn ) dumpColIndex();
2224     dumpHex< sal_uInt32 >( "xf-id", "CELL-XFID" );
2225 }
2226 
2227 // ============================================================================
2228 
2229 RootStorageObject::RootStorageObject( const DumperBase& rParent )
2230 {
2231     StorageObjectBase::construct( rParent );
2232 }
2233 
2234 void RootStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
2235 {
2236     OUString aExt = InputOutputHelper::getFileNameExtension( rStrmName );
2237     if(
2238         aExt.equalsIgnoreAsciiCaseAscii( "xlsb" ) ||
2239         aExt.equalsIgnoreAsciiCaseAscii( "xlsm" ) ||
2240         aExt.equalsIgnoreAsciiCaseAscii( "xlsx" ) ||
2241         aExt.equalsIgnoreAsciiCaseAscii( "xltm" ) ||
2242         aExt.equalsIgnoreAsciiCaseAscii( "xltx" ) )
2243     {
2244         Dumper( getContext(), rxStrm, rSysFileName ).dump();
2245     }
2246     else if(
2247         aExt.equalsIgnoreAsciiCaseAscii( "xla" ) ||
2248         aExt.equalsIgnoreAsciiCaseAscii( "xlc" ) ||
2249         aExt.equalsIgnoreAsciiCaseAscii( "xlm" ) ||
2250         aExt.equalsIgnoreAsciiCaseAscii( "xls" ) ||
2251         aExt.equalsIgnoreAsciiCaseAscii( "xlt" ) ||
2252         aExt.equalsIgnoreAsciiCaseAscii( "xlw" ) )
2253     {
2254         ::oox::dump::biff::Dumper( getContext(), rxStrm, rSysFileName ).dump();
2255     }
2256     else if(
2257         aExt.equalsIgnoreAsciiCaseAscii( "pptx" ) ||
2258         aExt.equalsIgnoreAsciiCaseAscii( "potx" ) )
2259     {
2260         ::oox::dump::pptx::Dumper( getContext(), rxStrm, rSysFileName ).dump();
2261     }
2262     else if(
2263         aExt.equalsIgnoreAsciiCaseAscii( "xml" ) ||
2264         aExt.equalsIgnoreAsciiCaseAscii( "vml" ) ||
2265         aExt.equalsIgnoreAsciiCaseAscii( "rels" ) )
2266     {
2267         XmlStreamObject( *this, rxStrm, rSysFileName ).dump();
2268     }
2269     else if( aExt.equalsIgnoreAsciiCaseAscii( "bin" ) )
2270     {
2271         if( rStrgPath.equalsAscii( "xl" ) && rStrmName.equalsAscii( "vbaProject.bin" ) )
2272         {
2273             StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, false ) );
2274             VbaProjectStorageObject( *this, xStrg, rSysFileName ).dump();
2275         }
2276         else if( rStrgPath.equalsAscii( "xl/embeddings" ) )
2277         {
2278             StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, false ) );
2279             OleStorageObject( *this, xStrg, rSysFileName ).dump();
2280         }
2281         else if(
2282             rStrgPath.equalsAscii( "xl" ) ||
2283             rStrgPath.equalsAscii( "xl/chartsheets" ) ||
2284             rStrgPath.equalsAscii( "xl/dialogsheets" ) ||
2285             rStrgPath.equalsAscii( "xl/externalLinks" ) ||
2286             rStrgPath.equalsAscii( "xl/macrosheets" ) ||
2287             rStrgPath.equalsAscii( "xl/pivotCache" ) ||
2288             rStrgPath.equalsAscii( "xl/pivotTables" ) ||
2289             rStrgPath.equalsAscii( "xl/queryTables" ) ||
2290             rStrgPath.equalsAscii( "xl/tables" ) ||
2291             rStrgPath.equalsAscii( "xl/worksheets" ) )
2292         {
2293             RecordStreamObject( *this, rxStrm, rSysFileName ).dump();
2294         }
2295         else if( rStrgPath.equalsAscii( "xl/activeX" ) )
2296         {
2297             StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, true ) );
2298             ActiveXStorageObject( *this, xStrg, rSysFileName ).dump();
2299         }
2300         else
2301         {
2302             BinaryStreamObject( *this, rxStrm, rSysFileName ).dump();
2303         }
2304     }
2305 }
2306 
2307 // ============================================================================
2308 
2309 #define DUMP_XLSB_CONFIG_ENVVAR "OOO_XLSBDUMPER"
2310 
2311 Dumper::Dumper( const FilterBase& rFilter )
2312 {
2313     ConfigRef xCfg( new Config( DUMP_XLSB_CONFIG_ENVVAR, rFilter ) );
2314     DumperBase::construct( xCfg );
2315 }
2316 
2317 Dumper::Dumper( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName )
2318 {
2319     if( rxContext.is() && rxInStrm.is() )
2320     {
2321         StorageRef xStrg( new ZipStorage( getContext(), rxInStrm ) );
2322         MediaDescriptor aMediaDesc;
2323         ConfigRef xCfg( new Config( DUMP_XLSB_CONFIG_ENVVAR, rxContext, xStrg, rSysFileName, aMediaDesc ) );
2324         DumperBase::construct( xCfg );
2325     }
2326 }
2327 
2328 void Dumper::implDump()
2329 {
2330     RootStorageObject( *this ).dump();
2331 }
2332 
2333 // ============================================================================
2334 
2335 } // namespace xlsb
2336 } // namespace dump
2337 } // namespace oox
2338 
2339 #endif
2340