Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <propread.hxx>
30 : : #include "rtl/tencinfo.h"
31 : : #include "rtl/textenc.h"
32 : :
33 : 75 : PropEntry::PropEntry( sal_uInt32 nId, const sal_uInt8* pBuf, sal_uInt32 nBufSize, sal_uInt16 nTextEnc ) :
34 : : mnId ( nId ),
35 : : mnSize ( nBufSize ),
36 : : mnTextEnc ( nTextEnc ),
37 : 75 : mpBuf ( new sal_uInt8[ nBufSize ] )
38 : : {
39 : 75 : memcpy( (void*)mpBuf, (void*)pBuf, nBufSize );
40 : 75 : };
41 : :
42 : 75 : PropEntry::PropEntry( const PropEntry& rProp ) :
43 : : mnId ( rProp.mnId ),
44 : : mnSize ( rProp.mnSize ),
45 : : mnTextEnc ( rProp.mnTextEnc ),
46 : 75 : mpBuf ( new sal_uInt8[ mnSize ] )
47 : : {
48 : 75 : memcpy( (void*)mpBuf, (void*)rProp.mpBuf, mnSize );
49 : 75 : };
50 : :
51 : 0 : const PropEntry& PropEntry::operator=(const PropEntry& rPropEntry)
52 : : {
53 [ # # ]: 0 : if ( this != &rPropEntry )
54 : : {
55 [ # # ]: 0 : delete[] mpBuf;
56 : 0 : mnId = rPropEntry.mnId;
57 : 0 : mnSize = rPropEntry.mnSize;
58 : 0 : mnTextEnc = rPropEntry.mnTextEnc;
59 : 0 : mpBuf = new sal_uInt8[ mnSize ];
60 : 0 : memcpy( (void*)mpBuf, (void*)rPropEntry.mpBuf, mnSize );
61 : : }
62 : 0 : return *this;
63 : : }
64 : :
65 : : // -----------------------------------------------------------------------
66 : :
67 : 18 : void PropItem::Clear()
68 : : {
69 : 18 : Seek( STREAM_SEEK_TO_BEGIN );
70 [ + - ]: 18 : delete[] (sal_uInt8*)SwitchBuffer();
71 : 18 : }
72 : :
73 : : // -----------------------------------------------------------------------
74 : :
75 : 9 : static xub_StrLen lcl_getMaxSafeStrLen(sal_uInt32 nSize)
76 : : {
77 : 9 : nSize -= 1; //Drop NULL terminator
78 : :
79 : : //If it won't fit in a string, clip it to the max size that does
80 [ - + ]: 9 : if (nSize > STRING_MAXLEN)
81 : 0 : nSize = STRING_MAXLEN;
82 : :
83 : 9 : return static_cast< xub_StrLen >( nSize );
84 : : }
85 : :
86 : 9 : sal_Bool PropItem::Read( String& rString, sal_uInt32 nStringType, sal_Bool bAlign )
87 : : {
88 : : sal_uInt32 i, nItemSize, nType, nItemPos;
89 : 9 : sal_Bool bRetValue = sal_False;
90 : :
91 : 9 : nItemPos = Tell();
92 : :
93 [ + - ]: 9 : if ( nStringType == VT_EMPTY )
94 [ + - ]: 9 : *this >> nType;
95 : : else
96 : 0 : nType = nStringType & VT_TYPEMASK;
97 : :
98 [ + - ]: 9 : *this >> nItemSize;
99 : :
100 [ + - - ]: 9 : switch( nType )
101 : : {
102 : : case VT_LPSTR :
103 : : {
104 [ + - ]: 9 : if ( nItemSize )
105 : : {
106 : : try
107 : : {
108 [ + - ]: 9 : sal_Char* pString = new sal_Char[ nItemSize ];
109 [ - + ]: 9 : if ( mnTextEnc == RTL_TEXTENCODING_UCS2 )
110 : : {
111 : 0 : nItemSize >>= 1;
112 [ # # ]: 0 : if ( nItemSize > 1 )
113 : : {
114 : 0 : sal_Unicode* pWString = (sal_Unicode*)pString;
115 [ # # ]: 0 : for ( i = 0; i < nItemSize; i++ )
116 [ # # ]: 0 : *this >> pWString[ i ];
117 [ # # ]: 0 : rString = rtl::OUString(pWString, lcl_getMaxSafeStrLen(nItemSize));
118 : : }
119 : : else
120 [ # # ][ # # ]: 0 : rString = String();
[ # # ]
121 : 0 : bRetValue = sal_True;
122 : : }
123 : : else
124 : : {
125 [ + - ]: 9 : SvMemoryStream::Read( pString, nItemSize );
126 [ + - ]: 9 : if ( pString[ nItemSize - 1 ] == 0 )
127 : : {
128 [ + - ]: 9 : if ( nItemSize > 1 )
129 [ + - ][ + - ]: 9 : rString = rtl::OUString(pString, rtl_str_getLength(pString), mnTextEnc);
130 : : else
131 [ # # ][ # # ]: 0 : rString = String();
[ # # ][ # # ]
132 : 9 : bRetValue = sal_True;
133 : : }
134 : : }
135 [ + - ]: 9 : delete[] pString;
136 : : }
137 : 0 : catch( const std::bad_alloc& )
138 : : {
139 : : OSL_FAIL( "sd PropItem::Read bad alloc" );
140 : : }
141 : : }
142 [ - + ]: 9 : if ( bAlign )
143 [ # # ]: 0 : SeekRel( ( 4 - ( nItemSize & 3 ) ) & 3 ); // dword align
144 : : }
145 : 9 : break;
146 : :
147 : : case VT_LPWSTR :
148 : : {
149 [ # # ]: 0 : if ( nItemSize )
150 : : {
151 : : try
152 : : {
153 [ # # ]: 0 : sal_Unicode* pString = new sal_Unicode[ nItemSize ];
154 [ # # ]: 0 : for ( i = 0; i < nItemSize; i++ )
155 [ # # ]: 0 : *this >> pString[ i ];
156 [ # # ]: 0 : if ( pString[ i - 1 ] == 0 )
157 : : {
158 [ # # ]: 0 : if ( (sal_uInt16)nItemSize > 1 )
159 [ # # ]: 0 : rString = rtl::OUString(pString, lcl_getMaxSafeStrLen(nItemSize));
160 : : else
161 [ # # ][ # # ]: 0 : rString = String();
[ # # ][ # # ]
162 : 0 : bRetValue = sal_True;
163 : : }
164 [ # # ]: 0 : delete[] pString;
165 : : }
166 : 0 : catch( const std::bad_alloc& )
167 : : {
168 : : OSL_FAIL( "sd PropItem::Read bad alloc" );
169 : : }
170 : : }
171 [ # # ][ # # ]: 0 : if ( bAlign && ( nItemSize & 1 ) )
172 [ # # ]: 0 : SeekRel( 2 ); // dword align
173 : : }
174 : 0 : break;
175 : : }
176 [ - + ]: 9 : if ( !bRetValue )
177 [ # # ]: 0 : Seek( nItemPos );
178 : 9 : return bRetValue;
179 : : }
180 : :
181 : : // -----------------------------------------------------------------------
182 : :
183 : 0 : PropItem& PropItem::operator=( PropItem& rPropItem )
184 : : {
185 [ # # ]: 0 : if ( this != &rPropItem )
186 : : {
187 : 0 : Seek( STREAM_SEEK_TO_BEGIN );
188 [ # # ]: 0 : delete[] (sal_uInt8*)SwitchBuffer();
189 : :
190 : 0 : mnTextEnc = rPropItem.mnTextEnc;
191 : 0 : sal_uInt32 nItemPos = rPropItem.Tell();
192 : 0 : rPropItem.Seek( STREAM_SEEK_TO_END );
193 : 0 : SvMemoryStream::Write( rPropItem.GetData(), rPropItem.Tell() );
194 : 0 : rPropItem.Seek( nItemPos );
195 : : }
196 : 0 : return *this;
197 : : }
198 : :
199 : : // -----------------------------------------------------------------------
200 : :
201 : 21 : Section::Section( const Section& rSection )
202 : : : mnTextEnc(rSection.mnTextEnc),
203 [ + - ][ + - ]: 21 : maEntries(rSection.maEntries.clone())
204 : : {
205 [ + + ]: 357 : for ( int i = 0; i < 16; i++ )
206 : 336 : aFMTID[ i ] = rSection.aFMTID[ i ];
207 : 21 : }
208 : :
209 : : // -----------------------------------------------------------------------
210 : :
211 : 21 : Section::Section( const sal_uInt8* pFMTID )
212 : : {
213 : 21 : mnTextEnc = RTL_TEXTENCODING_MS_1252;
214 [ + + ]: 357 : for ( int i = 0; i < 16; i++ )
215 : 336 : aFMTID[ i ] = pFMTID[ i ];
216 : 21 : }
217 : :
218 : : // -----------------------------------------------------------------------
219 : :
220 : 27 : sal_Bool Section::GetProperty( sal_uInt32 nId, PropItem& rPropItem )
221 : : {
222 [ + - ]: 27 : if ( nId )
223 : : {
224 [ + - ]: 27 : boost::ptr_vector<PropEntry>::const_iterator iter;
225 [ + - ][ + - ]: 75 : for (iter = maEntries.begin(); iter != maEntries.end(); ++iter)
[ + - ][ + - ]
[ + - ][ + + ]
226 : : {
227 [ + - ][ + + ]: 66 : if (iter->mnId == nId)
228 : 18 : break;
229 : : }
230 : :
231 [ + - ][ + - ]: 27 : if (iter != maEntries.end())
[ + + ]
232 : : {
233 [ + - ]: 18 : rPropItem.Clear();
234 : 18 : rPropItem.SetTextEncoding( mnTextEnc );
235 [ + - ][ + - ]: 18 : rPropItem.Write( iter->mpBuf,iter->mnSize );
[ + - ]
236 [ + - ]: 18 : rPropItem.Seek( STREAM_SEEK_TO_BEGIN );
237 : 27 : return sal_True;
238 : : }
239 : : }
240 : 27 : return sal_False;
241 : : }
242 : :
243 : : // -----------------------------------------------------------------------
244 : :
245 : 75 : void Section::AddProperty( sal_uInt32 nId, const sal_uInt8* pBuf, sal_uInt32 nBufSize )
246 : : {
247 : : // kleiner id check
248 : :
249 [ + - ]: 75 : if ( !nId )
250 : : return;
251 [ + + ]: 75 : if ( nId == 0xffffffff )
252 : 9 : nId = 0;
253 : :
254 : : // keine doppelten PropId's zulassen, sortieren
255 [ + - ]: 75 : boost::ptr_vector<PropEntry>::iterator iter;
256 [ + - ][ + - ]: 396 : for ( iter = maEntries.begin(); iter != maEntries.end(); ++iter )
[ + - ][ + - ]
[ + + ]
257 : : {
258 [ + - ][ - + ]: 357 : if ( iter->mnId == nId )
259 [ # # ][ # # ]: 0 : maEntries.replace( iter, new PropEntry( nId, pBuf, nBufSize, mnTextEnc ));
[ # # ][ # # ]
260 [ + - ][ + + ]: 357 : else if ( iter->mnId > nId )
261 [ + - ][ + - ]: 36 : maEntries.insert( iter, new PropEntry( nId, pBuf, nBufSize, mnTextEnc ));
[ + - ]
262 : : else
263 : 321 : continue;
264 : : return;
265 : : }
266 : :
267 [ + - ][ + - ]: 75 : maEntries.push_back( new PropEntry( nId, pBuf, nBufSize, mnTextEnc ) );
[ + - ]
268 : : }
269 : :
270 : : // -----------------------------------------------------------------------
271 : :
272 : 9 : sal_Bool Section::GetDictionary( Dictionary& rDict )
273 : : {
274 : 9 : sal_Bool bRetValue = sal_False;
275 : :
276 [ + - ]: 9 : boost::ptr_vector<PropEntry>::iterator iter;
277 [ + - ][ # # ]: 9 : for (iter = maEntries.begin(); iter != maEntries.end(); ++iter)
[ + - ][ + - ]
[ + - ]
278 : : {
279 [ + - ][ + - ]: 9 : if ( iter->mnId == 0 )
280 : 9 : break;
281 : : }
282 : :
283 [ + - ][ + - ]: 9 : if ( iter != maEntries.end() )
[ + - ]
284 : : {
285 : : sal_uInt32 nDictCount, nId, nSize, nPos;
286 [ + - ][ + - ]: 9 : SvMemoryStream aStream( (sal_Int8*)iter->mpBuf, iter->mnSize, STREAM_READ );
[ + - ]
287 [ + - ]: 9 : aStream.Seek( STREAM_SEEK_TO_BEGIN );
288 [ + - ]: 9 : aStream >> nDictCount;
289 [ + + ]: 18 : for ( sal_uInt32 i = 0; i < nDictCount; i++ )
290 : : {
291 [ + - ][ + - ]: 9 : aStream >> nId >> nSize;
292 [ + - ]: 9 : if ( nSize )
293 : : {
294 [ + - ]: 9 : String aString;
295 : 9 : nPos = aStream.Tell();
296 : : try
297 : : {
298 [ + - ]: 9 : sal_Char* pString = new sal_Char[ nSize ];
299 [ + - ]: 9 : aStream.Read( pString, nSize );
300 [ - + ]: 9 : if ( mnTextEnc == RTL_TEXTENCODING_UCS2 )
301 : : {
302 : 0 : nSize >>= 1;
303 [ # # ]: 0 : aStream.Seek( nPos );
304 : 0 : sal_Unicode* pWString = (sal_Unicode*)pString;
305 [ # # ]: 0 : for ( i = 0; i < nSize; i++ )
306 [ # # ]: 0 : aStream >> pWString[ i ];
307 [ # # ]: 0 : aString = rtl::OUString(pWString, lcl_getMaxSafeStrLen(nSize));
308 : : }
309 : : else
310 [ + - ][ + - ]: 9 : aString = rtl::OUString(pString, lcl_getMaxSafeStrLen(nSize), mnTextEnc);
[ # # ]
311 [ + - ]: 9 : delete[] pString;
312 : : }
313 : 0 : catch( const std::bad_alloc& )
314 : : {
315 : : OSL_FAIL( "sd Section::GetDictionary bad alloc" );
316 : : }
317 [ - + ]: 9 : if ( !aString.Len() )
318 : : break;
319 [ + - ][ + - ]: 9 : rDict.insert( std::make_pair(aString,nId) );
[ + - ][ + - ]
[ + - ]
320 : : }
321 : 9 : bRetValue = sal_True;
322 [ + - ]: 9 : }
323 : : }
324 : 9 : return bRetValue;
325 : : }
326 : :
327 : : // -----------------------------------------------------------------------
328 : :
329 : 21 : void Section::Read( SvStorageStream *pStrm )
330 : : {
331 : : sal_uInt32 i, nSecOfs, nSecSize, nPropCount, nPropId, nPropOfs, nPropType, nPropSize, nCurrent, nVectorCount, nTemp, nStrmSize;
332 : 21 : nSecOfs = pStrm->Tell();
333 : :
334 [ + - ]: 21 : pStrm->Seek( STREAM_SEEK_TO_END );
335 : 21 : nStrmSize = pStrm->Tell();
336 [ + - ]: 21 : pStrm->Seek( nSecOfs );
337 : :
338 : 21 : mnTextEnc = RTL_TEXTENCODING_MS_1252;
339 [ + - ][ + - ]: 21 : *pStrm >> nSecSize >> nPropCount;
340 [ + + ][ + - ]: 96 : while( nPropCount-- && ( pStrm->GetError() == ERRCODE_NONE ) )
[ + + ]
341 : : {
342 [ + - ][ + - ]: 75 : *pStrm >> nPropId >> nPropOfs;
343 : 75 : nCurrent = pStrm->Tell();
344 [ + - ]: 75 : pStrm->Seek( nPropOfs + nSecOfs );
345 [ + + ]: 75 : if ( nPropId ) // dictionary wird nicht eingelesen
346 : : {
347 : :
348 [ + - ]: 66 : *pStrm >> nPropType;
349 : :
350 : 66 : nPropSize = 4;
351 : :
352 [ + + ]: 66 : if ( nPropType & VT_VECTOR )
353 : : {
354 [ + - ]: 6 : *pStrm >> nVectorCount;
355 : 6 : nPropType &=~VT_VECTOR;
356 : 6 : nPropSize += 4;
357 : : }
358 : : else
359 : 60 : nVectorCount = 1;
360 : :
361 : :
362 : 66 : sal_Bool bVariant = ( nPropType == VT_VARIANT );
363 : :
364 [ + - ][ + + ]: 156 : for ( i = 0; nPropSize && ( i < nVectorCount ); i++ )
[ + + ]
365 : : {
366 [ + + ]: 90 : if ( bVariant )
367 : : {
368 [ + - ]: 18 : *pStrm >> nPropType;
369 : 18 : nPropSize += 4;
370 : : }
371 [ - + + - : 90 : switch( nPropType )
- + - +
- ]
372 : : {
373 : : case VT_UI1 :
374 : 0 : nPropSize++;
375 : 0 : break;
376 : :
377 : : case VT_I2 :
378 : : case VT_UI2 :
379 : : case VT_BOOL :
380 : 24 : nPropSize += 2;
381 : 24 : break;
382 : :
383 : : case VT_I4 :
384 : : case VT_R4 :
385 : : case VT_UI4 :
386 : : case VT_ERROR :
387 : 30 : nPropSize += 4;
388 : 30 : break;
389 : :
390 : : case VT_I8 :
391 : : case VT_R8 :
392 : : case VT_CY :
393 : : case VT_UI8 :
394 : : case VT_DATE :
395 : : case VT_FILETIME :
396 : 0 : nPropSize += 8;
397 : 0 : break;
398 : :
399 : : case VT_BSTR :
400 [ # # ]: 0 : *pStrm >> nTemp;
401 : 0 : nPropSize += ( nTemp + 4 );
402 : 0 : break;
403 : :
404 : : case VT_LPSTR :
405 [ + - ]: 27 : *pStrm >> nTemp;
406 : 27 : nPropSize += ( nTemp + 4 );
407 : 27 : break;
408 : :
409 : : case VT_LPWSTR :
410 : : {
411 [ # # ]: 0 : *pStrm >> nTemp;
412 : : // looks like these are aligned to 4 bytes
413 : 0 : sal_uInt32 nLength = nPropOfs + nSecOfs + nPropSize + ( nTemp << 1 ) + 4;
414 : 0 : nPropSize += ( nTemp << 1 ) + 4 + (nLength % 4);
415 : : }
416 : 0 : break;
417 : :
418 : : case VT_BLOB_OBJECT :
419 : : case VT_BLOB :
420 : : case VT_CF :
421 [ + - ]: 9 : *pStrm >> nTemp;
422 : 9 : nPropSize += ( nTemp + 4 );
423 : 9 : break;
424 : :
425 : : case VT_CLSID :
426 : : case VT_STREAM :
427 : : case VT_STORAGE :
428 : : case VT_STREAMED_OBJECT :
429 : : case VT_STORED_OBJECT :
430 : : case VT_VARIANT :
431 : : case VT_VECTOR :
432 : : default :
433 : 0 : nPropSize = 0;
434 : : }
435 [ + - ]: 90 : if ( nPropSize )
436 : : {
437 [ + + ]: 90 : if ( ( nVectorCount - i ) > 1 )
438 [ + - ]: 24 : pStrm->Seek( nPropOfs + nSecOfs + nPropSize );
439 : : }
440 : : else
441 : 0 : break;
442 : : }
443 [ + - ]: 66 : if ( nPropSize )
444 : : {
445 [ - + ]: 66 : if ( nPropSize > nStrmSize )
446 : : {
447 : 0 : nPropCount = 0;
448 : 0 : break;
449 : : }
450 [ + - ]: 66 : pStrm->Seek( nPropOfs + nSecOfs );
451 : : // make sure we don't overflow the section size
452 [ + + ]: 66 : if( nPropSize > nSecSize - nSecOfs )
453 : 9 : nPropSize = nSecSize - nSecOfs;
454 [ + - ]: 66 : sal_uInt8* pBuf = new sal_uInt8[ nPropSize ];
455 [ + - ]: 66 : pStrm->Read( pBuf, nPropSize );
456 [ + - ]: 66 : AddProperty( nPropId, pBuf, nPropSize );
457 [ + - ]: 66 : delete[] pBuf;
458 : : }
459 [ + + ]: 66 : if ( nPropId == 1 )
460 : : {
461 [ + - ]: 12 : PropItem aPropItem;
462 [ + - ][ + - ]: 12 : if ( GetProperty( 1, aPropItem ) )
463 : : {
464 : : sal_uInt16 nCodePage;
465 [ + - ]: 12 : aPropItem >> nPropType;
466 [ + - ]: 12 : if ( nPropType == VT_I2 )
467 : : {
468 [ + - ]: 12 : aPropItem >> nCodePage;
469 : :
470 [ - + ]: 12 : if ( nCodePage == 1200 )
471 : : {
472 : 0 : mnTextEnc = RTL_TEXTENCODING_UCS2;
473 : : }
474 : : else
475 : : {
476 [ + - ]: 12 : mnTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage );
477 [ - + ]: 12 : if ( mnTextEnc == RTL_TEXTENCODING_DONTKNOW )
478 : 0 : mnTextEnc = RTL_TEXTENCODING_MS_1252;
479 : : }
480 : : }
481 : : else
482 : : {
483 : 12 : mnTextEnc = RTL_TEXTENCODING_MS_1252;
484 : : }
485 [ + - ]: 12 : }
486 : : }
487 : : }
488 : : else
489 : : {
490 : : sal_uInt32 nDictCount, nSize;
491 [ + - ]: 9 : *pStrm >> nDictCount;
492 [ + + ]: 18 : for ( i = 0; i < nDictCount; i++ )
493 : : {
494 [ + - ][ + - ]: 9 : *pStrm >> nSize >> nSize;
495 [ + - ]: 9 : pStrm->SeekRel( nSize );
496 : : }
497 : 9 : nSize = pStrm->Tell();
498 [ + - ]: 9 : pStrm->Seek( nPropOfs + nSecOfs );
499 : 9 : nSize -= pStrm->Tell();
500 [ - + ]: 9 : if ( nSize > nStrmSize )
501 : : {
502 : 0 : nPropCount = 0;
503 : : break;
504 : : }
505 [ + - ]: 9 : sal_uInt8* pBuf = new sal_uInt8[ nSize ];
506 [ + - ]: 9 : pStrm->Read( pBuf, nSize );
507 [ + - ]: 9 : AddProperty( 0xffffffff, pBuf, nSize );
508 [ + - ]: 9 : delete[] pBuf;
509 : : }
510 [ + - ]: 75 : pStrm->Seek( nCurrent );
511 : : }
512 [ + - ]: 21 : pStrm->Seek( nSecOfs + nSecSize );
513 : 21 : }
514 : :
515 : : // -----------------------------------------------------------------------
516 : :
517 : 0 : Section& Section::operator=( const Section& rSection )
518 : : {
519 [ # # ]: 0 : if ( this != &rSection )
520 : : {
521 : 0 : memcpy( (void*)aFMTID, (void*)rSection.aFMTID, 16 );
522 : :
523 [ # # ][ # # ]: 0 : maEntries = rSection.maEntries.clone();
524 : : }
525 : 0 : return *this;
526 : : }
527 : :
528 : : // -----------------------------------------------------------------------
529 : :
530 : 12 : PropRead::PropRead( SvStorage& rStorage, const String& rName ) :
531 : : mbStatus ( sal_False ),
532 : : mnByteOrder ( 0xfffe ),
533 : : mnFormat ( 0 ),
534 : : mnVersionLo ( 4 ),
535 [ + - ]: 12 : mnVersionHi ( 2 )
536 : : {
537 [ + - ][ + - ]: 12 : if ( rStorage.IsStream( rName ) )
538 : : {
539 [ + - ][ + - ]: 12 : mpSvStream = rStorage.OpenSotStream( rName, STREAM_STD_READ );
540 [ + - ]: 12 : if ( mpSvStream )
541 : : {
542 [ + - ]: 12 : mpSvStream->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
543 : 12 : memset( mApplicationCLSID, 0, 16 );
544 : 12 : mbStatus = sal_True;
545 : : }
546 : : }
547 : 12 : }
548 : :
549 : : // -----------------------------------------------------------------------
550 : :
551 : 21 : void PropRead::AddSection( Section& rSection )
552 : : {
553 [ + - ]: 21 : maSections.push_back( new Section( rSection ) );
554 : 21 : }
555 : :
556 : : // -----------------------------------------------------------------------
557 : :
558 : 24 : const Section* PropRead::GetSection( const sal_uInt8* pFMTID )
559 : : {
560 [ + - ]: 24 : boost::ptr_vector<Section>::iterator it;
561 [ + - ][ + - ]: 36 : for ( it = maSections.begin(); it != maSections.end(); ++it)
[ + - ][ + - ]
[ + + ]
562 : : {
563 [ + - ][ + + ]: 33 : if ( memcmp( it->GetFMTID(), pFMTID, 16 ) == 0 )
564 [ + - ]: 21 : return &(*it);
565 : : }
566 : 24 : return NULL;
567 : : }
568 : :
569 : : // -----------------------------------------------------------------------
570 : :
571 : 12 : void PropRead::Read()
572 : : {
573 : 12 : maSections.clear();
574 : :
575 [ + - ]: 12 : if ( mbStatus )
576 : : {
577 : : sal_uInt32 nSections;
578 : : sal_uInt32 nSectionOfs;
579 : : sal_uInt32 nCurrent;
580 [ + - ][ + - ]: 12 : *mpSvStream >> mnByteOrder >> mnFormat >> mnVersionLo >> mnVersionHi;
[ + - ][ + - ]
581 [ + - ]: 12 : if ( mnByteOrder == 0xfffe )
582 : : {
583 [ + - ]: 12 : sal_uInt8* pSectCLSID = new sal_uInt8[ 16 ];
584 [ + - ]: 12 : mpSvStream->Read( mApplicationCLSID, 16 );
585 [ + - ]: 12 : *mpSvStream >> nSections;
586 [ - + ]: 12 : if ( nSections > 2 ) // sj: PowerPoint documents are containing max 2 sections
587 : : {
588 : 0 : mbStatus = sal_False;
589 : : }
590 [ + + ]: 33 : else for ( sal_uInt32 i = 0; i < nSections; i++ )
591 : : {
592 [ + - ]: 21 : mpSvStream->Read( pSectCLSID, 16 );
593 [ + - ]: 21 : *mpSvStream >> nSectionOfs;
594 : 21 : nCurrent = mpSvStream->Tell();
595 [ + - ]: 21 : mpSvStream->Seek( nSectionOfs );
596 [ + - ]: 21 : Section aSection( pSectCLSID );
597 [ + - ]: 21 : aSection.Read( mpSvStream );
598 [ + - ]: 21 : AddSection( aSection );
599 [ + - ]: 21 : mpSvStream->Seek( nCurrent );
600 [ + - ]: 21 : }
601 [ + - ]: 12 : delete[] pSectCLSID;
602 : : }
603 : : }
604 : 12 : }
605 : :
606 : : // -----------------------------------------------------------------------
607 : :
608 : 0 : PropRead& PropRead::operator=( const PropRead& rPropRead )
609 : : {
610 [ # # ]: 0 : if ( this != &rPropRead )
611 : : {
612 : 0 : mbStatus = rPropRead.mbStatus;
613 : 0 : mpSvStream = rPropRead.mpSvStream;
614 : :
615 : 0 : mnByteOrder = rPropRead.mnByteOrder;
616 : 0 : mnFormat = rPropRead.mnFormat;
617 : 0 : mnVersionLo = rPropRead.mnVersionLo;
618 : 0 : mnVersionHi = rPropRead.mnVersionHi;
619 : 0 : memcpy( mApplicationCLSID, rPropRead.mApplicationCLSID, 16 );
620 : :
621 [ # # ][ # # ]: 0 : maSections = rPropRead.maSections.clone();
622 : : }
623 : 0 : return *this;
624 : : }
625 : :
626 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|