xref: /aoo42x/main/oox/source/dump/biffdumper.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/biffdumper.hxx"
29 
30 #include <osl/thread.h>
31 #include <rtl/tencinfo.h>
32 #include "oox/core/filterbase.hxx"
33 #include "oox/dump/oledumper.hxx"
34 #include "oox/ole/olestorage.hxx"
35 #include "oox/xls/biffdetector.hxx"
36 #include "oox/xls/biffinputstream.hxx"
37 #include "oox/xls/formulabase.hxx"
38 
39 #if OOX_INCLUDE_DUMPER
40 
41 namespace oox {
42 namespace dump {
43 namespace biff {
44 
45 // ============================================================================
46 
47 using namespace ::com::sun::star::io;
48 using namespace ::com::sun::star::lang;
49 using namespace ::com::sun::star::uno;
50 using namespace ::com::sun::star::util;
51 using namespace ::oox::xls;
52 
53 using ::comphelper::MediaDescriptor;
54 using ::oox::core::FilterBase;
55 using ::rtl::OString;
56 using ::rtl::OStringBuffer;
57 using ::rtl::OStringToOUString;
58 using ::rtl::OUString;
59 using ::rtl::OUStringBuffer;
60 
61 // ============================================================================
62 
63 namespace  {
64 
65 // constants ------------------------------------------------------------------
66 
67 const sal_uInt16 BIFF_FONTFLAG_BOLD         = 0x0001;
68 const sal_uInt16 BIFF_FONTFLAG_ITALIC       = 0x0002;
69 
70 const sal_uInt16 BIFF_OBJTYPE_GROUP         = 0;
71 const sal_uInt16 BIFF_OBJTYPE_LINE          = 1;
72 const sal_uInt16 BIFF_OBJTYPE_RECTANGLE     = 2;
73 const sal_uInt16 BIFF_OBJTYPE_OVAL          = 3;
74 const sal_uInt16 BIFF_OBJTYPE_ARC           = 4;
75 const sal_uInt16 BIFF_OBJTYPE_CHART         = 5;
76 const sal_uInt16 BIFF_OBJTYPE_TEXT          = 6;
77 const sal_uInt16 BIFF_OBJTYPE_BUTTON        = 7;
78 const sal_uInt16 BIFF_OBJTYPE_PICTURE       = 8;
79 const sal_uInt16 BIFF_OBJTYPE_POLYGON       = 9;
80 const sal_uInt16 BIFF_OBJTYPE_CHECKBOX      = 11;
81 const sal_uInt16 BIFF_OBJTYPE_OPTIONBUTTON  = 12;
82 const sal_uInt16 BIFF_OBJTYPE_EDIT          = 13;
83 const sal_uInt16 BIFF_OBJTYPE_LABEL         = 14;
84 const sal_uInt16 BIFF_OBJTYPE_DIALOG        = 15;
85 const sal_uInt16 BIFF_OBJTYPE_SPIN          = 16;
86 const sal_uInt16 BIFF_OBJTYPE_SCROLLBAR     = 17;
87 const sal_uInt16 BIFF_OBJTYPE_LISTBOX       = 18;
88 const sal_uInt16 BIFF_OBJTYPE_GROUPBOX      = 19;
89 const sal_uInt16 BIFF_OBJTYPE_DROPDOWN      = 20;
90 const sal_uInt16 BIFF_OBJTYPE_NOTE          = 25;
91 const sal_uInt16 BIFF_OBJTYPE_DRAWING       = 30;
92 
93 const sal_uInt16 BIFF_OBJFLAGS_CONTROL      = 0x0010;   /// Form control.
94 const sal_uInt16 BIFF_OBJFLAGS_CTLSSTREAM   = 0x0020;   /// Data in Ctls stream.
95 
96 const sal_uInt16 BIFF_STYLE_BUILTIN         = 0x8000;
97 
98 const sal_uInt16 BIFF_PT_NOSTRING           = 0xFFFF;
99 
100 // ----------------------------------------------------------------------------
101 
102 void lclDumpDffClientPos( const OutputRef& rxOut, const BinaryInputStreamRef& rxStrm, const String& rName, sal_uInt16 nSubScale )
103 {
104     MultiItemsGuard aMultiGuard( rxOut );
105     TableGuard aTabGuard( rxOut, 17 );
106     {
107         sal_uInt16 nPos = rxStrm->readuInt16();
108         ItemGuard aItem( rxOut, rName );
109         rxOut->writeDec( nPos );
110     }
111     {
112         sal_uInt16 nSubUnits = rxStrm->readuInt16();
113         ItemGuard aItem( rxOut, "sub-units" );
114         rxOut->writeDec( nSubUnits );
115         rxOut->writeChar( '/' );
116         rxOut->writeDec( nSubScale );
117     }
118 }
119 
120 void lclDumpDffClientRect( const OutputRef& rxOut, const BinaryInputStreamRef& rxStrm )
121 {
122     lclDumpDffClientPos( rxOut, rxStrm, "start-col", 1024 );
123     lclDumpDffClientPos( rxOut, rxStrm, "start-row", 256 );
124     lclDumpDffClientPos( rxOut, rxStrm, "end-col", 1024 );
125     lclDumpDffClientPos( rxOut, rxStrm, "end-row", 256 );
126 }
127 
128 } // namespace
129 
130 // ============================================================================
131 // ============================================================================
132 
133 BiffDffStreamObject::BiffDffStreamObject( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm )
134 {
135     DffStreamObject::construct( rParent, rxStrm );
136 }
137 
138 void BiffDffStreamObject::implDumpClientAnchor()
139 {
140     dumpHex< sal_uInt16 >( "flags", "DFF-CLIENTANCHOR-FLAGS" );
141     lclDumpDffClientRect( mxOut, mxStrm );
142 }
143 
144 // ============================================================================
145 
146 BiffCtlsStreamObject::BiffCtlsStreamObject( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm )
147 {
148     InputObjectBase::construct( rParent, rxStrm );
149     mnStartPos = mnLength = 0;
150 }
151 
152 void BiffCtlsStreamObject::dumpControl( sal_uInt32 nStartPos, sal_uInt32 nLength )
153 {
154     mnStartPos = nStartPos;
155     mnLength = nLength;
156     dump();
157     mnStartPos = mnLength = 0;
158 }
159 
160 void BiffCtlsStreamObject::implDump()
161 {
162     if( mnLength > 0 )
163     {
164         mxOut->emptyLine();
165         writeEmptyItem( "CTLS-START" );
166         {
167             IndentGuard aIndGuard( mxOut );
168             mxStrm->seek( mnStartPos );
169             BinaryInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, mnLength ) );
170             FormControlStreamObject( *this, xRelStrm ).dump();
171         }
172         writeEmptyItem( "CTLS-END" );
173         mxOut->emptyLine();
174     }
175 }
176 
177 // ============================================================================
178 // ============================================================================
179 
180 BiffConfig::BiffConfig( const Config& rParent, BiffType eBiff ) :
181     meBiff( eBiff )
182 {
183     Config::construct( rParent );
184 }
185 
186 bool BiffConfig::implIsValid() const
187 {
188     return (meBiff != BIFF_UNKNOWN) && Config::implIsValid();
189 }
190 
191 NameListRef BiffConfig::implGetNameList( const OUString& rKey ) const
192 {
193     NameListRef xList = Config::implGetNameList( rKey );
194     if( !xList )
195     {
196         OUString aBaseKey = rKey + CREATE_OUSTRING( "-BIFF" );
197         switch( meBiff )
198         {
199             // fall-through intended!
200             case BIFF8: if( !xList ) xList = Config::implGetNameList( aBaseKey + OUString( sal_Unicode( '8' ) ) );
201             case BIFF5: if( !xList ) xList = Config::implGetNameList( aBaseKey + OUString( sal_Unicode( '5' ) ) );
202             case BIFF4: if( !xList ) xList = Config::implGetNameList( aBaseKey + OUString( sal_Unicode( '4' ) ) );
203             case BIFF3: if( !xList ) xList = Config::implGetNameList( aBaseKey + OUString( sal_Unicode( '3' ) ) );
204             case BIFF2: if( !xList ) xList = Config::implGetNameList( aBaseKey + OUString( sal_Unicode( '2' ) ) );
205             case BIFF_UNKNOWN: break;
206         }
207     }
208     return xList;
209 }
210 
211 // ============================================================================
212 
213 BiffSharedData::BiffSharedData( BiffType eBiff ) :
214     meBiff( eBiff ),
215     meTextEnc( osl_getThreadTextEncoding() )
216 {
217 }
218 
219 void BiffSharedData::initializePerSheet()
220 {
221     maFontEncs.clear();
222     maXfFontIds.clear();
223     meTextEnc = osl_getThreadTextEncoding();
224 }
225 
226 void BiffSharedData::setTextEncoding( rtl_TextEncoding eTextEnc )
227 {
228     if( eTextEnc != RTL_TEXTENCODING_DONTKNOW )
229         meTextEnc = eTextEnc;
230 }
231 
232 sal_uInt16 BiffSharedData::getFontCount() const
233 {
234     return static_cast< sal_uInt16 >( maFontEncs.size() );
235 }
236 
237 rtl_TextEncoding BiffSharedData::getFontEncoding( sal_uInt16 nFontId ) const
238 {
239     return (nFontId < getFontCount()) ? maFontEncs[ nFontId ] : meTextEnc;
240 }
241 
242 void BiffSharedData::appendFontEncoding( rtl_TextEncoding eFontEnc )
243 {
244     maFontEncs.push_back( (eFontEnc == RTL_TEXTENCODING_DONTKNOW) ? meTextEnc : eFontEnc );
245     if( maFontEncs.size() == 4 )
246         maFontEncs.push_back( meTextEnc );
247 }
248 
249 sal_uInt16 BiffSharedData::getXfCount() const
250 {
251     return static_cast< sal_uInt16 >( maXfFontIds.size() );
252 }
253 
254 rtl_TextEncoding BiffSharedData::getXfEncoding( sal_uInt16 nXfId ) const
255 {
256     sal_uInt16 nFontId = (nXfId < getXfCount()) ? maXfFontIds[ nXfId ] : 0;
257     return getFontEncoding( nFontId );
258 }
259 
260 void BiffSharedData::appendXfFontId( sal_uInt16 nFontId )
261 {
262     maXfFontIds.push_back( nFontId );
263 }
264 
265 bool BiffSharedData::implIsValid() const
266 {
267     return meBiff != BIFF_UNKNOWN;
268 }
269 
270 // ============================================================================
271 
272 BiffObjectBase::~BiffObjectBase()
273 {
274 }
275 
276 void BiffObjectBase::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, BiffType eBiff, const OUString& rSysFileName )
277 {
278     if( rParent.isValid() && rxStrm.get() && (eBiff != BIFF_UNKNOWN) )
279     {
280         mxBiffData.reset( new BiffSharedData( eBiff ) );
281         mxBiffStrm.reset( new BiffInputStream( *rxStrm ) );
282         RecordObjectBase::construct( rParent, rxStrm, rSysFileName, mxBiffStrm, "RECORD-NAMES", "SIMPLE-RECORDS" );
283         if( RecordObjectBase::implIsValid() )
284         {
285             reconstructConfig( ConfigRef( new BiffConfig( cfg(), eBiff ) ) );
286             mxDffObj.reset( new BiffDffStreamObject( *this, mxBiffStrm ) );
287             if( StorageBase* pRootStrg = cfg().getRootStorage().get() )
288             {
289                 BinaryInputStreamRef xCtlsStrm( new BinaryXInputStream( pRootStrg->openInputStream( CREATE_OUSTRING( "Ctls" ) ), true ) );
290                 mxCtlsObj.reset( new BiffCtlsStreamObject( *this, xCtlsStrm ) );
291             }
292             const Config& rCfg = cfg();
293             mxErrCodes = rCfg.getNameList( "ERRORCODES" );
294             mxConstType = rCfg.getNameList( "CONSTVALUE-TYPE" );
295             mxResultType = rCfg.getNameList( "FORMULA-RESULTTYPE" );
296             mnLastRecId = BIFF_ID_UNKNOWN;
297             mbMergeContRec = rCfg.getBoolOption( "merge-continue-record", true );
298         }
299     }
300 }
301 
302 void BiffObjectBase::construct( const BiffObjectBase& rParent )
303 {
304     *this = rParent;
305 }
306 
307 bool BiffObjectBase::implIsValid() const
308 {
309     return isValid( mxBiffData ) && mxBiffStrm.get() && isValid( mxDffObj ) && InputObjectBase::implIsValid();
310 }
311 
312 bool BiffObjectBase::implStartRecord( BinaryInputStream&, sal_Int64& ornRecPos, sal_Int64& ornRecId, sal_Int64& ornRecSize )
313 {
314     // previous record
315     mnLastRecId = mxBiffStrm->getRecId();
316     switch( mnLastRecId )
317     {
318         case BIFF_ID_CHBEGIN:
319             mxOut->incIndent();
320         break;
321     }
322 
323     // start next record
324     bool bValid = mxBiffStrm->startNextRecord();
325     ornRecPos = mxBiffStrm->tellBase() - 4;
326     ornRecId = mxBiffStrm->getRecId();
327 
328     // special CONTINUE handling
329     mxBiffStrm->resetRecord( mbMergeContRec );
330     if( mbMergeContRec ) switch( mxBiffStrm->getRecId() )
331     {
332         case BIFF_ID_OBJ:
333         case BIFF_ID_TXO:
334         case BIFF_ID_EOF:
335         case BIFF_ID_CONT:
336             mxBiffStrm->resetRecord( false );
337         break;
338         case BIFF_ID_MSODRAWINGGROUP:
339         case BIFF_ID_CHESCHERFORMAT:
340             mxBiffStrm->resetRecord( true, mxBiffStrm->getRecId() );
341         break;
342     }
343 
344     // record specific settings
345     switch( mxBiffStrm->getRecId() )
346     {
347         case BIFF2_ID_BOF:
348         case BIFF3_ID_BOF:
349         case BIFF4_ID_BOF:
350         case BIFF5_ID_BOF:
351         case BIFF_ID_INTERFACEHDR:
352             mxBiffStrm->enableDecoder( false );
353         break;
354         case BIFF_ID_CHEND:
355             mxOut->decIndent();
356         break;
357     }
358 
359     ornRecSize = mxBiffStrm->size();
360     return bValid;
361 }
362 
363 OUString BiffObjectBase::getErrorName( sal_uInt8 nErrCode ) const
364 {
365     return cfg().getName( mxErrCodes, nErrCode );
366 }
367 
368 // ----------------------------------------------------------------------------
369 
370 sal_Int32 BiffObjectBase::readCol( bool bCol16Bit )
371 {
372     return bCol16Bit ? mxBiffStrm->readuInt16() : mxBiffStrm->readuInt8();
373 }
374 
375 sal_Int32 BiffObjectBase::readRow( bool bRow32Bit )
376 {
377     return bRow32Bit ? mxBiffStrm->readInt32() : mxBiffStrm->readuInt16();
378 }
379 
380 void BiffObjectBase::readAddress( Address& orAddress, bool bCol16Bit, bool bRow32Bit )
381 {
382     orAddress.mnRow = readRow( bRow32Bit );
383     orAddress.mnCol = readCol( bCol16Bit );
384 }
385 
386 void BiffObjectBase::readRange( Range& orRange, bool bCol16Bit, bool bRow32Bit )
387 {
388     orRange.maFirst.mnRow = readRow( bRow32Bit );
389     orRange.maLast.mnRow = readRow( bRow32Bit );
390     orRange.maFirst.mnCol = readCol( bCol16Bit );
391     orRange.maLast.mnCol = readCol( bCol16Bit );
392 }
393 
394 void BiffObjectBase::readRangeList( RangeList& orRanges, bool bCol16Bit, bool bRow32Bit )
395 {
396     sal_uInt16 nCount;
397     *mxBiffStrm >> nCount;
398     orRanges.resize( nCount );
399     for( RangeList::iterator aIt = orRanges.begin(), aEnd = orRanges.end(); !mxBiffStrm->isEof() && (aIt != aEnd); ++aIt )
400         readRange( *aIt, bCol16Bit, bRow32Bit );
401 }
402 
403 // ----------------------------------------------------------------------------
404 
405 void BiffObjectBase::writeBooleanItem( const String& rName, sal_uInt8 nBool )
406 {
407     writeDecItem( rName, nBool, "BOOLEAN" );
408 }
409 
410 void BiffObjectBase::writeErrorCodeItem( const String& rName, sal_uInt8 nErrCode )
411 {
412     writeHexItem( rName, nErrCode, mxErrCodes );
413 }
414 
415 void BiffObjectBase::writeFontPortions( const FontPortionModelList& rPortions )
416 {
417     if( !rPortions.empty() )
418     {
419         writeDecItem( "font-count", static_cast< sal_uInt32 >( rPortions.size() ) );
420         TableGuard aTabGuard( mxOut, 14 );
421         for( FontPortionModelList::const_iterator aIt = rPortions.begin(), aEnd = rPortions.end(); aIt != aEnd; ++aIt )
422         {
423             MultiItemsGuard aMultiGuard( mxOut );
424             writeDecItem( "char-pos", aIt->mnPos );
425             writeDecItem( "font-idx", aIt->mnFontId, "FONTNAMES" );
426         }
427     }
428 }
429 
430 // ----------------------------------------------------------------------------
431 
432 OUString BiffObjectBase::dumpByteString( const String& rName, BiffStringFlags nFlags, rtl_TextEncoding eDefaultTextEnc )
433 {
434     OSL_ENSURE( !getFlag( nFlags, static_cast< BiffStringFlags >( ~(BIFF_STR_8BITLENGTH | BIFF_STR_EXTRAFONTS) ) ), "BiffObjectBase::dumpByteString - unknown flag" );
435     bool b8BitLength = getFlag( nFlags, BIFF_STR_8BITLENGTH );
436 
437     OString aString = mxBiffStrm->readByteString( !b8BitLength, true );
438     FontPortionModelList aPortions;
439     if( getFlag( nFlags, BIFF_STR_EXTRAFONTS ) )
440         aPortions.importPortions( *mxBiffStrm, false );
441 
442     // create string portions
443     OUStringBuffer aBuffer;
444     sal_Int32 nStrLen = aString.getLength();
445     if( nStrLen > 0 )
446     {
447         // add leading and trailing string position to ease the following loop
448         if( aPortions.empty() || (aPortions.front().mnPos > 0) )
449             aPortions.insert( aPortions.begin(), FontPortionModel( 0, -1 ) );
450         if( aPortions.back().mnPos < nStrLen )
451             aPortions.push_back( FontPortionModel( nStrLen, -1 ) );
452 
453         // use global text encoding, if nothing special is specified
454         if( eDefaultTextEnc == RTL_TEXTENCODING_DONTKNOW )
455             eDefaultTextEnc = getBiffData().getTextEncoding();
456 
457         // create all string portions according to the font id vector
458         for( FontPortionModelList::const_iterator aIt = aPortions.begin(); aIt->mnPos < nStrLen; ++aIt )
459         {
460             sal_Int32 nPortionLen = (aIt + 1)->mnPos - aIt->mnPos;
461             if( nPortionLen > 0 )
462             {
463                 // convert byte string to unicode string, using current font encoding
464                 rtl_TextEncoding eTextEnc = mxBiffData->getFontEncoding( static_cast< sal_uInt16 >( aIt->mnFontId ) );
465                 if( eTextEnc == RTL_TEXTENCODING_DONTKNOW )
466                     eTextEnc = eDefaultTextEnc;
467                 aBuffer.append( OStringToOUString( aString.copy( aIt->mnPos, nPortionLen ), eTextEnc ) );
468             }
469         }
470     }
471 
472     OUString aUniStr = aBuffer.makeStringAndClear();
473     writeStringItem( rName( "text" ), aUniStr );
474     return aUniStr;
475 }
476 
477 OUString BiffObjectBase::dumpUniString( const String& rName, BiffStringFlags nFlags )
478 {
479     OSL_ENSURE( !getFlag( nFlags, static_cast< BiffStringFlags >( ~(BIFF_STR_8BITLENGTH | BIFF_STR_SMARTFLAGS) ) ), "BiffObjectBase::dumpUniString - unknown flag" );
480     bool b8BitLength = getFlag( nFlags, BIFF_STR_8BITLENGTH );
481 
482     // --- string header ---
483     sal_uInt16 nChars = b8BitLength ? mxBiffStrm->readuInt8() : mxBiffStrm->readuInt16();
484     sal_uInt8 nFlagField = 0;
485     if( (nChars > 0) || !getFlag( nFlags, BIFF_STR_SMARTFLAGS ) )
486         *mxBiffStrm >> nFlagField;
487     bool b16Bit    = getFlag( nFlagField, BIFF_STRF_16BIT );
488     bool bFonts    = getFlag( nFlagField, BIFF_STRF_RICH );
489     bool bPhonetic = getFlag( nFlagField, BIFF_STRF_PHONETIC );
490     sal_uInt16 nFontCount = bFonts ? mxBiffStrm->readuInt16() : 0;
491     sal_uInt32 nPhoneticSize = bPhonetic ? mxBiffStrm->readuInt32() : 0;
492 
493     // --- character array ---
494     OUString aString = mxBiffStrm->readUniStringChars( nChars, b16Bit, true );
495     writeStringItem( rName( "text" ), aString );
496 
497     // --- formatting ---
498     // #122185# bRich flag may be set, but format runs may be missing
499     if( nFontCount > 0 )
500     {
501         IndentGuard aIndGuard( mxOut );
502         FontPortionModelList aPortions;
503         aPortions.importPortions( *mxBiffStrm, nFontCount, BIFF_FONTPORTION_16BIT );
504         writeFontPortions( aPortions );
505     }
506 
507     // --- phonetic information ---
508     // #122185# bPhonetic flag may be set, but phonetic data may be missing
509     if( nPhoneticSize > 0 )
510     {
511         sal_Int64 nStrmPos = mxBiffStrm->tell();
512         IndentGuard aIndGuard( mxOut );
513         writeEmptyItem( "phonetic-data" );
514         dumpUnused( 2 );
515         dumpDec< sal_uInt16 >( "size" );
516         dumpDec< sal_uInt16 >( "font-idx", "FONTNAMES" );
517         dumpHex< sal_uInt16 >( "flags", "PHONETICPR-FLAGS" );
518         sal_uInt16 nCount = dumpDec< sal_uInt16 >( "portion-count" );
519         sal_uInt16 nLen = dumpDec< sal_uInt16 >( "text-len" );
520         dumpUnicodeArray( "text", mxBiffStrm->readuInt16() );
521         if( nLen == 0 ) dumpUnused( 2 );
522         for( sal_uInt16 nPortion = 0; !mxBiffStrm->isEof() && (nPortion < nCount); ++nPortion )
523         {
524             MultiItemsGuard aMultiGuard( mxOut );
525             dumpDec< sal_uInt16 >( "first-portion-char" );
526             dumpDec< sal_uInt16 >( "first-main-char" );
527             dumpDec< sal_uInt16 >( "main-char-count" );
528         }
529         dumpRemainingTo( nStrmPos + nPhoneticSize );
530     }
531 
532     return aString;
533 }
534 
535 OUString BiffObjectBase::dumpString( const String& rName, BiffStringFlags nByteFlags, BiffStringFlags nUniFlags, rtl_TextEncoding eDefaultTextEnc )
536 {
537     return (getBiff() == BIFF8) ? dumpUniString( rName, nUniFlags ) : dumpByteString( rName, nByteFlags, eDefaultTextEnc );
538 }
539 
540 OUString BiffObjectBase::dumpSegmentedUniString( const String& rName )
541 {
542     sal_Int32 nLength = mxBiffStrm->readInt32();
543     OUStringBuffer aBuffer;
544     while( !mxBiffStrm->isEof() && (aBuffer.getLength() < nLength) )
545         aBuffer.append( mxBiffStrm->readUniString() );
546     OUString aString = aBuffer.makeStringAndClear();
547     writeStringItem( rName, aString );
548     return aString;
549 }
550 
551 void BiffObjectBase::dumpSegmentedUniStringArray( const String& rName )
552 {
553     writeEmptyItem( rName );
554     IndentGuard aIndGuard( mxOut );
555     mxOut->resetItemIndex();
556     for( sal_uInt16 nIndex = 0, nCount = dumpDec< sal_uInt16 >( "count" ); !mxBiffStrm->isEof() && (nIndex < nCount); ++nIndex )
557         dumpSegmentedUniString( "#entry" );
558 }
559 
560 sal_uInt8 BiffObjectBase::dumpBoolean( const String& rName )
561 {
562     sal_uInt8 nBool;
563     *mxBiffStrm >> nBool;
564     writeBooleanItem( rName( "boolean" ), nBool );
565     return nBool;
566 }
567 
568 sal_uInt8 BiffObjectBase::dumpErrorCode( const String& rName )
569 {
570     sal_uInt8 nErrCode;
571     *mxBiffStrm >> nErrCode;
572     writeErrorCodeItem( rName( "error-code" ), nErrCode );
573     return nErrCode;
574 }
575 
576 rtl_TextEncoding BiffObjectBase::dumpCodePage( const String& rName )
577 {
578     sal_uInt16 nCodePage = dumpDec< sal_uInt16 >( rName( "codepage" ), "CODEPAGES" );
579     return BiffHelper::calcTextEncodingFromCodePage( nCodePage );
580 }
581 
582 void BiffObjectBase::dumpFormulaResult( const String& rName )
583 {
584     MultiItemsGuard aMultiGuard( mxOut );
585     sal_uInt8 pnResult[ 8 ];
586     mxBiffStrm->readMemory( pnResult, 8 );
587     writeArrayItem( rName( "result" ), pnResult, 8 );
588     if( (pnResult[ 6 ] == 0xFF) && (pnResult[ 7 ] == 0xFF) )
589     {
590         sal_uInt8 nType = pnResult[ 0 ];
591         sal_uInt8 nData = pnResult[ 2 ];
592         writeHexItem( "type", nType, mxResultType );
593         switch( nType )
594         {
595             case 1: writeBooleanItem( "value", nData );     break;
596             case 2: writeErrorCodeItem( "value", nData );   break;
597         }
598     }
599     else
600     {
601         double* pfValue = reinterpret_cast< double* >( pnResult );
602         ByteOrderConverter::convertLittleEndian( *pfValue );
603         writeDecItem( "value", *pfValue );
604     }
605 }
606 
607 sal_Int32 BiffObjectBase::dumpColIndex( const String& rName, bool bCol16Bit )
608 {
609     sal_Int32 nCol = readCol( bCol16Bit );
610     writeColIndexItem( rName( "col-idx" ), nCol );
611     return nCol;
612 }
613 
614 sal_Int32 BiffObjectBase::dumpRowIndex( const String& rName, bool bRow32Bit )
615 {
616     sal_Int32 nRow = readRow( bRow32Bit );
617     writeRowIndexItem( rName( "row-idx" ), nRow );
618     return nRow;
619 }
620 
621 sal_Int32 BiffObjectBase::dumpColRange( const String& rName, bool bCol16Bit )
622 {
623     sal_Int32 nCol1 = readCol( bCol16Bit );
624     sal_Int32 nCol2 = readCol( bCol16Bit );
625     writeColRangeItem( rName( "col-range" ), nCol1, nCol2 );
626     return nCol2 - nCol1 + 1;
627 }
628 
629 sal_Int32 BiffObjectBase::dumpRowRange( const String& rName, bool bRow32Bit )
630 {
631     sal_Int32 nRow1 = readRow( bRow32Bit );
632     sal_Int32 nRow2 = readRow( bRow32Bit );
633     writeRowRangeItem( rName( "row-range" ), nRow1, nRow2 );
634     return nRow2 - nRow1 + 1;
635 }
636 
637 Address BiffObjectBase::dumpAddress( const String& rName, bool bCol16Bit, bool bRow32Bit )
638 {
639     Address aPos;
640     readAddress( aPos, bCol16Bit, bRow32Bit );
641     writeAddressItem( rName( "addr" ), aPos );
642     return aPos;
643 }
644 
645 Range BiffObjectBase::dumpRange( const String& rName, bool bCol16Bit, bool bRow32Bit )
646 {
647     Range aRange;
648     readRange( aRange, bCol16Bit, bRow32Bit );
649     writeRangeItem( rName( "range" ), aRange );
650     return aRange;
651 }
652 
653 void BiffObjectBase::dumpRangeList( const String& rName, bool bCol16Bit, bool bRow32Bit )
654 {
655     RangeList aRanges;
656     readRangeList( aRanges, bCol16Bit, bRow32Bit );
657     writeRangeListItem( rName( "range-list" ), aRanges );
658 }
659 
660 void BiffObjectBase::dumpConstArrayHeader( sal_uInt32& rnCols, sal_uInt32& rnRows )
661 {
662     MultiItemsGuard aMultiGuard( mxOut );
663     rnCols = dumpDec< sal_uInt8 >( "width" );
664     rnRows = dumpDec< sal_uInt16 >( "height" );
665     switch( getBiff() )
666     {
667         case BIFF2:
668         case BIFF3:
669         case BIFF4:
670         case BIFF5: if( rnCols == 0 ) rnCols = 256; break;
671         case BIFF8: ++rnCols; ++rnRows;             break;
672         case BIFF_UNKNOWN:                          break;
673     }
674     ItemGuard aItem( mxOut, "size" );
675     mxOut->writeDec( rnCols );
676     mxOut->writeChar( 'x' );
677     mxOut->writeDec( rnRows );
678     aItem.cont();
679     mxOut->writeDec( rnCols * rnRows );
680 }
681 
682 OUString BiffObjectBase::dumpConstValue( sal_Unicode cStrQuote )
683 {
684     MultiItemsGuard aMultiGuard( mxOut );
685     OUStringBuffer aValue;
686     switch( dumpDec< sal_uInt8 >( "type", mxConstType ) )
687     {
688         case BIFF_DATATYPE_EMPTY:
689             dumpUnused( 8 );
690             aValue.append( OOX_DUMP_EMPTYVALUE );
691         break;
692         case BIFF_DATATYPE_DOUBLE:
693             dumpDec< double >( "value" );
694             aValue.append( mxOut->getLastItemValue() );
695         break;
696         case BIFF_DATATYPE_STRING:
697             aValue.append( dumpString( "value", BIFF_STR_8BITLENGTH ) );
698             StringHelper::enclose( aValue, cStrQuote );
699         break;
700         case BIFF_DATATYPE_BOOL:
701             dumpBoolean( "value" );
702             aValue.append( mxOut->getLastItemValue() );
703             dumpUnused( 7 );
704         break;
705         case BIFF_DATATYPE_ERROR:
706             dumpErrorCode( "value" );
707             aValue.append( mxOut->getLastItemValue() );
708             dumpUnused( 7 );
709         break;
710     }
711     return aValue.makeStringAndClear();
712 }
713 
714 sal_uInt16 BiffObjectBase::dumpRepeatedRecId()
715 {
716     return dumpHex< sal_uInt16 >( "repeated-rec-id", getRecNames() );
717 }
718 
719 void BiffObjectBase::dumpFrHeader( bool bWithFlags, bool bWithRange )
720 {
721     dumpHex< sal_uInt16 >( "fr-rec-id", getRecNames() );
722     sal_Int16 nFlags = bWithFlags ? dumpHex< sal_uInt16 >( "fr-flags", "FR-FLAGS" ) : 0x0001;
723     if( bWithRange )
724     {
725         if( getFlag< sal_uInt16 >( nFlags, 0x0001 ) )
726             dumpRange( "fr-range" );
727         else
728             dumpUnused( 8 );
729     }
730 }
731 
732 void BiffObjectBase::dumpDffClientRect()
733 {
734     lclDumpDffClientRect( mxOut, mxStrm );
735 }
736 
737 void BiffObjectBase::dumpEmbeddedDff()
738 {
739     mxOut->decIndent();
740     writeEmptyItem( "EMBEDDED-DFF-START" );
741     mxOut->incIndent();
742     mxDffObj->dump();
743     mxOut->emptyLine();
744     mxOut->decIndent();
745     writeEmptyItem( "EMBEDDED-DFF-END" );
746     mxOut->incIndent();
747 }
748 
749 void BiffObjectBase::dumpControl()
750 {
751     sal_uInt32 nStartPos = dumpHex< sal_uInt32 >( "ctls-stream-pos", "CONV-DEC" );
752     sal_uInt32 nLength = dumpHex< sal_uInt32 >( "ctls-stream-length", "CONV-DEC" );
753     if( isValid( mxCtlsObj ) )
754         mxCtlsObj->dumpControl( nStartPos, nLength );
755 }
756 
757 // ============================================================================
758 // ============================================================================
759 
760 FormulaObject::FormulaObject( const BiffObjectBase& rParent ) :
761     mnSize( 0 )
762 {
763     BiffObjectBase::construct( rParent );
764     constructFmlaObj();
765 }
766 
767 FormulaObject::~FormulaObject()
768 {
769 }
770 
771 sal_uInt16 FormulaObject::readFormulaSize()
772 {
773     return (getBiff() == BIFF2) ? getBiffStream().readuInt8() : getBiffStream().readuInt16();
774 }
775 
776 sal_uInt16 FormulaObject::dumpFormulaSize( const String& rName )
777 {
778     sal_uInt16 nSize = readFormulaSize();
779     writeDecItem( rName( "formula-size" ), nSize );
780     return nSize;
781 }
782 
783 void FormulaObject::dumpCellFormula( const String& rName, sal_uInt16 nSize )
784 {
785     dumpFormula( rName, nSize, false );
786 }
787 
788 void FormulaObject::dumpCellFormula( const String& rName )
789 {
790     dumpFormula( rName, false );
791 }
792 
793 void FormulaObject::dumpNameFormula( const String& rName, sal_uInt16 nSize )
794 {
795     dumpFormula( rName, nSize, true );
796 }
797 
798 void FormulaObject::dumpNameFormula( const String& rName )
799 {
800     dumpFormula( rName, true );
801 }
802 
803 void FormulaObject::implDump()
804 {
805     {
806         MultiItemsGuard aMultiGuard( mxOut );
807         writeEmptyItem( maName );
808         writeDecItem( "formula-size", mnSize );
809     }
810     if( mnSize == 0 ) return;
811 
812     sal_Int64 nStartPos = mxStrm->tell();
813     sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->size() );
814 
815     bool bValid = mxTokens.get();
816     mxStack.reset( new FormulaStack );
817     maAddData.clear();
818     IndentGuard aIndGuard( mxOut );
819     {
820         TableGuard aTabGuard( mxOut, 8, 18 );
821         while( bValid && !mxStrm->isEof() && (mxStrm->tell() < nEndPos) )
822         {
823             MultiItemsGuard aMultiGuard( mxOut );
824             writeHexItem( EMPTY_STRING, static_cast< sal_uInt16 >( mxStrm->tell() - nStartPos ) );
825             sal_uInt8 nTokenId = dumpHex< sal_uInt8 >( EMPTY_STRING, mxTokens );
826             bValid = mxTokens->hasName( nTokenId );
827             if( bValid )
828             {
829                 sal_uInt8 nTokClass = nTokenId & BIFF_TOKCLASS_MASK;
830                 sal_uInt8 nBaseId = nTokenId & BIFF_TOKID_MASK;
831                 if( nTokClass == BIFF_TOKCLASS_NONE )
832                 {
833                     switch( nBaseId )
834                     {
835                         case BIFF_TOKID_EXP:        dumpExpToken( "EXP" );          break;
836                         case BIFF_TOKID_TBL:        dumpExpToken( "TBL" );          break;
837                         case BIFF_TOKID_ADD:        dumpBinaryOpToken( "+" );       break;
838                         case BIFF_TOKID_SUB:        dumpBinaryOpToken( "-" );       break;
839                         case BIFF_TOKID_MUL:        dumpBinaryOpToken( "*" );       break;
840                         case BIFF_TOKID_DIV:        dumpBinaryOpToken( "/" );       break;
841                         case BIFF_TOKID_POWER:      dumpBinaryOpToken( "^" );       break;
842                         case BIFF_TOKID_CONCAT:     dumpBinaryOpToken( "&" );       break;
843                         case BIFF_TOKID_LT:         dumpBinaryOpToken( "<" );       break;
844                         case BIFF_TOKID_LE:         dumpBinaryOpToken( "<=" );      break;
845                         case BIFF_TOKID_EQ:         dumpBinaryOpToken( "=" );       break;
846                         case BIFF_TOKID_GE:         dumpBinaryOpToken( ">=" );      break;
847                         case BIFF_TOKID_GT:         dumpBinaryOpToken( "<" );       break;
848                         case BIFF_TOKID_NE:         dumpBinaryOpToken( "<>" );      break;
849                         case BIFF_TOKID_ISECT:      dumpBinaryOpToken( " " );       break;
850                         case BIFF_TOKID_LIST:       dumpBinaryOpToken( "," );       break;
851                         case BIFF_TOKID_RANGE:      dumpBinaryOpToken( ":" );       break;
852                         case BIFF_TOKID_UPLUS:      dumpUnaryOpToken( "+", "" );    break;
853                         case BIFF_TOKID_UMINUS:     dumpUnaryOpToken( "-", "" );    break;
854                         case BIFF_TOKID_PERCENT:    dumpUnaryOpToken( "", "%" );    break;
855                         case BIFF_TOKID_PAREN:      dumpUnaryOpToken( "(", ")" );   break;
856                         case BIFF_TOKID_MISSARG:    dumpMissArgToken();             break;
857                         case BIFF_TOKID_STR:        dumpStringToken();              break;
858                         case BIFF_TOKID_NLR:        bValid = dumpNlrToken();        break;
859                         case BIFF_TOKID_ATTR:       bValid = dumpAttrToken();       break;
860                         case BIFF_TOKID_SHEET:      dumpSheetToken();               break;
861                         case BIFF_TOKID_ENDSHEET:   dumpEndSheetToken();            break;
862                         case BIFF_TOKID_ERR:        dumpErrorToken();               break;
863                         case BIFF_TOKID_BOOL:       dumpBoolToken();                break;
864                         case BIFF_TOKID_INT:        dumpIntToken();                 break;
865                         case BIFF_TOKID_NUM:        dumpDoubleToken();              break;
866                         default:                    bValid = false;
867                     }
868                 }
869                 else
870                 {
871                     OUString aTokClass = cfg().getName( mxClasses, nTokClass );
872                     switch( nBaseId )
873                     {
874                         case BIFF_TOKID_ARRAY:      dumpArrayToken( aTokClass );                break;
875                         case BIFF_TOKID_FUNC:       dumpFuncToken( aTokClass );                 break;
876                         case BIFF_TOKID_FUNCVAR:    dumpFuncVarToken( aTokClass );              break;
877                         case BIFF_TOKID_NAME:       dumpNameToken( aTokClass );                 break;
878                         case BIFF_TOKID_REF:        dumpRefToken( aTokClass, false );           break;
879                         case BIFF_TOKID_AREA:       dumpAreaToken( aTokClass, false );          break;
880                         case BIFF_TOKID_MEMAREA:    dumpMemAreaToken( aTokClass, true );        break;
881                         case BIFF_TOKID_MEMERR:     dumpMemAreaToken( aTokClass, false );       break;
882                         case BIFF_TOKID_MEMNOMEM:   dumpMemAreaToken( aTokClass, false );       break;
883                         case BIFF_TOKID_MEMFUNC:    dumpMemFuncToken( aTokClass );              break;
884                         case BIFF_TOKID_REFERR:     dumpRefErrToken( aTokClass, false );        break;
885                         case BIFF_TOKID_AREAERR:    dumpRefErrToken( aTokClass, true );         break;
886                         case BIFF_TOKID_REFN:       dumpRefToken( aTokClass, true );            break;
887                         case BIFF_TOKID_AREAN:      dumpAreaToken( aTokClass, true );           break;
888                         case BIFF_TOKID_MEMAREAN:   dumpMemFuncToken( aTokClass );              break;
889                         case BIFF_TOKID_MEMNOMEMN:  dumpMemFuncToken( aTokClass );              break;
890                         case BIFF_TOKID_FUNCCE:     dumpCmdToken( aTokClass );                  break;
891                         case BIFF_TOKID_NAMEX:      dumpNameXToken( aTokClass );                break;
892                         case BIFF_TOKID_REF3D:      dumpRef3dToken( aTokClass, mbNameMode );    break;
893                         case BIFF_TOKID_AREA3D:     dumpArea3dToken( aTokClass, mbNameMode );   break;
894                         case BIFF_TOKID_REFERR3D:   dumpRefErr3dToken( aTokClass, false );      break;
895                         case BIFF_TOKID_AREAERR3D:  dumpRefErr3dToken( aTokClass, true );       break;
896                         default:                    bValid = false;
897                     }
898                 }
899             }
900         }
901     }
902     bValid = nEndPos == mxStrm->tell();
903     if( bValid )
904     {
905         dumpAddTokenData();
906         writeInfoItem( "formula", mxStack->getFormulaString() );
907         writeInfoItem( "classes", mxStack->getClassesString() );
908     }
909     else
910         dumpBinary( OOX_DUMP_ERRASCII( "formula-error" ), nEndPos - mxStrm->tell(), false );
911 
912     mnSize = 0;
913 }
914 
915 void FormulaObject::dumpFormula( const String& rName, sal_uInt16 nSize, bool bNameMode )
916 {
917     maName = rName( "formula" );
918     mnSize = nSize;
919     mbNameMode = bNameMode;
920     dump();
921     mnSize = 0;
922 }
923 
924 void FormulaObject::dumpFormula( const String& rName, bool bNameMode )
925 {
926     dumpFormula( rName, readFormulaSize(), bNameMode );
927 }
928 
929 // private --------------------------------------------------------------------
930 
931 void FormulaObject::constructFmlaObj()
932 {
933     if( BiffObjectBase::implIsValid() )
934     {
935         mxFuncProv.reset( new FunctionProvider( FILTER_BIFF, getBiff(), true ) );
936 
937         Config& rCfg = cfg();
938         mxClasses   = rCfg.getNameList( "TOKENCLASSES" );
939         mxRelFlags  = rCfg.getNameList( "REFRELFLAGS" );
940         mxNlrTypes  = rCfg.getNameList( "NLRTYPES" );
941         mxAttrTypes = rCfg.getNameList( "ATTRTYPES" );
942         mxSpTypes   = rCfg.getNameList( "ATTRSPACETYPES" );
943 
944         // create classified token names
945         mxTokens = rCfg.createNameList< ConstList >( "TOKENS" );
946         mxTokens->includeList( rCfg.getNameList( "BASETOKENS" ) );
947 
948         NameListRef xClassTokens = rCfg.getNameList( "CLASSTOKENS" );
949         if( mxClasses.get() && xClassTokens.get() )
950             for( NameListBase::const_iterator aCIt = mxClasses->begin(), aCEnd = mxClasses->end(); aCIt != aCEnd; ++aCIt )
951                 for( NameListBase::const_iterator aTIt = xClassTokens->begin(), aTEnd = xClassTokens->end(); aTIt != aTEnd; ++aTIt )
952                     mxTokens->setName( aCIt->first | aTIt->first, aTIt->second + aCIt->second );
953 
954         mnColCount = 256;
955         mnRowCount = (getBiff() == BIFF8) ? 65536 : 16384;
956     }
957 }
958 
959 // ----------------------------------------------------------------------------
960 
961 namespace {
962 
963 OUString lclCreateName( const OUString& rRef, sal_uInt16 nNameIdx )
964 {
965     OUStringBuffer aName( rRef );
966     StringHelper::appendIndexedText( aName, CREATE_OUSTRING( "NAME" ), nNameIdx );
967     return aName.makeStringAndClear();
968 }
969 
970 OUString lclCreateNlr( const OUString& rData, bool bRel = true )
971 {
972     OUStringBuffer aNlr;
973     if( !bRel ) aNlr.append( OOX_DUMP_ADDRABS );
974     StringHelper::appendIndexedText( aNlr, CREATE_OUSTRING( "NLR" ), rData );
975     return aNlr.makeStringAndClear();
976 }
977 
978 OUString lclCreateNlr( const TokenAddress& rPos )
979 {
980     OUStringBuffer aAddr;
981     StringHelper::appendAddrCol( aAddr, rPos.mnCol, true );
982     StringHelper::appendAddrRow( aAddr, rPos.mnRow, true );
983     return lclCreateNlr( aAddr.makeStringAndClear(), rPos.mbRelRow );
984 }
985 
986 } // namespace
987 
988 // ----------------------------------------------------------------------------
989 
990 TokenAddress FormulaObject::createTokenAddress( sal_uInt16 nCol, sal_uInt16 nRow, bool bRelC, bool bRelR, bool bNameMode ) const
991 {
992     TokenAddress aPos;
993     aPos.mnCol = nCol;
994     if( bRelC && bNameMode && (nCol >= mnColCount / 2) ) aPos.mnCol -= mnColCount;
995     aPos.mbRelCol = bRelC;
996     aPos.mnRow = nRow;
997     if( bRelR && bNameMode && (nRow >= mnRowCount / 2) ) aPos.mnRow -= mnRowCount;
998     aPos.mbRelRow = bRelR;
999     return aPos;
1000 }
1001 
1002 OUString FormulaObject::createRef( const OUString& rData ) const
1003 {
1004     return maRefPrefix + rData;
1005 }
1006 
1007 OUString FormulaObject::createName( sal_uInt16 nNameIdx ) const
1008 {
1009     return lclCreateName( maRefPrefix, nNameIdx );
1010 }
1011 
1012 OUString FormulaObject::createPlaceHolder( size_t nIdx ) const
1013 {
1014     OUStringBuffer aStr;
1015     StringHelper::appendDec( aStr, static_cast< sal_uInt32 >( nIdx ) );
1016     StringHelper::enclose( aStr, OOX_DUMP_PLACEHOLDER );
1017     return aStr.makeStringAndClear();
1018 }
1019 
1020 OUString FormulaObject::createPlaceHolder() const
1021 {
1022     return createPlaceHolder( maAddData.size() );
1023 }
1024 
1025 sal_uInt16 FormulaObject::readFuncId()
1026 {
1027     return (getBiff() >= BIFF4) ? mxStrm->readuInt16() : mxStrm->readuInt8();
1028 }
1029 
1030 OUString FormulaObject::writeFuncIdItem( sal_uInt16 nFuncId, const FunctionInfo** oppFuncInfo )
1031 {
1032     ItemGuard aItemGuard( mxOut, "func-id" );
1033     writeHexItem( EMPTY_STRING, nFuncId, "FUNCID" );
1034     OUStringBuffer aBuffer;
1035     const FunctionInfo* pFuncInfo = mxFuncProv->getFuncInfoFromBiffFuncId( nFuncId );
1036     if( pFuncInfo )
1037         aBuffer.append( pFuncInfo->maOoxFuncName );
1038     else
1039     {
1040         bool bCmd = getFlag( nFuncId, BIFF_TOK_FUNCVAR_CMD );
1041         aBuffer.appendAscii( bCmd ? "CMD" : "FUNC" );
1042         StringHelper::appendIndex( aBuffer, nFuncId & BIFF_TOK_FUNCVAR_FUNCIDMASK );
1043     }
1044     OUString aFuncName = aBuffer.makeStringAndClear();
1045     aItemGuard.cont();
1046     mxOut->writeChar( OOX_DUMP_STRQUOTE );
1047     mxOut->writeString( aFuncName );
1048     mxOut->writeChar( OOX_DUMP_STRQUOTE );
1049     if( oppFuncInfo ) *oppFuncInfo = pFuncInfo;
1050     return aFuncName;
1051 }
1052 
1053 sal_uInt16 FormulaObject::dumpTokenCol( const String& rName, bool& rbRelC, bool& rbRelR )
1054 {
1055     sal_uInt16 nCol = 0;
1056     if( getBiff() == BIFF8 )
1057     {
1058         nCol = dumpHex< sal_uInt16 >( rName, mxRelFlags );
1059         rbRelC = getFlag( nCol, BIFF_TOK_REF_COLREL );
1060         rbRelR = getFlag( nCol, BIFF_TOK_REF_ROWREL );
1061         nCol &= BIFF_TOK_REF_COLMASK;
1062     }
1063     else
1064         nCol = dumpDec< sal_uInt8 >( rName );
1065     return nCol;
1066 }
1067 
1068 sal_uInt16 FormulaObject::dumpTokenRow( const String& rName, bool& rbRelC, bool& rbRelR )
1069 {
1070     sal_uInt16 nRow = 0;
1071     if( getBiff() == BIFF8 )
1072         nRow = dumpDec< sal_uInt16 >( rName );
1073     else
1074     {
1075         nRow = dumpHex< sal_uInt16 >( rName, mxRelFlags );
1076         rbRelC = getFlag( nRow, BIFF_TOK_REF_COLREL );
1077         rbRelR = getFlag( nRow, BIFF_TOK_REF_ROWREL );
1078         nRow &= BIFF_TOK_REF_ROWMASK;
1079     }
1080     return nRow;
1081 }
1082 
1083 TokenAddress FormulaObject::dumpTokenAddress( bool bNameMode )
1084 {
1085     bool bRelC = false;
1086     bool bRelR = false;
1087     sal_uInt16 nRow = dumpTokenRow( "row", bRelC, bRelR );
1088     sal_uInt16 nCol = dumpTokenCol( "col", bRelC, bRelR );
1089     return createTokenAddress( nCol, nRow, bRelC, bRelR, bNameMode );
1090 }
1091 
1092 TokenRange FormulaObject::dumpTokenRange( bool bNameMode )
1093 {
1094     bool bRelC1 = false;
1095     bool bRelR1 = false;
1096     bool bRelC2 = false;
1097     bool bRelR2 = false;
1098     sal_uInt16 nRow1 = dumpTokenRow( "row1", bRelC1, bRelR1 );
1099     sal_uInt16 nRow2 = dumpTokenRow( "row2", bRelC2, bRelR2 );
1100     sal_uInt16 nCol1 = dumpTokenCol( "col1", bRelC1, bRelR1 );
1101     sal_uInt16 nCol2 = dumpTokenCol( "col2", bRelC2, bRelR2 );
1102     TokenRange aRange;
1103     aRange.maFirst = createTokenAddress( nCol1, nRow1, bRelC1, bRelR1, bNameMode );
1104     aRange.maLast  = createTokenAddress( nCol2, nRow2, bRelC2, bRelR2, bNameMode );
1105     return aRange;
1106 }
1107 
1108 sal_Int16 FormulaObject::readTokenRefIdx()
1109 {
1110     sal_Int16 nRefIdx = dumpDec< sal_Int16 >( "ref-idx" );
1111     switch( getBiff() )
1112     {
1113         case BIFF2: dumpUnused( 1 );    break;
1114         case BIFF3: dumpUnused( 2 );    break;
1115         case BIFF4: dumpUnused( 2 );    break;
1116         case BIFF5: dumpUnused( 8 );    break;
1117         case BIFF8:                     break;
1118         case BIFF_UNKNOWN:              break;
1119     }
1120     return nRefIdx;
1121 }
1122 
1123 OUString FormulaObject::dumpTokenRefIdx()
1124 {
1125     OUStringBuffer aRef( CREATE_OUSTRING( "REF" ) );
1126     StringHelper::appendIndex( aRef, readTokenRefIdx() );
1127     aRef.append( OOX_DUMP_TABSEP );
1128     return aRef.makeStringAndClear();
1129 }
1130 
1131 OUString FormulaObject::dumpTokenRefTabIdxs()
1132 {
1133     sal_Int16 nRefIdx = readTokenRefIdx();
1134     OUStringBuffer aRef( CREATE_OUSTRING( "REF" ) );
1135     StringHelper::appendIndex( aRef, nRefIdx );
1136     if( getBiff() == BIFF5 )
1137     {
1138         dumpDec< sal_Int16 >( "tab1" );
1139         sal_Int16 nTab2 = dumpDec< sal_Int16 >( "tab2" );
1140         if( (nRefIdx > 0) && (nTab2 > 0) && (nRefIdx != nTab2) )
1141         {
1142             aRef.append( OOX_DUMP_RANGESEP );
1143             aRef.appendAscii( "REF" );
1144             StringHelper::appendIndex( aRef, nTab2 );
1145         }
1146     }
1147     aRef.append( OOX_DUMP_TABSEP );
1148     return aRef.makeStringAndClear();
1149 }
1150 
1151 void FormulaObject::dumpIntToken()
1152 {
1153     dumpDec< sal_uInt16 >( "value" );
1154     mxStack->pushOperand( mxOut->getLastItemValue() );
1155 }
1156 
1157 void FormulaObject::dumpDoubleToken()
1158 {
1159     dumpDec< double >( "value" );
1160     mxStack->pushOperand( mxOut->getLastItemValue() );
1161 }
1162 
1163 void FormulaObject::dumpStringToken()
1164 {
1165     OUStringBuffer aValue;
1166     aValue.append( dumpString( "value", BIFF_STR_8BITLENGTH, BIFF_STR_8BITLENGTH ) );
1167     StringHelper::enclose( aValue, OOX_DUMP_FMLASTRQUOTE );
1168     mxStack->pushOperand( aValue.makeStringAndClear() );
1169 }
1170 
1171 void FormulaObject::dumpBoolToken()
1172 {
1173     dumpBoolean( "value" );
1174     mxStack->pushOperand( mxOut->getLastItemValue() );
1175 }
1176 
1177 void FormulaObject::dumpErrorToken()
1178 {
1179     dumpErrorCode( "value" );
1180     mxStack->pushOperand( mxOut->getLastItemValue() );
1181 }
1182 
1183 void FormulaObject::dumpMissArgToken()
1184 {
1185     mxStack->pushOperand( OUString( OOX_DUMP_EMPTYVALUE ) );
1186 }
1187 
1188 void FormulaObject::dumpArrayToken( const OUString& rTokClass )
1189 {
1190     dumpUnused( (getBiff() == BIFF2) ? 6 : 7 );
1191     mxStack->pushOperand( createPlaceHolder(), rTokClass );
1192     maAddData.push_back( ADDDATA_ARRAY );
1193 }
1194 
1195 void FormulaObject::dumpNameToken( const OUString& rTokClass )
1196 {
1197     sal_uInt16 nNameIdx = dumpDec< sal_uInt16 >( "name-idx" );
1198     switch( getBiff() )
1199     {
1200         case BIFF2: dumpUnused( 5 );    break;
1201         case BIFF3:
1202         case BIFF4: dumpUnused( 8 );    break;
1203         case BIFF5: dumpUnused( 12 );   break;
1204         case BIFF8: dumpUnused( 2 );    break;
1205         case BIFF_UNKNOWN:              break;
1206     }
1207     mxStack->pushOperand( createName( nNameIdx ), rTokClass );
1208 }
1209 
1210 void FormulaObject::dumpNameXToken( const OUString& rTokClass )
1211 {
1212     OUString aRef = dumpTokenRefIdx();
1213     sal_uInt16 nNameIdx = dumpDec< sal_uInt16 >( "name-idx" );
1214     dumpUnused( (getBiff() == BIFF8) ? 2 : 12 );
1215     mxStack->pushOperand( lclCreateName( aRef, nNameIdx ), rTokClass );
1216 }
1217 
1218 void FormulaObject::dumpRefToken( const OUString& rTokClass, bool bNameMode )
1219 {
1220     TokenAddress aPos = dumpTokenAddress( bNameMode );
1221     writeTokenAddressItem( "addr", aPos, bNameMode );
1222     mxStack->pushOperand( createRef( mxOut->getLastItemValue() ), rTokClass );
1223 }
1224 
1225 void FormulaObject::dumpAreaToken( const OUString& rTokClass, bool bNameMode )
1226 {
1227     TokenRange aRange = dumpTokenRange( bNameMode );
1228     writeTokenRangeItem( "range", aRange, bNameMode );
1229     mxStack->pushOperand( createRef( mxOut->getLastItemValue() ), rTokClass );
1230 }
1231 
1232 void FormulaObject::dumpRefErrToken( const OUString& rTokClass, bool bArea )
1233 {
1234     dumpUnused( ((getBiff() == BIFF8) ? 4 : 3) * (bArea ? 2 : 1) );
1235     mxStack->pushOperand( createRef( getErrorName( BIFF_ERR_REF ) ), rTokClass );
1236 }
1237 
1238 void FormulaObject::dumpRef3dToken( const OUString& rTokClass, bool bNameMode )
1239 {
1240     OUString aRef = dumpTokenRefTabIdxs();
1241     TokenAddress aPos = dumpTokenAddress( bNameMode );
1242     writeTokenAddress3dItem( "addr", aRef, aPos, bNameMode );
1243     mxStack->pushOperand( mxOut->getLastItemValue(), rTokClass );
1244 }
1245 
1246 void FormulaObject::dumpArea3dToken( const OUString& rTokClass, bool bNameMode )
1247 {
1248     OUString aRef = dumpTokenRefTabIdxs();
1249     TokenRange aRange = dumpTokenRange( bNameMode );
1250     writeTokenRange3dItem( "range", aRef, aRange, bNameMode );
1251     mxStack->pushOperand( mxOut->getLastItemValue(), rTokClass );
1252 }
1253 
1254 void FormulaObject::dumpRefErr3dToken( const OUString& rTokClass, bool bArea )
1255 {
1256     OUString aRef = dumpTokenRefTabIdxs();
1257     dumpUnused( ((getBiff() == BIFF8) ? 4 : 3) * (bArea ? 2 : 1) );
1258     mxStack->pushOperand( aRef + getErrorName( BIFF_ERR_REF ), rTokClass );
1259 }
1260 
1261 void FormulaObject::dumpMemFuncToken( const OUString& /*rTokClass*/ )
1262 {
1263     dumpDec< sal_uInt16, sal_uInt8 >( getBiff() != BIFF2, "size" );
1264 }
1265 
1266 void FormulaObject::dumpMemAreaToken( const OUString& rTokClass, bool bAddData )
1267 {
1268     dumpUnused( (getBiff() == BIFF2) ? 3 : 4 );
1269     dumpMemFuncToken( rTokClass );
1270     if( bAddData )
1271         maAddData.push_back( ADDDATA_MEMAREA );
1272 }
1273 
1274 void FormulaObject::dumpExpToken( const String& rName )
1275 {
1276     Address aPos;
1277     aPos.mnRow = dumpDec< sal_uInt16 >( "row" );
1278     aPos.mnCol = dumpDec< sal_uInt16, sal_uInt8 >( getBiff() != BIFF2, "col" );
1279     writeAddressItem( "base-addr", aPos );
1280     OUStringBuffer aOp( rName );
1281     StringHelper::appendIndex( aOp, mxOut->getLastItemValue() );
1282     mxStack->pushOperand( aOp.makeStringAndClear() );
1283 }
1284 
1285 void FormulaObject::dumpUnaryOpToken( const String& rLOp, const String& rROp )
1286 {
1287     mxStack->pushUnaryOp( rLOp, rROp );
1288 }
1289 
1290 void FormulaObject::dumpBinaryOpToken( const String& rOp )
1291 {
1292     mxStack->pushBinaryOp( rOp );
1293 }
1294 
1295 void FormulaObject::dumpFuncToken( const OUString& rTokClass )
1296 {
1297     sal_uInt16 nFuncId = readFuncId();
1298     const FunctionInfo* pFuncInfo = 0;
1299     OUString aFuncName = writeFuncIdItem( nFuncId, &pFuncInfo );
1300     if( pFuncInfo && (pFuncInfo->mnMinParamCount == pFuncInfo->mnMaxParamCount) )
1301         mxStack->pushFuncOp( aFuncName, rTokClass, pFuncInfo->mnMinParamCount );
1302     else
1303         mxStack->setError();
1304 }
1305 
1306 void FormulaObject::dumpFuncVarToken( const OUString& rTokClass )
1307 {
1308     sal_uInt8 nParamCount;
1309     *mxStrm >> nParamCount;
1310     sal_uInt16 nFuncId = readFuncId();
1311     bool bCmd = getFlag( nFuncId, BIFF_TOK_FUNCVAR_CMD );
1312     if( bCmd )
1313         writeHexItem( "param-count", nParamCount, "PARAMCOUNT-CMD" );
1314     else
1315         writeDecItem( "param-count", nParamCount );
1316     OUString aFuncName = writeFuncIdItem( nFuncId );
1317     if( bCmd && getFlag( nParamCount, BIFF_TOK_FUNCVAR_CMDPROMPT ) )
1318     {
1319         aFuncName += OUString( OOX_DUMP_CMDPROMPT );
1320         nParamCount &= BIFF_TOK_FUNCVAR_COUNTMASK;
1321     }
1322     mxStack->pushFuncOp( aFuncName, rTokClass, nParamCount );
1323 }
1324 
1325 void FormulaObject::dumpCmdToken( const OUString& rTokClass )
1326 {
1327     sal_uInt8 nParamCount = dumpDec< sal_uInt8 >( "param-count", "PARAMCOUNT-CMD" );
1328     sal_uInt16 nCmdId = readFuncId() | BIFF_TOK_FUNCVAR_CMD;
1329     OUString aFuncName = writeFuncIdItem( nCmdId );
1330     if( getFlag( nParamCount, BIFF_TOK_FUNCVAR_CMDPROMPT ) )
1331     {
1332         aFuncName += OUString( OOX_DUMP_CMDPROMPT );
1333         nParamCount &= BIFF_TOK_FUNCVAR_COUNTMASK;
1334     }
1335     mxStack->pushFuncOp( aFuncName, rTokClass, nParamCount );
1336 }
1337 
1338 void FormulaObject::dumpSheetToken()
1339 {
1340     dumpUnused( (getBiff() == BIFF2) ? 4 : 6 );
1341     maRefPrefix = dumpTokenRefIdx();
1342 }
1343 
1344 void FormulaObject::dumpEndSheetToken()
1345 {
1346     dumpUnused( (getBiff() == BIFF2) ? 3 : 4 );
1347     maRefPrefix = OUString();
1348 }
1349 
1350 bool FormulaObject::dumpAttrToken()
1351 {
1352     bool bValid = true;
1353     bool bBiff2 = getBiff() == BIFF2;
1354     sal_uInt8 nType = dumpHex< sal_uInt8 >( "type", mxAttrTypes );
1355     switch( nType )
1356     {
1357         case BIFF_TOK_ATTR_VOLATILE:
1358             dumpUnused( bBiff2 ? 1 : 2 );
1359         break;
1360         case BIFF_TOK_ATTR_IF:
1361             dumpDec< sal_uInt16, sal_uInt8 >( !bBiff2, "skip" );
1362         break;
1363         case BIFF_TOK_ATTR_CHOOSE:
1364         {
1365             sal_uInt16 nCount = dumpDec< sal_uInt16, sal_uInt8 >( !bBiff2, "choices" );
1366             mxOut->resetItemIndex();
1367             for( sal_uInt16 nIdx = 0; nIdx < nCount; ++nIdx )
1368                 dumpDec< sal_uInt16, sal_uInt8 >( !bBiff2, "#skip" );
1369             dumpDec< sal_uInt16, sal_uInt8 >( !bBiff2, "skip-err" );
1370         }
1371         break;
1372         case 0:     // in array formulas and defined names, the skip-bit may be 0
1373         case BIFF_TOK_ATTR_SKIP:
1374             dumpDec< sal_uInt16, sal_uInt8 >( !bBiff2, "skip" );
1375         break;
1376         case BIFF_TOK_ATTR_SUM:
1377             dumpUnused( bBiff2 ? 1 : 2 );
1378             mxStack->pushFuncOp( CREATE_OUSTRING( "SUM" ), OUString( OOX_DUMP_BASECLASS ), 1 );
1379         break;
1380         case BIFF_TOK_ATTR_ASSIGN:
1381             dumpUnused( bBiff2 ? 1 : 2 );
1382         break;
1383         case BIFF_TOK_ATTR_SPACE:
1384         case BIFF_TOK_ATTR_SPACE | BIFF_TOK_ATTR_VOLATILE:
1385             switch( getBiff() )
1386             {
1387                 case BIFF2:
1388                     bValid = false;
1389                 break;
1390                 case BIFF3:
1391                     dumpDec< sal_uInt16 >( "leading-spaces" );
1392                 break;
1393                 case BIFF4:
1394                 case BIFF5:
1395                 case BIFF8:
1396                     dumpDec< sal_uInt8 >( "char-type", mxSpTypes );
1397                     dumpDec< sal_uInt8 >( "char-count" );
1398                 break;
1399                 case BIFF_UNKNOWN: break;
1400             }
1401         break;
1402         default:
1403             bValid = false;
1404     }
1405     return bValid;
1406 }
1407 
1408 bool FormulaObject::dumpNlrToken()
1409 {
1410     const OUString aRefClass = cfg().getName( mxClasses, BIFF_TOKCLASS_REF );
1411     const OUString aValClass = cfg().getName( mxClasses, BIFF_TOKCLASS_VAL );
1412 
1413     bool bValid = true;
1414     sal_uInt8 nType = dumpHex< sal_uInt8 >( "type", mxNlrTypes );
1415     switch( nType )
1416     {
1417         case BIFF_TOK_NLR_ERR:      dumpNlrErrToken();                      break;
1418         case BIFF_TOK_NLR_ROWR:     dumpNlrColRowToken( aRefClass, false ); break;
1419         case BIFF_TOK_NLR_COLR:     dumpNlrColRowToken( aRefClass, false ); break;
1420         case BIFF_TOK_NLR_ROWV:     dumpNlrColRowToken( aValClass, false ); break;
1421         case BIFF_TOK_NLR_COLV:     dumpNlrColRowToken( aValClass, false ); break;
1422         case BIFF_TOK_NLR_RANGE:    dumpNlrRangeToken( aRefClass, false );  break;
1423         case BIFF_TOK_NLR_SRANGE:   dumpNlrRangeToken( aRefClass, true );   break;
1424         case BIFF_TOK_NLR_SROWR:    dumpNlrColRowToken( aRefClass, true );  break;
1425         case BIFF_TOK_NLR_SCOLR:    dumpNlrColRowToken( aRefClass, true );  break;
1426         case BIFF_TOK_NLR_SROWV:    dumpNlrColRowToken( aValClass, true );  break;
1427         case BIFF_TOK_NLR_SCOLV:    dumpNlrColRowToken( aValClass, true );  break;
1428         case BIFF_TOK_NLR_RANGEERR: dumpNlrRangeErrToken();                 break;
1429         default:                    bValid = false;
1430     }
1431     return bValid;
1432 }
1433 
1434 void FormulaObject::dumpNlrErrToken()
1435 {
1436     dumpDec< sal_uInt32 >( "delname-idx" );
1437     mxStack->pushOperand( lclCreateNlr( getErrorName( BIFF_ERR_NAME ) ) );
1438 }
1439 
1440 void FormulaObject::dumpNlrColRowToken( const OUString& rTokClass, bool bAddData )
1441 {
1442     if( bAddData )
1443     {
1444         dumpUnused( 4 );
1445         mxStack->pushOperand( createPlaceHolder(), rTokClass );
1446         maAddData.push_back( ADDDATA_NLR );
1447     }
1448     else
1449     {
1450         TokenAddress aPos = dumpTokenAddress( false );
1451         writeInfoItem( "addr", lclCreateNlr( aPos ) );
1452         mxStack->pushOperand( mxOut->getLastItemValue(), rTokClass );
1453     }
1454 }
1455 
1456 void FormulaObject::dumpNlrRangeToken( const OUString& rTokClass, bool bAddData )
1457 {
1458     if( bAddData )
1459     {
1460         dumpUnused( 4 );
1461         mxStack->pushOperand( createPlaceHolder(), rTokClass );
1462         maAddData.push_back( ADDDATA_NLR );
1463     }
1464     else
1465     {
1466         TokenAddress aPos = dumpTokenAddress( false );
1467         writeInfoItem( "addr", lclCreateNlr( aPos ) );
1468         mxStack->pushOperand( mxOut->getLastItemValue(), rTokClass );
1469     }
1470     dumpUnknown( 1 );
1471     dumpRange( "target-range" );
1472 }
1473 
1474 void FormulaObject::dumpNlrRangeErrToken()
1475 {
1476     dumpDec< sal_uInt32 >( "delname-idx" );
1477     dumpUnused( 9 );
1478     mxStack->pushOperand( lclCreateNlr( getErrorName( BIFF_ERR_NAME ) ) );
1479 }
1480 
1481 void FormulaObject::dumpAddTokenData()
1482 {
1483     mxOut->resetItemIndex();
1484     for( AddDataTypeVec::const_iterator aIt = maAddData.begin(), aEnd = maAddData.end(); aIt != aEnd; ++aIt )
1485     {
1486         AddDataType eType = *aIt;
1487 
1488         {
1489             ItemGuard aItem( mxOut, "#add-data" );
1490             switch( eType )
1491             {
1492                 case ADDDATA_NLR:       mxOut->writeAscii( "tNlr" );      break;
1493                 case ADDDATA_ARRAY:     mxOut->writeAscii( "tArray" );    break;
1494                 case ADDDATA_MEMAREA:   mxOut->writeAscii( "tMemArea" );  break;
1495             }
1496         }
1497 
1498         size_t nIdx = aIt - maAddData.begin();
1499         IndentGuard aIndGuard( mxOut );
1500         switch( eType )
1501         {
1502             case ADDDATA_NLR:       dumpAddDataNlr( nIdx );     break;
1503             case ADDDATA_ARRAY:     dumpAddDataArray( nIdx );   break;
1504             case ADDDATA_MEMAREA:   dumpAddDataMemArea( nIdx ); break;
1505         }
1506     }
1507 }
1508 
1509 void FormulaObject::dumpAddDataNlr( size_t nIdx )
1510 {
1511     sal_uInt32 nFlags = dumpHex< sal_uInt32 >( "flags", "NLRADDFLAGS" );
1512     sal_uInt32 nCount = nFlags & BIFF_TOK_NLR_ADDMASK;
1513     OUStringBuffer aBuffer;
1514     for( sal_uInt32 nPos = 0; nPos < nCount; ++nPos )
1515     {
1516         Address aPos;
1517         readAddress( aPos );
1518         OUStringBuffer aAddr;
1519         StringHelper::appendAddress( aAddr, aPos );
1520         StringHelper::appendToken( aBuffer, aAddr.makeStringAndClear(), OOX_DUMP_LISTSEP );
1521     }
1522     OUString aAddrList = aBuffer.makeStringAndClear();
1523     writeInfoItem( "stacked-positions", aAddrList );
1524     mxStack->replaceOnTop( createPlaceHolder( nIdx ), lclCreateNlr( aAddrList ) );
1525 }
1526 
1527 void FormulaObject::dumpAddDataArray( size_t nIdx )
1528 {
1529     sal_uInt32 nCols, nRows;
1530     dumpConstArrayHeader( nCols, nRows );
1531 
1532     OUStringBuffer aOp;
1533     TableGuard aTabGuard( mxOut, 17 );
1534     for( sal_uInt32 nRow = 0; nRow < nRows; ++nRow )
1535     {
1536         OUStringBuffer aArrayLine;
1537         for( sal_uInt32 nCol = 0; nCol < nCols; ++nCol )
1538             StringHelper::appendToken( aArrayLine, dumpConstValue( OOX_DUMP_FMLASTRQUOTE ), OOX_DUMP_LISTSEP );
1539         StringHelper::appendToken( aOp, aArrayLine.makeStringAndClear(), OOX_DUMP_ARRAYSEP );
1540     }
1541     StringHelper::enclose( aOp, '{', '}' );
1542     mxStack->replaceOnTop( createPlaceHolder( nIdx ), aOp.makeStringAndClear() );
1543 }
1544 
1545 void FormulaObject::dumpAddDataMemArea( size_t /*nIdx*/ )
1546 {
1547     dumpRangeList( EMPTY_STRING, getBiff() == BIFF8 );
1548 }
1549 
1550 // ============================================================================
1551 // ============================================================================
1552 
1553 RecordStreamObject::~RecordStreamObject()
1554 {
1555 }
1556 
1557 void RecordStreamObject::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, BiffType eBiff, const OUString& rSysFileName )
1558 {
1559     BiffObjectBase::construct( rParent, rxStrm, eBiff, rSysFileName );
1560     if( BiffObjectBase::implIsValid() )
1561         mxFmlaObj.reset( new FormulaObject( *this ) );
1562 }
1563 
1564 bool RecordStreamObject::implIsValid() const
1565 {
1566     return isValid( mxFmlaObj ) && BiffObjectBase::implIsValid();
1567 }
1568 
1569 // ============================================================================
1570 
1571 WorkbookStreamObject::WorkbookStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
1572 {
1573     if( rxStrm.get() )
1574     {
1575         BiffType eBiff = BiffDetector::detectStreamBiffVersion( *rxStrm );
1576         RecordStreamObject::construct( rParent, rxStrm, eBiff, rSysFileName );
1577         if( RecordStreamObject::implIsValid() )
1578         {
1579             Config& rCfg = cfg();
1580             mxColors = rCfg.getNameList( "COLORS" );
1581             mxBorderStyles = rCfg.getNameList( "BORDERSTYLES" );
1582             mxFillPatterns = rCfg.getNameList( "FILLPATTERNS" );
1583             mnPTRowFields = 0;
1584             mnPTColFields = 0;
1585             mnPTRowColItemsIdx = 0;
1586             mbHasDff = false;
1587             initializePerSheet();
1588         }
1589     }
1590 }
1591 
1592 WorkbookStreamObject::~WorkbookStreamObject()
1593 {
1594     if( WorkbookStreamObject::implIsValid() )
1595     {
1596         Config& rCfg = cfg();
1597         rCfg.eraseNameList( "FONTNAMES" );
1598         rCfg.eraseNameList( "FORMATS" );
1599     }
1600 }
1601 
1602 void WorkbookStreamObject::implDumpRecordBody()
1603 {
1604     BiffInputStream& rStrm = getBiffStream();
1605     sal_uInt16 nRecId = rStrm.getRecId();
1606     sal_Int64 nRecSize = rStrm.size();
1607     BiffType eBiff = getBiff();
1608 
1609     switch( nRecId )
1610     {
1611         case BIFF2_ID_ARRAY:
1612         case BIFF3_ID_ARRAY:
1613             dumpRange( "array-range", false );
1614             dumpHex< sal_uInt16, sal_uInt8 >( eBiff != BIFF2, "flags", "ARRAY-FLAGS" );
1615             if( eBiff >= BIFF5 ) dumpUnused( 4 );
1616             getFormulaDumper().dumpCellFormula();
1617         break;
1618 
1619         case BIFF2_ID_BLANK:
1620         case BIFF3_ID_BLANK:
1621             dumpCellHeader( nRecId == BIFF2_ID_BLANK );
1622         break;
1623 
1624         case BIFF2_ID_BOF:
1625         case BIFF3_ID_BOF:
1626         case BIFF4_ID_BOF:
1627         case BIFF5_ID_BOF:
1628             dumpHex< sal_uInt16 >( "bof-type", "BOF-BIFFTYPE" );
1629             dumpHex< sal_uInt16 >( "sheet-type", "BOF-SHEETTYPE" );
1630             if( nRecSize >= 6 )  dumpDec< sal_uInt16 >( "build-id" );
1631             if( nRecSize >= 8 )  dumpDec< sal_uInt16 >( "build-year" );
1632             if( nRecSize >= 12 ) dumpHex< sal_uInt32 >( "history-flags", "BOF-HISTORY-FLAGS" );
1633             if( nRecSize >= 16 ) dumpHex< sal_uInt32 >( "lowest-version", "BOF-LOWESTVERSION-FLAGS" );
1634             if( (eBiff == BIFF4) && (getLastRecId() != BIFF_ID_OBJ) )
1635                 initializePerSheet();
1636         break;
1637 
1638         case BIFF_ID_BOOKEXT:
1639             dumpFrHeader( true, true );
1640             dumpDec< sal_uInt32 >( "rec-size" );
1641             dumpHex< sal_uInt32 >( "flags-1", "BOOKEXT-FLAGS1" );
1642             if( rStrm.getRemaining() > 0 ) dumpHex< sal_uInt8 >( "flags-2", "BOOKEXT-FLAGS2" );
1643             if( rStrm.getRemaining() > 0 ) dumpHex< sal_uInt8 >( "flags-3", "BOOKEXT-FLAGS3" );
1644         break;
1645 
1646         case BIFF2_ID_BOOLERR:
1647         case BIFF3_ID_BOOLERR:
1648             dumpCellHeader( nRecId == BIFF2_ID_BOOLERR );
1649             dumpBoolErr();
1650         break;
1651 
1652         case BIFF_ID_CFHEADER:
1653             dumpDec< sal_uInt16 >( "rule-count" );
1654             dumpHex< sal_uInt16 >( "flags", "CFHEADER-FLAGS" );
1655             dumpRange( "bounding-range" );
1656             dumpRangeList();
1657         break;
1658 
1659         case BIFF_ID_CFRULE:
1660         {
1661             dumpDec< sal_uInt8 >( "type", "CFRULE-TYPE" );
1662             dumpDec< sal_uInt8 >( "operator", "CFRULE-OPERATOR" );
1663             sal_uInt16 nFmla1Size = dumpDec< sal_uInt16 >( "formula1-size" );
1664             sal_uInt16 nFmla2Size = dumpDec< sal_uInt16 >( "formula2-size" );
1665             dumpCfRuleProp();
1666             if( nFmla1Size > 0 ) getFormulaDumper().dumpNameFormula( "formula1", nFmla1Size );
1667             if( nFmla2Size > 0 ) getFormulaDumper().dumpNameFormula( "formula2", nFmla2Size );
1668         }
1669         break;
1670 
1671         case BIFF_ID_CFRULE12:
1672         {
1673             dumpFrHeader( true, true );
1674             dumpDec< sal_uInt8 >( "type", "CFRULE12-TYPE" );
1675             dumpDec< sal_uInt8 >( "operator", "CFRULE-OPERATOR" );
1676             sal_uInt16 nFmla1Size = dumpDec< sal_uInt16 >( "formula1-size" );
1677             sal_uInt16 nFmla2Size = dumpDec< sal_uInt16 >( "formula2-size" );
1678             dumpDxf12Prop();
1679             if( nFmla1Size > 0 ) getFormulaDumper().dumpNameFormula( "formula1", nFmla1Size );
1680             if( nFmla2Size > 0 ) getFormulaDumper().dumpNameFormula( "formula2", nFmla2Size );
1681             getFormulaDumper().dumpNameFormula( "active-formula" );
1682             dumpHex< sal_uInt8 >( "flags", "CFRULE12-FLAGS" );
1683             dumpDec< sal_uInt16 >( "priority" );
1684             dumpCfRule12Param( dumpDec< sal_uInt16 >( "sub-type", "CFRULE12-SUBTYPE" ) );
1685         }
1686         break;
1687 
1688         case BIFF_ID_CFRULEEXT:
1689             dumpFrHeader( true, true );
1690             dumpBool< sal_uInt32 >( "cfrule12-follows" );
1691             dumpDec< sal_uInt16 >( "cfheader-id" );
1692             if( rStrm.getRemaining() >= 25 )
1693             {
1694                 dumpDec< sal_uInt16 >( "cfrule-idx" );
1695                 dumpDec< sal_uInt8 >( "operator", "CFRULE-OPERATOR" );
1696                 sal_uInt8 nSubType = dumpDec< sal_uInt8 >( "sub-type", "CFRULE12-SUBTYPE" );
1697                 dumpDec< sal_uInt16 >( "priority" );
1698                 dumpHex< sal_uInt8 >( "flags", "CFRULEEXT-FLAGS" );
1699                 if( dumpBoolean( "has-dxf-data" ) ) dumpDxf12Prop();
1700                 dumpCfRule12Param( nSubType );
1701             }
1702         break;
1703 
1704         case BIFF_ID_CH3DDATAFORMAT:
1705             dumpDec< sal_uInt8 >( "base", "CH3DDATAFORMAT-BASE" );
1706             dumpDec< sal_uInt8 >( "top", "CH3DDATAFORMAT-TOP" );
1707         break;
1708 
1709         case BIFF_ID_CHAREAFORMAT:
1710             dumpColorABGR( "fg-color" );
1711             dumpColorABGR( "bg-color" );
1712             dumpPatternIdx();
1713             dumpHex< sal_uInt16 >( "flags", "CHAREAFORMAT-FLAGS" );
1714             if( eBiff == BIFF8 ) dumpColorIdx( "fg-color-idx" );
1715             if( eBiff == BIFF8 ) dumpColorIdx( "bg-color-idx" );
1716         break;
1717 
1718         case BIFF_ID_CHAXESSET:
1719             dumpDec< sal_uInt16 >( "axesset-id", "CHAXESSET-ID" );
1720             dumpRect< sal_Int32 >( "inner-plotarea-pos", (eBiff <= BIFF4) ? "CONV-TWIP-TO-CM" : "" );
1721         break;
1722 
1723         case BIFF_ID_CHAXIS:
1724             dumpDec< sal_uInt16 >( "axis-type", "CHAXIS-TYPE" );
1725             if( eBiff <= BIFF4 )
1726                 dumpRect< sal_Int32 >( "position", "CONV-TWIP-TO-CM" );
1727             else
1728                 dumpUnused( 16 );
1729         break;
1730 
1731         case BIFF_ID_CHBAR:
1732             dumpDec< sal_Int16 >( "overlap", "CONV-PERCENT-NEG" );
1733             dumpDec< sal_Int16 >( "gap", "CONV-PERCENT" );
1734             dumpHex< sal_uInt16 >( "flags", "CHBAR-FLAGS" );
1735         break;
1736 
1737         case BIFF_ID_CHCHART:
1738             dumpRect< sal_Int32 >( "chart-frame", "CONV-PT1616-TO-CM", FORMATTYPE_FIX );
1739         break;
1740 
1741         case BIFF_ID_CHCHART3D:
1742             dumpDec< sal_uInt16 >( "rotation-angle", "CONV-DEG" );
1743             dumpDec< sal_Int16 >( "elevation-angle", "CONV-DEG" );
1744             dumpDec< sal_uInt16 >( "eye-distance" );
1745             dumpDec< sal_uInt16 >( "relative-height", "CONV-PERCENT" );
1746             dumpDec< sal_uInt16 >( "relative-depth", "CONV-PERCENT" );
1747             dumpDec< sal_uInt16 >( "depth-gap", "CONV-PERCENT" );
1748             dumpHex< sal_uInt16 >( "flags", "CHCHART3D-FLAGS" );
1749         break;
1750 
1751         case BIFF_ID_CHDATAFORMAT:
1752             dumpDec< sal_Int16 >( "point-idx", "CHDATAFORMAT-POINTIDX" );
1753             dumpDec< sal_Int16 >( "series-idx" );
1754             if( eBiff >= BIFF5 ) dumpDec< sal_Int16 >( "format-idx", "CHDATAFORMAT-FORMATIDX" );
1755             if( eBiff >= BIFF5 ) dumpHex< sal_uInt16 >( "flags", "CHDATAFORMAT-FLAGS" );
1756         break;
1757 
1758         case BIFF_ID_CHDATERANGE:
1759             dumpDec< sal_uInt16 >( "minimum-date" );
1760             dumpDec< sal_uInt16 >( "maximum-date" );
1761             dumpDec< sal_uInt16 >( "major-unit-value" );
1762             dumpDec< sal_uInt16 >( "major-unit", "CHDATERANGE-UNIT" );
1763             dumpDec< sal_uInt16 >( "minor-unit-value" );
1764             dumpDec< sal_uInt16 >( "minor-unit", "CHDATERANGE-UNIT" );
1765             dumpDec< sal_uInt16 >( "base-unit", "CHDATERANGE-UNIT" );
1766             dumpDec< sal_uInt16 >( "axis-crossing-date" );
1767             dumpHex< sal_uInt16 >( "flags", "CHDATERANGE-FLAGS" );
1768         break;
1769 
1770         case BIFF_ID_CHECKCOMPAT:
1771             dumpFrHeader( true, true );
1772             dumpBool< sal_uInt32 >( "check-compatibility" );
1773         break;
1774 
1775         case BIFF_ID_CHESCHERFORMAT:
1776             dumpEmbeddedDff();
1777         break;
1778 
1779         case BIFF_ID_CHFRAME:
1780             dumpDec< sal_uInt16 >( "format", "CHFRAME-FORMAT" );
1781             dumpHex< sal_uInt16 >( "flags", "CHFRAME-FLAGS" );
1782         break;
1783 
1784         case BIFF_ID_CHFRAMEPOS:
1785             dumpDec< sal_uInt16 >( "tl-mode", "CHFRAMEPOS-POSMODE" );
1786             dumpDec< sal_uInt16 >( "br-mode", "CHFRAMEPOS-POSMODE" );
1787             dumpRectWithGaps< sal_Int16 >( "position", 2 );
1788         break;
1789 
1790         case BIFF_ID_CHFRBLOCKBEGIN:
1791             dumpFrHeader( true, false );
1792             dumpDec< sal_uInt16 >( "type", "CHFRBLOCK-TYPE" );
1793             dumpDec< sal_uInt16 >( "context" );
1794             dumpDec< sal_uInt16 >( "value-1" );
1795             dumpDec< sal_uInt16 >( "value-2" );
1796         break;
1797 
1798         case BIFF_ID_CHFRBLOCKEND:
1799             dumpFrHeader( true, false );
1800             dumpDec< sal_uInt16 >( "type", "CHFRBLOCK-TYPE" );
1801             if( rStrm.getRemaining() >= 6 )
1802                 dumpUnused( 6 );
1803         break;
1804 
1805         case BIFF_ID_CHFRCATEGORYPROPS:
1806             dumpFrHeader( true, false );
1807             dumpDec< sal_uInt16 >( "label-offset", "CONV-PERCENT" );
1808             dumpDec< sal_uInt16 >( "alignment", "CHFRCATEGORYPROPS-ALIGN" );
1809             dumpHex< sal_uInt16 >( "flags", "CHFRCATEGORYPROPS-FLAGS" );
1810         break;
1811 
1812         case BIFF_ID_CHFREXTPROPS:
1813         {
1814             dumpFrHeader( true, true );
1815             dumpDec< sal_uInt32 >( "data-size" );
1816             dumpDec< sal_uInt8 >( "version" );
1817             dumpUnused( 1 );
1818             dumpDec< sal_uInt16 >( "parent", "CHFREXTPROPS-PARENT" );
1819             dumpChFrExtProps();
1820             dumpUnused( 4 );
1821         }
1822         break;
1823 
1824         case BIFF_ID_CHFRINFO:
1825         {
1826             dumpFrHeader( true, false );
1827             dumpDec< sal_uInt8 >( "creator", "CHFRINFO-APPVERSION" );
1828             dumpDec< sal_uInt8 >( "writer", "CHFRINFO-APPVERSION" );
1829             sal_uInt16 nCount = dumpDec< sal_uInt16 >( "rec-range-count" );
1830             mxOut->resetItemIndex();
1831             for( sal_uInt16 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex )
1832                 dumpHexPair< sal_uInt16 >( "#rec-range", '-' );
1833         }
1834         break;
1835 
1836         case BIFF_ID_CHFRLABELPROPS:
1837             dumpFrHeader( true, true );
1838             dumpHex< sal_uInt16 >( "flags", "CHFRLABELPROPS-FLAGS" );
1839             dumpUniString( "separator", BIFF_STR_SMARTFLAGS );
1840         break;
1841 
1842         case BIFF_ID_CHFRLAYOUT:
1843             dumpFrHeader( true, true );
1844             dumpHex< sal_uInt32 >( "checksum" );
1845             dumpHex< sal_uInt16 >( "flags", "CHFRLAYOUT-FLAGS" );
1846             dumpDec< sal_uInt16 >( "mode-x", "CHFRLAYOUT-MODE" );
1847             dumpDec< sal_uInt16 >( "mode-y", "CHFRLAYOUT-MODE" );
1848             dumpDec< sal_uInt16 >( "mode-w", "CHFRLAYOUT-MODE" );
1849             dumpDec< sal_uInt16 >( "mode-h", "CHFRLAYOUT-MODE" );
1850             dumpRect< double >( "position" );
1851             dumpUnused( 2 );
1852         break;
1853 
1854         case BIFF_ID_CHFRPLOTAREALAYOUT:
1855             dumpFrHeader( true, true );
1856             dumpHex< sal_uInt32 >( "checksum" );
1857             dumpHex< sal_uInt16 >( "flags", "CHFRPLOTAREALAYOUT-FLAGS" );
1858             dumpRect< sal_Int16 >( "position" );
1859             dumpDec< sal_uInt16 >( "mode-x", "CHFRLAYOUT-MODE" );
1860             dumpDec< sal_uInt16 >( "mode-y", "CHFRLAYOUT-MODE" );
1861             dumpDec< sal_uInt16 >( "mode-w", "CHFRLAYOUT-MODE" );
1862             dumpDec< sal_uInt16 >( "mode-h", "CHFRLAYOUT-MODE" );
1863             dumpRect< double >( "position" );
1864             dumpUnused( 2 );
1865         break;
1866 
1867         case BIFF_ID_CHFRSHAPEPROPS:
1868             dumpFrHeader( true, true );
1869             dumpDec< sal_uInt16 >( "context" );
1870             dumpUnused( 2 );
1871             dumpHex< sal_uInt32 >( "checksum" );
1872             dumpDec< sal_uInt32 >( "xml-size" );
1873         break;
1874 
1875         case BIFF_ID_CHFRTEXTPROPS:
1876             dumpFrHeader( true, true );
1877             dumpHex< sal_uInt32 >( "checksum" );
1878             dumpDec< sal_uInt32 >( "xml-size" );
1879         break;
1880 
1881         case BIFF_ID_CHFRUNITPROPS:
1882             dumpFrHeader( true, false );
1883             dumpDec< sal_Int16 >( "preset", "CHFRUNITPROPS-PRESET" );
1884             dumpDec< double >( "unit" );
1885             dumpHex< sal_uInt16 >( "flags", "CHFRUNITPROPS-FLAGS" );
1886         break;
1887 
1888         case BIFF_ID_CHFRWRAPPER:
1889             dumpFrHeader( true, false );
1890         break;
1891 
1892         case BIFF_ID_CHLABELRANGE:
1893             dumpDec< sal_uInt16 >( "axis-crossing" );
1894             dumpDec< sal_uInt16 >( "label-frequency" );
1895             dumpDec< sal_uInt16 >( "tick-frequency" );
1896             dumpHex< sal_uInt16 >( "flags", "CHLABELRANGE-FLAGS" );
1897         break;
1898 
1899         case BIFF_ID_CHLEGEND:
1900             dumpRect< sal_Int32 >( "position", (eBiff <= BIFF4) ? "CONV-TWIP-TO-CM" : "" );
1901             dumpDec< sal_uInt8 >( "docked-pos", "CHLEGEND-DOCKPOS" );
1902             dumpDec< sal_uInt8 >( "spacing", "CHLEGEND-SPACING" );
1903             dumpHex< sal_uInt16 >( "flags", "CHLEGEND-FLAGS" );
1904         break;
1905 
1906         case BIFF_ID_CHLINEFORMAT:
1907             dumpColorABGR();
1908             dumpDec< sal_uInt16 >( "line-type", "CHLINEFORMAT-LINETYPE" );
1909             dumpDec< sal_Int16 >( "line-weight", "CHLINEFORMAT-LINEWEIGHT" );
1910             dumpHex< sal_uInt16 >( "flags", "CHLINEFORMAT-FLAGS" );
1911             if( eBiff == BIFF8 ) dumpColorIdx();
1912         break;
1913 
1914         case BIFF_ID_CHMARKERFORMAT:
1915             dumpColorABGR( "border-color" );
1916             dumpColorABGR( "fill-color" );
1917             dumpDec< sal_uInt16 >( "marker-type", "CHMARKERFORMAT-TYPE" );
1918             dumpHex< sal_uInt16 >( "flags", "CHMARKERFORMAT-FLAGS" );
1919             if( eBiff == BIFF8 ) dumpColorIdx( "border-color-idx" );
1920             if( eBiff == BIFF8 ) dumpColorIdx( "fill-color-idx" );
1921             if( eBiff == BIFF8 ) dumpDec< sal_Int32 >( "marker-size", "CONV-TWIP-TO-PT" );
1922         break;
1923 
1924         case BIFF_ID_CHOBJECTLINK:
1925             dumpDec< sal_uInt16 >( "link-target", "CHOBJECTLINK-TARGET" );
1926             dumpDec< sal_Int16 >( "series-idx" );
1927             dumpDec< sal_Int16 >( "point-idx", "CHOBJECTLINK-POINT" );
1928         break;
1929 
1930         case BIFF_ID_CHPICFORMAT:
1931             dumpDec< sal_uInt16 >( "bitmap-mode", "CHPICFORMAT-BITMAP-MODE" );
1932             dumpUnused( 2 );
1933             dumpHex< sal_uInt16 >( "flags", "CHPICFORMAT-FLAGS" );
1934             dumpDec< double >( "scaling-factor" );
1935         break;
1936 
1937         case BIFF_ID_CHPIE:
1938             dumpDec< sal_uInt16 >( "angle", "CONV-DEG" );
1939             if( eBiff >= BIFF5 ) dumpDec< sal_uInt16 >( "hole-size" );
1940             if( eBiff >= BIFF8 ) dumpHex< sal_uInt16 >( "flags", "CHPIE-FLAGS" );
1941         break;
1942 
1943         case BIFF_ID_CHPIVOTFLAGS:
1944             dumpRepeatedRecId();
1945             dumpUnused( 2 );
1946             dumpHex< sal_uInt16 >( "flags", "CHPIVOTFLAGS-FLAGS" );
1947         break;
1948 
1949         case BIFF8_ID_CHPIVOTREF:
1950             dumpRepeatedRecId();
1951             dumpUnused( 4 );
1952             dumpUniString( "ref", BIFF_STR_8BITLENGTH );
1953         break;
1954 
1955         case BIFF_ID_CHPLOTGROWTH:
1956             dumpFix< sal_Int32 >( "horizontal-growth" );
1957             dumpFix< sal_Int32 >( "vertical-growth" );
1958         break;
1959 
1960         case BIFF_ID_CHPROPERTIES:
1961             dumpHex< sal_uInt16 >( "flags", "CHPROPERTIES-FLAGS" );
1962             dumpDec< sal_uInt8 >( "empty-cells", "CHPROPERTIES-EMPTYCELLS" );
1963         break;
1964 
1965         case BIFF_ID_CHSCATTER:
1966             if( eBiff == BIFF8 ) dumpDec< sal_uInt16 >( "bubble-size", "CONV-PERCENT" );
1967             if( eBiff == BIFF8 ) dumpDec< sal_uInt16 >( "size-type", "CHSCATTER-SIZETYPE" );
1968             if( eBiff == BIFF8 ) dumpHex< sal_uInt16 >( "flags", "CHSCATTER-FLAGS" );
1969         break;
1970 
1971         case BIFF_ID_CHSERERRORBAR:
1972             dumpDec< sal_uInt8 >( "type", "CHSERERRORBAR-TYPE" );
1973             dumpDec< sal_uInt8 >( "source", "CHSERERRORBAR-SOURCE" );
1974             dumpBool< sal_uInt8 >( "draw-t-shape" );
1975             dumpBool< sal_uInt8 >( "draw-line" );
1976             dumpDec< double >( "value" );
1977             dumpDec< sal_uInt16 >( "custom-count" );
1978         break;
1979 
1980         case BIFF_ID_CHSERIES:
1981             dumpDec< sal_uInt16 >( "categories-type", "CHSERIES-TYPE" );
1982             dumpDec< sal_uInt16 >( "values-type", "CHSERIES-TYPE" );
1983             dumpDec< sal_uInt16 >( "categories-count" );
1984             dumpDec< sal_uInt16 >( "values-count" );
1985             if( eBiff == BIFF8 ) dumpDec< sal_uInt16 >( "bubbles-type", "CHSERIES-TYPE" );
1986             if( eBiff == BIFF8 ) dumpDec< sal_uInt16 >( "bubbles-count" );
1987         break;
1988 
1989         case BIFF_ID_CHSERTRENDLINE:
1990             switch( dumpDec< sal_uInt8 >( "type", "CHSERTRENDLINE-TYPE" ) )
1991             {
1992                 case 0:     dumpDec< sal_uInt8 >( "order" );            break;
1993                 case 4:     dumpDec< sal_uInt8 >( "average-period" );   break;
1994                 default:    dumpUnused( 1 );
1995             }
1996             dumpDec< double >( "intercept" );
1997             dumpBool< sal_uInt8 >( "show-equation" );
1998             dumpBool< sal_uInt8 >( "show-r-sqrare" );
1999             dumpDec< double >( "forecast-forward" );
2000             dumpDec< double >( "forecast-backward" );
2001         break;
2002 
2003         case BIFF_ID_CHSOURCELINK:
2004             dumpDec< sal_uInt8 >( "link-target", "CHSOURCELINK-TARGET" );
2005             dumpDec< sal_uInt8 >( "link-type", "CHSOURCELINK-TYPE" );
2006             dumpHex< sal_uInt16 >( "flags", "CHSOURCELINK-FLAGS" );
2007             dumpFormatIdx();
2008             getFormulaDumper().dumpNameFormula();
2009         break;
2010 
2011         case BIFF_ID_CHSTRING:
2012             dumpDec< sal_uInt16 >( "text-type", "CHSTRING-TYPE" );
2013             dumpString( "text", BIFF_STR_8BITLENGTH, BIFF_STR_8BITLENGTH );
2014         break;
2015 
2016         case BIFF_ID_CHTEXT:
2017             dumpDec< sal_uInt8 >( "horizontal-align", "CHTEXT-HORALIGN" );
2018             dumpDec< sal_uInt8 >( "vertical-align", "CHTEXT-VERALIGN" );
2019             dumpDec< sal_uInt16 >( "fill-mode", "CHTEXT-FILLMODE" );
2020             dumpColorABGR();
2021             dumpRect< sal_Int32 >( "position", (eBiff <= BIFF4) ? "CONV-TWIP-TO-CM" : "" );
2022             dumpHex< sal_uInt16 >( "flags-1", "CHTEXT-FLAGS1" );
2023             if( eBiff == BIFF8 ) dumpColorIdx();
2024             if( eBiff == BIFF8 ) dumpHex< sal_uInt16 >( "flags-2", "CHTEXT-FLAGS2" );
2025             if( eBiff == BIFF8 ) dumpDec< sal_uInt16 >( "rotation", "TEXTROTATION" );
2026         break;
2027 
2028         case BIFF_ID_CHTICK:
2029             dumpDec< sal_uInt8 >( "major-ticks", "CHTICK-TYPE" );
2030             dumpDec< sal_uInt8 >( "minor-ticks", "CHTICK-TYPE" );
2031             dumpDec< sal_uInt8 >( "label-position", "CHTICK-LABELPOS" );
2032             dumpDec< sal_uInt8 >( "fill-mode", "CHTEXT-FILLMODE" );
2033             dumpColorABGR( "label-color" );
2034             dumpUnused( 16 );
2035             dumpHex< sal_uInt16 >( "flags", "CHTICK-FLAGS" );
2036             if( eBiff == BIFF8 ) dumpColorIdx( "label-color-idx" );
2037             if( eBiff == BIFF8 ) dumpDec< sal_uInt16 >( "label-rotation", "TEXTROTATION" );
2038         break;
2039 
2040         case BIFF_ID_CHTYPEGROUP:
2041             dumpUnused( 16 );
2042             dumpHex< sal_uInt16 >( "flags", "CHTYPEGROUP-FLAGS" );
2043             if( eBiff >= BIFF5 ) dumpDec< sal_uInt16 >( "group-idx" );
2044         break;
2045 
2046         case BIFF_ID_CHVALUERANGE:
2047             dumpDec< double >( "minimum" );
2048             dumpDec< double >( "maximum" );
2049             dumpDec< double >( "major-inc" );
2050             dumpDec< double >( "minor-inc" );
2051             dumpDec< double >( "axis-crossing" );
2052             dumpHex< sal_uInt16 >( "flags", "CHVALUERANGE-FLAGS" );
2053         break;
2054 
2055         case BIFF_ID_CODENAME:
2056             dumpUniString( "codename" );
2057         break;
2058 
2059         case BIFF_ID_CODEPAGE:
2060             getBiffData().setTextEncoding( dumpCodePage() );
2061             mbHasCodePage = true;
2062         break;
2063 
2064         case BIFF_ID_COLINFO:
2065             dumpColRange();
2066             dumpDec< sal_uInt16 >( "col-width", "CONV-COLWIDTH" );
2067             dumpXfIdx( "xf-idx" );
2068             dumpHex< sal_uInt16 >( "flags", "COLINFO-FLAGS" );
2069             dumpUnused( 2 );
2070         break;
2071 
2072         case BIFF_ID_COLUMNDEFAULT:
2073             mxOut->resetItemIndex();
2074             for( sal_Int32 nCol = 0, nCount = dumpColRange(); nCol < nCount; ++nCol )
2075                 dumpXfIdx( "#xf-idx", true );
2076             dumpUnused( 2 );
2077         break;
2078 
2079         case BIFF_ID_COLWIDTH:
2080             dumpColRange( EMPTY_STRING, false );
2081             dumpDec< sal_uInt16 >( "col-width", "CONV-COLWIDTH" );
2082         break;
2083 
2084         case BIFF_ID_COMPRESSPICS:
2085             dumpFrHeader( true, true );
2086             dumpBool< sal_uInt32 >( "recommend-compress-pics" );
2087         break;
2088 
2089         case BIFF_ID_CONNECTION:
2090         {
2091             dumpFrHeader( true, false );
2092             sal_uInt16 nType = dumpDec< sal_uInt16 >( "data-source-type", "CONNECTION-SOURCETYPE" );
2093             sal_uInt16 nFlags1 = dumpHex< sal_uInt16 >( "flags", "CONNECTION-FLAGS" );
2094             dumpDec< sal_uInt16 >( "param-count" );
2095             dumpUnused( 2 );
2096             dumpHex< sal_uInt16 >( "querytable-flags", "QUERYTABLESETTINGS-FLAGS" );
2097             switch( nType )
2098             {
2099                 case 4:     dumpHex< sal_uInt16 >( "html-flags", "QUERYTABLESETTINGS-HTML-FLAGS" );     break;
2100                 case 5:     dumpHex< sal_uInt16 >( "oledb-flags", "QUERYTABLESETTINGS-OLEDB-FLAGS" );   break;
2101                 case 7:     dumpHex< sal_uInt16 >( "ado-flags", "QUERYTABLESETTINGS-ADO-FLAGS" );       break;
2102                 default:    dumpUnused( 2 );
2103             }
2104             dumpDec< sal_uInt8 >( "edited-version" );
2105             dumpDec< sal_uInt8 >( "refreshed-version" );
2106             dumpDec< sal_uInt8 >( "min-refresh-version" );
2107             dumpDec< sal_uInt16 >( "refresh-interval", "QUERYTABLESETTINGS-INTERVAL" );
2108             dumpDec< sal_uInt16 >( "html-format", "QUERYTABLESETTINGS-HTMLFORMAT" );
2109             dumpDec< sal_Int32 >( "reconnect-type", "CONNECTION-RECONNECTTYPE" );
2110             dumpDec< sal_uInt8 >( "credentials", "CONNECTION-CREDENTIALS" );
2111             dumpUnused( 1 );
2112             dumpSegmentedUniString( "source-file" );
2113             dumpSegmentedUniString( "source-conn-file" );
2114             dumpSegmentedUniString( "name" );
2115             dumpSegmentedUniString( "description" );
2116             dumpSegmentedUniString( "sso-id" );
2117             if( nFlags1 & 0x0004 ) dumpSegmentedUniString( "table-names" );
2118             if( nFlags1 & 0x0010 )
2119             {
2120                 break;   // TODO: parameter array structure
2121             }
2122             bool bEscape = false;
2123             switch( nType )
2124             {
2125                 case 1:
2126                     dumpSegmentedUniString( "connection-string" );
2127                 break;
2128                 case 4:
2129                     dumpSegmentedUniStringArray( "urls" );
2130                     dumpSegmentedUniStringArray( "post-method" );
2131                 break;
2132                 case 5:
2133                     bEscape = true;
2134                 break;
2135                 case 6:
2136                     bEscape = true;
2137                 break;
2138             }
2139             if( bEscape )
2140                 break;
2141             dumpSegmentedUniStringArray( "sql-command" );
2142             dumpSegmentedUniStringArray( "orig-sql-command" );
2143             dumpSegmentedUniStringArray( "webquery-dialog-url" );
2144             switch( dumpDec< sal_uInt8 >( "linked-object-type", "CONNECTION-LINKEDOBJECTTYPE" ) )
2145             {
2146                 case 1: dumpSegmentedUniString( "defined-name" );   break;
2147                 case 2: dumpHex< sal_uInt16 >( "cache-id" );        break;
2148             }
2149         }
2150         break;
2151 
2152         case BIFF_ID_CONT:
2153             if( (eBiff == BIFF8) && (getLastRecId() == BIFF_ID_OBJ) )
2154                 dumpEmbeddedDff();
2155         break;
2156 
2157         case BIFF_ID_COORDLIST:
2158         {
2159             mxOut->resetItemIndex();
2160             TableGuard aTabGuard( mxOut, 12, 10 );
2161             while( rStrm.getRemaining() >= 4 )
2162             {
2163                 MultiItemsGuard aMultiGuard( mxOut );
2164                 writeEmptyItem( "#point" );
2165                 dumpDec< sal_uInt16 >( "x" );
2166                 dumpDec< sal_uInt16 >( "y" );
2167             }
2168         }
2169         break;
2170 
2171         case BIFF_ID_COUNTRY:
2172             dumpDec< sal_uInt16 >( "ui-country", "COUNTRY" );
2173             dumpDec< sal_uInt16 >( "sys-country", "COUNTRY" );
2174         break;
2175 
2176         case BIFF_ID_CRN:
2177         {
2178             sal_Int32 nCol2 = dumpColIndex( "last-col-idx", false );
2179             sal_Int32 nCol1 = dumpColIndex( "first-col-idx", false );
2180             sal_Int32 nRow = dumpRowIndex( "row-idx" );
2181             TableGuard aTabGuard( mxOut, 14, 17 );
2182             for( Address aPos( nCol1, nRow ); !rStrm.isEof() && (aPos.mnCol <= nCol2); ++aPos.mnCol )
2183             {
2184                 MultiItemsGuard aMultiGuard( mxOut );
2185                 writeAddressItem( "pos", aPos );
2186                 dumpConstValue();
2187             }
2188         }
2189         break;
2190 
2191         case BIFF_ID_DCONBINAME:
2192             dumpDec< sal_uInt8 >( "builtin-id", "DEFINEDNAME-BUILTINID" );
2193             dumpUnused( 3 );
2194             dumpString( "source-link", BIFF_STR_8BITLENGTH, BIFF_STR_SMARTFLAGS );
2195         break;
2196 
2197         case BIFF_ID_DCONNAME:
2198             dumpString( "source-name", BIFF_STR_8BITLENGTH );
2199             dumpString( "source-link", BIFF_STR_8BITLENGTH, BIFF_STR_SMARTFLAGS );
2200         break;
2201 
2202         case BIFF_ID_DCONREF:
2203             dumpRange( "source-range", false );
2204             dumpString( "source-link", BIFF_STR_8BITLENGTH, BIFF_STR_SMARTFLAGS );
2205         break;
2206 
2207         case BIFF2_ID_DATATABLE:
2208             dumpRange( "table-range", false );
2209             dumpBoolean( "recalc-always" );
2210             dumpBoolean( "row-table" );
2211             dumpAddress( "ref1" );
2212         break;
2213 
2214         case BIFF3_ID_DATATABLE:
2215             dumpRange( "table-range", false );
2216             dumpHex< sal_uInt16 >( "flags", "DATATABLE-FLAGS" );
2217             dumpAddress( "ref1" );
2218             dumpAddress( "ref2" );
2219         break;
2220 
2221         case BIFF2_ID_DATATABLE2:
2222             dumpRange( "table-range", false );
2223             dumpBoolean( "recalc-always" );
2224             dumpUnused( 1 );
2225             dumpAddress( "ref1" );
2226             dumpAddress( "ref2" );
2227         break;
2228 
2229         case BIFF_ID_DATAVALIDATION:
2230         {
2231             dumpHex< sal_uInt32 >( "flags", "DATAVALIDATION-FLAGS" );
2232             dumpUniString( "input-title" );
2233             dumpUniString( "error-title" );
2234             dumpUniString( "input-message" );
2235             dumpUniString( "error-message" );
2236             sal_uInt16 nFmla1Size = getFormulaDumper().dumpFormulaSize( "formula1-size" );
2237             dumpUnused( 2 );
2238             if( nFmla1Size > 0 )
2239                 getFormulaDumper().dumpNameFormula( "formula1", nFmla1Size );
2240             sal_uInt16 nFmla2Size = getFormulaDumper().dumpFormulaSize( "formula2-size" );
2241             dumpUnused( 2 );
2242             if( nFmla2Size > 0 )
2243                 getFormulaDumper().dumpNameFormula( "formula2", nFmla2Size );
2244             dumpRangeList();
2245         }
2246         break;
2247 
2248         case BIFF_ID_DATAVALIDATIONS:
2249             dumpHex< sal_uInt16 >( "flags", "DATAVALIDATIONS-FLAGS" );
2250             dumpDec< sal_Int32 >( "input-box-pos-x" );
2251             dumpDec< sal_Int32 >( "input-box-pos-y" );
2252             dumpDec< sal_Int32 >( "dropdown-object-id" );
2253             dumpDec< sal_Int32 >( "dval-entry-count" );
2254         break;
2255 
2256         case BIFF_ID_DBCELL:
2257             dumpDec< sal_uInt32 >( "reverse-offset-to-row" );
2258             mxOut->resetItemIndex();
2259             while( rStrm.getRemaining() >= 2 )
2260                 dumpDec< sal_uInt16 >( "#cell-offset" );
2261         break;
2262 
2263         case BIFF_ID_DBQUERY:
2264             if( eBiff == BIFF8 )
2265             {
2266                 if( (getLastRecId() != BIFF_ID_PCITEM_STRING) && (getLastRecId() != BIFF_ID_DBQUERY) )
2267                 {
2268                     dumpHex< sal_uInt16 >( "flags", "DBQUERY-FLAGS" );
2269                     dumpDec< sal_uInt16 >( "sql-param-count" );
2270                     dumpDec< sal_uInt16 >( "command-count" );
2271                     dumpDec< sal_uInt16 >( "post-method-count" );
2272                     dumpDec< sal_uInt16 >( "server-sql-count" );
2273                     dumpDec< sal_uInt16 >( "odbc-connection-count" );
2274                 }
2275             }
2276         break;
2277 
2278         case BIFF2_ID_DEFINEDNAME:
2279         case BIFF3_ID_DEFINEDNAME:
2280         {
2281             rtl_TextEncoding eTextEnc = getBiffData().getTextEncoding();
2282             dumpHex< sal_uInt16, sal_uInt8 >( eBiff != BIFF2, "flags", "DEFINEDNAME-FLAGS" );
2283             if( eBiff == BIFF2 ) dumpDec< sal_uInt8 >( "macro-type", "DEFINEDNAME-MACROTYPE-BIFF2" );
2284             dumpChar( "accelerator", eTextEnc );
2285             sal_uInt8 nNameLen = dumpDec< sal_uInt8 >( "name-len" );
2286             sal_uInt16 nFmlaSize = getFormulaDumper().dumpFormulaSize();
2287             if( eBiff >= BIFF5 )
2288             {
2289                 bool bBiff8 = eBiff == BIFF8;
2290                 if( bBiff8 ) dumpUnused( 2 ); else dumpDec< sal_uInt16 >( "externsheet-idx", "DEFINEDNAME-SHEETIDX" );
2291                 dumpDec< sal_uInt16 >( "sheet-idx", "DEFINEDNAME-SHEETIDX" );
2292                 sal_uInt8 nMenuLen = dumpDec< sal_uInt8 >( "menu-text-len" );
2293                 sal_uInt8 nDescrLen = dumpDec< sal_uInt8 >( "description-text-len" );
2294                 sal_uInt8 nHelpLen = dumpDec< sal_uInt8 >( "help-text-len" );
2295                 sal_uInt8 nStatusLen = dumpDec< sal_uInt8 >( "statusbar-text-len" );
2296                 writeStringItem( "name", bBiff8 ? rStrm.readUniStringBody( nNameLen, true ) : rStrm.readCharArrayUC( nNameLen, eTextEnc, true ) );
2297                 getFormulaDumper().dumpNameFormula( EMPTY_STRING, nFmlaSize );
2298                 if( nMenuLen > 0 ) writeStringItem( "menu-text", bBiff8 ? rStrm.readUniStringBody( nMenuLen, true ) : rStrm.readCharArrayUC( nMenuLen, eTextEnc, true ) );
2299                 if( nDescrLen > 0 ) writeStringItem( "description-text", bBiff8 ? rStrm.readUniStringBody( nDescrLen, true ) : rStrm.readCharArrayUC( nDescrLen, eTextEnc, true ) );
2300                 if( nHelpLen > 0 ) writeStringItem( "help-text", bBiff8 ? rStrm.readUniStringBody( nHelpLen, true ) : rStrm.readCharArrayUC( nHelpLen, eTextEnc, true ) );
2301                 if( nStatusLen > 0 ) writeStringItem( "statusbar-text", bBiff8 ? rStrm.readUniStringBody( nStatusLen, true ) : rStrm.readCharArrayUC( nStatusLen, eTextEnc, true ) );
2302             }
2303             else
2304             {
2305                 writeStringItem( "name", rStrm.readCharArrayUC( nNameLen, eTextEnc, true ) );
2306                 getFormulaDumper().dumpNameFormula( EMPTY_STRING, nFmlaSize );
2307                 if( eBiff == BIFF2 ) getFormulaDumper().dumpFormulaSize();
2308             }
2309         }
2310         break;
2311 
2312         case BIFF3_ID_DEFROWHEIGHT:
2313             dumpHex< sal_uInt16 >( "flags", "DEFROWHEIGHT-FLAGS" );
2314             dumpDec< sal_uInt16 >( "row-height", "CONV-TWIP-TO-PT" );
2315         break;
2316 
2317         case BIFF2_ID_DIMENSION:
2318         case BIFF3_ID_DIMENSION:
2319             dumpRange( "used-area", true, (nRecId == BIFF3_ID_DIMENSION) && (eBiff == BIFF8) );
2320             if( nRecId == BIFF3_ID_DIMENSION ) dumpUnused( 2 );
2321         break;
2322 
2323         case BIFF_ID_DXF:
2324             dumpFrHeader( true, true );
2325             dumpHex< sal_uInt16 >( "flags", "DXF-FLAGS" );
2326             dumpDxfProp();
2327         break;
2328 
2329         case BIFF_ID_EXTERNALBOOK:
2330         {
2331             sal_uInt16 nCount = dumpDec< sal_uInt16 >( "sheet-count" );
2332             if( rStrm.getRemaining() == 2 )
2333                 dumpHex< sal_uInt16 >( "special-key", "EXTERNALBOOK-KEY" );
2334             else
2335             {
2336                 dumpString( "workbook-url" );
2337                 mxOut->resetItemIndex();
2338                 for( sal_uInt16 nSheet = 0; !rStrm.isEof() && (nSheet < nCount); ++nSheet )
2339                     dumpString( "#sheet-name" );
2340             }
2341         }
2342         break;
2343 
2344         case BIFF2_ID_EXTERNALNAME:
2345         case BIFF3_ID_EXTERNALNAME:
2346         {
2347             sal_uInt16 nFlags = (eBiff >= BIFF3) ? dumpHex< sal_uInt16 >( "flags", "EXTERNALNAME-FLAGS" ) : 0;
2348             if( eBiff >= BIFF5 )
2349             {
2350                 if( getFlag< sal_uInt16 >( nFlags, 0x0010 ) )
2351                 {
2352                     dumpHex< sal_uInt32 >( "storage-id" );
2353                 }
2354                 else
2355                 {
2356                     dumpDec< sal_uInt16 >( "externsheet-idx" );
2357                     dumpUnused( 2 );
2358                 }
2359             }
2360             OUString aName = dumpString( "name", BIFF_STR_8BITLENGTH, BIFF_STR_8BITLENGTH );
2361             if( (aName.getLength() > 0) && (aName[ 0 ] == 1) && (rStrm.getRemaining() >= 2) )
2362                 getFormulaDumper().dumpNameFormula();
2363         }
2364         break;
2365 
2366         case BIFF_ID_EXTERNSHEET:
2367             if( eBiff == BIFF8 )
2368             {
2369                 sal_uInt16 nCount = dumpDec< sal_uInt16 >( "ref-count" );
2370                 TableGuard aTabGuard( mxOut, 10, 17, 24 );
2371                 mxOut->resetItemIndex();
2372                 for( sal_uInt16 nRefId = 0; !rStrm.isEof() && (nRefId < nCount); ++nRefId )
2373                 {
2374                     MultiItemsGuard aMultiGuard( mxOut );
2375                     writeEmptyItem( "#ref" );
2376                     dumpDec< sal_uInt16 >( "extbook-idx" );
2377                     dumpDec< sal_Int16 >( "first-sheet", "EXTERNSHEET-IDX" );
2378                     dumpDec< sal_Int16 >( "last-sheet", "EXTERNSHEET-IDX" );
2379                 }
2380             }
2381             else
2382             {
2383                 OStringBuffer aUrl( rStrm.readByteString( false, true ) );
2384                 if( (aUrl.getLength() > 0) && (aUrl[ 0 ] == '\x03') )
2385                     aUrl.append( static_cast< sal_Char >( rStrm.readuInt8() ) );
2386                 writeStringItem( "encoded-url", OStringToOUString( aUrl.makeStringAndClear(), getBiffData().getTextEncoding() ) );
2387             }
2388         break;
2389 
2390         case BIFF_ID_FILEPASS:
2391         {
2392             rStrm.enableDecoder( false );
2393             if( eBiff == BIFF8 )
2394             {
2395                 switch( dumpDec< sal_uInt16 >( "type", "FILEPASS-TYPE" ) )
2396                 {
2397                     case 0:
2398                         dumpHex< sal_uInt16 >( "key" );
2399                         dumpHex< sal_uInt16 >( "verifier" );
2400                     break;
2401                     case 1:
2402                     {
2403                         sal_uInt16 nMajor = dumpDec< sal_uInt16 >( "major-version", "FILEPASS-MAJOR" );
2404                         dumpDec< sal_uInt16 >( "minor-version" );
2405                         switch( nMajor )
2406                         {
2407                             case 1:
2408                                 dumpArray( "salt", 16 );
2409                                 dumpArray( "verifier", 16 );
2410                                 dumpArray( "verifier-hash", 16 );
2411                             break;
2412                         }
2413                     }
2414                     break;
2415                 }
2416             }
2417             else
2418             {
2419                 dumpHex< sal_uInt16 >( "key" );
2420                 dumpHex< sal_uInt16 >( "verifier" );
2421             }
2422             rStrm.seekToStart();
2423             BiffDecoderRef xDecoder = BiffCodecHelper::implReadFilePass( rStrm, eBiff );
2424             if( xDecoder.get() )
2425                 cfg().requestEncryptionData( *xDecoder );
2426             setBinaryOnlyMode( !xDecoder || !xDecoder->isValid() );
2427         }
2428         break;
2429 
2430         case BIFF_ID_FILESHARING:
2431             dumpBool< sal_uInt16 >( "recommend-read-only" );
2432             dumpHex< sal_uInt16 >( "password-hash" );
2433             dumpString( "password-creator", BIFF_STR_8BITLENGTH, BIFF_STR_SMARTFLAGS );
2434         break;
2435 
2436         case BIFF_ID_FILTERCOLUMN:
2437         {
2438             dumpDec< sal_uInt16 >( "column-index" );
2439             dumpHex< sal_uInt16 >( "flags", "FILTERCOLUMN-FLAGS" );
2440             sal_uInt8 nStrLen1 = dumpFilterColumnOperator( "operator-1" );
2441             sal_uInt8 nStrLen2 = dumpFilterColumnOperator( "operator-2" );
2442             bool bBiff8 = eBiff == BIFF8;
2443             rtl_TextEncoding eTextEnc = getBiffData().getTextEncoding();
2444             if( nStrLen1 > 0 ) writeStringItem( "string-1", bBiff8 ? rStrm.readUniStringBody( nStrLen1, true ) : rStrm.readCharArrayUC( nStrLen1, eTextEnc, true ) );
2445             if( nStrLen2 > 0 ) writeStringItem( "string-2", bBiff8 ? rStrm.readUniStringBody( nStrLen2, true ) : rStrm.readCharArrayUC( nStrLen2, eTextEnc, true ) );
2446         }
2447         break;
2448 
2449         case BIFF2_ID_FONT:
2450         case BIFF3_ID_FONT:
2451             dumpFontRec();
2452         break;
2453 
2454         case BIFF_ID_FORCEFULLCALC:
2455             dumpFrHeader( true, true );
2456             dumpBool< sal_Int32 >( "recalc-all-formulas" );
2457         break;
2458 
2459         case BIFF2_ID_FORMAT:
2460         case BIFF4_ID_FORMAT:
2461             dumpFormatRec();
2462         break;
2463 
2464         case BIFF2_ID_FORMULA:
2465         case BIFF3_ID_FORMULA:
2466         case BIFF4_ID_FORMULA:
2467             dumpCellHeader( eBiff == BIFF2 );
2468             dumpFormulaResult();
2469             dumpHex< sal_uInt16, sal_uInt8 >( eBiff != BIFF2, "flags", "FORMULA-FLAGS" );
2470             if( eBiff >= BIFF5 ) dumpUnused( 4 );
2471             getFormulaDumper().dumpCellFormula();
2472         break;
2473 
2474         case BIFF_ID_FOOTER:
2475             if( rStrm.getRemaining() > 0 )
2476                 dumpString( "footer", BIFF_STR_8BITLENGTH );
2477         break;
2478 
2479         case BIFF_ID_GUTS:
2480             dumpDec< sal_uInt16 >( "row-outlines-width" );
2481             dumpDec< sal_uInt16 >( "column-outlines-height" );
2482             dumpDec< sal_uInt16 >( "row-levels", "GUTS-LEVELS" );
2483             dumpDec< sal_uInt16 >( "column-levels", "GUTS-LEVELS" );
2484         break;
2485 
2486         case BIFF_ID_HEADER:
2487             if( rStrm.getRemaining() > 0 )
2488                 dumpString( "header", BIFF_STR_8BITLENGTH );
2489         break;
2490 
2491         case BIFF_ID_HEADERFOOTER:
2492         {
2493             dumpFrHeader( true, true );
2494             dumpGuid( "view-guid" );
2495             dumpHex< sal_uInt16 >( "flags", "HEADERFOOTER-FLAGS" );
2496             sal_uInt16 nEvenHLen = dumpDec< sal_uInt16 >( "even-h-len" );
2497             sal_uInt16 nEvenFLen = dumpDec< sal_uInt16 >( "even-f-len" );
2498             sal_uInt16 nFirstHLen = dumpDec< sal_uInt16 >( "first-h-len" );
2499             sal_uInt16 nFirstFLen = dumpDec< sal_uInt16 >( "first-f-len" );
2500             if( nEvenHLen > 0 ) dumpUniString( "even-h" );
2501             if( nEvenFLen > 0 ) dumpUniString( "even-f" );
2502             if( nFirstHLen > 0 ) dumpUniString( "first-h" );
2503             if( nFirstFLen > 0 ) dumpUniString( "first-f" );
2504         }
2505         break;
2506 
2507         case BIFF_ID_HYPERLINK:
2508             dumpRange();
2509             if( cfg().getStringOption( dumpGuid( "guid" ), OUString() ).equalsAscii( "StdHlink" ) )
2510                 StdHlinkObject( *this ).dump();
2511         break;
2512 
2513         case BIFF3_ID_IMGDATA:
2514         case BIFF8_ID_IMGDATA:
2515         {
2516             sal_uInt16 nFormat = dumpDec< sal_uInt16 >( "image-format", "IMGDATA-FORMAT" );
2517             dumpDec< sal_uInt16 >( "environment", "IMGDATA-ENV" );
2518             dumpDec< sal_uInt32 >( "data-size" );
2519             if( nFormat == 9 )
2520             {
2521                 writeEmptyItem( "bitmap-header" );
2522                 IndentGuard aIndGuard( mxOut );
2523                 if( dumpDec< sal_uInt32 >( "header-size" ) == 12 )
2524                 {
2525                     dumpDec< sal_Int16 >( "width" );
2526                     dumpDec< sal_Int16 >( "height" );
2527                     dumpDec< sal_Int16 >( "planes" );
2528                     dumpDec< sal_Int16 >( "bit-count" );
2529                 }
2530             }
2531         }
2532         break;
2533 
2534         case BIFF2_ID_INDEX:
2535         case BIFF3_ID_INDEX:
2536             if( eBiff <= BIFF4 )
2537                 dumpHex< sal_uInt32 >( "first-defname-pos", "CONV-DEC" );
2538             else
2539                 dumpUnused( 4 );
2540             dumpRowIndex( "first-row-with-cell", eBiff == BIFF8 );
2541             dumpRowIndex( "first-free-row", eBiff == BIFF8 );
2542             if( nRecId == BIFF3_ID_INDEX ) dumpHex< sal_uInt32 >( (eBiff <= BIFF4) ? "first-xf-pos" : "defcolwidth-pos", "CONV-DEC" );
2543             mxOut->resetItemIndex();
2544             while( rStrm.getRemaining() >= 4 )
2545                 dumpHex< sal_uInt32 >( "#first-row-pos-of-block", "CONV-DEC" );
2546         break;
2547 
2548         case BIFF2_ID_INTEGER:
2549             dumpCellHeader( true );
2550             dumpDec< sal_uInt16 >( "value" );
2551         break;
2552 
2553         case BIFF2_ID_LABEL:
2554         case BIFF3_ID_LABEL:
2555         {
2556             bool bBiff2 = nRecId == BIFF2_ID_LABEL;
2557             sal_uInt16 nXfIdx = dumpCellHeader( bBiff2 );
2558             rtl_TextEncoding eOldTextEnc = getBiffData().getTextEncoding();
2559             getBiffData().setTextEncoding( getBiffData().getXfEncoding( nXfIdx ) );
2560             dumpString( "value", bBiff2 ? BIFF_STR_8BITLENGTH : BIFF_STR_DEFAULT );
2561             getBiffData().setTextEncoding( eOldTextEnc );
2562         }
2563         break;
2564 
2565         case BIFF_ID_LABELRANGES:
2566             dumpRangeList( "row-ranges" );
2567             dumpRangeList( "col-ranges" );
2568         break;
2569 
2570         case BIFF_ID_LABELSST:
2571             dumpCellHeader();
2572             dumpDec< sal_Int32 >( "sst-idx" );
2573         break;
2574 
2575         case BIFF_ID_MERGEDCELLS:
2576             mxOut->resetItemIndex();
2577             for( sal_uInt16 nIdx = 0, nCount = dumpDec< sal_uInt16 >( "count" ); !rStrm.isEof() && (nIdx < nCount); ++nIdx )
2578                 dumpRange( "#range" );
2579         break;
2580 
2581         case BIFF_ID_MSODRAWING:
2582         case BIFF_ID_MSODRAWINGGROUP:
2583         case BIFF_ID_MSODRAWINGSEL:
2584             dumpEmbeddedDff();
2585             mbHasDff = true;
2586         break;
2587 
2588         case BIFF_ID_MTHREADSETTINGS:
2589             dumpFrHeader( true, true );
2590             dumpBool< sal_Int32 >( "multi-thread-enabled" );
2591             dumpBool< sal_Int32 >( "manual-thread-count" );
2592             dumpDec< sal_Int32 >( "thread-count" );
2593         break;
2594 
2595         case BIFF_ID_MULTBLANK:
2596         {
2597             Address aPos = dumpAddress();
2598             {
2599                 TableGuard aTabGuard( mxOut, 12 );
2600                 for( ; rStrm.getRemaining() >= 4; ++aPos.mnCol )
2601                 {
2602                     MultiItemsGuard aMultiGuard( mxOut );
2603                     writeAddressItem( "pos", aPos );
2604                     dumpXfIdx();
2605                 }
2606             }
2607             dumpColIndex( "last-col-idx" );
2608         }
2609         break;
2610 
2611         case BIFF_ID_MULTRK:
2612         {
2613             Address aPos = dumpAddress();
2614             {
2615                 TableGuard aTabGuard( mxOut, 12, 12 );
2616                 for( ; rStrm.getRemaining() >= 8; ++aPos.mnCol )
2617                 {
2618                     MultiItemsGuard aMultiGuard( mxOut );
2619                     writeAddressItem( "pos", aPos );
2620                     dumpXfIdx();
2621                     dumpRk( "value" );
2622                 }
2623             }
2624             dumpColIndex( "last-col-idx" );
2625         }
2626         break;
2627 
2628         case BIFF_ID_NOTE:
2629             dumpAddress( "anchor-cell" );
2630             if( eBiff == BIFF8 )
2631             {
2632                 dumpHex< sal_uInt16 >( "flags", "NOTE-FLAGS" );
2633                 dumpDec< sal_uInt16 >( "obj-id" );
2634                 dumpUniString( "author" );
2635                 dumpUnused( 1 );
2636             }
2637             else
2638             {
2639                 sal_uInt16 nTextLen = dumpDec< sal_uInt16 >( "text-len" );
2640                 nTextLen = ::std::min( nTextLen, static_cast< sal_uInt16 >( rStrm.getRemaining() ) );
2641                 writeStringItem( "note-text", rStrm.readCharArrayUC( nTextLen, getBiffData().getTextEncoding(), true ) );
2642             }
2643         break;
2644 
2645         case BIFF_ID_NOTESOUND:
2646             dumpHex< sal_uInt32 >( "identifier" );
2647             dumpDec< sal_uInt32 >( "total-data-size" );
2648             dumpDec< sal_uInt32 >( "wave-data-size" );
2649             if( dumpDec< sal_uInt32 >( "fmt-size" ) >= 16 )
2650             {
2651                 dumpDec< sal_uInt16 >( "format", "NOTESOUND-FORMAT" );
2652                 dumpDec< sal_uInt16 >( "channels" );
2653                 dumpDec< sal_uInt32 >( "sampling-rate" );
2654                 dumpDec< sal_uInt32 >( "data-rate" );
2655                 dumpDec< sal_uInt16 >( "data-block-size" );
2656                 dumpDec< sal_uInt16 >( "bits-per-sample" );
2657             }
2658         break;
2659 
2660         case BIFF2_ID_NUMBER:
2661         case BIFF3_ID_NUMBER:
2662             dumpCellHeader( nRecId == BIFF2_ID_NUMBER );
2663             dumpDec< double >( "value" );
2664         break;
2665 
2666         case BIFF_ID_OBJ:
2667             dumpObjRec();
2668         break;
2669 
2670         case BIFF_ID_OLESIZE:
2671             dumpUnused( 2 );
2672             dumpRange( "visible-range", false );
2673         break;
2674 
2675         case BIFF_ID_PAGELAYOUTVIEW:
2676             dumpFrHeader( true, true );
2677             dumpDec< sal_uInt16 >( "scaling", "CONV-PERCENT" );
2678             dumpHex< sal_uInt16 >( "flags", "PAGELAYOUTVIEW-FLAGS" );
2679         break;
2680 
2681         case BIFF_ID_PAGESETUP:
2682             dumpDec< sal_uInt16 >( "paper-size", "PAGESETUP-PAPERSIZE" );
2683             dumpDec< sal_uInt16 >( "scaling", "CONV-PERCENT" );
2684             dumpDec< sal_uInt16 >( "first-page" );
2685             dumpDec< sal_uInt16 >( "scale-to-width", "PAGESETUP-SCALETOPAGES" );
2686             dumpDec< sal_uInt16 >( "scale-to-height", "PAGESETUP-SCALETOPAGES" );
2687             dumpHex< sal_uInt16 >( "flags", "PAGESETUP-FLAGS" );
2688             if( eBiff >= BIFF5 )
2689             {
2690                 dumpDec< sal_uInt16 >( "horizontal-res", "PAGESETUP-DPI" );
2691                 dumpDec< sal_uInt16 >( "vertical-res", "PAGESETUP-DPI" );
2692                 dumpDec< double >( "header-margin", "CONV-INCH-TO-CM" );
2693                 dumpDec< double >( "footer-margin", "CONV-INCH-TO-CM" );
2694                 dumpDec< sal_uInt16 >( "copies" );
2695             }
2696         break;
2697 
2698         case BIFF_ID_PALETTE:
2699             mxOut->resetItemIndex( 8 );
2700             for( sal_uInt16 nIdx = 0, nCount = dumpDec< sal_uInt16 >( "count" ); !rStrm.isEof() && (nIdx < nCount); ++nIdx )
2701             {
2702                 OUStringBuffer aColorName;
2703                 StringHelper::appendHex( aColorName, dumpColorABGR( "#color" ) );
2704                 mxColors->setName( nIdx + 8, aColorName.makeStringAndClear() );
2705             }
2706         break;
2707 
2708         case BIFF_ID_PANE:
2709             dumpDec< sal_uInt16 >( "x-pos", "CONV-TWIP-TO-CM" );
2710             dumpDec< sal_uInt16 >( "y-pos", "CONV-TWIP-TO-CM" );
2711             dumpAddress( "first-visible-cell" );
2712             dumpDec< sal_uInt8 >( "active-pane", "PANE-ID" );
2713         break;
2714 
2715         case BIFF_ID_PCITEM_STRING:
2716             dumpString( "value" );
2717         break;
2718 
2719         case BIFF_ID_PHONETICPR:
2720             dumpDec< sal_uInt16 >( "font-id", "FONTNAMES" );
2721             dumpHex< sal_uInt16 >( "flags", "PHONETICPR-FLAGS" );
2722             dumpRangeList( "show-phonetic" );
2723         break;
2724 
2725         case BIFF_ID_PROJEXTSHEET:
2726             dumpDec< sal_uInt8 >( "sheet-type", "PROJEXTSHEET-TYPE" );
2727             dumpUnused( 1 );
2728             dumpByteString( "sheet-link", BIFF_STR_8BITLENGTH );
2729         break;
2730 
2731         case BIFF_ID_PTDATAFIELD:
2732             dumpDec< sal_Int16 >( "field" );
2733             dumpDec< sal_uInt16 >( "subtotal", "PTDATAFIELD-SUBTOTAL" );
2734             dumpDec< sal_uInt16 >( "show-data-as", "PTDATAFIELD-SHOWDATAAS" );
2735             dumpDec< sal_Int16 >( "base-field" );
2736             dumpDec< sal_Int16 >( "base-item", "PTDATAFIELD-BASEITEM" );
2737             dumpFormatIdx();
2738             dumpPivotString( "name" );
2739         break;
2740 
2741         case BIFF_ID_PTDEFINITION:
2742         {
2743             dumpRange( "output-range" );
2744             dumpRowIndex( "first-header-row-idx" );
2745             dumpAddress( "first-data-pos" );
2746             dumpDec< sal_uInt16 >( "cache-idx" );
2747             dumpUnused( 2 );
2748             dumpDec< sal_uInt16 >( "default-data-axis", "PTFIELD-AXISTYPE" );
2749             dumpDec< sal_Int16 >( "default-data-pos", "PTDEFINITION-DATAFIELD-POS" );
2750             dumpDec< sal_uInt16 >( "field-count" );
2751             mnPTRowFields = dumpDec< sal_uInt16 >( "row-field-count" );
2752             mnPTColFields = dumpDec< sal_uInt16 >( "column-field-count" );
2753             dumpDec< sal_uInt16 >( "page-field-count" );
2754             dumpDec< sal_uInt16 >( "data-field-count" );
2755             dumpDec< sal_uInt16 >( "data-row-count" );
2756             dumpDec< sal_uInt16 >( "data-column-count" );
2757             dumpHex< sal_uInt16 >( "flags", "PTDEFINITION-FLAGS" );
2758             dumpDec< sal_uInt16 >( "auto-format-idx" );
2759             sal_uInt16 nTabNameLen = dumpDec< sal_uInt16 >( "table-name-len" );
2760             sal_uInt16 nDataNameLen = dumpDec< sal_uInt16 >( "data-name-len" );
2761             dumpPivotString( "table-name", nTabNameLen );
2762             dumpPivotString( "data-name", nDataNameLen );
2763             mnPTRowColItemsIdx = 0;
2764         }
2765         break;
2766 
2767         case BIFF_ID_PTDEFINITION2:
2768         {
2769             dumpDec< sal_uInt16 >( "format-rec-count" );
2770             sal_uInt16 nErrCaptLen = dumpDec< sal_uInt16 >( "error-caption-len" );
2771             sal_uInt16 nMissCaptLen = dumpDec< sal_uInt16 >( "missing-caption-len" );
2772             sal_uInt16 nTagLen = dumpDec< sal_uInt16 >( "tag-len" );
2773             dumpDec< sal_uInt16 >( "select-rec-count" );
2774             dumpDec< sal_uInt16 >( "page-rows" );
2775             dumpDec< sal_uInt16 >( "page-cols" );
2776             dumpHex< sal_uInt32 >( "flags", "PTDEFINITION2-FLAGS" );
2777             sal_uInt16 nPageStyleLen = dumpDec< sal_uInt16 >( "page-field-style-len" );
2778             sal_uInt16 nTabStyleLen = dumpDec< sal_uInt16 >( "pivot-table-style-len" );
2779             sal_uInt16 nVacStyleLen = dumpDec< sal_uInt16 >( "vacated-style-len" );
2780             dumpPivotString( "error-caption", nErrCaptLen );
2781             dumpPivotString( "missing-caption", nMissCaptLen );
2782             dumpPivotString( "tag", nTagLen );
2783             dumpPivotString( "page-field-style", nPageStyleLen );
2784             dumpPivotString( "pivot-table-style", nTabStyleLen );
2785             dumpPivotString( "vacated-style", nVacStyleLen );
2786         }
2787         break;
2788 
2789         case BIFF_ID_PTFIELD:
2790             dumpDec< sal_uInt16 >( "axis-type", "PTFIELD-AXISTYPE" );
2791             dumpDec< sal_uInt16 >( "subtotal-count" );
2792             dumpHex< sal_uInt16 >( "subtotals", "PTFIELD-SUBTOTALS" );
2793             dumpDec< sal_uInt16 >( "item-count" );
2794             dumpPivotString( "field-name" );
2795         break;
2796 
2797         case BIFF_ID_PTFIELD2:
2798             dumpHex< sal_uInt32 >( "flags", "PTFIELD2-FLAGS" );
2799             dumpDec< sal_Int16 >( "autosort-basefield-idx" );
2800             dumpDec< sal_Int16 >( "autoshow-basefield-idx" );
2801             dumpFormatIdx();
2802             if( rStrm.getRemaining() >= 2 )
2803             {
2804                 sal_uInt16 nFuncNameLen = dumpDec< sal_uInt16 >( "subtotal-func-name-len" );
2805                 dumpUnused( 8 );
2806                 dumpPivotString( "subtotal-func-name", nFuncNameLen );
2807             }
2808         break;
2809 
2810         case BIFF_ID_PTFITEM:
2811             dumpDec< sal_uInt16 >( "item-type", "PTFITEM-ITEMTYPE" );
2812             dumpHex< sal_uInt16 >( "flags", "PTFITEM-FLAGS" );
2813             dumpDec< sal_Int16 >( "cache-idx", "PTFITEM-CACHEIDX" );
2814             dumpPivotString( "item-name" );
2815         break;
2816 
2817         case BIFF_ID_PTPAGEFIELDS:
2818         {
2819             mxOut->resetItemIndex();
2820             TableGuard aTabGuard( mxOut, 17, 17, 17 );
2821             while( rStrm.getRemaining() >= 6 )
2822             {
2823                 writeEmptyItem( "#page-field" );
2824                 MultiItemsGuard aMultiGuard( mxOut );
2825                 IndentGuard aIndGuard( mxOut );
2826                 dumpDec< sal_Int16 >( "base-field" );
2827                 dumpDec< sal_Int16 >( "item", "PTPAGEFIELDS-ITEM" );
2828                 dumpDec< sal_uInt16 >( "dropdown-obj-id" );
2829             }
2830         }
2831         break;
2832 
2833         case BIFF_ID_PTROWCOLFIELDS:
2834             mxOut->resetItemIndex();
2835             for( sal_Int64 nIdx = 0, nCount = rStrm.getRemaining() / 2; nIdx < nCount; ++nIdx )
2836                 dumpDec< sal_Int16 >( "#field-idx" );
2837         break;
2838 
2839         case BIFF_ID_PTROWCOLITEMS:
2840             if( mnPTRowColItemsIdx < 2 )
2841             {
2842                 sal_uInt16 nCount = (mnPTRowColItemsIdx == 0) ? mnPTRowFields : mnPTColFields;
2843                 sal_Int64 nLineSize = 8 + 2 * nCount;
2844                 mxOut->resetItemIndex();
2845                 while( rStrm.getRemaining() >= nLineSize )
2846                 {
2847                     writeEmptyItem( "#line-data" );
2848                     IndentGuard aIndGuard( mxOut );
2849                     MultiItemsGuard aMultiGuard( mxOut );
2850                     dumpDec< sal_uInt16 >( "ident-count" );
2851                     dumpDec< sal_uInt16 >( "item-type", "PTROWCOLITEMS-ITEMTYPE" );
2852                     dumpDec< sal_uInt16 >( "used-count" );
2853                     dumpHex< sal_uInt16 >( "flags", "PTROWCOLITEMS-FLAGS" );
2854                     OUStringBuffer aItemList;
2855                     for( sal_uInt16 nIdx = 0; nIdx < nCount; ++nIdx )
2856                         StringHelper::appendToken( aItemList, mxStrm->readInt16() );
2857                     writeInfoItem( "item-idxs", aItemList.makeStringAndClear() );
2858                 }
2859                 ++mnPTRowColItemsIdx;
2860             }
2861         break;
2862 
2863         case BIFF_ID_QUERYTABLE:
2864             dumpHex< sal_uInt16 >( "flags", "QUERYTABLE-FLAGS" );
2865             dumpDec< sal_uInt16 >( "autoformat-id" );
2866             dumpHex< sal_uInt16 >( "autoformat-flags", "QUERYTABLE-AUTOFORMAT-FLAGS" );
2867             dumpUnused( 4 );
2868             dumpUniString( "defined-name" );
2869             dumpUnused( 2 );
2870         break;
2871 
2872         case BIFF_ID_QUERYTABLEREFRESH:
2873         {
2874             dumpFrHeader( true, false );
2875             bool bPivot = dumpBool< sal_uInt16 >( "pivot-table" );
2876             dumpHex< sal_uInt16 >( "flags", "QUERYTABLEREFRESH-FLAGS" );
2877             dumpHex< sal_uInt32 >( bPivot ? "pivottable-flags" : "querytable-flags", bPivot ? "QUERYTABLEREFRESH-PTFLAGS" : "QUERYTABLEREFRESH-QTFLAGS" );
2878             dumpDec< sal_uInt8 >( "refreshed-version" );
2879             dumpDec< sal_uInt8 >( "min-refresh-version" );
2880             dumpUnused( 2 );
2881             dumpUniString( "table-name" );
2882             dumpUnused( 2 );
2883         }
2884         break;
2885 
2886         case BIFF_ID_QUERYTABLESETTINGS:
2887         {
2888             dumpFrHeader( true, false );
2889             sal_uInt16 nType = dumpDec< sal_uInt16 >( "data-source-type", "CONNECTION-SOURCETYPE" );
2890             dumpHex< sal_uInt16 >( "flags-1", "QUERYTABLESETTINGS-FLAGS" );
2891             switch( nType )
2892             {
2893                 case 4:     dumpHex< sal_uInt16 >( "html-flags", "QUERYTABLESETTINGS-HTML-FLAGS" );     break;
2894                 case 5:     dumpHex< sal_uInt16 >( "oledb-flags", "QUERYTABLESETTINGS-OLEDB-FLAGS" );   break;
2895                 case 7:     dumpHex< sal_uInt16 >( "ado-flags", "QUERYTABLESETTINGS-ADO-FLAGS" );       break;
2896                 default:    dumpUnused( 2 );
2897             }
2898             dumpHex< sal_uInt16 >( "ext-flags", "QUERYTABLESETTINGS-EXT-FLAGS" );
2899             dumpDec< sal_uInt8 >( "edited-version" );
2900             dumpDec< sal_uInt8 >( "refreshed-version" );
2901             dumpDec< sal_uInt8 >( "min-refresh-version" );
2902             dumpUnused( 3 );
2903             dumpDec< sal_uInt16 >( "oledb-count" );
2904             dumpDec< sal_uInt16 >( "future-data-size" );
2905             dumpDec< sal_uInt16 >( "refresh-interval", "QUERYTABLESETTINGS-INTERVAL" );
2906             dumpDec< sal_uInt16 >( "html-format", "QUERYTABLESETTINGS-HTMLFORMAT" );
2907         }
2908         break;
2909 
2910         case BIFF_ID_QUERYTABLESTRING:
2911             dumpFrHeader( true, false );
2912             dumpUniString( "connection-string" );
2913         break;
2914 
2915         case BIFF_ID_RECALCID:
2916             dumpFrHeader( true, false );
2917             dumpDec< sal_uInt32 >( "recalc-engine-id" );
2918         break;
2919 
2920         case BIFF_ID_RK:
2921             dumpCellHeader();
2922             dumpRk( "value" );
2923         break;
2924 
2925         case BIFF2_ID_ROW:
2926         {
2927             dumpRowIndex();
2928             dumpColIndex( "first-used-col-idx" );
2929             dumpColIndex( "first-free-col-idx" );
2930             dumpHex< sal_uInt16 >( "height", "ROW-HEIGHT" );
2931             dumpUnused( 2 );
2932             bool bHasDefXf = dumpBool< sal_uInt8 >( "custom-format" );
2933             dumpDec< sal_uInt16 >( "cell-offset" );
2934             if( bHasDefXf ) dumpXfIdx( "custom-format", true );
2935             if( bHasDefXf ) dumpXfIdx( "custom-xf-idx", false );
2936         }
2937         break;
2938 
2939         case BIFF3_ID_ROW:
2940             dumpRowIndex();
2941             dumpColIndex( "first-used-col-idx" );
2942             dumpColIndex( "first-free-col-idx" );
2943             dumpHex< sal_uInt16 >( "height", "ROW-HEIGHT" );
2944             dumpUnused( (eBiff <= BIFF4) ? 2 : 4 );
2945             if( eBiff <= BIFF4 ) dumpDec< sal_uInt16 >( "cell-offset" );
2946             dumpHex< sal_uInt32 >( "flags", "ROW-FLAGS" );
2947         break;
2948 
2949         case BIFF_ID_RSTRING:
2950         {
2951             sal_uInt16 nXfIdx = dumpCellHeader();
2952             rtl_TextEncoding eOldTextEnc = getBiffData().getTextEncoding();
2953             getBiffData().setTextEncoding( getBiffData().getXfEncoding( nXfIdx ) );
2954             dumpString( "value" );
2955             getBiffData().setTextEncoding( eOldTextEnc );
2956             FontPortionModelList aPortions;
2957             aPortions.importPortions( rStrm, eBiff == BIFF8 );
2958             writeFontPortions( aPortions );
2959         }
2960         break;
2961 
2962         case BIFF_ID_SCENARIO:
2963         {
2964             sal_uInt16 nCellCount = dumpDec< sal_uInt16 >( "cell-count" );
2965             // two bytes instead of flag field
2966             dumpBoolean( "locked" );
2967             dumpBoolean( "hidden" );
2968             sal_uInt16 nNameLen = dumpDec< sal_uInt8 >( "name-len" );
2969             sal_uInt16 nCommentLen = dumpDec< sal_uInt8 >( "comment-len" );
2970             sal_uInt16 nUserLen = dumpDec< sal_uInt8 >( "user-len" );
2971             writeStringItem( "name", rStrm.readUniStringBody( nNameLen, true ) );
2972             if( nUserLen > 0 ) dumpUniString( "user" );         // repeated string length
2973             if( nCommentLen > 0 ) dumpUniString( "comment" );   // repeated string length
2974             mxOut->resetItemIndex();
2975             for( sal_uInt16 nCell = 0; !rStrm.isEof() && (nCell < nCellCount); ++nCell )
2976                 dumpAddress( "#pos" );
2977             mxOut->resetItemIndex();
2978             for( sal_uInt16 nCell = 0; !rStrm.isEof() && (nCell < nCellCount); ++nCell )
2979                 dumpString( "#value" );
2980             dumpUnused( 2 * nCellCount );
2981         }
2982         break;
2983 
2984         case BIFF_ID_SCENARIOS:
2985             dumpDec< sal_uInt16 >( "count" );
2986             dumpDec< sal_uInt16 >( "selected" );
2987             dumpDec< sal_uInt16 >( "shown" );
2988             dumpRangeList( "result-cells" );
2989         break;
2990 
2991         case BIFF_ID_SCL:
2992         {
2993             sal_uInt16 nNum = dumpDec< sal_uInt16 >( "numerator" );
2994             sal_uInt16 nDen = dumpDec< sal_uInt16 >( "denominator" );
2995             if( nDen > 0 ) writeDecItem( "current-zoom", static_cast< sal_uInt16 >( nNum * 100 / nDen ), "CONV-PERCENT" );
2996         }
2997         break;
2998 
2999         case BIFF_ID_SCREENTIP:
3000             dumpFrHeader( false, true );
3001             dumpNullUnicodeArray( "tooltip" );
3002         break;
3003 
3004         case BIFF_ID_SELECTION:
3005             dumpDec< sal_uInt8 >( "pane", "PANE-ID" );
3006             dumpAddress( "active-cell" );
3007             dumpDec< sal_uInt16 >( "list-idx" );
3008             dumpRangeList( "selection", false );
3009         break;
3010 
3011         case BIFF_ID_SHAREDFEATHEAD:
3012         {
3013             dumpFrHeader( true, true );
3014             sal_uInt16 nType = dumpDec< sal_uInt16 >( "feature-type", "SHAREDFEATHEAD-TYPE" );
3015             dumpUnused( 1 );
3016             if( dumpBool< sal_Int32 >( "has-data" ) ) switch( nType )
3017             {
3018                 case 2:
3019                     dumpHex< sal_uInt32 >( "allowed-flags", "SHAREDFEATHEAD-PROT-FLAGS" );
3020                 break;
3021             }
3022         }
3023         break;
3024 
3025         case BIFF_ID_SHAREDFMLA:
3026             dumpRange( "formula-range", false );
3027             dumpUnused( 1 );
3028             dumpDec< sal_uInt8 >( "cell-count" );
3029             getFormulaDumper().dumpCellFormula();
3030         break;
3031 
3032         case BIFF_ID_SHEET:
3033             if( eBiff >= BIFF5 )
3034             {
3035                 rStrm.enableDecoder( false );
3036                 dumpHex< sal_uInt32 >( "sheet-stream-pos", "CONV-DEC" );
3037                 rStrm.enableDecoder( true );
3038                 dumpDec< sal_uInt8 >( "sheet-state", "SHEET-STATE" );
3039                 dumpDec< sal_uInt8 >( "sheet-type", "SHEET-TYPE" );
3040             }
3041             dumpString( "sheet-name", BIFF_STR_8BITLENGTH, BIFF_STR_8BITLENGTH );
3042         break;
3043 
3044         case BIFF_ID_SHEETEXT:
3045             dumpFrHeader( true, true );
3046             dumpDec< sal_uInt32 >( "rec-size" );
3047             dumpDec< sal_uInt32 >( "flags-1", "SHEETEXT-FLAGS1" );
3048             if( rStrm.getRemaining() >= 20 )
3049             {
3050                 dumpDec< sal_uInt32 >( "flags-2", "SHEETEXT-FLAGS2" );
3051                 dumpExtCfColor( "tab-color" );
3052             }
3053         break;
3054 
3055         case BIFF_ID_SHEETHEADER:
3056             dumpHex< sal_uInt32 >( "substream-size", "CONV-DEC" );
3057             dumpByteString( "sheet-name", BIFF_STR_8BITLENGTH );
3058         break;
3059 
3060         case BIFF_ID_SST:
3061             dumpDec< sal_uInt32 >( "string-cell-count" );
3062             dumpDec< sal_uInt32 >( "sst-size" );
3063             mxOut->resetItemIndex();
3064             while( !rStrm.isEof() && (rStrm.getRemaining() >= 3) )
3065                 dumpUniString( "#entry" );
3066         break;
3067 
3068         case BIFF2_ID_STRING:
3069         case BIFF3_ID_STRING:
3070             dumpString( "result", ((nRecId == BIFF2_ID_STRING) && (eBiff <= BIFF4)) ? BIFF_STR_8BITLENGTH : BIFF_STR_DEFAULT );
3071         break;
3072 
3073         case BIFF_ID_STYLE:
3074         {
3075             sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "STYLE-FLAGS" );
3076             if( getFlag( nFlags, BIFF_STYLE_BUILTIN ) )
3077             {
3078                 dumpDec< sal_Int8 >( "builtin-idx", "STYLE-BUILTIN" );
3079                 dumpDec< sal_Int8 >( "outline-level" );
3080             }
3081             else
3082                 dumpString( "style-name", BIFF_STR_8BITLENGTH );
3083         }
3084         break;
3085 
3086         case BIFF_ID_STYLEEXT:
3087             dumpFrHeader( true, true );
3088             dumpHex< sal_uInt8 >( "flags", "STYLEEXT-FLAGS" );
3089             dumpDec< sal_uInt8 >( "category", "STYLEEXT-CATEGORY" );
3090             dumpDec< sal_Int8 >( "builtin-idx", "STYLEEXT-BUILTIN" );
3091             dumpDec< sal_Int8 >( "outline-level" );
3092             dumpUnicodeArray( "style-name", rStrm.readuInt16() );
3093             dumpDxfProp();
3094         break;
3095 
3096         case BIFF_ID_TABLESTYLES:
3097         {
3098             dumpFrHeader( true, true );
3099             dumpDec< sal_uInt32 >( "table-style-count" );
3100             sal_uInt16 nDefTableLen, nDefPivotLen;
3101             rStrm >> nDefTableLen >> nDefPivotLen;
3102             dumpUnicodeArray( "def-table-style", nDefTableLen );
3103             dumpUnicodeArray( "def-pivot-style", nDefPivotLen );
3104         }
3105         break;
3106 
3107         case BIFF_ID_THEME:
3108             dumpFrHeader( true, true );
3109             dumpDec< sal_uInt32 >( "theme-version", "THEME-VERSION" );
3110         break;
3111 
3112         case BIFF_ID_TXO:
3113             dumpHex< sal_uInt16 >( "flags", "TXO-FLAGS" );
3114             dumpDec< sal_uInt16 >( "orientation", "TEXTORIENTATION" );
3115             dumpHex< sal_uInt16 >( "button-flags", "OBJ-BUTTON-FLAGS" );
3116             dumpUnicode( "accelerator" );
3117             dumpUnicode( "fareast-accelerator" );
3118             dumpDec< sal_uInt16 >( "text-len" );
3119             dumpDec< sal_uInt16 >( "format-run-size" );
3120             dumpUnused( 4 );
3121         break;
3122 
3123         case BIFF_ID_WINDOW1:
3124             dumpDec< sal_uInt16 >( "window-x", "CONV-TWIP-TO-CM" );
3125             dumpDec< sal_uInt16 >( "window-y", "CONV-TWIP-TO-CM" );
3126             dumpDec< sal_uInt16 >( "window-width", "CONV-TWIP-TO-CM" );
3127             dumpDec< sal_uInt16 >( "window-height", "CONV-TWIP-TO-CM" );
3128             if( eBiff <= BIFF4 )
3129             {
3130                 dumpBool< sal_uInt8 >( "hidden" );
3131             }
3132             else
3133             {
3134                 dumpHex< sal_uInt16 >( "flags", "WINDOW1-FLAGS" );
3135                 dumpDec< sal_uInt16 >( "active-tab" );
3136                 dumpDec< sal_uInt16 >( "first-visible-tab" );
3137                 dumpDec< sal_uInt16 >( "selected-tabs" );
3138                 dumpDec< sal_uInt16 >( "tabbar-ratio", "WINDOW1-TABBARRATIO" );
3139             }
3140         break;
3141 
3142         case BIFF2_ID_WINDOW2:
3143             dumpBool< sal_uInt8 >( "show-formulas" );
3144             dumpBool< sal_uInt8 >( "show-gridlines" );
3145             dumpBool< sal_uInt8 >( "show-headings" );
3146             dumpBool< sal_uInt8 >( "frozen-panes" );
3147             dumpBool< sal_uInt8 >( "show-zeros" );
3148             dumpAddress( "first-visible-cell" );
3149             dumpBool< sal_uInt8 >( "auto-grid-color" );
3150             dumpColorABGR( "grid-color" );
3151         break;
3152 
3153         case BIFF3_ID_WINDOW2:
3154             dumpHex< sal_uInt16 >( "flags", "WINDOW2-FLAGS" );
3155             dumpAddress( "first-visible-cell" );
3156             if( eBiff == BIFF8 )
3157             {
3158                 dumpColorIdx( "grid-color-idx" );
3159                 dumpUnused( 2 );
3160                 if( rStrm.getRemaining() >= 8 )
3161                 {
3162                     dumpDec< sal_uInt16 >( "pagebreak-zoom", "CONV-PERCENT" );
3163                     dumpDec< sal_uInt16 >( "normal-zoom", "CONV-PERCENT" );
3164                     dumpUnused( 4 );
3165                 }
3166             }
3167             else
3168                 dumpColorABGR( "grid-color" );
3169         break;
3170 
3171         case BIFF_ID_WRITEACCESS:
3172             dumpString( "user-name", BIFF_STR_8BITLENGTH );
3173         break;
3174 
3175         case BIFF_ID_XCT:
3176             dumpDec< sal_uInt16 >( "crn-count" );
3177             if( eBiff == BIFF8 ) dumpDec< sal_Int16 >( "sheet-idx" );
3178         break;
3179 
3180         case BIFF2_ID_XF:
3181         case BIFF3_ID_XF:
3182         case BIFF4_ID_XF:
3183         case BIFF5_ID_XF:
3184             dumpXfRec();
3185         break;
3186 
3187         case BIFF_ID_XFCRC:
3188             dumpFrHeader( true, true );
3189             dumpUnused( 2 );
3190             dumpDec< sal_uInt16 >( "xf-count" );
3191             dumpHex< sal_uInt32 >( "xf-checksum" );
3192         break;
3193 
3194         case BIFF_ID_XFEXT:
3195             dumpFrHeader( true, true );
3196             dumpUnused( 2 );
3197             dumpXfIdx( "xf-idx" );
3198             dumpUnused( 2 );
3199             dumpXfExtProp();
3200         break;
3201     }
3202 }
3203 
3204 void WorkbookStreamObject::initializePerSheet()
3205 {
3206     getBiffData().initializePerSheet();
3207     mxFontNames = cfg().createNameList< ConstList >( "FONTNAMES" );
3208     mxFontNames->setName( 0, createFontName( CREATE_OUSTRING( "Arial" ), 200, false, false ) );
3209     mxFormats = cfg().createNameList< ConstList >( "FORMATS" );
3210     mxFormats->includeList( cfg().getNameList( "BUILTIN-FORMATS" ) );
3211     mnFormatIdx = 0;
3212     mbHasCodePage = false;
3213 }
3214 
3215 OUString WorkbookStreamObject::createFontName( const OUString& rName, sal_uInt16 nHeight, bool bBold, bool bItalic ) const
3216 {
3217     OUStringBuffer aName( rName );
3218     StringHelper::enclose( aName, OOX_DUMP_STRQUOTE );
3219     StringHelper::appendToken( aName, cfg().getName( "CONV-TWIP-TO-PT", nHeight ), ',' );
3220     if( bBold )
3221         StringHelper::appendToken( aName, CREATE_OUSTRING( "bold" ), ',' );
3222     if( bItalic )
3223         StringHelper::appendToken( aName, CREATE_OUSTRING( "italic" ), ',' );
3224     return aName.makeStringAndClear();
3225 }
3226 
3227 sal_uInt16 WorkbookStreamObject::dumpPatternIdx( const String& rName, bool b16Bit )
3228 {
3229     return dumpDec< sal_uInt16, sal_uInt8 >( b16Bit, rName( "fill-pattern" ), mxFillPatterns );
3230 }
3231 
3232 sal_uInt16 WorkbookStreamObject::dumpColorIdx( const String& rName, bool b16Bit )
3233 {
3234     return dumpDec< sal_uInt16, sal_uInt8 >( b16Bit, rName( "color-idx" ), mxColors );
3235 }
3236 
3237 sal_uInt16 WorkbookStreamObject::dumpFontIdx( const String& rName, bool b16Bit )
3238 {
3239     return dumpDec< sal_uInt16, sal_uInt8 >( b16Bit, rName( "font-idx" ), mxFontNames );
3240 }
3241 
3242 sal_uInt16 WorkbookStreamObject::dumpFormatIdx( const String& rName )
3243 {
3244     return dumpDec< sal_uInt16, sal_uInt8 >( getBiff() >= BIFF5, rName( "fmt-idx" ), mxFormats );
3245 }
3246 
3247 sal_uInt16 WorkbookStreamObject::dumpXfIdx( const String& rName, bool bBiff2Style )
3248 {
3249     String aName = rName( "xf-idx" );
3250     sal_uInt16 nXfIdx = 0;
3251     if( bBiff2Style )
3252     {
3253         dumpHex< sal_uInt8 >( aName, "CELL-XFINDEX" );
3254         dumpHex< sal_uInt8 >( "fmt-font-idx", "CELL-XFFORMAT" );
3255         dumpHex< sal_uInt8 >( "style", "CELL-XFSTYLE" );
3256     }
3257     else
3258         nXfIdx = dumpDec< sal_uInt16 >( aName );
3259     return nXfIdx;
3260 }
3261 
3262 void WorkbookStreamObject::dumpExtColorValue( sal_uInt32 nColorType )
3263 {
3264     switch( nColorType )
3265     {
3266         case 0:     dumpUnused( 4 );                                break;
3267         case 1:     dumpDec< sal_uInt32 >( "color-idx", mxColors ); break;
3268         case 2:     dumpColorABGR();                                break;
3269         case 3:     dumpDec< sal_uInt32 >( "theme-id" );            break;
3270         case 4:     dumpUnused( 4 );                                break;
3271         default:    dumpUnknown( 4 );
3272     }
3273 }
3274 
3275 void WorkbookStreamObject::dumpExtColor( const String& rName )
3276 {
3277     MultiItemsGuard aMultiGuard( mxOut );
3278     writeEmptyItem( rName( "color" ) );
3279     switch( extractValue< sal_uInt8 >( dumpDec< sal_uInt8 >( "flags", "EXTCOLOR-FLAGS" ), 1, 7 ) )
3280     {
3281         case 0:     dumpUnused( 1 );                    break;
3282         case 1:     dumpColorIdx( "color-idx", false ); break;
3283         case 2:     dumpUnused( 1 );                    break;
3284         case 3:     dumpDec< sal_uInt8 >( "theme-id" ); break;
3285         case 4:     dumpUnused( 1 );                    break;
3286         default:    dumpUnknown( 1 );
3287     }
3288     dumpDec< sal_Int16 >( "tint", "CONV-TINT" );
3289     dumpColorABGR();
3290 }
3291 
3292 void WorkbookStreamObject::dumpExtCfColor( const String& rName )
3293 {
3294     MultiItemsGuard aMultiGuard( mxOut );
3295     writeEmptyItem( rName( "color" ) );
3296     dumpExtColorValue( dumpExtColorType< sal_uInt32 >() );
3297     dumpDec< double >( "tint", "CONV-FLOAT-TO-PERC" );
3298 }
3299 
3300 void WorkbookStreamObject::dumpExtGradientHead()
3301 {
3302     dumpDec< sal_Int32 >( "gradient-type", "EXTGRADIENT-TYPE" );
3303     dumpDec< double >( "linear-angle" );
3304     dumpDec< double >( "pos-left" );
3305     dumpDec< double >( "pos-right" );
3306     dumpDec< double >( "pos-top" );
3307     dumpDec< double >( "pos-bottom" );
3308 }
3309 
3310 sal_uInt8 WorkbookStreamObject::dumpFilterColumnOperator( const String& rName )
3311 {
3312     sal_uInt8 nStrLen = 0;
3313     writeEmptyItem( rName );
3314     IndentGuard aIndGuard( mxOut );
3315     sal_uInt8 nType = dumpDec< sal_uInt8 >( "data-type", "FILTERCOLUMN-DATATYPE" );
3316     dumpDec< sal_uInt8 >( "operator", "FILTERCOLUMN-OPERATOR" );
3317     switch( nType )
3318     {
3319         case 2:
3320             dumpRk( "value" );
3321             dumpUnused( 4 );
3322         break;
3323         case 4:
3324             dumpDec< double >( "value" );
3325         break;
3326         case 6:
3327             dumpUnused( 4 );
3328             nStrLen = dumpDec< sal_uInt8 >( "length" );
3329             dumpBoolean( "simple" );
3330             dumpUnused( 2 );
3331         break;
3332         case 8:
3333             dumpBoolErr();
3334             dumpUnused( 6 );
3335         break;
3336         default:
3337             dumpUnused( 8 );
3338     }
3339     return nStrLen;
3340 }
3341 
3342 OUString WorkbookStreamObject::dumpPivotString( const String& rName, sal_uInt16 nStrLen )
3343 {
3344     OUString aString;
3345     if( nStrLen != BIFF_PT_NOSTRING )
3346     {
3347         aString = (getBiff() == BIFF8) ?
3348             getBiffStream().readUniStringBody( nStrLen ) :
3349             getBiffStream().readCharArrayUC( nStrLen, getBiffData().getTextEncoding() );
3350         writeStringItem( rName, aString );
3351     }
3352     return aString;
3353 }
3354 
3355 OUString WorkbookStreamObject::dumpPivotString( const String& rName )
3356 {
3357     sal_uInt16 nStrLen = dumpDec< sal_uInt16 >( "string-len", "PIVOT-NAMELEN" );
3358     return dumpPivotString( rName, nStrLen );
3359 }
3360 
3361 sal_uInt16 WorkbookStreamObject::dumpCellHeader( bool bBiff2Style )
3362 {
3363     dumpAddress();
3364     return dumpXfIdx( EMPTY_STRING, bBiff2Style );
3365 }
3366 
3367 void WorkbookStreamObject::dumpBoolErr()
3368 {
3369     MultiItemsGuard aMultiGuard( mxOut );
3370     sal_uInt8 nValue = dumpHex< sal_uInt8 >( "value" );
3371     bool bErrCode = dumpBool< sal_uInt8 >( "is-error-code" );
3372     if( bErrCode )
3373         writeErrorCodeItem( "error-code", nValue );
3374     else
3375         writeBooleanItem( "boolean", nValue );
3376 }
3377 
3378 void WorkbookStreamObject::dumpCfRuleProp()
3379 {
3380     BiffInputStream& rStrm = getBiffStream();
3381     sal_uInt32 nFlags1 = dumpHex< sal_uInt32 >( "flags-1", "CFRULE-FLAGS1" );
3382     sal_uInt16 nFlags2 = dumpHex< sal_uInt16 >( "flags-2", "CFRULE-FLAGS2" );
3383     if( getFlag< sal_uInt32 >( nFlags1, 0x02000000 ) )
3384     {
3385         writeEmptyItem( "numfmt-block" );
3386         IndentGuard aIndGuard( mxOut );
3387         if( getFlag< sal_uInt16 >( nFlags2, 0x0001 ) )
3388         {
3389             dumpDec< sal_uInt16 >( "size" );
3390             dumpUniString( "numfmt" );
3391         }
3392         else
3393         {
3394             dumpUnused( 1 );
3395             dumpDec< sal_uInt8 >( "fmt-idx", mxFormats );
3396         }
3397     }
3398     if( getFlag< sal_uInt32 >( nFlags1, 0x04000000 ) )
3399     {
3400         writeEmptyItem( "font-block" );
3401         IndentGuard aIndGuard( mxOut );
3402         sal_Int64 nRecPos = rStrm.tell();
3403         dumpUniString( "name", BIFF_STR_8BITLENGTH );
3404         dumpUnused( static_cast< sal_Int32 >( nRecPos + 64 - rStrm.tell() ) );
3405         dumpDec< sal_Int32 >( "height", "CONV-TWIP-TO-PT" );
3406         dumpHex< sal_uInt32 >( "flags", "CFRULE-FONTFLAGS" );
3407         dumpDec< sal_Int16 >( "weight", "CFRULE-FONTWEIGHT" );
3408         dumpDec< sal_Int16 >( "escapement", "CFRULE-FONTESCAPEMENT" );
3409         dumpDec< sal_Int8 >( "underline", "CFRULE-FONTUNDERLINE" );
3410         dumpDec< sal_uInt8 >( "family", "FONT-FAMILY" );
3411         dumpDec< sal_uInt8 >( "charset", "CHARSET" );
3412         dumpUnused( 1 );
3413         dumpDec< sal_Int32 >( "color", "CFRULE-FONTCOLOR" );
3414         dumpUnused( 4 );
3415         dumpHex< sal_uInt32 >( "used-flags", "CFRULE-FONTUSEDFLAGS" );
3416         dumpDec< sal_uInt32 >( "escapement-used", "CFRULE-FONTUSED" );
3417         dumpDec< sal_uInt32 >( "underline-used", "CFRULE-FONTUSED" );
3418         dumpDec< sal_uInt32 >( "weight-used", "CFRULE-FONTUSED" );
3419         dumpUnused( 4 );
3420         dumpDec< sal_Int32 >( "first-char" );
3421         dumpDec< sal_Int32 >( "char-count" );
3422         dumpDec< sal_uInt16 >( "font-idx" );
3423     }
3424     if( getFlag< sal_uInt32 >( nFlags1, 0x08000000 ) )
3425     {
3426         writeEmptyItem( "alignment-block" );
3427         IndentGuard aIndGuard( mxOut );
3428         dumpHex< sal_uInt8 >( "alignent", "CFRULE-ALIGNMENT" );
3429         dumpHex< sal_uInt8 >( "rotation", "TEXTROTATION" );
3430         dumpHex< sal_uInt16 >( "indent", "CFRULE-INDENT" );
3431         dumpDec< sal_Int32 >( "relative-indent" );
3432     }
3433     if( getFlag< sal_uInt32 >( nFlags1, 0x10000000 ) )
3434     {
3435         writeEmptyItem( "border-block" );
3436         IndentGuard aIndGuard( mxOut );
3437         dumpHex< sal_uInt16 >( "border-style", "XF-BORDERSTYLE" );
3438         dumpHex< sal_uInt16 >( "border-color1", "XF-BORDERCOLOR1" );
3439         dumpHex< sal_uInt32 >( "border-color2", "CFRULE-BORDERCOLOR2" );
3440     }
3441     if( getFlag< sal_uInt32 >( nFlags1, 0x20000000 ) )
3442     {
3443         writeEmptyItem( "pattern-block" );
3444         IndentGuard aIndGuard( mxOut );
3445         dumpHex< sal_uInt32 >( "pattern", "CFRULE-FILLBLOCK" );
3446     }
3447     if( getFlag< sal_uInt32 >( nFlags1, 0x40000000 ) )
3448     {
3449         writeEmptyItem( "protection-block" );
3450         IndentGuard aIndGuard( mxOut );
3451         dumpHex< sal_uInt16 >( "flags", "CFRULE-PROTECTION-FLAGS" );
3452     }
3453 }
3454 
3455 void WorkbookStreamObject::dumpXfExtProp()
3456 {
3457     BiffInputStream& rStrm = getBiffStream();
3458     for( sal_uInt16 nIndex = 0, nCount = dumpDec< sal_uInt16 >( "subrec-count" ); !rStrm.isEof() && (nIndex < nCount); ++nIndex )
3459     {
3460         mxOut->startMultiItems();
3461         sal_Int64 nStartPos = rStrm.tell();
3462         writeEmptyItem( "SUBREC" );
3463         sal_uInt16 nSubRecId = dumpDec< sal_uInt16 >( "id", "XFEXT-SUBREC" );
3464         sal_uInt16 nSubRecSize = dumpDec< sal_uInt16 >( "size" );
3465         sal_Int64 nEndPos = nStartPos + nSubRecSize;
3466         mxOut->endMultiItems();
3467         IndentGuard aIndGuard( mxOut );
3468         switch( nSubRecId )
3469         {
3470             case 4: case 5: case 7: case 8: case 9: case 10: case 11: case 13:
3471             {
3472                 sal_uInt16 nColorType = dumpExtColorType< sal_uInt16 >();
3473                 dumpDec< sal_Int16 >( "tint", "CONV-TINT" );
3474                 dumpExtColorValue( nColorType );
3475                 dumpUnused( 8 );
3476             }
3477             break;
3478             case 6:
3479                 dumpExtGradientHead();
3480                 mxOut->resetItemIndex();
3481                 for( sal_Int32 nStop = 0, nStopCount = dumpDec< sal_Int32 >( "stop-count" ); (nStop < nStopCount) && !mxStrm->isEof(); ++nStop )
3482                 {
3483                     writeEmptyItem( "#stop" );
3484                     IndentGuard aIndGuard2( mxOut );
3485                     sal_uInt16 nColorType = dumpExtColorType< sal_uInt16 >();
3486                     dumpExtColorValue( nColorType );
3487                     dumpDec< double >( "stop-pos" );
3488                     dumpDec< double >( "tint", "CONV-FLOAT-TO-PERC" );
3489                 }
3490             break;
3491             case 14:
3492                 dumpDec< sal_Int8 >( "font-scheme", "EXTFONT-SCHEME" );
3493             break;
3494             case 15:
3495                 dumpDec< sal_uInt16 >( "indent" );
3496             break;
3497         }
3498         dumpRemainingTo( nEndPos );
3499     }
3500 }
3501 
3502 void WorkbookStreamObject::dumpDxfProp()
3503 {
3504     BiffInputStream& rStrm = getBiffStream();
3505     dumpUnused( 2 );
3506     for( sal_uInt16 nIndex = 0, nCount = dumpDec< sal_uInt16 >( "subrec-count" ); !rStrm.isEof() && (nIndex < nCount); ++nIndex )
3507     {
3508         mxOut->startMultiItems();
3509         sal_Int64 nStartPos = rStrm.tell();
3510         writeEmptyItem( "SUBREC" );
3511         sal_uInt16 nSubRecId = dumpDec< sal_uInt16 >( "id", "DXF-SUBREC" );
3512         sal_uInt16 nSubRecSize = dumpDec< sal_uInt16 >( "size" );
3513         sal_Int64 nEndPos = nStartPos + nSubRecSize;
3514         mxOut->endMultiItems();
3515         IndentGuard aIndGuard( mxOut );
3516         switch( nSubRecId )
3517         {
3518             case 0:
3519                 dumpDec< sal_uInt8 >( "pattern", mxFillPatterns );
3520             break;
3521             case 1: case 2: case 5:
3522                 dumpExtColor();
3523             break;
3524             case 3:
3525                 dumpExtGradientHead();
3526             break;
3527             case 4:
3528                 dumpDec< sal_uInt16 >( "index" );
3529                 dumpDec< double >( "stop-position" );
3530                 dumpExtColor( "stop-color" );
3531             break;
3532             case 6: case 7: case 8: case 9: case 10: case 11: case 12:
3533                 dumpExtColor( "color" );
3534                 dumpDec< sal_uInt16 >( "style", mxBorderStyles );
3535             break;
3536             case 13: case 14:
3537                 dumpBoolean( "value" );
3538             break;
3539             case 15:
3540                 dumpDec< sal_uInt8 >( "alignment", "XF-HORALIGN" );
3541             break;
3542             case 16:
3543                 dumpDec< sal_uInt8 >( "alignment", "XF-VERALIGN" );
3544             break;
3545             case 17:
3546                 dumpDec< sal_uInt8 >( "rotation", "TEXTROTATION" );
3547             break;
3548             case 18:
3549                 dumpDec< sal_uInt16 >( "indent" );
3550             break;
3551             case 19:
3552                 dumpDec< sal_uInt8 >( "text-dir", "XF-TEXTDIRECTION" );
3553             break;
3554             case 20: case 21: case 22: case 23:
3555                 dumpBoolean( "value" );
3556             break;
3557             case 24:
3558                 dumpUnicodeArray( "name", rStrm.readuInt16() );
3559             break;
3560             case 25:
3561                 dumpDec< sal_uInt16 >( "weight", "FONT-WEIGHT" );
3562             break;
3563             case 26:
3564                 dumpDec< sal_uInt16 >( "underline", "FONT-UNDERLINE" );
3565             break;
3566             case 27:
3567                 dumpDec< sal_uInt16 >( "escapement", "FONT-ESCAPEMENT" );
3568             break;
3569             case 28: case 29: case 30: case 31: case 32: case 33:
3570                 dumpBoolean( "value" );
3571             break;
3572             case 34:
3573                 dumpDec< sal_uInt8 >( "charset", "CHARSET" );
3574             break;
3575             case 35:
3576                 dumpDec< sal_uInt8 >( "family", "FONT-FAMILY" );
3577             break;
3578             case 36:
3579                 dumpDec< sal_Int32 >( "height", "CONV-TWIP-TO-PT" );
3580             break;
3581             case 37:
3582                 dumpDec< sal_uInt8 >( "scheme", "EXTFONT-SCHEME" );
3583             break;
3584             case 38:
3585                 dumpUnicodeArray( "numfmt", rStrm.readuInt16() );
3586             break;
3587             case 41:
3588                 dumpDec< sal_uInt16 >( "fmt-idx", mxFormats );
3589             break;
3590             case 42:
3591                 dumpDec< sal_Int16 >( "relative-indent" );
3592             break;
3593             case 43: case 44:
3594                 dumpBoolean( "value" );
3595             break;
3596         }
3597         dumpRemainingTo( nEndPos );
3598     }
3599 }
3600 
3601 void WorkbookStreamObject::dumpDxf12Prop()
3602 {
3603     BiffInputStream& rStrm = getBiffStream();
3604     writeEmptyItem( "dxf-data" );
3605     IndentGuard aIndGuard( mxOut );
3606     sal_uInt32 nSize = dumpDec< sal_uInt32 >( "dxf-size" );
3607     if( nSize == 0 )
3608     {
3609         dumpUnused( 2 );
3610     }
3611     else
3612     {
3613         sal_Int64 nEndPos = rStrm.tell() + nSize;
3614         dumpCfRuleProp();
3615         if( rStrm.tell() + 8 <= nEndPos )
3616         {
3617             dumpUnused( 6 );
3618             dumpXfExtProp();
3619         }
3620         dumpRemainingTo( nEndPos );
3621     }
3622 }
3623 
3624 void WorkbookStreamObject::dumpCfRule12Param( sal_uInt16 nSubType )
3625 {
3626     sal_uInt8 nSize = dumpDec< sal_uInt8 >( "params-size" );
3627     sal_Int64 nEndPos = getBiffStream().tell() + nSize;
3628     {
3629         writeEmptyItem( "params" );
3630         IndentGuard aIndGuard( mxOut );
3631         switch( nSubType )
3632         {
3633             case 5:
3634                 dumpHex< sal_uInt8 >( "flags", "CFRULE12-TOP10-FLAGS" );
3635                 dumpDec< sal_uInt16 >( "rank" );
3636                 dumpUnused( 13 );
3637             break;
3638             case 8:
3639                 dumpDec< sal_uInt16 >( "operator", "CFRULE12-TEXT-OPERATOR" );
3640                 dumpUnused( 14 );
3641             break;
3642             case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24:
3643                 dumpDec< sal_uInt16 >( "operator", "CFRULE12-DATE-OPERATOR" );
3644                 dumpUnused( 14 );
3645             break;
3646             case 25: case 26: case 29: case 30:
3647                 dumpDec< sal_uInt16 >( "std-dev" );
3648                 dumpUnused( 14 );
3649             break;
3650             default:
3651                 dumpUnused( 16 );
3652         }
3653     }
3654     dumpRemainingTo( nEndPos );
3655 }
3656 
3657 void WorkbookStreamObject::dumpFontRec()
3658 {
3659     sal_uInt16 nFontId = getBiffData().getFontCount();
3660     mxOut->resetItemIndex( nFontId );
3661     writeEmptyItem( "#font" );
3662     sal_uInt16 nHeight = dumpDec< sal_uInt16 >( "height", "CONV-TWIP-TO-PT" );
3663     sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "FONT-FLAGS" );
3664     bool bBold = getFlag( nFlags, BIFF_FONTFLAG_BOLD );
3665     bool bItalic = getFlag( nFlags, BIFF_FONTFLAG_ITALIC );
3666     rtl_TextEncoding eFontEnc = RTL_TEXTENCODING_DONTKNOW;
3667     if( getBiff() >= BIFF3 )
3668         dumpColorIdx();
3669     if( getBiff() >= BIFF5 )
3670     {
3671         bBold = dumpDec< sal_uInt16 >( "weight", "FONT-WEIGHT" ) > 450;
3672         dumpDec< sal_uInt16 >( "escapement", "FONT-ESCAPEMENT" );
3673         dumpDec< sal_uInt8 >( "underline", "FONT-UNDERLINE" );
3674         dumpDec< sal_uInt8 >( "family", "FONT-FAMILY" );
3675         sal_uInt8 nCharSet = dumpDec< sal_uInt8 >( "charset", "CHARSET" );
3676         eFontEnc = rtl_getTextEncodingFromWindowsCharset( nCharSet );
3677         dumpUnused( 1 );
3678     }
3679     OUString aName = dumpString( "name", BIFF_STR_8BITLENGTH, BIFF_STR_8BITLENGTH );
3680 
3681     // append font data to vector
3682     mxFontNames->setName( nFontId, createFontName( aName, nHeight, bBold, bItalic ) );
3683 
3684     // store font encoding
3685     getBiffData().appendFontEncoding( eFontEnc );
3686 
3687     // set font encoding as default text encoding in case of missing CODEPAGE record
3688     if( !mbHasCodePage && (nFontId == 0) )
3689         getBiffData().setTextEncoding( eFontEnc );
3690 }
3691 
3692 void WorkbookStreamObject::dumpFormatRec()
3693 {
3694     sal_uInt16 nFormatIdx = 0;
3695     switch( getBiff() )
3696     {
3697         case BIFF2:
3698         case BIFF3:
3699             nFormatIdx = mnFormatIdx++;
3700             mxOut->resetItemIndex( nFormatIdx );
3701             writeEmptyItem( "#fmt" );
3702         break;
3703         case BIFF4:
3704             nFormatIdx = mnFormatIdx++;
3705             mxOut->resetItemIndex( nFormatIdx );
3706             writeEmptyItem( "#fmt" );
3707             dumpUnused( 2 );
3708         break;
3709         case BIFF5:
3710         case BIFF8:
3711             getBiffStream() >> nFormatIdx;
3712             mxOut->resetItemIndex( nFormatIdx );
3713             writeEmptyItem( "#fmt" );
3714             writeDecItem( "fmt-idx", nFormatIdx );
3715         break;
3716         case BIFF_UNKNOWN: break;
3717     }
3718     OUString aFormat = dumpString( "format", BIFF_STR_8BITLENGTH );
3719     mxFormats->setName( nFormatIdx, aFormat );
3720 }
3721 
3722 void WorkbookStreamObject::dumpXfRec()
3723 {
3724     sal_uInt16 nXfId = getBiffData().getXfCount();
3725     mxOut->resetItemIndex( nXfId );
3726     writeEmptyItem( "#xf" );
3727     sal_uInt16 nFontId = dumpFontIdx( EMPTY_STRING, getBiff() >= BIFF5 );
3728     switch( getBiff() )
3729     {
3730         case BIFF2:
3731             dumpUnused( 1 );
3732             dumpHex< sal_uInt8 >( "type-flags", "XF-TYPEFLAGS" );
3733             dumpHex< sal_uInt8 >( "style-flags", "XF-STYLEFLAGS" );
3734         break;
3735         case BIFF3:
3736             dumpFormatIdx();
3737             dumpHex< sal_uInt8 >( "type-flags", "XF-TYPEFLAGS" );
3738             dumpHex< sal_uInt8 >( "used-attributes", "XF-USEDATTRIBS-FLAGS" );
3739             dumpHex< sal_uInt16 >( "alignment", "XF-ALIGNMENT" );
3740             dumpHex< sal_uInt16 >( "fill-style", "XF-FILL" );
3741             dumpHex< sal_uInt32 >( "border-style", "XF-BORDER" );
3742         break;
3743         case BIFF4:
3744             dumpFormatIdx();
3745             dumpHex< sal_uInt16 >( "type-flags", "XF-TYPEFLAGS" );
3746             dumpHex< sal_uInt8 >( "alignment", "XF-ALIGNMENT" );
3747             dumpHex< sal_uInt8 >( "used-attributes", "XF-USEDATTRIBS-FLAGS" );
3748             dumpHex< sal_uInt16 >( "fill-style", "XF-FILL" );
3749             dumpHex< sal_uInt32 >( "border-style", "XF-BORDER" );
3750         break;
3751         case BIFF5:
3752             dumpFormatIdx();
3753             dumpHex< sal_uInt16 >( "type-flags", "XF-TYPEFLAGS" );
3754             dumpHex< sal_uInt8 >( "alignment", "XF-ALIGNMENT" );
3755             dumpHex< sal_uInt8 >( "orientation", "XF-ORIENTATTRIBS" );
3756             dumpHex< sal_uInt32 >( "fill-style", "XF-FILL" );
3757             dumpHex< sal_uInt32 >( "border-style", "XF-BORDER" );
3758         break;
3759         case BIFF8:
3760             dumpFormatIdx();
3761             dumpHex< sal_uInt16 >( "type-flags", "XF-TYPEFLAGS" );
3762             dumpHex< sal_uInt8 >( "alignment", "XF-ALIGNMENT" );
3763             dumpDec< sal_uInt8 >( "rotation", "TEXTROTATION" );
3764             dumpHex< sal_uInt8 >( "text-flags", "XF-TEXTFLAGS" );
3765             dumpHex< sal_uInt8 >( "used-attributes", "XF-USEDATTRIBS-FLAGS" );
3766             dumpHex< sal_uInt16 >( "border-style", "XF-BORDERSTYLE" );
3767             dumpHex< sal_uInt16 >( "border-color1", "XF-BORDERCOLOR1" );
3768             dumpHex< sal_uInt32 >( "border-color2", "XF-BORDERCOLOR2" );
3769             dumpHex< sal_uInt16 >( "fill-color", "XF-FILLCOLOR" );
3770         break;
3771         case BIFF_UNKNOWN: break;
3772     }
3773     getBiffData().appendXfFontId( nFontId );
3774 }
3775 
3776 void WorkbookStreamObject::dumpObjRec()
3777 {
3778     switch( getBiff() )
3779     {
3780         case BIFF3:
3781             dumpObjRecBiff3();
3782         break;
3783         case BIFF4:
3784             dumpObjRecBiff4();
3785         break;
3786         case BIFF5:
3787             dumpObjRecBiff5();
3788         break;
3789         case BIFF8:
3790             // #i61786# OBJ records without DFF stream are in BIFF5 format
3791             if( mbHasDff ) dumpObjRecBiff8(); else dumpObjRecBiff5();
3792         break;
3793         default:;
3794     }
3795 }
3796 
3797 void WorkbookStreamObject::dumpObjRecBiff3()
3798 {
3799     dumpDec< sal_uInt32 >( "obj-count" );
3800     sal_uInt16 nObjType = dumpDec< sal_uInt16 >( "obj-type", "OBJ-TYPE" );
3801     dumpDec< sal_uInt16 >( "obj-id" );
3802     dumpHex< sal_uInt16 >( "flags", "OBJ-FLAGS" );
3803     dumpDffClientRect();
3804     sal_uInt16 nMacroSize = dumpDec< sal_uInt16 >( "macro-size" );
3805     dumpUnused( 2 );
3806     sal_uInt16 nTextLen = 0, nFormatSize = 0, nLinkSize = 0;
3807     switch( nObjType )
3808     {
3809         case BIFF_OBJTYPE_GROUP:
3810             dumpUnused( 4 );
3811             dumpDec< sal_uInt16 >( "next-ungrouped-id" );
3812             dumpUnused( 16 );
3813             dumpObjRecString( "macro", nMacroSize, true );
3814         break;
3815         case BIFF_OBJTYPE_LINE:
3816             dumpObjRecLineData();
3817             dumpHex< sal_uInt16 >( "line-end", "OBJ-LINEENDS" );
3818             dumpDec< sal_uInt8 >( "line-direction", "OBJ-LINEDIR" );
3819             dumpUnused( 1 );
3820             dumpObjRecString( "macro", nMacroSize, true );
3821         break;
3822         case BIFF_OBJTYPE_RECTANGLE:
3823         case BIFF_OBJTYPE_OVAL:
3824             dumpObjRecRectData();
3825             dumpObjRecString( "macro", nMacroSize, true );
3826         break;
3827         case BIFF_OBJTYPE_ARC:
3828             dumpObjRecFillData();
3829             dumpObjRecLineData();
3830             dumpDec< sal_uInt8 >( "quadrant", "OBJ-ARC-QUADRANT" );
3831             dumpUnused( 1 );
3832             dumpObjRecString( "macro", nMacroSize, true );
3833         break;
3834         case BIFF_OBJTYPE_CHART:
3835             dumpObjRecRectData();
3836             dumpUnused( 18 );
3837             dumpObjRecString( "macro", nMacroSize, true );
3838         break;
3839         case BIFF_OBJTYPE_TEXT:
3840         case BIFF_OBJTYPE_BUTTON:
3841             dumpObjRecRectData();
3842             dumpObjRecTextDataBiff3( nTextLen, nFormatSize );
3843             dumpObjRecString( "macro", nMacroSize, true );
3844             dumpObjRecString( "text", nTextLen, false );
3845             dumpObjRecTextFmt( nFormatSize );
3846         break;
3847         case BIFF_OBJTYPE_PICTURE:
3848             dumpObjRecRectData();
3849             dumpDec< sal_Int16 >( "image-format", "IMGDATA-FORMAT" );
3850             dumpUnused( 4 );
3851             nLinkSize = dumpDec< sal_uInt16 >( "pic-link-size" );
3852             dumpUnused( 2 );
3853             dumpHex< sal_uInt16 >( "flags", "OBJ-PICTURE-FLAGS" );
3854             dumpObjRecString( "macro", nMacroSize, true );
3855             dumpObjRecPictFmla( nLinkSize );
3856         break;
3857     }
3858 }
3859 
3860 void WorkbookStreamObject::dumpObjRecBiff4()
3861 {
3862     dumpDec< sal_uInt32 >( "obj-count" );
3863     sal_uInt16 nObjType = dumpDec< sal_uInt16 >( "obj-type", "OBJ-TYPE" );
3864     dumpDec< sal_uInt16 >( "obj-id" );
3865     dumpHex< sal_uInt16 >( "flags", "OBJ-FLAGS" );
3866     dumpDffClientRect();
3867     sal_uInt16 nMacroSize = dumpDec< sal_uInt16 >( "macro-size" );
3868     dumpUnused( 2 );
3869     sal_uInt16 nTextLen = 0, nFormatSize = 0, nLinkSize = 0;
3870     switch( nObjType )
3871     {
3872         case BIFF_OBJTYPE_GROUP:
3873             dumpUnused( 4 );
3874             dumpDec< sal_uInt16 >( "next-ungrouped-id" );
3875             dumpUnused( 16 );
3876             dumpObjRecFmla( "macro", nMacroSize );
3877         break;
3878         case BIFF_OBJTYPE_LINE:
3879             dumpObjRecLineData();
3880             dumpHex< sal_uInt16 >( "line-end", "OBJ-LINEENDS" );
3881             dumpDec< sal_uInt8 >( "line-direction", "OBJ-LINEDIR" );
3882             dumpUnused( 1 );
3883             dumpObjRecFmla( "macro", nMacroSize );
3884         break;
3885         case BIFF_OBJTYPE_RECTANGLE:
3886         case BIFF_OBJTYPE_OVAL:
3887             dumpObjRecRectData();
3888             dumpObjRecFmla( "macro", nMacroSize );
3889         break;
3890         case BIFF_OBJTYPE_ARC:
3891             dumpObjRecFillData();
3892             dumpObjRecLineData();
3893             dumpDec< sal_uInt8 >( "quadrant", "OBJ-ARC-QUADRANT" );
3894             dumpUnused( 1 );
3895             dumpObjRecFmla( "macro", nMacroSize );
3896         break;
3897         case BIFF_OBJTYPE_CHART:
3898             dumpObjRecRectData();
3899             dumpUnused( 18 );
3900             dumpObjRecFmla( "macro", nMacroSize );
3901         break;
3902         case BIFF_OBJTYPE_TEXT:
3903         case BIFF_OBJTYPE_BUTTON:
3904             dumpObjRecRectData();
3905             dumpObjRecTextDataBiff3( nTextLen, nFormatSize );
3906             dumpObjRecFmla( "macro", nMacroSize );
3907             dumpObjRecString( "text", nTextLen, false );
3908             dumpObjRecTextFmt( nFormatSize );
3909         break;
3910         case BIFF_OBJTYPE_PICTURE:
3911             dumpObjRecRectData();
3912             dumpDec< sal_Int16 >( "image-format", "IMGDATA-FORMAT" );
3913             dumpUnused( 4 );
3914             nLinkSize = dumpDec< sal_uInt16 >( "pic-link-size" );
3915             dumpUnused( 2 );
3916             dumpHex< sal_uInt16 >( "flags", "OBJ-PICTURE-FLAGS" );
3917             dumpObjRecFmla( "macro", nMacroSize );
3918             dumpObjRecPictFmla( nLinkSize );
3919         break;
3920         case BIFF_OBJTYPE_POLYGON:
3921             dumpObjRecRectData();
3922             dumpHex< sal_uInt16 >( "flags", "OBJ-POLYGON-FLAGS" );
3923             dumpUnused( 10 );
3924             dumpDec< sal_uInt16 >( "point-count" );
3925             dumpUnused( 8 );
3926             dumpObjRecFmla( "macro", nMacroSize );
3927         break;
3928     }
3929 }
3930 
3931 void WorkbookStreamObject::dumpObjRecBiff5()
3932 {
3933     BiffInputStream& rStrm = getBiffStream();
3934     dumpDec< sal_uInt32 >( "obj-count" );
3935     sal_uInt16 nObjType = dumpDec< sal_uInt16 >( "obj-type", "OBJ-TYPE" );
3936     dumpDec< sal_uInt16 >( "obj-id" );
3937     dumpHex< sal_uInt16 >( "flags", "OBJ-FLAGS" );
3938     dumpDffClientRect();
3939     sal_uInt16 nMacroSize = dumpDec< sal_uInt16 >( "macro-size" );
3940     dumpUnused( 2 );
3941     sal_uInt16 nNameLen = dumpDec< sal_uInt16 >( "name-len" );
3942     dumpUnused( 2 );
3943     sal_uInt16 nTextLen = 0, nFormatSize = 0, nLinkSize = 0;
3944     switch( nObjType )
3945     {
3946         case BIFF_OBJTYPE_GROUP:
3947             dumpUnused( 4 );
3948             dumpDec< sal_uInt16 >( "next-ungrouped-id" );
3949             dumpUnused( 16 );
3950             dumpObjRecString( "obj-name", nNameLen, true );
3951             dumpObjRecFmla( "macro", nMacroSize );
3952         break;
3953         case BIFF_OBJTYPE_LINE:
3954             dumpObjRecLineData();
3955             dumpHex< sal_uInt16 >( "line-end", "OBJ-LINEENDS" );
3956             dumpDec< sal_uInt8 >( "line-direction", "OBJ-LINEDIR" );
3957             dumpUnused( 1 );
3958             dumpObjRecString( "obj-name", nNameLen, true );
3959             dumpObjRecFmla( "macro", nMacroSize );
3960         break;
3961         case BIFF_OBJTYPE_RECTANGLE:
3962         case BIFF_OBJTYPE_OVAL:
3963             dumpObjRecRectData();
3964             dumpObjRecString( "obj-name", nNameLen, true );
3965             dumpObjRecFmla( "macro", nMacroSize );
3966         break;
3967         case BIFF_OBJTYPE_ARC:
3968             dumpObjRecFillData();
3969             dumpObjRecLineData();
3970             dumpDec< sal_uInt8 >( "quadrant", "OBJ-ARC-QUADRANT" );
3971             dumpUnused( 1 );
3972             dumpObjRecString( "obj-name", nNameLen, true );
3973             dumpObjRecFmla( "macro", nMacroSize );
3974         break;
3975         case BIFF_OBJTYPE_CHART:
3976             dumpObjRecRectData();
3977             dumpHex< sal_uInt16 >( "chart-flags", "OBJ-CHART-FLAGS" );
3978             dumpUnused( 16 );
3979             dumpObjRecString( "obj-name", nNameLen, true );
3980             dumpObjRecFmla( "macro", nMacroSize );
3981         break;
3982         case BIFF_OBJTYPE_TEXT:
3983         case BIFF_OBJTYPE_BUTTON:
3984         case BIFF_OBJTYPE_LABEL:
3985         case BIFF_OBJTYPE_DIALOG:
3986             dumpObjRecRectData();
3987             dumpObjRecTextDataBiff5( nTextLen, nFormatSize, nLinkSize );
3988             dumpObjRecString( "obj-name", nNameLen, true );
3989             dumpObjRecFmla( "macro", nMacroSize );
3990             dumpObjRecString( "text", nTextLen, false );
3991             dumpObjRecFmla( "text-link", nLinkSize );
3992             dumpObjRecTextFmt( nFormatSize );
3993         break;
3994         case BIFF_OBJTYPE_PICTURE:
3995             dumpObjRecRectData();
3996             dumpDec< sal_Int16 >( "image-format", "IMGDATA-FORMAT" );
3997             dumpUnused( 4 );
3998             nLinkSize = dumpDec< sal_uInt16 >( "pic-link-size" );
3999             dumpUnused( 2 );
4000             dumpHex< sal_uInt16 >( "flags", "OBJ-PICTURE-FLAGS" );
4001             dumpUnused( 4 );
4002             dumpObjRecString( "obj-name", nNameLen, true );
4003             dumpObjRecFmla( "macro", nMacroSize );
4004             dumpObjRecPictFmla( nLinkSize );
4005             if( rStrm.getRemaining() >= 4 )
4006                 dumpHex< sal_uInt32 >( "ole-storage-id" );
4007         break;
4008         case BIFF_OBJTYPE_POLYGON:
4009             dumpObjRecRectData();
4010             dumpHex< sal_uInt16 >( "flags", "OBJ-POLYGON-FLAGS" );
4011             dumpUnused( 10 );
4012             dumpDec< sal_uInt16 >( "point-count" );
4013             dumpUnused( 8 );
4014             dumpObjRecString( "obj-name", nNameLen, true );
4015             dumpObjRecFmla( "macro", nMacroSize );
4016         break;
4017         case BIFF_OBJTYPE_CHECKBOX:
4018             dumpObjRecRectData();
4019             dumpUnused( 10 );
4020             dumpHex< sal_uInt16 >( "flags", "OBJ-TEXT-FLAGS" );
4021             dumpUnused( 20 );
4022             dumpObjRecString( "obj-name", nNameLen, true );
4023             dumpObjRecFmla( "macro", dumpDec< sal_uInt16 >( "macro-size" ) );
4024             dumpObjRecFmla( "cell-link", dumpDec< sal_uInt16 >( "cell-link-size" ) );
4025             dumpObjRecString( "text", dumpDec< sal_uInt16 >( "text-len" ), false );
4026             dumpObjRecCblsData();
4027         break;
4028         case BIFF_OBJTYPE_OPTIONBUTTON:
4029             dumpObjRecRectData();
4030             dumpUnused( 10 );
4031             dumpHex< sal_uInt16 >( "flags", "OBJ-TEXT-FLAGS" );
4032             dumpUnused( 32 );
4033             dumpObjRecString( "obj-name", nNameLen, true );
4034             dumpObjRecFmla( "macro", dumpDec< sal_uInt16 >( "macro-size" ) );
4035             dumpObjRecFmla( "cell-link", dumpDec< sal_uInt16 >( "cell-link-size" ) );
4036             dumpObjRecString( "text", dumpDec< sal_uInt16 >( "text-len" ), false );
4037             dumpObjRecCblsData();
4038             dumpObjRecRboData();
4039         break;
4040         case BIFF_OBJTYPE_EDIT:
4041             dumpObjRecRectData();
4042             dumpUnused( 10 );
4043             dumpHex< sal_uInt16 >( "flags", "OBJ-TEXT-FLAGS" );
4044             dumpUnused( 14 );
4045             dumpObjRecString( "obj-name", nNameLen, true );
4046             dumpObjRecFmla( "macro", dumpDec< sal_uInt16 >( "macro-size" ) );
4047             dumpObjRecString( "text", dumpDec< sal_uInt16 >( "text-len" ), false );
4048             dumpObjRecEdoData();
4049         break;
4050         case BIFF_OBJTYPE_SPIN:
4051         case BIFF_OBJTYPE_SCROLLBAR:
4052             dumpObjRecRectData();
4053             dumpObjRecSbsData();
4054             dumpObjRecString( "obj-name", nNameLen, true );
4055             dumpObjRecFmla( "macro", dumpDec< sal_uInt16 >( "macro-size" ) );
4056             dumpObjRecFmla( "cell-link", dumpDec< sal_uInt16 >( "cell-link-size" ) );
4057         break;
4058         case BIFF_OBJTYPE_LISTBOX:
4059             dumpObjRecRectData();
4060             dumpObjRecSbsData();
4061             dumpUnused( 18 );
4062             dumpFontIdx( "font-idx" );
4063             dumpUnused( 4 );
4064             dumpObjRecString( "obj-name", nNameLen, true );
4065             dumpObjRecFmla( "macro", dumpDec< sal_uInt16 >( "macro-size" ) );
4066             dumpObjRecFmla( "cell-link", dumpDec< sal_uInt16 >( "cell-link-size" ) );
4067             dumpObjRecLbsData();
4068         break;
4069         case BIFF_OBJTYPE_GROUPBOX:
4070             dumpObjRecRectData();
4071             dumpUnused( 10 );
4072             dumpHex< sal_uInt16 >( "flags", "OBJ-TEXT-FLAGS" );
4073             dumpUnused( 26 );
4074             dumpObjRecString( "obj-name", nNameLen, true );
4075             dumpObjRecFmla( "macro", dumpDec< sal_uInt16 >( "macro-size" ) );
4076             dumpObjRecString( "text", dumpDec< sal_uInt16 >( "text-len" ), false );
4077             dumpObjRecGboData();
4078         break;
4079         case BIFF_OBJTYPE_DROPDOWN:
4080             dumpObjRecRectData();
4081             dumpObjRecSbsData();
4082             dumpUnused( 18 );
4083             dumpFontIdx( "font-idx" );
4084             dumpUnused( 14 );
4085             dumpDec< sal_uInt16 >( "bounding-left" );
4086             dumpDec< sal_uInt16 >( "bounding-top" );
4087             dumpDec< sal_uInt16 >( "bounding-right" );
4088             dumpDec< sal_uInt16 >( "bounding-bottom" );
4089             dumpUnused( 4 );
4090             dumpObjRecString( "obj-name", nNameLen, true );
4091             dumpObjRecFmla( "macro", dumpDec< sal_uInt16 >( "macro-size" ) );
4092             dumpObjRecFmla( "cell-link", dumpDec< sal_uInt16 >( "cell-link-size" ) );
4093             dumpObjRecLbsData();
4094             dumpDec< sal_uInt16 >( "type", "OBJ-DROPDOWN-TYPE" );
4095             dumpDec< sal_uInt16 >( "line-count" );
4096             dumpDec< sal_uInt16 >( "min-list-width" );
4097             dumpObjRecString( "text", dumpDec< sal_uInt16 >( "text-len" ), false );
4098         break;
4099     }
4100 }
4101 
4102 void WorkbookStreamObject::dumpObjRecBiff8()
4103 {
4104     BiffInputStream& rStrm = getBiffStream();
4105     NameListRef xRecNames = cfg().getNameList( "OBJ-RECNAMES" );
4106     sal_uInt16 nObjType = 0xFFFF;
4107     bool bControl = false;
4108     bool bCtlsStrm = false;
4109     bool bLoop = true;
4110     while( bLoop && (rStrm.getRemaining() >= 4) )
4111     {
4112         mxOut->emptyLine();
4113         sal_uInt16 nSubRecId, nSubRecSize;
4114         {
4115             MultiItemsGuard aMultiGuard( mxOut );
4116             writeEmptyItem( "OBJREC" );
4117             writeHexItem( "pos", static_cast< sal_uInt32 >( rStrm.tell() ) );
4118             rStrm >> nSubRecId >> nSubRecSize;
4119             writeHexItem( "size", nSubRecSize );
4120             writeHexItem( "id", nSubRecId, xRecNames );
4121         }
4122 
4123         sal_Int64 nSubRecStart = rStrm.tell();
4124         // sometimes the last subrecord has an invalid length
4125         sal_Int64 nRealRecSize = ::std::min< sal_Int64 >( nSubRecSize, rStrm.getRemaining() );
4126         sal_Int64 nSubRecEnd = nSubRecStart + nRealRecSize;
4127 
4128         IndentGuard aIndGuard( mxOut );
4129         switch( nSubRecId )
4130         {
4131             case BIFF_ID_OBJMACRO:
4132                 dumpObjRecFmlaRaw();
4133             break;
4134             case BIFF_ID_OBJCF:
4135                 dumpDec< sal_Int16 >( "clipboard-format", "IMGDATA-FORMAT" );
4136             break;
4137             case BIFF_ID_OBJFLAGS:
4138             {
4139                 sal_uInt16 nFlags = dumpHex< sal_uInt16 >( "flags", "OBJFLAGS-FLAGS" );
4140                 bControl = getFlag( nFlags, BIFF_OBJFLAGS_CONTROL );
4141                 bCtlsStrm = getFlag( nFlags, BIFF_OBJFLAGS_CTLSSTREAM );
4142             }
4143             break;
4144             case BIFF_ID_OBJPICTFMLA:
4145             {
4146                 dumpObjRecPictFmla( dumpDec< sal_uInt16 >( "pic-link-size" ) );
4147                 if( rStrm.tell() + 4 <= nSubRecEnd )
4148                 {
4149                     if( bControl && bCtlsStrm )
4150                         dumpControl();
4151                     else
4152                         dumpHex< sal_uInt32 >( "ole-storage-id" );
4153                 }
4154                 if( bControl && (rStrm.tell() + 8 <= nSubRecEnd) )
4155                 {
4156                     sal_uInt32 nKeySize = dumpDec< sal_uInt32 >( "licence-key-size" );
4157                     if( nKeySize > 0 )
4158                     {
4159                         IndentGuard aIndGuard2( mxOut );
4160                         sal_Int64 nKeyEnd = rStrm.tell() + nKeySize;
4161                         dumpArray( "licence-key", static_cast< sal_Int32 >( nKeySize ) );
4162                         rStrm.seek( nKeyEnd );
4163                     }
4164                     dumpObjRecFmla( "cell-link", dumpDec< sal_uInt16 >( "cell-link-size" ) );
4165                     dumpObjRecFmla( "source-range", dumpDec< sal_uInt16 >( "source-range-size" ) );
4166                 }
4167             }
4168             break;
4169             case BIFF_ID_OBJCBLS:
4170                 dumpDec< sal_uInt16 >( "state", "OBJ-CHECKBOX-STATE" );
4171                 dumpUnused( 4 );
4172                 dumpUnicode( "accelerator" );
4173                 dumpUnicode( "fareast-accelerator" );
4174                 dumpHex< sal_uInt16 >( "checkbox-flags", "OBJ-CHECKBOX-FLAGS" );
4175             break;
4176             case BIFF_ID_OBJRBO:
4177                 dumpUnused( 4 );
4178                 dumpBool< sal_uInt16 >( "first-in-group" );
4179             break;
4180             case BIFF_ID_OBJSBS:
4181                 dumpObjRecSbsData();
4182             break;
4183             case BIFF_ID_OBJGBODATA:
4184                 dumpObjRecGboData();
4185             break;
4186             case BIFF_ID_OBJEDODATA:
4187                 dumpObjRecEdoData();
4188             break;
4189             case BIFF_ID_OBJRBODATA:
4190                 dumpObjRecRboData();
4191             break;
4192             case BIFF_ID_OBJCBLSDATA:
4193                 dumpObjRecCblsData();
4194             break;
4195             case BIFF_ID_OBJLBSDATA:
4196                 dumpObjRecLbsData();
4197                 if( nObjType == BIFF_OBJTYPE_DROPDOWN )
4198                 {
4199                     dumpHex< sal_uInt16 >( "dropdown-flags", "OBJ-DROPDOWN-FLAGS" );
4200                     dumpDec< sal_uInt16 >( "line-count" );
4201                     dumpDec< sal_uInt16 >( "min-list-width" );
4202                     dumpObjRecString( "text", dumpDec< sal_uInt16 >( "text-len" ), false );
4203                 }
4204             break;
4205             case BIFF_ID_OBJCBLSFMLA:
4206             case BIFF_ID_OBJSBSFMLA:
4207                 dumpObjRecFmlaRaw();
4208             break;
4209             case BIFF_ID_OBJCMO:
4210                 nObjType = dumpDec< sal_uInt16 >( "type", "OBJ-TYPE" );
4211                 dumpDec< sal_uInt16 >( "id" );
4212                 dumpHex< sal_uInt16 >( "flags", "OBJCMO-FLAGS" );
4213                 dumpUnused( 12 );
4214             break;
4215         }
4216         // remaining undumped data
4217         if( !rStrm.isEof() && (rStrm.tell() == nSubRecStart) )
4218             dumpRawBinary( nRealRecSize, false );
4219         else
4220             dumpRemainingTo( nSubRecEnd );
4221     }
4222 }
4223 
4224 void WorkbookStreamObject::dumpObjRecLineData()
4225 {
4226     dumpColorIdx( "line-color-idx", false );
4227     dumpDec< sal_uInt8 >( "line-type", "OBJ-LINETYPE" );
4228     dumpDec< sal_uInt8 >( "line-weight", "OBJ-LINEWEIGHT" );
4229     dumpHex< sal_uInt8 >( "line-flags", "OBJ-AUTO-FLAGS" );
4230 }
4231 
4232 void WorkbookStreamObject::dumpObjRecFillData()
4233 {
4234     dumpColorIdx( "back-color-idx", false );
4235     dumpColorIdx( "patt-color-idx", false );
4236     dumpPatternIdx( EMPTY_STRING, false );
4237     dumpHex< sal_uInt8 >( "area-flags", "OBJ-AUTO-FLAGS" );
4238 }
4239 
4240 void WorkbookStreamObject::dumpObjRecRectData()
4241 {
4242     dumpObjRecFillData();
4243     dumpObjRecLineData();
4244     dumpHex< sal_uInt16 >( "frame-style", "OBJ-FRAMESTYLE-FLAGS" );
4245 }
4246 
4247 void WorkbookStreamObject::dumpObjRecTextDataBiff3( sal_uInt16& ornTextLen, sal_uInt16& ornFormatSize )
4248 {
4249     ornTextLen = dumpDec< sal_uInt16 >( "text-len" );
4250     dumpUnused( 2 );
4251     ornFormatSize = dumpDec< sal_uInt16 >( "format-run-size" );
4252     dumpFontIdx( "default-font-idx" );
4253     dumpUnused( 2 );
4254     dumpHex< sal_uInt16 >( "flags", "OBJ-TEXT-FLAGS" );
4255     dumpDec< sal_uInt16 >( "orientation", "TEXTORIENTATION" );
4256     dumpUnused( 8 );
4257 }
4258 
4259 void WorkbookStreamObject::dumpObjRecTextDataBiff5( sal_uInt16& ornTextLen, sal_uInt16& ornFormatSize, sal_uInt16& ornLinkSize )
4260 {
4261     ornTextLen = dumpDec< sal_uInt16 >( "text-len" );
4262     dumpUnused( 2 );
4263     ornFormatSize = dumpDec< sal_uInt16 >( "format-run-size" );
4264     dumpFontIdx( "default-font-idx" );
4265     dumpUnused( 2 );
4266     dumpHex< sal_uInt16 >( "flags", "OBJ-TEXT-FLAGS" );
4267     dumpDec< sal_uInt16 >( "orientation", "TEXTORIENTATION" );
4268     dumpUnused( 2 );
4269     ornLinkSize = dumpDec< sal_uInt16 >( "link-size" );
4270     dumpUnused( 2 );
4271     dumpHex< sal_uInt16 >( "button-flags", "OBJ-BUTTON-FLAGS" );
4272     dumpUnicode( "accelerator" );
4273     dumpUnicode( "fareast-accelerator" );
4274 }
4275 
4276 void WorkbookStreamObject::dumpObjRecSbsData()
4277 {
4278     dumpUnused( 4 );
4279     dumpDec< sal_uInt16 >( "value" );
4280     dumpDec< sal_uInt16 >( "min" );
4281     dumpDec< sal_uInt16 >( "max" );
4282     dumpDec< sal_uInt16 >( "step" );
4283     dumpDec< sal_uInt16 >( "page-step" );
4284     dumpBool< sal_uInt16 >( "horizontal" );
4285     dumpDec< sal_uInt16 >( "thumb-width" );
4286     dumpHex< sal_uInt16 >( "scrollbar-flags", "OBJ-SCROLLBAR-FLAGS" );
4287 }
4288 
4289 void WorkbookStreamObject::dumpObjRecGboData()
4290 {
4291     dumpUnicode( "accelerator" );
4292     dumpUnicode( "fareast-accelerator" );
4293     dumpHex< sal_uInt16 >( "groupbox-flags", "OBJ-GROUPBOX-FLAGS" );
4294 }
4295 
4296 void WorkbookStreamObject::dumpObjRecEdoData()
4297 {
4298     dumpDec< sal_uInt16 >( "type", "OBJ-EDIT-TYPE" );
4299     dumpBool< sal_uInt16 >( "multiline" );
4300     dumpBool< sal_uInt16 >( "scrollbar" );
4301     dumpDec< sal_uInt16 >( "listbox-obj-id" );
4302 }
4303 
4304 void WorkbookStreamObject::dumpObjRecRboData()
4305 {
4306     dumpDec< sal_uInt16 >( "next-in-group" );
4307     dumpBool< sal_uInt16 >( "first-in-group" );
4308 }
4309 
4310 void WorkbookStreamObject::dumpObjRecCblsData()
4311 {
4312     dumpDec< sal_uInt16 >( "state", "OBJ-CHECKBOX-STATE" );
4313     dumpUnicode( "accelerator" );
4314     dumpUnicode( "fareast-accelerator" );
4315     dumpHex< sal_uInt16 >( "checkbox-flags", "OBJ-CHECKBOX-FLAGS" );
4316 }
4317 
4318 void WorkbookStreamObject::dumpObjRecLbsData()
4319 {
4320     dumpObjRecFmla( "source-range", dumpDec< sal_uInt16 >( "source-range-size" ) );
4321     dumpDec< sal_uInt16 >( "entry-count" );
4322     dumpDec< sal_uInt16 >( "selected-entry" );
4323     dumpHex< sal_uInt16 >( "listbox-flags", "OBJ-LISTBOX-FLAGS" );
4324     dumpDec< sal_uInt16 >( "edit-obj-id" );
4325 }
4326 
4327 void WorkbookStreamObject::dumpObjRecPadding()
4328 {
4329     if( getBiffStream().tell() & 1 )
4330     {
4331         IndentGuard aIndGuard( mxOut );
4332         dumpHex< sal_uInt8 >( "padding" );
4333     }
4334 }
4335 
4336 void WorkbookStreamObject::dumpObjRecString( const String& rName, sal_uInt16 nTextLen, bool bRepeatLen )
4337 {
4338     if( nTextLen > 0 )
4339     {
4340         if( bRepeatLen )
4341             dumpByteString( rName, BIFF_STR_8BITLENGTH );
4342         else
4343             writeStringItem( rName, getBiffStream().readCharArrayUC( nTextLen, getBiffData().getTextEncoding() ) );
4344         dumpObjRecPadding();
4345     }
4346 }
4347 
4348 void WorkbookStreamObject::dumpObjRecTextFmt( sal_uInt16 nFormatSize )
4349 {
4350     FontPortionModelList aPortions;
4351     aPortions.importPortions( getBiffStream(), nFormatSize / 8, BIFF_FONTPORTION_OBJ );
4352     writeFontPortions( aPortions );
4353 }
4354 
4355 void WorkbookStreamObject::dumpObjRecFmlaRaw()
4356 {
4357     sal_uInt16 nFmlaSize = dumpDec< sal_uInt16 >( "fmla-size" );
4358     dumpUnused( 4 );
4359     getFormulaDumper().dumpNameFormula( "fmla", nFmlaSize );
4360     dumpObjRecPadding();
4361 }
4362 
4363 void WorkbookStreamObject::dumpObjRecFmla( const String& rName, sal_uInt16 nFmlaSize )
4364 {
4365     BiffInputStream& rStrm = getBiffStream();
4366     if( nFmlaSize > 0 )
4367     {
4368         writeEmptyItem( rName );
4369         IndentGuard aIndGuard( mxOut );
4370         sal_Int64 nStrmEnd = rStrm.tell() + nFmlaSize;
4371         dumpObjRecFmlaRaw();
4372         if( rStrm.isEof() || (rStrm.tell() != nStrmEnd) )
4373             writeEmptyItem( OOX_DUMP_ERRASCII( "fmla-size" ) );
4374         dumpRemainingTo( nStrmEnd );
4375     }
4376 }
4377 
4378 void WorkbookStreamObject::dumpObjRecPictFmla( sal_uInt16 nFmlaSize )
4379 {
4380     BiffInputStream& rStrm = getBiffStream();
4381     if( nFmlaSize > 0 )
4382     {
4383         writeEmptyItem( "pic-link" );
4384         IndentGuard aIndGuard( mxOut );
4385         sal_Int64 nStrmEnd = rStrm.tell() + nFmlaSize;
4386         if( (getBiff() == BIFF3) && (nStrmEnd & 1) ) ++nStrmEnd; // BIFF3 size without padding
4387         dumpObjRecFmlaRaw();
4388         if( rStrm.tell() + 2 <= nStrmEnd )
4389         {
4390             dumpString( "class-name", BIFF_STR_DEFAULT, BIFF_STR_SMARTFLAGS );
4391             dumpObjRecPadding();
4392         }
4393         if( rStrm.isEof() || (rStrm.tell() != nStrmEnd) )
4394             writeEmptyItem( OOX_DUMP_ERRASCII( "pic-link-size" ) );
4395         dumpRemainingTo( nStrmEnd );
4396     }
4397 }
4398 
4399 void WorkbookStreamObject::dumpChFrExtProps()
4400 {
4401     BiffInputStream& rStrm = getBiffStream();
4402     bool bValid = true;
4403     while( bValid && (rStrm.getRemaining() > 4) )
4404     {
4405         ChFrExtPropInfo aInfo = dumpChFrExtPropHeader();
4406         IndentGuard aIndGuard( mxOut );
4407         switch( aInfo.first )
4408         {
4409             case 0: // start
4410             case 1: // end
4411             break;
4412             case 2: // bool
4413                 dumpBoolean( "value" );
4414                 dumpUnused( 1 );
4415             break;
4416             case 3: // double
4417                 dumpUnused( 4 );
4418                 dumpDec< double >( "value", aInfo.second );
4419             break;
4420             case 4: // int32
4421                 dumpDec< sal_Int32 >( "value", aInfo.second );
4422             break;
4423             case 5: // string
4424                 dumpUnicodeArray( "value", rStrm.readInt32() );
4425             break;
4426             case 6: // uint16
4427                 dumpDec< sal_uInt16 >( "value", aInfo.second );
4428             break;
4429             case 7: // blob
4430                 dumpBinary( "value", rStrm.readuInt32() );
4431             break;
4432             default:
4433                 bValid = false;
4434         }
4435     }
4436 }
4437 
4438 WorkbookStreamObject::ChFrExtPropInfo WorkbookStreamObject::dumpChFrExtPropHeader()
4439 {
4440     MultiItemsGuard aMultiGuard( mxOut );
4441     ChFrExtPropInfo aInfo;
4442     aInfo.first = dumpDec< sal_uInt8 >( "datatype", "CHFREXTPROPS-TYPE" );
4443     dumpUnused( 1 );
4444     sal_uInt16 nTag = dumpDec< sal_uInt16 >( "tag", "CHFREXTPROPS-TAG" );
4445     aInfo.second = cfg().getName( "CHFREXTPROPS-TAG-NAMELIST", nTag );
4446     return aInfo;
4447 }
4448 
4449 // ============================================================================
4450 
4451 PivotCacheStreamObject::PivotCacheStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, BiffType eBiff, const ::rtl::OUString& rSysFileName )
4452 {
4453     RecordStreamObject::construct( rParent, rxStrm, eBiff, rSysFileName );
4454 }
4455 
4456 void PivotCacheStreamObject::implDumpRecordBody()
4457 {
4458     BiffInputStream& rStrm = getBiffStream();
4459     sal_uInt16 nRecId = rStrm.getRecId();
4460 
4461     switch( nRecId )
4462     {
4463         case BIFF_ID_PCDEFINITION:
4464             dumpDec< sal_Int32 >( "source-records" );
4465             dumpHex< sal_uInt16 >( "cache-id" );
4466             dumpHex< sal_uInt16 >( "flags", "PCDEFINITION-FLAGS" );
4467             dumpUnused( 2 );
4468             dumpDec< sal_uInt16 >( "sourcedata-field-count" );
4469             dumpDec< sal_uInt16 >( "cache-field-count" );
4470             dumpDec< sal_uInt16 >( "report-record-count" );
4471             dumpDec< sal_uInt16 >( "database-type", "PCDSOURCE-TYPE" );
4472             dumpString( "user-name" );
4473         break;
4474 
4475         case BIFF_ID_PCDEFINITION2:
4476             dumpDec< double >( "refreshed-date" );
4477             dumpDec< sal_Int32 >( "formula-count" );
4478         break;
4479 
4480         case BIFF_ID_PCDFDISCRETEPR:
4481             mxOut->resetItemIndex();
4482             while( !rStrm.isEof() && (rStrm.getRemaining() >= 2) )
4483                 dumpDec< sal_uInt16 >( "#item-index" );
4484         break;
4485 
4486         case BIFF_ID_PCDFIELD:
4487             dumpHex< sal_uInt16 >( "flags", "PCDFIELD-FLAGS" );
4488             dumpDec< sal_uInt16 >( "group-parent-field" );
4489             dumpDec< sal_uInt16 >( "group-base-field" );
4490             dumpDec< sal_uInt16 >( "unique-items" );
4491             dumpDec< sal_uInt16 >( "group-items" );
4492             dumpDec< sal_uInt16 >( "base-items" );
4493             dumpDec< sal_uInt16 >( "shared-items" );
4494             if( rStrm.getRemaining() >= 3 )
4495                 dumpString( "item-name" );
4496         break;
4497 
4498         case BIFF_ID_PCITEM_DATE:
4499         {
4500             DateTime aDateTime;
4501             aDateTime.Year = mxStrm->readuInt16();
4502             aDateTime.Month = mxStrm->readuInt16();
4503             aDateTime.Day = mxStrm->readuInt8();
4504             aDateTime.Hours = mxStrm->readuInt8();
4505             aDateTime.Minutes = mxStrm->readuInt8();
4506             aDateTime.Seconds = mxStrm->readuInt8();
4507             writeDateTimeItem( "value", aDateTime );
4508         }
4509         break;
4510 
4511         case BIFF_ID_PCITEM_STRING:
4512             dumpString( "value" );
4513         break;
4514     }
4515 }
4516 
4517 // ============================================================================
4518 // ============================================================================
4519 
4520 RootStorageObject::RootStorageObject( const DumperBase& rParent )
4521 {
4522     OleStorageObject::construct( rParent );
4523     addPreferredStream( "Book" );
4524     addPreferredStream( "Workbook" );
4525 }
4526 
4527 void RootStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
4528 {
4529     if( (rStrgPath.getLength() == 0) && (rStrmName.equalsAscii( "Book" ) || rStrmName.equalsAscii( "Workbook" )) )
4530         WorkbookStreamObject( *this, rxStrm, rSysFileName ).dump();
4531     else if( rStrgPath.equalsAscii( "_SX_DB" ) )
4532         PivotCacheStreamObject( *this, rxStrm, BIFF5, rSysFileName ).dump();
4533     else if( rStrgPath.equalsAscii( "_SX_DB_CUR" ) )
4534         PivotCacheStreamObject( *this, rxStrm, BIFF8, rSysFileName ).dump();
4535     else
4536         OleStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
4537 }
4538 
4539 void RootStorageObject::implDumpStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
4540 {
4541     if( rStrgPath.equalsAscii( "_VBA_PROJECT_CUR" ) )
4542         VbaProjectStorageObject( *this, rxStrg, rSysPath ).dump();
4543     else if( rStrgPath.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "MBD" ) ) )
4544         VbaContainerStorageObject( *this, rxStrg, rSysPath ).dump();
4545     else
4546         OleStorageObject::implDumpStorage( rxStrg, rStrgPath, rSysPath );
4547 }
4548 
4549 void RootStorageObject::implDumpBaseStream( const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
4550 {
4551     WorkbookStreamObject( *this, rxStrm, rSysFileName ).dump();
4552 }
4553 
4554 // ============================================================================
4555 // ============================================================================
4556 
4557 #define DUMP_BIFF_CONFIG_ENVVAR "OOO_BIFFDUMPER"
4558 
4559 Dumper::Dumper( const FilterBase& rFilter )
4560 {
4561     ConfigRef xCfg( new Config( DUMP_BIFF_CONFIG_ENVVAR, rFilter ) );
4562     DumperBase::construct( xCfg );
4563 }
4564 
4565 Dumper::Dumper( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName )
4566 {
4567     if( rxContext.is() && rxInStrm.is() )
4568     {
4569         StorageRef xStrg( new ::oox::ole::OleStorage( rxContext, rxInStrm, true ) );
4570         MediaDescriptor aMediaDesc;
4571         ConfigRef xCfg( new Config( DUMP_BIFF_CONFIG_ENVVAR, rxContext, xStrg, rSysFileName, aMediaDesc ) );
4572         DumperBase::construct( xCfg );
4573     }
4574 }
4575 
4576 void Dumper::implDump()
4577 {
4578     RootStorageObject( *this ).dump();
4579 }
4580 
4581 // ============================================================================
4582 // ============================================================================
4583 
4584 } // namespace biff
4585 } // namespace dump
4586 } // namespace oox
4587 
4588 #endif
4589