xref: /aoo41x/main/oox/source/dump/oledumper.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "oox/dump/oledumper.hxx"
29 
30 #include <com/sun/star/io/XInputStream.hpp>
31 #include <com/sun/star/io/XOutputStream.hpp>
32 #include <osl/file.hxx>
33 #include <osl/thread.h>
34 #include <rtl/tencinfo.h>
35 #include "oox/core/filterbase.hxx"
36 #include "oox/helper/binaryoutputstream.hxx"
37 #include "oox/ole/olestorage.hxx"
38 #include "oox/ole/vbainputstream.hxx"
39 
40 #if OOX_INCLUDE_DUMPER
41 
42 namespace oox {
43 namespace dump {
44 
45 // ============================================================================
46 
47 using namespace ::com::sun::star::io;
48 using namespace ::com::sun::star::uno;
49 
50 using ::rtl::OString;
51 using ::rtl::OStringToOUString;
52 using ::rtl::OUString;
53 using ::rtl::OUStringBuffer;
54 
55 // ============================================================================
56 // ============================================================================
57 
58 OUString OleInputObjectBase::dumpAnsiString32( const String& rName )
59 {
60     return dumpCharArray( rName, mxStrm->readInt32(), RTL_TEXTENCODING_MS_1252 );
61 }
62 
63 OUString OleInputObjectBase::dumpUniString32( const String& rName )
64 {
65     return dumpUnicodeArray( rName, mxStrm->readInt32() );
66 }
67 
68 sal_Int32 OleInputObjectBase::dumpStdClipboardFormat( const String& rName )
69 {
70     return dumpDec< sal_Int32 >( rName( "clipboard-format" ), "OLE-STD-CLIPBOARD-FORMAT" );
71 }
72 
73 OUString OleInputObjectBase::dumpAnsiString32OrStdClip( const String& rName )
74 {
75     sal_Int32 nLen = mxStrm->readInt32();
76     return (nLen < 0) ? OUString::valueOf( dumpStdClipboardFormat( rName ) ) : dumpCharArray( rName, nLen, RTL_TEXTENCODING_MS_1252 );
77 }
78 
79 OUString OleInputObjectBase::dumpUniString32OrStdClip( const String& rName )
80 {
81     sal_Int32 nLen = mxStrm->readInt32();
82     return (nLen < 0) ? OUString::valueOf( dumpStdClipboardFormat( rName ) ) : dumpUnicodeArray( rName, nLen );
83 }
84 
85 void OleInputObjectBase::writeOleColorItem( const String& rName, sal_uInt32 nColor )
86 {
87     MultiItemsGuard aMultiGuard( mxOut );
88     writeHexItem( rName, nColor, "OLE-COLOR" );
89 }
90 
91 sal_uInt32 OleInputObjectBase::dumpOleColor( const String& rName )
92 {
93     sal_uInt32 nOleColor = mxStrm->readuInt32();
94     writeOleColorItem( rName, nOleColor );
95     return nOleColor;
96 }
97 
98 // ============================================================================
99 // ============================================================================
100 
101 StdFontObject::StdFontObject( const InputObjectBase& rParent )
102 {
103     construct( rParent );
104 }
105 
106 void StdFontObject::implDump()
107 {
108     dumpDec< sal_uInt8 >( "version" );
109     dumpDec< sal_uInt16 >( "charset", "CHARSET" );
110     dumpHex< sal_uInt8 >( "flags", "STDFONT-FLAGS" );
111     dumpDec< sal_uInt16 >( "weight", "FONT-WEIGHT" );
112     dumpDec< sal_uInt32 >( "height", "STDFONT-HEIGHT" );
113     dumpCharArray( "name", mxStrm->readuInt8(), RTL_TEXTENCODING_ASCII_US );
114 }
115 
116 // ============================================================================
117 
118 StdPicObject::StdPicObject( const InputObjectBase& rParent )
119 {
120     construct( rParent );
121 }
122 
123 void StdPicObject::implDump()
124 {
125     dumpHex< sal_uInt32 >( "identifier", "STDPIC-ID" );
126     sal_uInt32 nSize = dumpHex< sal_uInt32 >( "image-size", "CONV-DEC" );
127     dumpBinary( "image-data", nSize );
128 }
129 
130 // ============================================================================
131 
132 namespace {
133 
134 const sal_uInt32 STDHLINK_HASTARGET         = 0x00000001;   /// Has hyperlink moniker.
135 const sal_uInt32 STDHLINK_ABSOLUTE          = 0x00000002;   /// Absolute path.
136 const sal_uInt32 STDHLINK_HASLOCATION       = 0x00000008;   /// Has target location.
137 const sal_uInt32 STDHLINK_HASDISPLAY        = 0x00000010;   /// Has display string.
138 const sal_uInt32 STDHLINK_HASGUID           = 0x00000020;   /// Has identification GUID.
139 const sal_uInt32 STDHLINK_HASTIME           = 0x00000040;   /// Has creation time.
140 const sal_uInt32 STDHLINK_HASFRAME          = 0x00000080;   /// Has frame.
141 const sal_uInt32 STDHLINK_ASSTRING          = 0x00000100;   /// Hyperlink as simple string.
142 
143 } // namespace
144 
145 StdHlinkObject::StdHlinkObject( const InputObjectBase& rParent )
146 {
147     construct( rParent );
148 }
149 
150 void StdHlinkObject::implDump()
151 {
152     dumpDec< sal_uInt32 >( "stream-version" );
153     sal_uInt32 nFlags = dumpHex< sal_uInt32 >( "flags", "STDHLINK-FLAGS" );
154     if( getFlag( nFlags, STDHLINK_HASDISPLAY ) )
155         dumpHyperlinkString( "display", true );
156     if( getFlag( nFlags, STDHLINK_HASFRAME ) )
157         dumpHyperlinkString( "frame", true );
158     if( getFlag( nFlags, STDHLINK_HASTARGET ) )
159     {
160         if( getFlag( nFlags, STDHLINK_ASSTRING ) )
161             dumpHyperlinkString( "filename", true );
162         else if( !dumpGuidAndMoniker() )
163             return;
164     }
165     if( getFlag( nFlags, STDHLINK_HASLOCATION ) )
166         dumpHyperlinkString( "location", true );
167     if( getFlag( nFlags, STDHLINK_HASGUID ) )
168         dumpGuid( "id-guid" );
169     if( getFlag( nFlags, STDHLINK_HASTIME ) )
170         dumpFileTime( "creation-time" );
171 }
172 
173 OUString StdHlinkObject::dumpHyperlinkString( const String& rName, bool bUnicode )
174 {
175     return bUnicode ? dumpUniString32( rName ) : dumpAnsiString32( rName );
176 }
177 
178 bool StdHlinkObject::dumpGuidAndMoniker()
179 {
180     bool bValidMoniker = true;
181     OUString aGuid = cfg().getStringOption( dumpGuid( "moniker" ), OUString() );
182     IndentGuard aIndGuard( mxOut );
183     if( aGuid.equalsAscii( "URLMoniker" ) )
184         dumpUrlMoniker();
185     else if( aGuid.equalsAscii( "FileMoniker" ) )
186         dumpFileMoniker();
187     else if( aGuid.equalsAscii( "ItemMoniker" ) )
188         dumpItemMoniker();
189     else if( aGuid.equalsAscii( "AntiMoniker" ) )
190         dumpAntiMoniker();
191     else if( aGuid.equalsAscii( "CompositeMoniker" ) )
192         dumpCompositeMoniker();
193     else
194         bValidMoniker = false;
195     return bValidMoniker;
196 }
197 
198 void StdHlinkObject::dumpUrlMoniker()
199 {
200     sal_Int32 nBytes = dumpDec< sal_Int32 >( "url-bytes" );
201     sal_Int64 nEndPos = mxStrm->tell() + ::std::max< sal_Int32 >( nBytes, 0 );
202     dumpNullUnicodeArray( "url" );
203     if( mxStrm->tell() + 24 == nEndPos )
204     {
205         dumpGuid( "implementation-id" );
206         dumpDec< sal_uInt32 >( "version" );
207         dumpHex< sal_uInt32 >( "flags", "STDHLINK-URL-FLAGS" );
208     }
209     dumpRemainingTo( nEndPos );
210 }
211 
212 void StdHlinkObject::dumpFileMoniker()
213 {
214     dumpDec< sal_Int16 >( "up-levels" );
215     dumpHyperlinkString( "ansi-filename", false );
216     dumpDec< sal_Int16 >( "server-path-len" );
217     dumpHex< sal_uInt16 >( "version" );
218     dumpUnused( 20 );
219     sal_Int32 nBytes = dumpDec< sal_Int32 >( "total-bytes" );
220     sal_Int64 nEndPos = mxStrm->tell() + ::std::max< sal_Int32 >( nBytes, 0 );
221     if( nBytes > 0 )
222     {
223         sal_Int32 nFileBytes = dumpDec< sal_Int32 >( "uni-filename-bytes" );
224         dumpDec< sal_uInt16 >( "key-value" );
225         dumpUnicodeArray( "unicode-filename", nFileBytes / 2 );
226     }
227     dumpRemainingTo( nEndPos );
228 }
229 
230 void StdHlinkObject::dumpItemMoniker()
231 {
232     sal_Int32 nBytes = dumpDec< sal_Int32 >( "delimiter-bytes" );
233     sal_Int64 nEndPos = mxStrm->tell() + ::std::max< sal_Int32 >( nBytes, 0 );
234     dumpNullCharArray( "ansi-delimiter", RTL_TEXTENCODING_MS_1252 );
235     if( mxStrm->tell() < nEndPos )
236         dumpUnicodeArray( "unicode-delimiter", (nEndPos - mxStrm->tell()) / 2 );
237     mxStrm->seek( nEndPos );
238 
239     nBytes = dumpDec< sal_Int32 >( "item-bytes" );
240     nEndPos = mxStrm->tell() + ::std::max< sal_Int32 >( nBytes, 0 );
241     dumpNullCharArray( "ansi-item", RTL_TEXTENCODING_MS_1252 );
242     if( mxStrm->tell() < nEndPos )
243         dumpUnicodeArray( "unicode-item", (nEndPos - mxStrm->tell()) / 2 );
244     mxStrm->seek( nEndPos );
245 }
246 
247 void StdHlinkObject::dumpAntiMoniker()
248 {
249     dumpDec< sal_Int32 >( "count" );
250 }
251 
252 void StdHlinkObject::dumpCompositeMoniker()
253 {
254     sal_Int32 nCount = dumpDec< sal_Int32 >( "moniker-count" );
255     for( sal_Int32 nIndex = 0; !mxStrm->isEof() && (nIndex < nCount); ++nIndex )
256         dumpGuidAndMoniker();
257 }
258 
259 // ============================================================================
260 // ============================================================================
261 
262 OleStreamObject::OleStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
263 {
264     construct( rParent, rxStrm, rSysFileName );
265 }
266 
267 // ============================================================================
268 
269 OleCompObjObject::OleCompObjObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName ) :
270     OleStreamObject( rParent, rxStrm, rSysFileName )
271 {
272 }
273 
274 void OleCompObjObject::implDump()
275 {
276     dumpUnused( 4 );
277     dumpDec< sal_uInt32 >( "version" );
278     dumpUnused( 20 );
279     dumpAnsiString32( "ansi-display-name" );
280     dumpAnsiString32OrStdClip( "ansi-clipboard-format" );
281     if( mxStrm->getRemaining() >= 4 )
282     {
283         sal_Int32 nLen = mxStrm->readInt32();
284         if( (0 <= nLen) && (nLen <= 40) )
285         {
286             dumpCharArray( "ansi-unused", nLen, RTL_TEXTENCODING_MS_1252 );
287             if( (mxStrm->getRemaining() >= 4) && (dumpHex< sal_Int32 >( "unicode-marker" ) == 0x71B239F4) )
288             {
289                 dumpUniString32( "unicode-display-name" );
290                 dumpUniString32OrStdClip( "unicode-clipboard-format" );
291                 dumpUniString32( "unicode-unused" );
292             }
293         }
294         else
295             writeDecItem( "length", nLen );
296     }
297     dumpRemainingStream();
298 }
299 
300 // ============================================================================
301 // ============================================================================
302 
303 namespace {
304 
305 const sal_Int32 OLEPROP_ID_DICTIONARY   = 0;
306 const sal_Int32 OLEPROP_ID_CODEPAGE     = 1;
307 
308 const sal_uInt16 OLEPROP_TYPE_INT16     = 2;
309 const sal_uInt16 OLEPROP_TYPE_INT32     = 3;
310 const sal_uInt16 OLEPROP_TYPE_FLOAT     = 4;
311 const sal_uInt16 OLEPROP_TYPE_DOUBLE    = 5;
312 const sal_uInt16 OLEPROP_TYPE_DATE      = 7;
313 const sal_uInt16 OLEPROP_TYPE_STRING    = 8;
314 const sal_uInt16 OLEPROP_TYPE_STATUS    = 10;
315 const sal_uInt16 OLEPROP_TYPE_BOOL      = 11;
316 const sal_uInt16 OLEPROP_TYPE_VARIANT   = 12;
317 const sal_uInt16 OLEPROP_TYPE_INT8      = 16;
318 const sal_uInt16 OLEPROP_TYPE_UINT8     = 17;
319 const sal_uInt16 OLEPROP_TYPE_UINT16    = 18;
320 const sal_uInt16 OLEPROP_TYPE_UINT32    = 19;
321 const sal_uInt16 OLEPROP_TYPE_INT64     = 20;
322 const sal_uInt16 OLEPROP_TYPE_UINT64    = 21;
323 const sal_uInt16 OLEPROP_TYPE_STRING8   = 30;
324 const sal_uInt16 OLEPROP_TYPE_STRING16  = 31;
325 const sal_uInt16 OLEPROP_TYPE_FILETIME  = 64;
326 const sal_uInt16 OLEPROP_TYPE_BLOB      = 65;
327 const sal_uInt16 OLEPROP_TYPE_STREAM    = 66;
328 const sal_uInt16 OLEPROP_TYPE_STORAGE   = 67;
329 const sal_uInt16 OLEPROP_TYPE_CLIPFMT   = 71;
330 
331 const sal_uInt16 OLEPROP_TYPE_SIMPLE    = 0x0000;
332 const sal_uInt16 OLEPROP_TYPE_VECTOR    = 0x1000;
333 const sal_uInt16 OLEPROP_TYPE_ARRAY     = 0x2000;
334 
335 const sal_uInt16 CODEPAGE_UNICODE       = 1200;
336 
337 const sal_uInt32 AX_STRING_COMPRESSED   = 0x80000000;
338 
339 } // namespace
340 
341 // ============================================================================
342 
343 OlePropertyStreamObject::OlePropertyStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
344 {
345     construct( rParent, rxStrm, rSysFileName );
346 }
347 
348 void OlePropertyStreamObject::implDump()
349 {
350     OUStringVector aGuidVec;
351     ::std::vector< sal_uInt32 > aStartPosVec;
352 
353     // dump header
354     writeEmptyItem( "HEADER" );
355     {
356         IndentGuard aIndGuard( mxOut );
357         dumpHex< sal_uInt16 >( "byte-order", "OLEPROP-BYTE-ORDER" );
358         dumpDec< sal_uInt16 >( "version" );
359         dumpDec< sal_uInt16 >( "os-minor" );
360         dumpDec< sal_uInt16 >( "os-type", "OLEPROP-OSTYPE" );
361         dumpGuid( "guid" );
362         sal_Int32 nSectCount = dumpDec< sal_Int32 >( "section-count" );
363 
364         // dump table of section positions
365         {
366             TableGuard aTabGuard( mxOut, 15, 60 );
367             mxOut->resetItemIndex();
368             for( sal_Int32 nSectIdx = 0; !mxStrm->isEof() && (nSectIdx < nSectCount); ++nSectIdx )
369             {
370                 MultiItemsGuard aMultiGuard( mxOut );
371                 writeEmptyItem( "#section" );
372                 aGuidVec.push_back( dumpGuid( "guid" ) );
373                 aStartPosVec.push_back( dumpHex< sal_uInt32 >( "start-pos", "CONV-DEC" ) );
374             }
375         }
376     }
377     mxOut->emptyLine();
378 
379     // dump sections
380     for( size_t nSectIdx = 0; !mxStrm->isEof() && (nSectIdx < aStartPosVec.size()); ++nSectIdx )
381         dumpSection( aGuidVec[ nSectIdx ], aStartPosVec[ nSectIdx ] );
382 }
383 
384 void OlePropertyStreamObject::dumpSection( const OUString& rGuid, sal_uInt32 nStartPos )
385 {
386     // property ID names
387     mxPropIds = cfg().createNameList< ConstList >( "OLEPROP-IDS" );
388     OUString aGuidName = cfg().getStringOption( rGuid, OUString() );
389     if( aGuidName.equalsAscii( "GlobalDocProp" ) )
390         mxPropIds->includeList( cfg().getNameList( "OLEPROP-GLOBALIDS" ) );
391     else if( aGuidName.equalsAscii( "BuiltinDocProp" ) )
392         mxPropIds->includeList( cfg().getNameList( "OLEPROP-BUILTINIDS" ) );
393     else
394         mxPropIds->includeList( cfg().getNameList( "OLEPROP-BASEIDS" ) );
395 
396     // property ID/position map
397     typedef ::std::map< sal_Int32, sal_uInt32 > PropertyPosMap;
398     PropertyPosMap aPropMap;
399 
400     // dump section header line
401     writeSectionHeader( rGuid, nStartPos );
402 
403     // seek to section
404     IndentGuard aIndGuard( mxOut );
405     if( startElement( nStartPos ) )
406     {
407         // dump section header
408         dumpDec< sal_Int32 >( "size" );
409         sal_Int32 nPropCount = dumpDec< sal_Int32 >( "property-count" );
410 
411         // dump table of property positions
412         {
413             TableGuard aTabGuard( mxOut, 15, 25 );
414             mxOut->resetItemIndex();
415             for( sal_Int32 nPropIdx = 0; !mxStrm->isEof() && (nPropIdx < nPropCount); ++nPropIdx )
416             {
417                 MultiItemsGuard aMultiGuard( mxOut );
418                 writeEmptyItem( "#property" );
419                 sal_Int32 nPropId = dumpDec< sal_Int32 >( "id", mxPropIds );
420                 sal_uInt32 nPropPos = nStartPos + dumpHex< sal_uInt32 >( "start-pos", "CONV-DEC" );
421                 aPropMap[ nPropId ] = nPropPos;
422             }
423         }
424     }
425     mxOut->emptyLine();
426 
427     // code page property
428     meTextEnc = RTL_TEXTENCODING_MS_1252;
429     mbIsUnicode = false;
430     PropertyPosMap::iterator aCodePageIt = aPropMap.find( OLEPROP_ID_CODEPAGE );
431     if( aCodePageIt != aPropMap.end() )
432     {
433         dumpCodePageProperty( aCodePageIt->second );
434         aPropMap.erase( aCodePageIt );
435     }
436 
437     // dictionary property
438     PropertyPosMap::iterator aDictIt = aPropMap.find( OLEPROP_ID_DICTIONARY );
439     if( aDictIt != aPropMap.end() )
440     {
441         dumpDictionaryProperty( aDictIt->second );
442         aPropMap.erase( aDictIt );
443     }
444 
445     // other properties
446     for( PropertyPosMap::const_iterator aIt = aPropMap.begin(), aEnd = aPropMap.end(); aIt != aEnd; ++aIt )
447         dumpProperty( aIt->first, aIt->second );
448 
449     // remove the user defined list of property ID names
450     cfg().eraseNameList( "OLEPROP-IDS" );
451 }
452 
453 void OlePropertyStreamObject::dumpProperty( sal_Int32 nPropId, sal_uInt32 nStartPos )
454 {
455     writePropertyHeader( nPropId, nStartPos );
456     IndentGuard aIndGuard( mxOut );
457     if( startElement( nStartPos ) )
458         dumpPropertyContents( nPropId );
459     mxOut->emptyLine();
460 }
461 
462 void OlePropertyStreamObject::dumpCodePageProperty( sal_uInt32 nStartPos )
463 {
464     writePropertyHeader( OLEPROP_ID_CODEPAGE, nStartPos );
465     IndentGuard aIndGuard( mxOut );
466     if( startElement( nStartPos ) )
467     {
468         sal_uInt16 nType = dumpPropertyType();
469         if( nType == OLEPROP_TYPE_INT16 )
470         {
471             sal_uInt16 nCodePage = dumpDec< sal_uInt16 >( "codepage", "CODEPAGES" );
472             rtl_TextEncoding eNewTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage );
473             if( eNewTextEnc != RTL_TEXTENCODING_DONTKNOW )
474                 meTextEnc = eNewTextEnc;
475             mbIsUnicode = nCodePage == CODEPAGE_UNICODE;
476         }
477         else
478             dumpPropertyContents( OLEPROP_ID_CODEPAGE );
479     }
480     mxOut->emptyLine();
481 }
482 
483 void OlePropertyStreamObject::dumpDictionaryProperty( sal_uInt32 nStartPos )
484 {
485     writePropertyHeader( OLEPROP_ID_DICTIONARY, nStartPos );
486     IndentGuard aIndGuard( mxOut );
487     if( startElement( nStartPos ) )
488     {
489         sal_Int32 nCount = dumpDec< sal_Int32 >( "count" );
490         for( sal_Int32 nIdx = 0; !mxStrm->isEof() && (nIdx < nCount); ++nIdx )
491         {
492             MultiItemsGuard aMultiGuard( mxOut );
493             TableGuard aTabGuard( mxOut, 10, 20 );
494             sal_Int32 nId = dumpDec< sal_Int32 >( "id" );
495             OUString aName = dumpString8( "name" );
496             if( mxPropIds.get() )
497                 mxPropIds->setName( nId, aName );
498         }
499     }
500     mxOut->emptyLine();
501 }
502 
503 sal_uInt16 OlePropertyStreamObject::dumpPropertyContents( sal_Int32 nPropId )
504 {
505     sal_uInt16 nType = dumpPropertyType();
506     sal_uInt16 nBaseType = static_cast< sal_uInt16 >( nType & 0x0FFF );
507     sal_uInt16 nArrayType = static_cast< sal_uInt16 >( nType & 0xF000 );
508     switch( nArrayType )
509     {
510         case OLEPROP_TYPE_SIMPLE:   dumpPropertyValue( nPropId, nBaseType );    break;
511         case OLEPROP_TYPE_VECTOR:   dumpPropertyVector( nPropId, nBaseType );   break;
512         case OLEPROP_TYPE_ARRAY:    dumpPropertyArray( nPropId, nBaseType );    break;
513     }
514     return nType;
515 }
516 
517 void OlePropertyStreamObject::dumpPropertyValue( sal_Int32 nPropId, sal_uInt16 nBaseType )
518 {
519     switch( nBaseType )
520     {
521         case OLEPROP_TYPE_INT16:        dumpDec< sal_Int16 >( "value" );        break;
522         case OLEPROP_TYPE_INT32:        dumpDec< sal_Int32 >( "value" );        break;
523         case OLEPROP_TYPE_FLOAT:        dumpDec< float >( "value" );            break;
524         case OLEPROP_TYPE_DOUBLE:       dumpDec< double >( "value" );           break;
525         case OLEPROP_TYPE_DATE:         dumpDec< double >( "date" );            break;
526         case OLEPROP_TYPE_STRING:       dumpString8( "value" );                 break;
527         case OLEPROP_TYPE_STATUS:       dumpHex< sal_Int32 >( "status" );       break;
528         case OLEPROP_TYPE_BOOL:         dumpBool< sal_Int16 >( "value" );       break;
529         case OLEPROP_TYPE_VARIANT:      dumpPropertyContents( nPropId );        break;
530         case OLEPROP_TYPE_INT8:         dumpDec< sal_Int8 >( "value" );         break;
531         case OLEPROP_TYPE_UINT8:        dumpDec< sal_uInt8 >( "value" );        break;
532         case OLEPROP_TYPE_UINT16:       dumpDec< sal_uInt16 >( "value" );       break;
533         case OLEPROP_TYPE_UINT32:       dumpDec< sal_uInt32 >( "value" );       break;
534         case OLEPROP_TYPE_INT64:        dumpDec< sal_Int64 >( "value" );        break;
535         case OLEPROP_TYPE_UINT64:       dumpDec< sal_uInt64 >( "value" );       break;
536         case OLEPROP_TYPE_STRING8:      dumpString8( "value" );                 break;
537         case OLEPROP_TYPE_STRING16:     dumpString16( "value" );                break;
538         case OLEPROP_TYPE_FILETIME:     dumpFileTime( "file-time" );            break;
539         case OLEPROP_TYPE_BLOB:         dumpBlob( nPropId, "data" );            break;
540         case OLEPROP_TYPE_STREAM:       dumpString8( "stream-name" );           break;
541         case OLEPROP_TYPE_STORAGE:      dumpString8( "storage-name" );          break;
542         case OLEPROP_TYPE_CLIPFMT:      dumpBlob( nPropId, "clip-data" );       break;
543     }
544 }
545 
546 void OlePropertyStreamObject::dumpPropertyVector( sal_Int32 nPropId, sal_uInt16 nBaseType )
547 {
548     sal_Int32 nElemCount = dumpDec< sal_Int32 >( "element-count" );
549     for( sal_Int32 nElemIdx = 0; !mxStrm->isEof() && (nElemIdx < nElemCount); ++nElemIdx )
550     {
551         mxOut->resetItemIndex( nElemIdx );
552         writeEmptyItem( "#element" );
553         IndentGuard aIndGuard( mxOut );
554         dumpPropertyValue( nPropId, nBaseType );
555     }
556 }
557 
558 void OlePropertyStreamObject::dumpPropertyArray( sal_Int32 /*nPropId*/, sal_uInt16 /*nBaseType*/ )
559 {
560     // TODO
561 }
562 
563 sal_uInt16 OlePropertyStreamObject::dumpPropertyType()
564 {
565     return static_cast< sal_uInt16 >( dumpHex< sal_Int32 >( "type", "OLEPROP-TYPE" ) & 0xFFFF );
566 }
567 
568 void OlePropertyStreamObject::dumpBlob( sal_Int32 nPropId, const String& rName )
569 {
570     sal_Int32 nSize = dumpDec< sal_Int32 >( "data-size" );
571     if( nSize > 0 )
572     {
573         OUString aPropName = mxPropIds->getName( cfg(), nPropId );
574         if( aPropName == CREATE_OUSTRING( "'_PID_HLINKS'" ) )
575             dumpHlinks( nSize );
576         else
577             dumpBinary( rName, nSize );
578     }
579 }
580 
581 OUString OlePropertyStreamObject::dumpString8( const String& rName )
582 {
583     sal_Int32 nLen = dumpDec< sal_Int32 >( "string-len" );
584     return mbIsUnicode ? dumpCharArray16( rName, nLen ) : dumpCharArray8( rName, nLen );
585 }
586 
587 OUString OlePropertyStreamObject::dumpCharArray8( const String& rName, sal_Int32 nLen )
588 {
589     sal_Int32 nNewLen = getLimitedValue< sal_Int32, sal_Int32 >( nLen, 0, 1024 );
590     OUString aData = mxStrm->readCharArrayUC( nNewLen, meTextEnc );
591     writeStringItem( rName, aData );
592     return aData;
593 }
594 
595 OUString OlePropertyStreamObject::dumpString16( const String& rName )
596 {
597     sal_Int32 nLen = dumpDec< sal_Int32 >( "string-len" );
598     return dumpCharArray16( rName, nLen );
599 }
600 
601 OUString OlePropertyStreamObject::dumpCharArray16( const String& rName, sal_Int32 nLen )
602 {
603     sal_Int32 nNewLen = getLimitedValue< sal_Int32, sal_Int32 >( nLen, 0, 1024 );
604     OUString aData = mxStrm->readUnicodeArray( nNewLen );
605     writeStringItem( rName, aData );
606     if( nNewLen & 1 ) dumpUnused( 2 ); // always padding to 32bit
607     return aData;
608 }
609 
610 bool OlePropertyStreamObject::dumpTypedProperty( const String& rName, sal_uInt16 nExpectedType )
611 {
612     writeEmptyItem( rName );
613     IndentGuard aIndGuard( mxOut );
614     return (dumpPropertyContents( -1 ) == nExpectedType) && !mxStrm->isEof();
615 }
616 
617 void OlePropertyStreamObject::dumpHlinks( sal_Int32 nSize )
618 {
619     sal_Int64 nEndPos = mxStrm->tell() + nSize;
620     sal_Int32 nCount = dumpDec< sal_Int32 >( "property-count" );
621     bool bValid = true;
622     for( sal_Int32 nHlinkIndex = 0, nHlinkCount = nCount / 6; bValid && !mxStrm->isEof() && (nHlinkIndex < nHlinkCount); ++nHlinkIndex )
623     {
624         writeEmptyItem( "HYPERLINK" );
625         IndentGuard aIndGuard( mxOut );
626         bValid =
627             dumpTypedProperty( "hash", OLEPROP_TYPE_INT32 ) &&
628             dumpTypedProperty( "app", OLEPROP_TYPE_INT32 ) &&
629             dumpTypedProperty( "shape-id", OLEPROP_TYPE_INT32 ) &&
630             dumpTypedProperty( "info", OLEPROP_TYPE_INT32 ) &&
631             dumpTypedProperty( "target", OLEPROP_TYPE_STRING16 ) &&
632             dumpTypedProperty( "location", OLEPROP_TYPE_STRING16 );
633     }
634     dumpRemainingTo( nEndPos );
635 }
636 
637 bool OlePropertyStreamObject::startElement( sal_uInt32 nStartPos )
638 {
639     mxStrm->seek( nStartPos );
640     if( mxStrm->isEof() )
641         writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM );
642     return !mxStrm->isEof();
643 }
644 
645 void OlePropertyStreamObject::writeSectionHeader( const OUString& rGuid, sal_uInt32 nStartPos )
646 {
647     MultiItemsGuard aMultiGuard( mxOut );
648     writeEmptyItem( "SECTION" );
649     writeHexItem( "pos", nStartPos, "CONV-DEC" );
650     writeGuidItem( "guid", rGuid );
651 }
652 
653 void OlePropertyStreamObject::writePropertyHeader( sal_Int32 nPropId, sal_uInt32 nStartPos )
654 {
655     MultiItemsGuard aMultiGuard( mxOut );
656     writeEmptyItem( "PROPERTY" );
657     writeHexItem( "pos", nStartPos, "CONV-DEC" );
658     writeDecItem( "id", nPropId, mxPropIds );
659 }
660 
661 // ============================================================================
662 
663 OleStorageObject::OleStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath )
664 {
665     construct( rParent, rxStrg, rSysPath );
666 }
667 
668 void OleStorageObject::construct( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath )
669 {
670     StorageObjectBase::construct( rParent, rxStrg, rSysPath );
671 }
672 
673 void OleStorageObject::construct( const ObjectBase& rParent )
674 {
675     StorageObjectBase::construct( rParent );
676 }
677 
678 void OleStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& /*rStrgPath*/, const OUString& rStrmName, const OUString& rSysFileName )
679 {
680     if( rStrmName.equalsAscii( "\001CompObj" ) )
681         OleCompObjObject( *this, rxStrm, rSysFileName ).dump();
682     else if( rStrmName.equalsAscii( "\005SummaryInformation" ) || rStrmName.equalsAscii( "\005DocumentSummaryInformation" ) )
683         OlePropertyStreamObject( *this, rxStrm, rSysFileName ).dump();
684     else
685         BinaryStreamObject( *this, rxStrm, rSysFileName ).dump();
686 }
687 
688 // ============================================================================
689 // ============================================================================
690 
691 ComCtlObjectBase::ComCtlObjectBase( const InputObjectBase& rParent,
692         sal_uInt32 nDataId5, sal_uInt32 nDataId6, sal_uInt16 nVersion, bool bCommonPart, bool bComplexPart ) :
693     mnDataId5( nDataId5 ),
694     mnDataId6( nDataId6 ),
695     mnVersion( nVersion ),
696     mbCommonPart( bCommonPart ),
697     mbComplexPart( bComplexPart )
698 {
699     construct( rParent );
700 }
701 
702 void ComCtlObjectBase::implDump()
703 {
704     sal_uInt32 nCommonSize = 0;
705     dumpComCtlSize() && dumpComCtlData( nCommonSize ) && (!mbCommonPart || dumpComCtlCommon( nCommonSize )) && (!mbComplexPart || dumpComCtlComplex());
706 }
707 
708 void ComCtlObjectBase::implDumpCommonExtra( sal_Int64 /*nEndPos*/ )
709 {
710 }
711 
712 void ComCtlObjectBase::implDumpCommonTrailing()
713 {
714 }
715 
716 bool ComCtlObjectBase::dumpComCtlHeader( sal_uInt32 nExpId, sal_uInt16 nExpMajor, sal_uInt16 nExpMinor )
717 {
718     // no idea if all this is correct...
719     sal_uInt32 nId = dumpHex< sal_uInt32 >( "header-id", "COMCTL-HEADER-IDS" );
720     ItemGuard aItem( mxOut, "version" );
721     sal_uInt16 nMinor, nMajor;
722     *mxStrm >> nMinor >> nMajor;
723     mxOut->writeDec( nMajor );
724     mxOut->writeChar( '.' );
725     mxOut->writeDec( nMinor );
726     return !mxStrm->isEof() && (nId == nExpId) && ((nExpMajor == SAL_MAX_UINT16) || (nExpMajor == nMajor)) && ((nExpMinor == SAL_MAX_UINT16) || (nExpMinor == nMinor));
727 }
728 
729 bool ComCtlObjectBase::dumpComCtlSize()
730 {
731     if( dumpComCtlHeader( 0x12344321, 0, 8 ) )
732     {
733         IndentGuard aIndGuard( mxOut );
734         dumpDec< sal_Int32 >( "width", "CONV-HMM-TO-CM" );
735         dumpDec< sal_Int32 >( "height", "CONV-HMM-TO-CM" );
736         return !mxStrm->isEof();
737     }
738     return false;
739 }
740 
741 bool ComCtlObjectBase::dumpComCtlData( sal_uInt32& ornCommonPartSize )
742 {
743     if( dumpComCtlHeader( (mnVersion == 5) ? mnDataId5 : mnDataId6, mnVersion ) )
744     {
745         IndentGuard aIndGuard( mxOut );
746         if( mbCommonPart )
747             ornCommonPartSize = dumpDec< sal_uInt32 >( "common-part-size" );
748         implDumpProperties();
749         return !mxStrm->isEof();
750     }
751     return false;
752 }
753 
754 bool ComCtlObjectBase::dumpComCtlCommon( sal_uInt32 nPartSize )
755 {
756     sal_Int64 nEndPos = mxStrm->tell() + nPartSize;
757     if( (nPartSize >= 16) && dumpComCtlHeader( 0xABCDEF01, 5, 0 ) )
758     {
759         IndentGuard aIndGuard( mxOut );
760         dumpUnknown( 4 );
761         dumpHex< sal_uInt32 >( "common-flags", "COMCTL-COMMON-FLAGS" );
762         implDumpCommonExtra( nEndPos );
763         dumpRemainingTo( nEndPos );
764         implDumpCommonTrailing();
765         return !mxStrm->isEof();
766     }
767     return false;
768 }
769 
770 bool ComCtlObjectBase::dumpComCtlComplex()
771 {
772     if( dumpComCtlHeader( 0xBDECDE1F, 5, 1 ) )
773     {
774         IndentGuard aIndGuard( mxOut );
775         sal_uInt32 nFlags = dumpHex< sal_uInt32 >( "comctl-complex-flags", "COMCTL-COMPLEX-FLAGS" );
776         if( !mxStrm->isEof() && (nFlags & 0x01) )
777         {
778             writeEmptyItem( "font" );
779             IndentGuard aIndGuard2( mxOut );
780             OUString aClassName = cfg().getStringOption( dumpGuid(), OUString() );
781             if( aClassName.equalsAscii( "StdFont" ) )
782                 StdFontObject( *this ).dump();
783         }
784         if( !mxStrm->isEof() && (nFlags & 0x02) )
785         {
786             writeEmptyItem( "mouse-icon" );
787             IndentGuard aIndGuard2( mxOut );
788             OUString aClassName = cfg().getStringOption( dumpGuid(), OUString() );
789             if( aClassName.equalsAscii( "StdPic" ) )
790                 StdPicObject( *this ).dump();
791         }
792         return !mxStrm->isEof();
793     }
794     return false;
795 }
796 
797 // ============================================================================
798 
799 ComCtlScrollBarObject::ComCtlScrollBarObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
800     ComCtlObjectBase( rParent, SAL_MAX_UINT32, 0x99470A83, nVersion, true, true )
801 {
802 }
803 
804 void ComCtlScrollBarObject::implDumpProperties()
805 {
806     dumpHex< sal_uInt32 >( "flags", "COMCTL-SCROLLBAR-FLAGS" );
807     dumpDec< sal_Int32 >( "large-change" );
808     dumpDec< sal_Int32 >( "small-change" );
809     dumpDec< sal_Int32 >( "min" );
810     dumpDec< sal_Int32 >( "max" );
811     dumpDec< sal_Int32 >( "value" );
812 }
813 
814 // ============================================================================
815 
816 ComCtlProgressBarObject::ComCtlProgressBarObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
817     ComCtlObjectBase( rParent, 0xE6E17E84, 0x97AB8A01, nVersion, true, true )
818 {
819 }
820 
821 void ComCtlProgressBarObject::implDumpProperties()
822 {
823     dumpDec< float >( "min" );
824     dumpDec< float >( "max" );
825     if( mnVersion == 6 )
826     {
827         dumpBool< sal_uInt16 >( "vertical" );
828         dumpBool< sal_uInt16 >( "smooth-scroll" );
829     }
830 }
831 
832 // ============================================================================
833 
834 ComCtlSliderObject::ComCtlSliderObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
835     ComCtlObjectBase( rParent, 0xE6E17E86, 0x0A2BAE11, nVersion, true, true )
836 {
837 }
838 
839 void ComCtlSliderObject::implDumpProperties()
840 {
841     dumpBool< sal_Int32 >( "vertical" );
842     dumpDec< sal_Int32 >( "large-change" );
843     dumpDec< sal_Int32 >( "small-change" );
844     dumpDec< sal_Int32 >( "min" );
845     dumpDec< sal_Int32 >( "max" );
846     dumpDec< sal_Int16 >( "select-range", "COMCTL-SLIDER-SELECTRANGE" );
847     dumpUnused( 2 );
848     dumpDec< sal_Int32 >( "select-start" );
849     dumpDec< sal_Int32 >( "select-length" );
850     dumpDec< sal_Int32 >( "tick-style", "COMCTL-SLIDER-TICKSTYLE" );
851     dumpDec< sal_Int32 >( "tick-frequency" );
852     dumpDec< sal_Int32 >( "value" );
853     if( mnVersion == 6 )
854         dumpBool< sal_Int32 >( "tooltip-below" );
855 }
856 
857 // ============================================================================
858 
859 ComCtlUpDownObject::ComCtlUpDownObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
860     ComCtlObjectBase( rParent, 0xFF3626A0, 0xFF3626A0, nVersion, false, false )
861 {
862 }
863 
864 void ComCtlUpDownObject::implDumpProperties()
865 {
866     dumpUnknown( 16 ); // buddy-property, somehow
867     dumpDec< sal_Int32 >( "buddy-control" );
868     dumpUnknown( 8 );
869     dumpDec< sal_Int32 >( "value" );
870     dumpUnknown( 4 );
871     dumpDec< sal_Int32 >( "increment" );
872     dumpDec< sal_Int32 >( "max" );
873     dumpDec< sal_Int32 >( "min" );
874     dumpHex< sal_uInt32 >( "flags-1", "COMCTL-UPDOWN-FLAGS1" );
875     dumpHex< sal_uInt32 >( "flags-2", "COMCTL-UPDOWN-FLAGS2" );
876     dumpUnknown( 4 );
877 }
878 
879 // ============================================================================
880 
881 ComCtlImageListObject::ComCtlImageListObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
882     ComCtlObjectBase( rParent, 0xE6E17E80, 0xE6E17E80, nVersion, true, false )
883 {
884 }
885 
886 void ComCtlImageListObject::implDumpProperties()
887 {
888     dumpDec< sal_uInt16 >( "image-width" );
889     dumpDec< sal_uInt16 >( "image-height" );
890     dumpOleColor( "mask-color" );
891     dumpBool< sal_Int16 >( "use-mask-color" );
892     dumpUnknown( 2 );
893 }
894 
895 void ComCtlImageListObject::implDumpCommonExtra( sal_Int64 /*nEndPos*/ )
896 {
897     dumpUnknown( 4 );
898     dumpOleColor( "back-color" );
899     dumpUnknown( 4 );
900     sal_Int32 nImageCount = dumpDec< sal_Int32 >( "image-count" );
901     mxOut->resetItemIndex();
902     for( sal_Int32 nImageIndex = 0; (nImageIndex < nImageCount) && !mxStrm->isEof(); ++nImageIndex )
903     {
904         writeEmptyItem( "#image" );
905         IndentGuard aIndGuard( mxOut );
906         sal_uInt8 nFlags = dumpHex< sal_uInt8 >( "text-flags", "COMCTL-IMAGELIST-TEXTFLAGS" );
907         if( nFlags & 0x01 ) dumpUniString32( "caption" );
908         if( nFlags & 0x02 ) dumpUniString32( "key" );
909     }
910 }
911 
912 void ComCtlImageListObject::implDumpCommonTrailing()
913 {
914     sal_Int32 nImageCount = dumpDec< sal_Int32 >( "image-count" );
915     mxOut->resetItemIndex();
916     for( sal_Int32 nImageIndex = 0; (nImageIndex < nImageCount) && !mxStrm->isEof(); ++nImageIndex )
917     {
918         writeEmptyItem( "#image" );
919         IndentGuard aIndGuard( mxOut );
920         dumpDec< sal_Int32 >( "index" );
921         StdPicObject( *this ).dump();
922     }
923 }
924 
925 // ============================================================================
926 
927 ComCtlTabStripObject::ComCtlTabStripObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
928     ComCtlObjectBase( rParent, 0xE6E17E8A, 0xD12A7AC1, nVersion, true, true )
929 {
930 }
931 
932 void ComCtlTabStripObject::implDumpProperties()
933 {
934     dumpHex< sal_uInt32 >( "flags-1", "COMCTL-TABSTRIP-FLAGS1" );
935     dumpDec< sal_uInt16 >( "tab-fixed-width", "CONV-HMM-TO-CM" );
936     dumpDec< sal_uInt16 >( "tab-fixed-height", "CONV-HMM-TO-CM" );
937     if( mnVersion == 6 )
938     {
939         dumpHex< sal_uInt32 >( "flags-2", "COMCTL-TABSTRIP-FLAGS2" );
940         dumpDec< sal_uInt16 >( "tab-min-width", "CONV-HMM-TO-CM" );
941         dumpUnknown( 2 );
942         dumpHex< sal_uInt32 >( "flags-3", "COMCTL-TABSTRIP-FLAGS3" );
943     }
944 }
945 
946 void ComCtlTabStripObject::implDumpCommonExtra( sal_Int64 /*nEndPos*/ )
947 {
948     dumpUnknown( 12 );
949     dumpUniString32( "image-list" );
950     sal_Int32 nTabCount = dumpDec< sal_Int32 >( "tab-count" );
951     mxOut->resetItemIndex();
952     for( sal_Int32 nTabIndex = 0; (nTabIndex < nTabCount) && !mxStrm->isEof(); ++nTabIndex )
953     {
954         writeEmptyItem( "#tab" );
955         IndentGuard aIndGuard( mxOut );
956         dumpUnknown( 4 );
957         sal_uInt32 nTabFlags = dumpHex< sal_uInt32 >( "tab-flags", "COMCTL-TABSTRIP-TABFLAGS" );
958         if( nTabFlags & 0x01 ) dumpUniString32( "caption" );
959         if( nTabFlags & 0x02 ) dumpUniString32( "key" );
960         if( nTabFlags & 0x04 ) dumpUniString32( "tag" );
961         if( nTabFlags & 0x08 ) dumpUniString32( "tooltip" );
962         dumpDec< sal_uInt16 >( "image-id" );
963     }
964 }
965 
966 // ============================================================================
967 
968 ComCtlTreeViewObject::ComCtlTreeViewObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
969     ComCtlObjectBase( rParent, 0xE6E17E8E, 0x6AC13CB1, nVersion, true, true ),
970     mnStringFlags( 0 )
971 {
972 }
973 
974 void ComCtlTreeViewObject::implDumpProperties()
975 {
976     dumpHex< sal_uInt32 >( "flags", "COMCTL-TREEVIEW-FLAGS" );
977     dumpDec< sal_Int32 >( "indentation", "CONV-HMM-TO-CM" );
978     if( mnVersion == 6 )
979         dumpHex< sal_uInt32 >( "flags-2", "COMCTL-TREEVIEW-FLAGS2" );
980     mnStringFlags = dumpHex< sal_uInt32 >( "string-flags", "COMCTL-TREEVIEW-STRINGFLAGS" );
981 }
982 
983 void ComCtlTreeViewObject::implDumpCommonExtra( sal_Int64 /*nEndPos*/ )
984 {
985     dumpOleColor( "text-color" );
986     dumpOleColor( "back-color" );
987     dumpUnknown( 4 );
988     if( mnStringFlags & 0x02 )
989         dumpUniString32( "image-list" );
990     dumpUniString32( "path-separator" );
991 }
992 
993 // ============================================================================
994 
995 ComCtlStatusBarObject::ComCtlStatusBarObject( const InputObjectBase& rParent, sal_uInt16 nVersion ) :
996     ComCtlObjectBase( rParent, 0xE6E17E88, SAL_MAX_UINT32, nVersion, true, true )
997 {
998 }
999 
1000 void ComCtlStatusBarObject::implDumpProperties()
1001 {
1002     dumpBool< sal_Int32 >( "style-simple-text" );
1003     dumpBool< sal_Int16 >( "show-tips" );
1004     dumpUnknown( 2 );
1005 }
1006 
1007 void ComCtlStatusBarObject::implDumpCommonExtra( sal_Int64 /*nEndPos*/ )
1008 {
1009     dumpUnknown( 12 );
1010     dumpUniString32( "simple-text" );
1011     sal_Int32 nPanelCount = dumpDec< sal_Int32 >( "panel-count" );
1012     mxOut->resetItemIndex();
1013     for( sal_Int32 nPanelIndex = 0; (nPanelIndex < nPanelCount) && !mxStrm->isEof(); ++nPanelIndex )
1014     {
1015         writeEmptyItem( "#panel" );
1016         IndentGuard aIndGuard( mxOut );
1017         dumpHex< sal_uInt32 >( "panel-flags", "COMCTL-STATUSBAR-PANELFLAGS" );
1018         dumpDec< sal_Int32 >( "current-width", "CONV-HMM-TO-CM" );
1019         dumpDec< sal_Int32 >( "minimal-width", "CONV-HMM-TO-CM" );
1020         sal_uInt32 nTextFlags = dumpHex< sal_uInt32 >( "text-flags", "COMCTL-STATUSBAR-TEXTFLAGS" );
1021         if( nTextFlags & 0x01 ) dumpUniString32( "text" );
1022         if( nTextFlags & 0x02 ) dumpUniString32( "vis-text" );
1023         if( nTextFlags & 0x04 ) dumpUniString32( "key" );
1024         if( nTextFlags & 0x08 ) dumpUniString32( "tag" );
1025         if( nTextFlags & 0x10 ) dumpUniString32( "tooltip" );
1026     }
1027 }
1028 
1029 void ComCtlStatusBarObject::implDumpCommonTrailing()
1030 {
1031     sal_Int32 nImageCount = dumpDec< sal_Int32 >( "image-count" );
1032     mxOut->resetItemIndex();
1033     for( sal_Int32 nImageIndex = 0; (nImageIndex < nImageCount) && !mxStrm->isEof(); ++nImageIndex )
1034     {
1035         writeEmptyItem( "#image" );
1036         IndentGuard aIndGuard( mxOut );
1037         dumpDec< sal_Int32 >( "panel-index" );
1038         StdPicObject( *this ).dump();
1039     }
1040 }
1041 
1042 // ============================================================================
1043 // ============================================================================
1044 
1045 void AxPropertyObjectBase::construct( const ObjectBase& rParent,
1046         const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, const String& rPropNameList, bool b64BitPropFlags )
1047 {
1048     OleInputObjectBase::construct( rParent, rxStrm, rSysFileName );
1049     constructAxPropObj( rPropNameList, b64BitPropFlags );
1050 }
1051 
1052 void AxPropertyObjectBase::construct( const OutputObjectBase& rParent,
1053         const BinaryInputStreamRef& rxStrm, const String& rPropNameList, bool b64BitPropFlags )
1054 {
1055     OleInputObjectBase::construct( rParent, rxStrm );
1056     constructAxPropObj( rPropNameList, b64BitPropFlags );
1057 }
1058 
1059 void AxPropertyObjectBase::construct( const InputObjectBase& rParent,
1060         const String& rPropNameList, bool b64BitPropFlags )
1061 {
1062     OleInputObjectBase::construct( rParent );
1063     constructAxPropObj( rPropNameList, b64BitPropFlags );
1064 }
1065 
1066 bool AxPropertyObjectBase::implIsValid() const
1067 {
1068     return OleInputObjectBase::implIsValid() && mxStrm->isSeekable();
1069 }
1070 
1071 void AxPropertyObjectBase::implDump()
1072 {
1073     mbValid = true;
1074     // header
1075     setAlignAnchor();
1076     dumpVersion();
1077     sal_uInt16 nSize = dumpDec< sal_uInt16 >( "size" );
1078     mnPropertiesEnd = mxStrm->tell() + nSize;
1079     // property flags
1080     maLargeProps.clear();
1081     maStreamProps.clear();
1082     mnPropFlags = dumpHex< sal_Int64, sal_uInt32 >( mb64BitPropFlags, "properties", mxPropNames );
1083     mnCurrProp = 0;
1084     // properties
1085     dumpShortProperties();
1086     dumpLargeProperties();
1087     setAlignAnchor();
1088     if( ensureValid() )
1089         implDumpExtended();
1090 }
1091 
1092 void AxPropertyObjectBase::implDumpShortProperties()
1093 {
1094 }
1095 
1096 void AxPropertyObjectBase::implDumpExtended()
1097 {
1098 }
1099 
1100 bool AxPropertyObjectBase::ensureValid( bool bCondition )
1101 {
1102     if( mbValid && (!bCondition || mxStrm->isEof()) )
1103     {
1104         if( !bCondition )
1105             writeInfoItem( "state", OOX_DUMP_ERRASCII( "format-error" ) );
1106         mbValid = false;
1107     }
1108     return mbValid;
1109 }
1110 
1111 void AxPropertyObjectBase::setAlignAnchor()
1112 {
1113     mnPropertiesStart = mxStrm->tell();
1114 }
1115 
1116 bool AxPropertyObjectBase::startNextProperty()
1117 {
1118     if( mnCurrProp == 0 ) mnCurrProp = 1; else mnCurrProp <<= 1;
1119     bool bHasProp = getFlag( mnPropFlags, mnCurrProp );
1120     setFlag( mnPropFlags, mnCurrProp, false );
1121     return ensureValid() && bHasProp;
1122 }
1123 
1124 OUString AxPropertyObjectBase::getPropertyName() const
1125 {
1126     return cfg().getName( mxPropNames, mnCurrProp );
1127 }
1128 
1129 sal_uInt32 AxPropertyObjectBase::dumpFlagsProperty( sal_uInt32 nDefault, const sal_Char* pcNameList )
1130 {
1131     if( startNextProperty() )
1132     {
1133         alignInput< sal_uInt32 >();
1134         return dumpHex< sal_uInt32 >( getPropertyName(), pcNameList );
1135     }
1136     return nDefault;
1137 }
1138 
1139 sal_uInt32 AxPropertyObjectBase::dumpColorProperty( sal_uInt32 nDefault )
1140 {
1141     if( startNextProperty() )
1142     {
1143         alignInput< sal_uInt32 >();
1144         return dumpOleColor( getPropertyName() );
1145     }
1146     return nDefault;
1147 }
1148 
1149 sal_Unicode AxPropertyObjectBase::dumpUnicodeProperty()
1150 {
1151     if( startNextProperty() )
1152     {
1153         alignInput< sal_uInt16 >();
1154         return dumpUnicode( getPropertyName() );
1155     }
1156     return '\0';
1157 }
1158 
1159 void AxPropertyObjectBase::dumpUnknownProperty()
1160 {
1161     if( startNextProperty() )
1162         ensureValid( false );
1163 }
1164 
1165 void AxPropertyObjectBase::dumpPosProperty()
1166 {
1167     if( startNextProperty() )
1168         maLargeProps.push_back( LargeProperty( LargeProperty::PROPTYPE_POS, getPropertyName(), 8 ) );
1169 }
1170 
1171 void AxPropertyObjectBase::dumpSizeProperty()
1172 {
1173     if( startNextProperty() )
1174         maLargeProps.push_back( LargeProperty( LargeProperty::PROPTYPE_SIZE, getPropertyName(), 8 ) );
1175 }
1176 
1177 void AxPropertyObjectBase::dumpGuidProperty( OUString* pValue )
1178 {
1179     if( startNextProperty() )
1180         maLargeProps.push_back( LargeProperty( LargeProperty::PROPTYPE_GUID, getPropertyName(), 16, pValue ) );
1181 }
1182 
1183 void AxPropertyObjectBase::dumpStringProperty( OUString* pValue )
1184 {
1185     if( startNextProperty() )
1186     {
1187         alignInput< sal_uInt32 >();
1188         sal_uInt32 nLen = dumpHex< sal_uInt32 >( getPropertyName(), "AX-STRINGLEN" );
1189         maLargeProps.push_back( LargeProperty( LargeProperty::PROPTYPE_STRING, getPropertyName(), nLen, pValue ) );
1190     }
1191 }
1192 
1193 void AxPropertyObjectBase::dumpStringArrayProperty()
1194 {
1195     if( startNextProperty() )
1196     {
1197         alignInput< sal_uInt32 >();
1198         sal_uInt32 nLen = dumpHex< sal_uInt32 >( getPropertyName(), "CONV-DEC" );
1199         maLargeProps.push_back( LargeProperty( LargeProperty::PROPTYPE_STRINGARRAY, getPropertyName(), nLen ) );
1200     }
1201 }
1202 
1203 void AxPropertyObjectBase::dumpStreamProperty()
1204 {
1205     if( startNextProperty() )
1206     {
1207         alignInput< sal_uInt16 >();
1208         sal_uInt16 nData = dumpHex< sal_uInt16 >( getPropertyName() );
1209         maStreamProps.push_back( StreamProperty( getPropertyName(), nData ) );
1210     }
1211 }
1212 
1213 void AxPropertyObjectBase::dumpEmbeddedFont()
1214 {
1215     if( ensureValid() )
1216     {
1217         writeEmptyItem( "embedded-fontdata" );
1218         IndentGuard aIndGuard( mxOut );
1219         AxCFontNewObject( *this ).dump();
1220     }
1221 }
1222 
1223 void AxPropertyObjectBase::dumpToPosition( sal_Int64 nPos )
1224 {
1225     dumpRemainingTo( nPos );
1226     mbValid = true;
1227     ensureValid();
1228 }
1229 
1230 void AxPropertyObjectBase::constructAxPropObj( const String& rPropNameList, bool b64BitPropFlags )
1231 {
1232     if( OleInputObjectBase::implIsValid() )
1233     {
1234         mxPropNames = cfg().getNameList( rPropNameList );
1235         mb64BitPropFlags = b64BitPropFlags;
1236         mbValid = true;
1237     }
1238 }
1239 
1240 void AxPropertyObjectBase::dumpVersion()
1241 {
1242     ItemGuard aItem( mxOut, "version" );
1243     sal_uInt8 nMinor, nMajor;
1244     *mxStrm >> nMinor >> nMajor;
1245     mxOut->writeDec( nMajor );
1246     mxOut->writeChar( '.' );
1247     mxOut->writeDec( nMinor );
1248 }
1249 
1250 OUString AxPropertyObjectBase::dumpString( const String& rName, sal_uInt32 nSize, bool bArray )
1251 {
1252     bool bCompressed = getFlag( nSize, AX_STRING_COMPRESSED );
1253     sal_uInt32 nBufSize = extractValue< sal_uInt32 >( nSize, 0, 31 );
1254     OUString aString = bCompressed ?
1255         dumpCharArray( rName, nBufSize, RTL_TEXTENCODING_ISO_8859_1 ) :
1256         dumpUnicodeArray( rName, bArray ? nBufSize : (nBufSize / 2) );
1257     alignInput< sal_Int32 >();
1258     return aString;
1259 }
1260 
1261 void AxPropertyObjectBase::dumpShortProperties()
1262 {
1263     if( ensureValid() )
1264     {
1265         writeEmptyItem( "short-properties" );
1266         IndentGuard aIndGuard( mxOut );
1267         implDumpShortProperties();
1268         alignInput< sal_uInt32 >();
1269     }
1270 }
1271 
1272 void AxPropertyObjectBase::dumpLargeProperties()
1273 {
1274     if( ensureValid( mnPropFlags == 0 ) && !maLargeProps.empty() )
1275     {
1276         writeEmptyItem( "large-properties" );
1277         IndentGuard aIndGuard( mxOut );
1278         for( LargePropertyVector::iterator aIt = maLargeProps.begin(), aEnd = maLargeProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
1279         {
1280             switch( aIt->mePropType )
1281             {
1282                 case LargeProperty::PROPTYPE_POS:
1283                 {
1284                     MultiItemsGuard aMultiGuard( mxOut );
1285                     writeEmptyItem( aIt->maItemName );
1286                     dumpDec< sal_Int32 >( "top", "CONV-HMM-TO-CM" );
1287                     dumpDec< sal_Int32 >( "left", "CONV-HMM-TO-CM" );
1288                 }
1289                 break;
1290                 case LargeProperty::PROPTYPE_SIZE:
1291                 {
1292                     MultiItemsGuard aMultiGuard( mxOut );
1293                     writeEmptyItem( aIt->maItemName );
1294                     dumpDec< sal_Int32 >( "width", "CONV-HMM-TO-CM" );
1295                     dumpDec< sal_Int32 >( "height", "CONV-HMM-TO-CM" );
1296                 }
1297                 break;
1298                 case LargeProperty::PROPTYPE_GUID:
1299                 {
1300                     OUString aGuid = dumpGuid( aIt->maItemName );
1301                     if( aIt->mpItemValue )
1302                         *aIt->mpItemValue = cfg().getStringOption( aGuid, OUString() );
1303                 }
1304                 break;
1305                 case LargeProperty::PROPTYPE_STRING:
1306                 {
1307                     OUString aString = dumpString( aIt->maItemName, aIt->mnDataSize, false );
1308                     if( aIt->mpItemValue )
1309                         *aIt->mpItemValue = aString;
1310                 }
1311                 break;
1312                 case LargeProperty::PROPTYPE_STRINGARRAY:
1313                 {
1314                     writeEmptyItem( aIt->maItemName );
1315                     IndentGuard aIndGuard2( mxOut );
1316                     mxOut->resetItemIndex();
1317                     sal_Int64 nEndPos = mxStrm->tell() + aIt->mnDataSize;
1318                     while( mxStrm->tell() < nEndPos )
1319                     {
1320                         MultiItemsGuard aMultiGuard( mxOut );
1321                         sal_uInt32 nDataSize = dumpHex< sal_uInt32 >( "#flags", "AX-ARRAYSTRINGLEN" );
1322                         dumpString( "string", nDataSize, true );
1323                     }
1324                     dumpToPosition( nEndPos );
1325                 }
1326                 break;
1327             }
1328         }
1329     }
1330     dumpToPosition( mnPropertiesEnd );
1331 
1332     if( ensureValid() && !maStreamProps.empty() )
1333     {
1334         writeEmptyItem( "stream-properties" );
1335         IndentGuard aIndGuard( mxOut );
1336         for( StreamPropertyVector::iterator aIt = maStreamProps.begin(), aEnd = maStreamProps.end(); ensureValid() && (aIt != aEnd); ++aIt )
1337         {
1338             writeEmptyItem( aIt->maItemName );
1339             if( ensureValid( aIt->mnData == 0xFFFF ) )
1340             {
1341                 IndentGuard aIndGuard2( mxOut );
1342                 OUString aClassName = cfg().getStringOption( dumpGuid(), OUString() );
1343                 if( aClassName.equalsAscii( "StdFont" ) )
1344                     StdFontObject( *this ).dump();
1345                 else if( aClassName.equalsAscii( "StdPic" ) )
1346                     StdPicObject( *this ).dump();
1347                 else if( aClassName.equalsAscii( "CFontNew" ) )
1348                     AxCFontNewObject( *this ).dump();
1349                 else
1350                     ensureValid( false );
1351             }
1352         }
1353     }
1354 }
1355 
1356 // ============================================================================
1357 
1358 AxCFontNewObject::AxCFontNewObject( const InputObjectBase& rParent )
1359 {
1360     AxPropertyObjectBase::construct( rParent, "AX-CFONTNEW-PROPERTIES" );
1361 }
1362 
1363 void AxCFontNewObject::implDumpShortProperties()
1364 {
1365     dumpStringProperty();
1366     dumpFlagsProperty( 0, "AX-CFONTNEW-FLAGS" );
1367     dumpDecProperty< sal_Int32 >( 160 );
1368     dumpDecProperty< sal_Int32 >( 0 );
1369     dumpDecProperty< sal_uInt8 >( WINDOWS_CHARSET_DEFAULT, "CHARSET" );
1370     dumpDecProperty< sal_uInt8 >( 0, "FONT-PITCHFAMILY" );
1371     dumpDecProperty< sal_uInt8 >( 1, "AX-CFONTNEW-ALIGNMENT" );
1372     dumpDecProperty< sal_uInt16 >( 400, "FONT-WEIGHT" );
1373 }
1374 
1375 // ============================================================================
1376 
1377 AxColumnInfoObject::AxColumnInfoObject( const InputObjectBase& rParent )
1378 {
1379     AxPropertyObjectBase::construct( rParent, "AX-COLUMNINFO-PROPERTIES" );
1380 }
1381 
1382 void AxColumnInfoObject::implDumpShortProperties()
1383 {
1384     dumpDecProperty< sal_Int32 >( -1, "CONV-HMM-TO-CM" );
1385 }
1386 
1387 // ============================================================================
1388 
1389 AxCommandButtonObject::AxCommandButtonObject( const InputObjectBase& rParent )
1390 {
1391     AxPropertyObjectBase::construct( rParent, "AX-COMMANDBUTTON-PROPERTIES" );
1392 }
1393 
1394 void AxCommandButtonObject::implDumpShortProperties()
1395 {
1396     dumpColorProperty( 0x80000012 );
1397     dumpColorProperty( 0x80000008 );
1398     dumpFlagsProperty( 0x0000001B );
1399     dumpStringProperty();
1400     dumpImagePosProperty();
1401     dumpSizeProperty();
1402     dumpMousePtrProperty();
1403     dumpStreamProperty();
1404     dumpUnicodeProperty();
1405     dumpBoolProperty();
1406     dumpStreamProperty();
1407 }
1408 
1409 void AxCommandButtonObject::implDumpExtended()
1410 {
1411     dumpEmbeddedFont();
1412 }
1413 
1414 // ============================================================================
1415 
1416 AxMorphControlObject::AxMorphControlObject( const InputObjectBase& rParent )
1417 {
1418     AxPropertyObjectBase::construct( rParent, "AX-MORPH-PROPERTIES", true );
1419 }
1420 
1421 void AxMorphControlObject::implDumpShortProperties()
1422 {
1423     dumpFlagsProperty( 0x2C80081B );
1424     dumpColorProperty( 0x80000005 );
1425     dumpColorProperty( 0x80000008 );
1426     dumpDecProperty< sal_uInt32 >( 0 );
1427     dumpBorderStyleProperty< sal_uInt8 >( 0 );
1428     dumpDecProperty< sal_uInt8 >( 0, "AX-MORPH-SCROLLBARS" );
1429     mnCtrlType = dumpDecProperty< sal_uInt8 >( 1, "AX-MORPH-CONTROLTYPE" );
1430     dumpMousePtrProperty();
1431     dumpSizeProperty();
1432     dumpUnicodeProperty();
1433     dumpDecProperty< sal_uInt32 >( 0, "CONV-HMM-TO-CM" );
1434     dumpDecProperty< sal_uInt16 >( 1, "AX-MORPH-BOUNDCOLUMN" );
1435     dumpDecProperty< sal_Int16 >( -1, "AX-MORPH-TEXTCOLUMN" );
1436     dumpDecProperty< sal_Int16 >( 1, "AX-MORPH-COLUMNCOUNT" );
1437     dumpDecProperty< sal_uInt16 >( 8 );
1438     mnColInfoCount = dumpDecProperty< sal_uInt16 >( 1 );
1439     dumpDecProperty< sal_uInt8 >( 2, "AX-MORPH-MATCHENTRYTYPE" );
1440     dumpDecProperty< sal_uInt8 >( 0, "AX-MORPH-LISTSTYLE" );
1441     dumpDecProperty< sal_uInt8 >( 0, "AX-MORPH-SHOWDROPDOWNMODE" );
1442     dumpUnknownProperty();
1443     dumpDecProperty< sal_uInt8 >( 1, "AX-MORPH-DROPDOWNSTYLE" );
1444     dumpDecProperty< sal_uInt8 >( 0, "AX-MORPH-SELECTIONTYPE" );
1445     dumpStringProperty();
1446     dumpStringProperty();
1447     dumpImagePosProperty();
1448     dumpColorProperty( 0x80000006 );
1449     dumpSpecialEffectProperty< sal_uInt32 >( 2 );
1450     dumpStreamProperty();
1451     dumpStreamProperty();
1452     dumpUnicodeProperty();
1453     dumpUnknownProperty();
1454     dumpBoolProperty();
1455     dumpStringProperty();
1456 }
1457 
1458 void AxMorphControlObject::implDumpExtended()
1459 {
1460     dumpEmbeddedFont();
1461     dumpColumnInfos();
1462 }
1463 
1464 void AxMorphControlObject::dumpColumnInfos()
1465 {
1466     if( ensureValid() && (mnColInfoCount > 0) && ((mnCtrlType == 2) || (mnCtrlType == 3)) )
1467     {
1468         mxOut->resetItemIndex();
1469         for( sal_uInt16 nIdx = 0; ensureValid() && (nIdx < mnColInfoCount); ++nIdx )
1470         {
1471             writeEmptyItem( "#column-info" );
1472             IndentGuard aIndGuard( mxOut );
1473             AxColumnInfoObject( *this ).dump();
1474         }
1475     }
1476 }
1477 
1478 // ============================================================================
1479 
1480 AxLabelObject::AxLabelObject( const InputObjectBase& rParent )
1481 {
1482     AxPropertyObjectBase::construct( rParent, "AX-LABEL-PROPERTIES" );
1483 }
1484 
1485 void AxLabelObject::implDumpShortProperties()
1486 {
1487     dumpColorProperty( 0x80000012 );
1488     dumpColorProperty( 0x8000000F );
1489     dumpFlagsProperty( 0x0080001B );
1490     dumpStringProperty();
1491     dumpImagePosProperty();
1492     dumpSizeProperty();
1493     dumpMousePtrProperty();
1494     dumpColorProperty( 0x80000006 );
1495     dumpBorderStyleProperty< sal_uInt16 >( 0 );
1496     dumpSpecialEffectProperty< sal_uInt16 >( 0 );
1497     dumpStreamProperty();
1498     dumpUnicodeProperty();
1499     dumpStreamProperty();
1500 }
1501 
1502 void AxLabelObject::implDumpExtended()
1503 {
1504     dumpEmbeddedFont();
1505 }
1506 
1507 // ============================================================================
1508 
1509 AxImageObject::AxImageObject( const InputObjectBase& rParent )
1510 {
1511     AxPropertyObjectBase::construct( rParent, "AX-IMAGE-PROPERTIES" );
1512 }
1513 
1514 void AxImageObject::implDumpShortProperties()
1515 {
1516     dumpUnknownProperty();
1517     dumpUnknownProperty();
1518     dumpBoolProperty();
1519     dumpColorProperty( 0x80000006 );
1520     dumpColorProperty( 0x8000000F );
1521     dumpBorderStyleProperty< sal_uInt8 >( 1 );
1522     dumpMousePtrProperty();
1523     dumpImageSizeModeProperty();
1524     dumpSpecialEffectProperty< sal_uInt8 >( 0 );
1525     dumpSizeProperty();
1526     dumpStreamProperty();
1527     dumpImageAlignProperty();
1528     dumpBoolProperty();
1529     dumpFlagsProperty( 0x0000001B );
1530     dumpStreamProperty();
1531 }
1532 
1533 // ============================================================================
1534 
1535 AxScrollBarObject::AxScrollBarObject( const InputObjectBase& rParent )
1536 {
1537     AxPropertyObjectBase::construct( rParent, "AX-SCROLLBAR-PROPERTIES" );
1538 }
1539 
1540 void AxScrollBarObject::implDumpShortProperties()
1541 {
1542     dumpColorProperty( 0x80000012 );
1543     dumpColorProperty( 0x8000000F );
1544     dumpFlagsProperty( 0x0000001B );
1545     dumpSizeProperty();
1546     dumpMousePtrProperty();
1547     dumpDecProperty< sal_Int32 >( 0 );
1548     dumpDecProperty< sal_Int32 >( 32767 );
1549     dumpDecProperty< sal_Int32 >( 0 );
1550     dumpHexProperty< sal_uInt32 >( 0 );
1551     dumpEnabledProperty();
1552     dumpEnabledProperty();
1553     dumpDecProperty< sal_Int32 >( 1 );
1554     dumpDecProperty< sal_Int32 >( 1 );
1555     dumpOrientationProperty();
1556     dumpDecProperty< sal_Int16 >( -1, "AX-SCROLLBAR-PROPTHUMB" );
1557     dumpDelayProperty();
1558     dumpStreamProperty();
1559 }
1560 
1561 // ============================================================================
1562 
1563 AxSpinButtonObject::AxSpinButtonObject( const InputObjectBase& rParent )
1564 {
1565     AxPropertyObjectBase::construct( rParent, "AX-SPINBUTTON-PROPERTIES" );
1566 }
1567 
1568 void AxSpinButtonObject::implDumpShortProperties()
1569 {
1570     dumpColorProperty( 0x80000012 );
1571     dumpColorProperty( 0x8000000F );
1572     dumpFlagsProperty( 0x0000001B );
1573     dumpSizeProperty();
1574     dumpHexProperty< sal_uInt32 >( 0 );
1575     dumpDecProperty< sal_Int32 >( 0 );
1576     dumpDecProperty< sal_Int32 >( 100 );
1577     dumpDecProperty< sal_Int32 >( 0 );
1578     dumpEnabledProperty();
1579     dumpEnabledProperty();
1580     dumpDecProperty< sal_Int32 >( 1 );
1581     dumpOrientationProperty();
1582     dumpDelayProperty();
1583     dumpStreamProperty();
1584     dumpMousePtrProperty();
1585 }
1586 
1587 // ============================================================================
1588 
1589 AxTabStripObject::AxTabStripObject( const InputObjectBase& rParent )
1590 {
1591     AxPropertyObjectBase::construct( rParent, "AX-TABSTRIP-PROPERTIES" );
1592 }
1593 
1594 void AxTabStripObject::implDumpShortProperties()
1595 {
1596     dumpDecProperty< sal_Int32 >( -1 );
1597     dumpColorProperty( 0x8000000F );
1598     dumpColorProperty( 0x80000012 );
1599     dumpUnknownProperty();
1600     dumpSizeProperty();
1601     dumpStringArrayProperty();
1602     dumpMousePtrProperty();
1603     dumpUnknownProperty();
1604     dumpDecProperty< sal_uInt32 >( 0, "AX-TABSTRIP-ORIENTATION" );
1605     dumpDecProperty< sal_uInt32 >( 0, "AX-TABSTRIP-TABSTYLE" );
1606     dumpBoolProperty();
1607     dumpHmmProperty();
1608     dumpHmmProperty();
1609     dumpBoolProperty();
1610     dumpUnknownProperty();
1611     dumpStringArrayProperty();
1612     dumpUnknownProperty();
1613     dumpStringArrayProperty();
1614     dumpFlagsProperty( 0x0000001B );
1615     dumpBoolProperty();
1616     dumpDecProperty< sal_uInt32 >( 0 );
1617     dumpStringArrayProperty();
1618     mnTabFlagCount = dumpDecProperty< sal_Int32 >( 0 );
1619     dumpStringArrayProperty();
1620     dumpStreamProperty();
1621 }
1622 
1623 void AxTabStripObject::implDumpExtended()
1624 {
1625     dumpEmbeddedFont();
1626     if( mnTabFlagCount > 0 )
1627     {
1628         writeEmptyItem( "tab-flags" );
1629         IndentGuard aIndGuard( mxOut );
1630         mxOut->resetItemIndex();
1631         for( sal_Int32 nIdx = 0; ensureValid() && (nIdx < mnTabFlagCount); ++nIdx )
1632             dumpHex< sal_uInt32 >( "#flags", "AX-TABSTRIP-FLAGS" );
1633     }
1634 }
1635 
1636 // ============================================================================
1637 // ============================================================================
1638 
1639 FormControlStreamObject::FormControlStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, const OUString* pProgId )
1640 {
1641     construct( rParent, rxStrm, rSysFileName );
1642     constructFormCtrlStrmObj( pProgId );
1643 }
1644 
1645 FormControlStreamObject::FormControlStreamObject( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString* pProgId )
1646 {
1647     construct( rParent, rxStrm );
1648     constructFormCtrlStrmObj( pProgId );
1649 }
1650 
1651 void FormControlStreamObject::implDump()
1652 {
1653     if( mbReadGuid )
1654         maProgId = cfg().getStringOption( dumpGuid(), OUString() );
1655 
1656     if( (maProgId.getLength() > 0) && !mxStrm->isEof() )
1657     {
1658         if( maProgId.equalsAscii( "Forms.CommandButton.1" ) )
1659             AxCommandButtonObject( *this ).dump();
1660         else if( maProgId.equalsAscii( "Forms.TextBox.1" ) ||
1661                  maProgId.equalsAscii( "Forms.ListBox.1" ) ||
1662                  maProgId.equalsAscii( "Forms.ComboBox.1" ) ||
1663                  maProgId.equalsAscii( "Forms.CheckBox.1" ) ||
1664                  maProgId.equalsAscii( "Forms.OptionButton.1" ) ||
1665                  maProgId.equalsAscii( "Forms.ToggleButton.1" ) ||
1666                  maProgId.equalsAscii( "RefEdit.Ctrl" ) )
1667             AxMorphControlObject( *this ).dump();
1668         else if( maProgId.equalsAscii( "Forms.Label.1" ) )
1669             AxLabelObject( *this ).dump();
1670         else if( maProgId.equalsAscii( "Forms.Image.1" ) )
1671             AxImageObject( *this ).dump();
1672         else if( maProgId.equalsAscii( "Forms.ScrollBar.1" ) )
1673             AxScrollBarObject( *this ).dump();
1674         else if( maProgId.equalsAscii( "Forms.SpinButton.1" ) )
1675             AxSpinButtonObject( *this ).dump();
1676         else if( maProgId.equalsAscii( "Forms.TabStrip.1" ) )
1677             AxTabStripObject( *this ).dump();
1678         else if( maProgId.equalsAscii( "MSComCtl2.FlatScrollBar.2" ) )
1679             ComCtlScrollBarObject( *this, 6 ).dump();
1680         else if( maProgId.equalsAscii( "COMCTL.ProgCtrl.1" ) )
1681             ComCtlProgressBarObject( *this, 5 ).dump();
1682         else if( maProgId.equalsAscii( "MSComctlLib.ProgCtrl.2" ) )
1683             ComCtlProgressBarObject( *this, 6 ).dump();
1684         else if( maProgId.equalsAscii( "COMCTL.Slider.1" ) )
1685             ComCtlSliderObject( *this, 5 ).dump();
1686         else if( maProgId.equalsAscii( "MSComctlLib.Slider.2" ) )
1687             ComCtlSliderObject( *this, 6 ).dump();
1688         else if( maProgId.equalsAscii( "ComCtl2.UpDown.1" ) )
1689             ComCtlUpDownObject( *this, 5 ).dump();
1690         else if( maProgId.equalsAscii( "MSComCtl2.UpDown.2" ) )
1691             ComCtlUpDownObject( *this, 6 ).dump();
1692         else if( maProgId.equalsAscii( "COMCTL.ImageListCtrl.1" ) )
1693             ComCtlImageListObject( *this, 5 ).dump();
1694         else if( maProgId.equalsAscii( "MSComctlLib.ImageListCtrl.2" ) )
1695             ComCtlImageListObject( *this, 6 ).dump();
1696         else if( maProgId.equalsAscii( "COMCTL.TabStrip.1" ) )
1697             ComCtlTabStripObject( *this, 5 ).dump();
1698         else if( maProgId.equalsAscii( "MSComctlLib.TabStrip.2" ) )
1699             ComCtlTabStripObject( *this, 6 ).dump();
1700         else if( maProgId.equalsAscii( "COMCTL.TreeCtrl.1" ) )
1701             ComCtlTreeViewObject( *this, 5 ).dump();
1702         else if( maProgId.equalsAscii( "MSComctlLib.TreeCtrl.2" ) )
1703             ComCtlTreeViewObject( *this, 6 ).dump();
1704         else if( maProgId.equalsAscii( "COMCTL.SBarCtrl.1" ) )
1705             ComCtlStatusBarObject( *this, 5 ).dump();
1706         else if( maProgId.equalsAscii( "StdPic" ) )
1707             StdPicObject( *this ).dump();
1708     }
1709     dumpRemainingStream();
1710 }
1711 
1712 void FormControlStreamObject::constructFormCtrlStrmObj( const OUString* pProgId )
1713 {
1714     mbReadGuid = pProgId == 0;
1715     if( pProgId )
1716         maProgId = *pProgId;
1717 }
1718 
1719 // ============================================================================
1720 // ============================================================================
1721 
1722 VbaFormClassInfoObject::VbaFormClassInfoObject( const InputObjectBase& rParent, VbaFormSharedData& rFormData ) :
1723     mrFormData( rFormData )
1724 {
1725     AxPropertyObjectBase::construct( rParent, "VBA-CLASSINFO-PROPERTIES" );
1726 }
1727 
1728 void VbaFormClassInfoObject::implDumpShortProperties()
1729 {
1730     mrFormData.maClassInfoProgIds.push_back( OUString() );
1731     dumpGuidProperty( &mrFormData.maClassInfoProgIds.back() );
1732     dumpGuidProperty();
1733     dumpUnknownProperty();
1734     dumpGuidProperty();
1735     dumpFlagsProperty( 0, "VBA-CLASSINFO-FLAGS" );
1736     dumpDecProperty< sal_uInt32 >( 0 );
1737     dumpDecProperty< sal_Int32 >( -1 );
1738     dumpDecProperty< sal_uInt16 >( 0 );
1739     dumpDecProperty< sal_uInt16 >( 0 );
1740     dumpDecProperty< sal_uInt16 >( 0, "OLEPROP-TYPE" );
1741     dumpDecProperty< sal_uInt16 >( 0 );
1742     dumpDecProperty< sal_uInt16 >( 0 );
1743     dumpDecProperty< sal_uInt16 >( 0, "OLEPROP-TYPE" );
1744     dumpDecProperty< sal_Int32 >( -1 );
1745     dumpDecProperty< sal_uInt16 >( 0 );
1746 }
1747 
1748 // ============================================================================
1749 
1750 namespace {
1751 
1752 const sal_uInt32 VBA_FORMSITE_OBJSTREAM         = 0x0010;
1753 
1754 const sal_uInt16 VBA_FORMSITE_CLASSTABLEINDEX   = 0x8000;
1755 const sal_uInt16 VBA_FORMSITE_CLASSTABLEMASK    = 0x7FFF;
1756 
1757 } // namespace
1758 
1759 // ----------------------------------------------------------------------------
1760 
1761 VbaFormSiteObject::VbaFormSiteObject( const InputObjectBase& rParent, VbaFormSharedData& rFormData ) :
1762     mrFormData( rFormData )
1763 {
1764     AxPropertyObjectBase::construct( rParent, "VBA-FORMSITE-PROPERTIES" );
1765 }
1766 
1767 void VbaFormSiteObject::implDumpShortProperties()
1768 {
1769     VbaFormSiteInfo aSiteInfo;
1770     dumpStringProperty();
1771     dumpStringProperty();
1772     sal_Int32 nId = dumpDecProperty< sal_Int32 >( 0 );
1773     dumpDecProperty< sal_Int32 >( 0 );
1774     sal_uInt32 nFlags = dumpFlagsProperty( 0x00000033, "VBA-FORMSITE-FLAGS" );
1775     sal_uInt32 nLength = dumpDecProperty< sal_uInt32 >( 0 );
1776     dumpDecProperty< sal_Int16 >( -1 );
1777     sal_uInt16 nClassId = dumpHexProperty< sal_uInt16 >( 0x7FFF, "VBA-FORMSITE-CLASSIDCACHE" );
1778     dumpPosProperty();
1779     dumpDecProperty< sal_uInt16 >( 0 );
1780     dumpUnknownProperty();
1781     dumpStringProperty();
1782     dumpStringProperty();
1783     dumpStringProperty();
1784     dumpStringProperty();
1785 
1786     sal_uInt16 nIndex = nClassId & VBA_FORMSITE_CLASSTABLEMASK;
1787     if( getFlag( nClassId, VBA_FORMSITE_CLASSTABLEINDEX ) )
1788     {
1789         if( nIndex < mrFormData.maClassInfoProgIds.size() )
1790             aSiteInfo.maProgId = mrFormData.maClassInfoProgIds[ nIndex ];
1791     }
1792     else
1793     {
1794         if( cfg().hasName( "VBA-FORMSITE-CLASSNAMES", nIndex ) )
1795             aSiteInfo.maProgId = cfg().getName( "VBA-FORMSITE-CLASSNAMES", nIndex );
1796     }
1797     aSiteInfo.mnId = nId;
1798     aSiteInfo.mnLength = nLength;
1799     aSiteInfo.mbInStream = getFlag( nFlags, VBA_FORMSITE_OBJSTREAM );
1800 
1801     mrFormData.maSiteInfos.push_back( aSiteInfo );
1802 }
1803 
1804 // ============================================================================
1805 
1806 VbaFormDesignExtObject::VbaFormDesignExtObject( const InputObjectBase& rParent )
1807 {
1808     AxPropertyObjectBase::construct( rParent, "VBA-FORMDESIGNEXT-PROPERTIES" );
1809 }
1810 
1811 void VbaFormDesignExtObject::implDumpShortProperties()
1812 {
1813     dumpFlagsProperty( 0x00015F55, "VBA-FORMDESIGNEXT-FLAGS" );
1814     dumpHmmProperty();
1815     dumpHmmProperty();
1816     dumpDecProperty< sal_Int8 >( 0, "VBA-FORMDESIGNEXT-CLICKCTRLMODE" );
1817     dumpDecProperty< sal_Int8 >( 0, "VBA-FORMDESIGNEXT-DBLCLICKCTRLMODE" );
1818 }
1819 
1820 // ============================================================================
1821 
1822 namespace {
1823 
1824 const sal_uInt32 AX_FORM_HASDESIGNEXTENDER      = 0x00004000;
1825 const sal_uInt32 AX_FORM_SKIPCLASSTABLE         = 0x00008000;
1826 
1827 const sal_uInt8 AX_FORM_SITECOUNTTYPE_COUNT     = 0x80;
1828 const sal_uInt8 AX_FORM_SITECOUNTTYPE_MASK      = 0x7F;
1829 
1830 } // namespace
1831 
1832 // ----------------------------------------------------------------------------
1833 
1834 VbaFStreamObject::VbaFStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, VbaFormSharedData& rFormData ) :
1835     mrFormData( rFormData )
1836 {
1837     AxPropertyObjectBase::construct( rParent, rxStrm, rSysFileName, "VBA-FORM-PROPERTIES" );
1838 }
1839 
1840 void VbaFStreamObject::implDumpShortProperties()
1841 {
1842     dumpUnknownProperty();
1843     dumpColorProperty( 0x8000000F );
1844     dumpColorProperty( 0x80000012 );
1845     dumpDecProperty< sal_uInt32 >( 0 );
1846     dumpUnknownProperty();
1847     dumpUnknownProperty();
1848     mnFlags = dumpFlagsProperty( 0x00000004, "VBA-FORM-FLAGS" );
1849     dumpBorderStyleProperty< sal_uInt8 >( 0 );
1850     dumpMousePtrProperty();
1851     dumpHexProperty< sal_uInt8 >( 0x0C, "VBA-FORM-SCROLLBARS" );
1852     dumpSizeProperty();
1853     dumpSizeProperty();
1854     dumpPosProperty();
1855     dumpDecProperty< sal_uInt32 >( 0 );
1856     dumpUnknownProperty();
1857     dumpStreamProperty();
1858     dumpDecProperty< sal_uInt8 >( 0, "VBA-FORM-CYCLE" );
1859     dumpSpecialEffectProperty< sal_uInt8 >( 0 );
1860     dumpColorProperty( 0x80000012 );
1861     dumpStringProperty();
1862     dumpStreamProperty();
1863     dumpStreamProperty();
1864     dumpDecProperty< sal_Int32 >( 100, "CONV-PERCENT" );
1865     dumpImageAlignProperty();
1866     dumpBoolProperty();
1867     dumpImageSizeModeProperty();
1868     dumpDecProperty< sal_uInt32 >( 0 );
1869     dumpDecProperty< sal_uInt32 >( 0 );
1870 }
1871 
1872 void VbaFStreamObject::implDumpExtended()
1873 {
1874     dumpClassInfos();
1875     dumpSiteData();
1876     dumpDesignExtender();
1877     dumpRemainingStream();
1878 }
1879 
1880 void VbaFStreamObject::dumpClassInfos()
1881 {
1882     if( ensureValid() && !getFlag( mnFlags, AX_FORM_SKIPCLASSTABLE ) )
1883     {
1884         mxOut->emptyLine();
1885         sal_uInt16 nCount = dumpDec< sal_uInt16 >( "class-info-count" );
1886         mxOut->resetItemIndex();
1887         for( sal_uInt16 nIdx = 0; ensureValid() && (nIdx < nCount); ++nIdx )
1888         {
1889             writeEmptyItem( "#class-info" );
1890             IndentGuard aIndGuard( mxOut );
1891             VbaFormClassInfoObject( *this, mrFormData ).dump();
1892         }
1893     }
1894 }
1895 
1896 void VbaFStreamObject::dumpFormSites( sal_uInt32 nCount )
1897 {
1898     mxOut->resetItemIndex();
1899     for( sal_uInt32 nIdx = 0; ensureValid() && (nIdx < nCount); ++nIdx )
1900     {
1901         mxOut->emptyLine();
1902         writeEmptyItem( "#form-site" );
1903         IndentGuard aIndGuard( mxOut );
1904         VbaFormSiteObject( *this, mrFormData ).dump();
1905     }
1906 }
1907 
1908 void VbaFStreamObject::dumpSiteData()
1909 {
1910     if( ensureValid() )
1911     {
1912         mxOut->emptyLine();
1913         setAlignAnchor();
1914         sal_uInt32 nSiteCount = dumpDec< sal_uInt32 >( "site-count" );
1915         sal_uInt32 nSiteLength = dumpDec< sal_uInt32 >( "site-data-size" );
1916         sal_Int64 nEndPos = mxStrm->tell() + nSiteLength;
1917         if( ensureValid( nEndPos <= mxStrm->size() ) )
1918         {
1919             mxOut->resetItemIndex();
1920             sal_uInt32 nSiteIdx = 0;
1921             while( ensureValid() && (nSiteIdx < nSiteCount) )
1922             {
1923                 mxOut->emptyLine();
1924                 writeEmptyItem( "#site-info" );
1925                 IndentGuard aIndGuard( mxOut );
1926                 dumpDec< sal_uInt8 >( "depth" );
1927                 sal_uInt8 nTypeCount = dumpHex< sal_uInt8 >( "type-count", "VBA-FORM-SITE-TYPECOUNT" );
1928                 if( getFlag( nTypeCount, AX_FORM_SITECOUNTTYPE_COUNT ) )
1929                 {
1930                     dumpDec< sal_uInt8 >( "repeated-type" );
1931                     nSiteIdx += (nTypeCount & AX_FORM_SITECOUNTTYPE_MASK);
1932                 }
1933                 else
1934                 {
1935                     ++nSiteIdx;
1936                 }
1937             }
1938             alignInput< sal_uInt32 >();
1939             dumpFormSites( nSiteCount );
1940             dumpToPosition( nEndPos );
1941         }
1942     }
1943 }
1944 
1945 void VbaFStreamObject::dumpDesignExtender()
1946 {
1947     if( ensureValid() && getFlag( mnFlags, AX_FORM_HASDESIGNEXTENDER ) )
1948     {
1949         mxOut->emptyLine();
1950         writeEmptyItem( "design-extender" );
1951         IndentGuard aIndGuard( mxOut );
1952         VbaFormDesignExtObject( *this ).dump();
1953     }
1954 }
1955 
1956 // ============================================================================
1957 
1958 VbaOStreamObject::VbaOStreamObject( const ObjectBase& rParent,
1959         const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, VbaFormSharedData& rFormData ) :
1960     mrFormData( rFormData )
1961 {
1962     OleInputObjectBase::construct( rParent, rxStrm, rSysFileName );
1963 }
1964 
1965 void VbaOStreamObject::implDump()
1966 {
1967     for( VbaFormSiteInfoVector::iterator aIt = mrFormData.maSiteInfos.begin(), aEnd = mrFormData.maSiteInfos.end(); !mxStrm->isEof() && (aIt != aEnd); ++aIt )
1968     {
1969         if( (aIt->mbInStream) && (aIt->mnLength > 0) )
1970         {
1971             mxOut->emptyLine();
1972             writeDecItem( "control-id", aIt->mnId );
1973             writeInfoItem( "prog-id", aIt->maProgId );
1974             IndentGuard aIndGuard( mxOut );
1975             BinaryInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, aIt->mnLength ) );
1976             FormControlStreamObject( *this, xRelStrm, &aIt->maProgId ).dump();
1977         }
1978     }
1979     dumpRemainingStream();
1980 }
1981 
1982 // ============================================================================
1983 
1984 VbaPageObject::VbaPageObject( const InputObjectBase& rParent )
1985 {
1986     AxPropertyObjectBase::construct( rParent, "VBA-PAGE-PROPERTIES" );
1987 }
1988 
1989 void VbaPageObject::implDumpShortProperties()
1990 {
1991     dumpUnknownProperty();
1992     dumpDecProperty< sal_uInt32 >( 0, "VBA-PAGE-TRANSITIONEFFECT" );
1993     dumpDecProperty< sal_uInt32 >( 0, "AX-CONV-MS" );
1994 }
1995 
1996 // ============================================================================
1997 
1998 VbaMultiPageObject::VbaMultiPageObject( const InputObjectBase& rParent )
1999 {
2000     AxPropertyObjectBase::construct( rParent, "VBA-MULTIPAGE-PROPERTIES" );
2001 }
2002 
2003 void VbaMultiPageObject::implDumpShortProperties()
2004 {
2005     dumpUnknownProperty();
2006     mnPageCount = dumpDecProperty< sal_Int32 >( 0 );
2007     dumpDecProperty< sal_Int32 >( 0 );
2008     dumpBoolProperty();
2009 }
2010 
2011 void VbaMultiPageObject::implDumpExtended()
2012 {
2013     if( ensureValid() && (mnPageCount > 0) )
2014     {
2015         writeEmptyItem( "page-ids" );
2016         IndentGuard aIndGuard( mxOut );
2017         mxOut->resetItemIndex();
2018         for( sal_Int32 nIdx = 0; ensureValid() && (nIdx < mnPageCount); ++nIdx )
2019             dumpDec< sal_Int32 >( "#id" );
2020     }
2021 }
2022 
2023 // ============================================================================
2024 
2025 VbaXStreamObject::VbaXStreamObject( const ObjectBase& rParent,
2026         const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, VbaFormSharedData& rFormData ) :
2027     mrFormData( rFormData )
2028 {
2029     InputObjectBase::construct( rParent, rxStrm,  rSysFileName );
2030 }
2031 
2032 void VbaXStreamObject::implDump()
2033 {
2034     for( size_t nIdx = 0, nCount = mrFormData.maSiteInfos.size(); !mxStrm->isEof() && (nIdx < nCount); ++nIdx )
2035     {
2036         mxOut->emptyLine();
2037         writeEmptyItem( "page" );
2038         IndentGuard aIndGuard( mxOut );
2039         VbaPageObject( *this ).dump();
2040     }
2041     if( !mxStrm->isEof() )
2042     {
2043         mxOut->emptyLine();
2044         writeEmptyItem( "multi-page" );
2045         IndentGuard aIndGuard( mxOut );
2046         VbaMultiPageObject( *this ).dump();
2047     }
2048     dumpRemainingStream();
2049 }
2050 
2051 // ============================================================================
2052 
2053 VbaContainerStorageObject::VbaContainerStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath ) :
2054     OleStorageObject( rParent, rxStrg, rSysPath )
2055 {
2056     addPreferredStream( "f" );
2057 }
2058 
2059 void VbaContainerStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
2060 {
2061     if( rStrmName.equalsAscii( "f" ) )
2062         VbaFStreamObject( *this, rxStrm, rSysFileName, maFormData ).dump();
2063     else if( rStrmName.equalsAscii( "o" ) )
2064         VbaOStreamObject( *this, rxStrm, rSysFileName, maFormData ).dump();
2065     else if( rStrmName.equalsAscii( "x" ) )
2066         VbaXStreamObject( *this, rxStrm, rSysFileName, maFormData ).dump();
2067     else
2068         OleStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
2069 }
2070 
2071 void VbaContainerStorageObject::implDumpStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
2072 {
2073     if( isFormStorage( rStrgPath ) )
2074         VbaContainerStorageObject( *this, rxStrg, rSysPath ).dump();
2075     else
2076         OleStorageObject( *this, rxStrg, rSysPath ).dump();
2077 }
2078 
2079 bool VbaContainerStorageObject::isFormStorage( const OUString& rStrgPath ) const
2080 {
2081     if( (rStrgPath.getLength() >= 3) && (rStrgPath[ 0 ] == 'i') )
2082     {
2083         OUString aId = rStrgPath.copy( 1 );
2084         if( (aId.getLength() == 2) && (aId[ 0 ] == '0') )
2085             aId = aId.copy( 1 );
2086         sal_Int32 nId = aId.toInt32();
2087         if( (nId > 0) && (OUString::valueOf( nId ) == aId) )
2088             for( VbaFormSiteInfoVector::const_iterator aIt = maFormData.maSiteInfos.begin(), aEnd = maFormData.maSiteInfos.end(); aIt != aEnd; ++aIt )
2089                 if( aIt->mnId == nId )
2090                     return true;
2091     }
2092     return false;
2093 }
2094 
2095 // ============================================================================
2096 // ============================================================================
2097 
2098 VbaSharedData::VbaSharedData() :
2099     meTextEnc( RTL_TEXTENCODING_MS_1252 )
2100 {
2101 }
2102 
2103 bool VbaSharedData::isModuleStream( const ::rtl::OUString& rStrmName ) const
2104 {
2105     return maStrmOffsets.count( rStrmName ) > 0;
2106 }
2107 
2108 sal_Int32 VbaSharedData::getStreamOffset( const OUString& rStrmName ) const
2109 {
2110     StreamOffsetMap::const_iterator aIt = maStrmOffsets.find( rStrmName );
2111     return (aIt == maStrmOffsets.end()) ? 0 : aIt->second;
2112 }
2113 
2114 // ============================================================================
2115 
2116 VbaDirStreamObject::VbaDirStreamObject( const ObjectBase& rParent,
2117         const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName, VbaSharedData& rVbaData ) :
2118     mrVbaData( rVbaData )
2119 {
2120     mxInStrm = rxStrm;
2121     if( mxInStrm.get() )
2122     {
2123         BinaryInputStreamRef xVbaStrm( new ::oox::ole::VbaInputStream( *mxInStrm ) );
2124         SequenceRecordObjectBase::construct( rParent, xVbaStrm, rSysFileName, "VBA-DIR-RECORD-NAMES", "VBA-DIR-SIMPLE-RECORDS" );
2125     }
2126 }
2127 
2128 bool VbaDirStreamObject::implIsValid() const
2129 {
2130     return mxInStrm.get() && SequenceRecordObjectBase::implIsValid();
2131 }
2132 
2133 bool VbaDirStreamObject::implReadRecordHeader( BinaryInputStream& rBaseStrm, sal_Int64& ornRecId, sal_Int64& ornRecSize )
2134 {
2135     ornRecId = rBaseStrm.readuInt16();
2136     ornRecSize = rBaseStrm.readInt32();
2137 
2138     // for no obvious reason, PROJECTVERSION record contains size field of 4, but is 6 bytes long
2139     if( ornRecId == 9 )
2140         ornRecSize = 6;
2141 
2142     return !rBaseStrm.isEof();
2143 }
2144 
2145 void VbaDirStreamObject::implDumpRecordBody()
2146 {
2147     switch( getRecId() )
2148     {
2149         case 0x0003:
2150             mrVbaData.meTextEnc = rtl_getTextEncodingFromWindowsCodePage( dumpDec< sal_uInt16 >( "codepage", "CODEPAGES" ) );
2151         break;
2152         case 0x0004:
2153             dumpByteString( "name" );
2154         break;
2155         case 0x0005:
2156             dumpByteString( "description" );
2157         break;
2158         case 0x0006:
2159             dumpByteString( "helpfile-path" );
2160         break;
2161         case 0x0009:
2162             dumpDec< sal_uInt32 >( "major" );
2163             dumpDec< sal_uInt16 >( "minor" );
2164         break;
2165         case 0x000C:
2166             dumpByteString( "constants" );
2167         break;
2168         case 0x000D:
2169             dumpByteStringWithLength( "lib-id" );
2170             dumpUnused( 6 );
2171         break;
2172         case 0x000E:
2173             dumpByteStringWithLength( "lib-id-absolute" );
2174             dumpByteStringWithLength( "lib-id-relative" );
2175             dumpDec< sal_uInt32 >( "major" );
2176             dumpDec< sal_uInt16 >( "minor" );
2177         break;
2178         case 0x0016:
2179             dumpByteString( "name" );
2180         break;
2181         case 0x0019:
2182             dumpByteString( "name" );
2183             maCurrStream = OUString();
2184             mnCurrOffset = 0;
2185         break;
2186         case 0x001A:
2187             maCurrStream = dumpByteString( "stream-name" );
2188         break;
2189         case 0x001C:
2190             dumpByteString( "description" );
2191         break;
2192         case 0x002B:
2193             if( maCurrStream.getLength() > 0 )
2194                 mrVbaData.maStrmOffsets[ maCurrStream ] = mnCurrOffset;
2195             maCurrStream = OUString();
2196             mnCurrOffset = 0;
2197         break;
2198         case 0x002F:
2199             dumpByteStringWithLength( "lib-id-twiddled" );
2200             dumpUnused( 6 );
2201         break;
2202         case 0x0030:
2203             dumpByteStringWithLength( "lib-id-extended" );
2204             dumpUnused( 6 );
2205             dumpGuid( "original-typelib" );
2206             dumpDec< sal_uInt32 >( "cookie" );
2207         break;
2208         case 0x0031:
2209             mnCurrOffset = dumpHex< sal_Int32 >( "stream-offset", "CONV-DEC" );
2210         break;
2211         case 0x0032:
2212             dumpUniString( "stream-name" );
2213         break;
2214         case 0x0033:
2215             dumpByteString( "lib-id-original" );
2216         break;
2217         case 0x003C:
2218             dumpUniString( "constants" );
2219         break;
2220         case 0x003D:
2221             dumpByteString( "helpfile-path" );
2222         break;
2223         case 0x003E:
2224             dumpUniString( "name" );
2225         break;
2226         case 0x0040:
2227             dumpUniString( "description" );
2228         break;
2229         case 0x0047:
2230             dumpUniString( "name" );
2231         break;
2232         case 0x0048:
2233             dumpUniString( "description" );
2234         break;
2235     }
2236 }
2237 
2238 OUString VbaDirStreamObject::dumpByteString( const String& rName )
2239 {
2240     return dumpCharArray( rName, static_cast< sal_Int32 >( getRecSize() ), mrVbaData.meTextEnc );
2241 }
2242 
2243 OUString VbaDirStreamObject::dumpUniString( const String& rName )
2244 {
2245     return dumpUnicodeArray( rName, static_cast< sal_Int32 >( getRecSize() / 2 ) );
2246 }
2247 
2248 OUString VbaDirStreamObject::dumpByteStringWithLength( const String& rName )
2249 {
2250     return dumpCharArray( rName, mxStrm->readInt32(), mrVbaData.meTextEnc );
2251 }
2252 
2253 // ============================================================================
2254 
2255 VbaModuleStreamObject::VbaModuleStreamObject(
2256         const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm,
2257         const OUString& rSysFileName, VbaSharedData& rVbaData, sal_Int32 nStrmOffset ) :
2258     mrVbaData( rVbaData ),
2259     mnStrmOffset( nStrmOffset )
2260 {
2261     InputObjectBase::construct( rParent, rxStrm, rSysFileName );
2262 }
2263 
2264 void VbaModuleStreamObject::implDump()
2265 {
2266     dumpBinary( "perf-cache", mnStrmOffset );
2267     mxOut->emptyLine();
2268     writeEmptyItem( "source-code" );
2269     IndentGuard aIndGuard( mxOut );
2270     BinaryInputStreamRef xVbaStrm( new ::oox::ole::VbaInputStream( *mxStrm ) );
2271     TextLineStreamObject( *this, xVbaStrm, mrVbaData.meTextEnc ).dump();
2272 }
2273 
2274 // ============================================================================
2275 
2276 VbaStorageObject::VbaStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath, VbaSharedData& rVbaData ) :
2277     OleStorageObject( rParent, rxStrg, rSysPath ),
2278     mrVbaData( rVbaData )
2279 {
2280     addPreferredStream( "dir" );
2281 }
2282 
2283 void VbaStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
2284 {
2285     if( (rStrgPath.getLength() == 0) && rStrmName.equalsAscii( "dir" ) )
2286         VbaDirStreamObject( *this, rxStrm, rSysFileName, mrVbaData ).dump();
2287     else if( mrVbaData.isModuleStream( rStrmName ) )
2288         VbaModuleStreamObject( *this, rxStrm, rSysFileName, mrVbaData, mrVbaData.getStreamOffset( rStrmName ) ).dump();
2289     else
2290         OleStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
2291 }
2292 
2293 // ============================================================================
2294 
2295 VbaFormStorageObject::VbaFormStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath, VbaSharedData& rVbaData ) :
2296     VbaContainerStorageObject( rParent, rxStrg, rSysPath ),
2297     mrVbaData( rVbaData )
2298 {
2299 }
2300 
2301 void VbaFormStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
2302 {
2303     if( rStrmName.equalsAscii( "\003VBFrame" ) )
2304         TextLineStreamObject( *this, rxStrm, mrVbaData.meTextEnc, rSysFileName ).dump();
2305     else
2306         VbaContainerStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
2307 }
2308 
2309 // ============================================================================
2310 
2311 VbaProjectStorageObject::VbaProjectStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath ) :
2312     OleStorageObject( rParent, rxStrg, rSysPath )
2313 {
2314     addPreferredStorage( "VBA" );
2315 }
2316 
2317 void VbaProjectStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
2318 {
2319     if( (rStrgPath.getLength() == 0) && rStrmName.equalsAscii( "PROJECT" ) )
2320         TextLineStreamObject( *this, rxStrm, maVbaData.meTextEnc, rSysFileName ).dump();
2321     else
2322         OleStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
2323 }
2324 
2325 void VbaProjectStorageObject::implDumpStorage( const StorageRef& rxStrg, const OUString& rStrgPath, const OUString& rSysPath )
2326 {
2327     if( rStrgPath.equalsAscii( "VBA" ) )
2328         VbaStorageObject( *this, rxStrg, rSysPath, maVbaData ).dump();
2329     else
2330         VbaFormStorageObject( *this, rxStrg, rSysPath, maVbaData ).dump();
2331 }
2332 
2333 // ============================================================================
2334 // ============================================================================
2335 
2336 ActiveXStorageObject::ActiveXStorageObject( const ObjectBase& rParent, const StorageRef& rxStrg, const OUString& rSysPath ) :
2337     VbaContainerStorageObject( rParent, rxStrg, rSysPath )
2338 {
2339 }
2340 
2341 void ActiveXStorageObject::implDumpBaseStream( const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
2342 {
2343     FormControlStreamObject( *this, rxStrm, rSysFileName ).dump();
2344 }
2345 
2346 // ============================================================================
2347 // ============================================================================
2348 
2349 } // namespace dump
2350 } // namespace oox
2351 
2352 #endif
2353