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