xref: /aoo41x/main/oox/source/dump/dffdumper.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/dffdumper.hxx"
29 
30 #if OOX_INCLUDE_DUMPER
31 
32 namespace oox {
33 namespace dump {
34 
35 // ============================================================================
36 
37 using ::rtl::OUString;
38 
39 // ============================================================================
40 
41 namespace {
42 
43 const sal_uInt16 DFF_ID_BSE                 = 0xF007;   /// BLIP store entry.
44 const sal_uInt16 DFF_ID_BSTORECONTAINER     = 0xF001;   /// BLIP store container.
45 const sal_uInt16 DFF_ID_CHILDANCHOR         = 0xF00F;   /// Child anchor (in groups).
46 const sal_uInt16 DFF_ID_CLIENTANCHOR        = 0xF010;   /// Client anchor.
47 const sal_uInt16 DFF_ID_DG                  = 0xF008;   /// Drawing.
48 const sal_uInt16 DFF_ID_DGG                 = 0xF006;   /// Drawing group.
49 const sal_uInt16 DFF_ID_OPT                 = 0xF00B;   /// Property set.
50 const sal_uInt16 DFF_ID_OPT2                = 0xF121;   /// Secondary property set.
51 const sal_uInt16 DFF_ID_OPT3                = 0xF122;   /// Ternary property set.
52 const sal_uInt16 DFF_ID_SP                  = 0xF00A;   /// Shape.
53 const sal_uInt16 DFF_ID_SPGR                = 0xF009;   /// Shape group.
54 const sal_uInt16 DFF_ID_SPLITMENUCOLORS     = 0xF11E;   /// Current toolbar colors.
55 
56 const sal_uInt16 DFF_OPT_IDMASK             = 0x3FFF;
57 const sal_uInt16 DFF_OPT_PICTURE            = 0x4000;
58 const sal_uInt16 DFF_OPT_COMPLEX            = 0x8000;
59 const sal_uInt16 DFF_OPT_FLAGSMASK          = 0x003F;
60 
61 } // namespace
62 
63 // ============================================================================
64 
65 void DffStreamObject::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
66 {
67     SequenceRecordObjectBase::construct( rParent, rxStrm, rSysFileName, "DFF-RECORD-NAMES" );
68     constructDffObj();
69 }
70 
71 void DffStreamObject::construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm )
72 {
73     SequenceRecordObjectBase::construct( rParent, rxStrm, "DFF-RECORD-NAMES" );
74     constructDffObj();
75 }
76 
77 bool DffStreamObject::implReadRecordHeader( BinaryInputStream& rBaseStrm, sal_Int64& ornRecId, sal_Int64& ornRecSize )
78 {
79     sal_uInt16 nRecId;
80     rBaseStrm >> mnInstVer >> nRecId >> mnRealSize;
81     ornRecId = nRecId;
82     ornRecSize = isContainer() ? 0 : mnRealSize;
83     return !rBaseStrm.isEof();
84 }
85 
86 void DffStreamObject::implWriteExtHeader()
87 {
88     const sal_Char* pcListName = "DFF-RECORD-INST";
89     switch( getRecId() )
90     {
91         case DFF_ID_BSE:                pcListName = "DFFBSE-RECORD-INST";          break;  // BLIP type
92         case DFF_ID_BSTORECONTAINER:    pcListName = "DFFBSTORECONT-RECORD-INST";   break;  // BLIP count
93         case DFF_ID_DG:                 pcListName = "DFFDG-RECORD-INST";           break;  // drawing ID
94         case DFF_ID_OPT:                pcListName = "DFFOPT-RECORD-INST";          break;  // property count
95         case DFF_ID_SP:                 pcListName = "DFFSP-RECORD-INST";           break;  // shape type
96         case DFF_ID_SPLITMENUCOLORS:    pcListName = "DFFSPLITMENUC-RECORD-INST";   break;  // number of colors
97     }
98     MultiItemsGuard aMultiGuard( mxOut );
99     writeHexItem( "instance", mnInstVer, pcListName );
100     if( isContainer() ) writeDecItem( "container-size", mnRealSize );
101 }
102 
103 void DffStreamObject::implDumpRecordBody()
104 {
105     switch( getRecId() )
106     {
107         case DFF_ID_BSE:
108             dumpDec< sal_uInt8 >( "win-type", "DFFBSE-TYPE" );
109             dumpDec< sal_uInt8 >( "mac-type", "DFFBSE-TYPE" );
110             dumpGuid( "guid" );
111             dumpDec< sal_uInt16 >( "tag" );
112             dumpDec< sal_uInt32 >( "blip-size" );
113             dumpDec< sal_uInt32 >( "blip-refcount" );
114             dumpDec< sal_uInt32 >( "blip-streampos" );
115             dumpDec< sal_uInt8 >( "blip-usage", "DFFBSE-USAGE" );
116             dumpDec< sal_uInt8 >( "blip-name-len" );
117             dumpUnused( 2 );
118         break;
119 
120         case DFF_ID_CHILDANCHOR:
121             dumpDec< sal_uInt32 >( "left" );
122             dumpDec< sal_uInt32 >( "top" );
123             dumpDec< sal_uInt32 >( "right" );
124             dumpDec< sal_uInt32 >( "bottom" );
125         break;
126 
127         case DFF_ID_CLIENTANCHOR:
128             implDumpClientAnchor();
129         break;
130 
131         case DFF_ID_DG:
132             dumpDec< sal_uInt32 >( "shape-count" );
133             dumpHex< sal_uInt32 >( "max-shape-id", "CONV-DEC" );
134         break;
135 
136         case DFF_ID_DGG:
137         {
138             dumpHex< sal_uInt32 >( "max-shape-id", "CONV-DEC" );
139             sal_uInt32 nClusters = dumpDec< sal_uInt32 >( "id-cluster-count" );
140             dumpDec< sal_uInt32 >( "shape-count" );
141             dumpDec< sal_uInt32 >( "drawing-count" );
142             mxOut->resetItemIndex( 1 );
143             TableGuard aTabGuard( mxOut, 15, 16 );
144             for( sal_uInt32 nCluster = 1; !mxStrm->isEof() && (nCluster < nClusters); ++nCluster )
145             {
146                 MultiItemsGuard aMultiGuard( mxOut );
147                 writeEmptyItem( "#cluster" );
148                 dumpDec< sal_uInt32 >( "drawing-id" );
149                 dumpHex< sal_uInt32 >( "next-free-id", "CONV-DEC" );
150             }
151         }
152         break;
153 
154         case DFF_ID_OPT:
155         case DFF_ID_OPT2:
156         case DFF_ID_OPT3:
157             dumpDffOpt();
158         break;
159 
160         case DFF_ID_SP:
161             dumpHex< sal_uInt32 >( "shape-id", "CONV-DEC" );
162             dumpHex< sal_uInt32 >( "shape-flags", "DFFSP-FLAGS" );
163         break;
164 
165         case DFF_ID_SPGR:
166             dumpDec< sal_uInt32 >( "left" );
167             dumpDec< sal_uInt32 >( "top" );
168             dumpDec< sal_uInt32 >( "right" );
169             dumpDec< sal_uInt32 >( "bottom" );
170         break;
171 
172         case DFF_ID_SPLITMENUCOLORS:
173             dumpDffSimpleColor( "fill-color" );
174             dumpDffSimpleColor( "line-color" );
175             dumpDffSimpleColor( "shadow-color" );
176             dumpDffSimpleColor( "3d-color" );
177         break;
178     }
179 }
180 
181 void DffStreamObject::implDumpClientAnchor()
182 {
183 }
184 
185 void DffStreamObject::constructDffObj()
186 {
187     mnInstVer = 0;
188     mnRealSize = 0;
189     if( SequenceRecordObjectBase::implIsValid() )
190     {
191         maSimpleProps.insertFormats( cfg().getNameList( "DFFOPT-SIMPLE-PROPERTIES" ) );
192         maComplexProps.insertFormats( cfg().getNameList( "DFFOPT-COMPLEX-PROPERTIES" ) );
193     }
194 }
195 
196 sal_uInt32 DffStreamObject::dumpDffSimpleColor( const String& rName )
197 {
198     return dumpHex< sal_uInt32 >( rName, "DFF-SIMPLE-COLOR" );
199 }
200 
201 sal_uInt32 DffStreamObject::dumpDffColor( const String& rName )
202 {
203     return dumpHex< sal_uInt32 >( rName, "DFF-COLOR" );
204 }
205 
206 namespace {
207 
208 enum PropType { PROPTYPE_BINARY, PROPTYPE_STRING, PROPTYPE_BLIP, PROPTYPE_COLORARRAY };
209 
210 struct PropInfo
211 {
212     OUString            maName;
213     PropType            meType;
214     sal_uInt16          mnId;
215     sal_uInt32          mnSize;
216     inline explicit     PropInfo( const OUString& rName, PropType eType, sal_uInt16 nId, sal_uInt32 nSize ) :
217                             maName( rName ), meType( eType ), mnId( nId ), mnSize( nSize ) {}
218 };
219 
220 typedef ::std::vector< PropInfo > PropInfoVector;
221 
222 } // namespace
223 
224 void DffStreamObject::dumpDffOpt()
225 {
226     sal_uInt16 nPropCount = getInst();
227     PropInfoVector aPropInfos;
228     mxOut->resetItemIndex();
229     for( sal_uInt16 nPropIdx = 0; !mxStrm->isEof() && (nPropIdx < nPropCount); ++nPropIdx )
230     {
231         sal_uInt16 nPropId = dumpDffOptPropHeader();
232         sal_uInt16 nBaseId = nPropId & DFF_OPT_IDMASK;
233         sal_uInt32 nValue = mxStrm->readuInt32();
234 
235         IndentGuard aIndent( mxOut );
236         if( getFlag( nPropId, DFF_OPT_COMPLEX ) )
237         {
238             writeHexItem( "complex-size", nValue, "CONV-DEC" );
239             String aName;
240             PropType eType = PROPTYPE_BINARY;
241             ItemFormatMap::const_iterator aIt = maComplexProps.find( nBaseId );
242             if( aIt != maComplexProps.end() )
243             {
244                 const ItemFormat& rItemFmt = aIt->second;
245                 aName = rItemFmt.maItemName;
246                 if( rItemFmt.maListName.equalsAscii( "binary" ) )
247                     eType = PROPTYPE_BINARY;
248                 else if( rItemFmt.maListName.equalsAscii( "string" ) )
249                     eType = PROPTYPE_STRING;
250                 else if( rItemFmt.maListName.equalsAscii( "blip" ) )
251                     eType = PROPTYPE_BLIP;
252                 else if( rItemFmt.maListName.equalsAscii( "colorarray" ) )
253                     eType = PROPTYPE_COLORARRAY;
254             }
255             aPropInfos.push_back( PropInfo( aName( "property-data" ), eType, nBaseId, nValue ) );
256         }
257         else
258         {
259             ItemFormatMap::const_iterator aIt = maSimpleProps.find( nBaseId );
260             if( aIt != maSimpleProps.end() )
261             {
262                 const ItemFormat& rItemFmt = aIt->second;
263                 // flags always at end of block of 64 properties
264                 if( (nBaseId & DFF_OPT_FLAGSMASK) == DFF_OPT_FLAGSMASK )
265                 {
266                     FlagsList* pFlagsList = dynamic_cast< FlagsList* >( cfg().getNameList( rItemFmt.maListName ).get() );
267                     sal_Int64 nOldIgnoreFlags = 0;
268                     if( pFlagsList )
269                     {
270                         nOldIgnoreFlags = pFlagsList->getIgnoreFlags();
271                         pFlagsList->setIgnoreFlags( nOldIgnoreFlags | 0xFFFF0000 | ~(nValue >> 16) );
272                     }
273                     writeValueItem( rItemFmt, nValue );
274                     if( pFlagsList )
275                         pFlagsList->setIgnoreFlags( nOldIgnoreFlags );
276                 }
277                 else
278                     writeValueItem( rItemFmt, nValue );
279             }
280             else
281                 writeHexItem( "value", nValue );
282         }
283     }
284 
285     mxOut->resetItemIndex();
286     for( PropInfoVector::iterator aIt = aPropInfos.begin(), aEnd = aPropInfos.end(); !mxStrm->isEof() && (aIt != aEnd); ++aIt )
287     {
288         mxOut->startMultiItems();
289         writeEmptyItem( "#complex-data" );
290         writeHexItem( "id", aIt->mnId, "DFFOPT-PROPERTY-NAMES" );
291         mxOut->endMultiItems();
292         IndentGuard aIndent( mxOut );
293         switch( aIt->meType )
294         {
295             case PROPTYPE_BINARY:
296                 dumpBinary( aIt->maName, aIt->mnSize );
297             break;
298             case PROPTYPE_STRING:
299                 dumpUnicodeArray( aIt->maName, aIt->mnSize / 2, true );
300             break;
301             case PROPTYPE_BLIP:
302                 dumpBinary( aIt->maName, aIt->mnSize );
303             break;
304             case PROPTYPE_COLORARRAY:
305                 dumpBinary( aIt->maName, aIt->mnSize );
306             break;
307         }
308     }
309 }
310 
311 sal_uInt16 DffStreamObject::dumpDffOptPropHeader()
312 {
313     MultiItemsGuard aMultiGuard( mxOut );
314     TableGuard aTabGuard( mxOut, 11 );
315     writeEmptyItem( "#prop" );
316     return dumpHex< sal_uInt16 >( "id", "DFFOPT-PROPERTY-ID" );
317 }
318 
319 // ============================================================================
320 
321 } // namespace dump
322 } // namespace oox
323 
324 #endif
325