LibreOffice Module sd (master) 1
propread.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include "propread.hxx"
21#include <rtl/tencinfo.h>
22#include <rtl/textenc.h>
23#include <sal/log.hxx>
25#include <osl/diagnose.h>
26#include <memory>
27
28PropEntry::PropEntry( sal_uInt32 nId, const sal_uInt8* pBuf, sal_uInt32 nBufSize ) :
29 mnId ( nId ),
30 mnSize ( nBufSize ),
31 mpBuf ( new sal_uInt8[ nBufSize ] )
32{
33 memcpy( mpBuf.get(), pBuf, nBufSize );
34};
35
37 mnId ( rProp.mnId ),
38 mnSize ( rProp.mnSize ),
39 mpBuf ( new sal_uInt8[ mnSize ] )
40{
41 memcpy( mpBuf.get(), rProp.mpBuf.get(), mnSize );
42};
43
45{
46 if ( this != &rPropEntry )
47 {
48 mnId = rPropEntry.mnId;
49 mnSize = rPropEntry.mnSize;
50 mpBuf.reset( new sal_uInt8[ mnSize ] );
51 memcpy( mpBuf.get(), rPropEntry.mpBuf.get(), mnSize );
52 }
53 return *this;
54}
55
57{
59 delete[] static_cast<sal_uInt8*>(SwitchBuffer());
60}
61
62static sal_Int32 lcl_getMaxSafeStrLen(sal_uInt32 nSize)
63{
64 nSize -= 1; //Drop NULL terminator
65
66 //If it won't fit in a string, clip it to the max size that does
67 if (nSize > SAL_MAX_INT32)
68 nSize = SAL_MAX_INT32;
69
70 return static_cast< sal_Int32 >( nSize );
71}
72
73bool PropItem::Read( OUString& rString, sal_uInt32 nStringType, bool bAlign )
74{
75 sal_uInt32 nType, nItemPos;
76 bool bRetValue = false;
77
78 nItemPos = Tell();
79
80 if ( nStringType == VT_EMPTY )
81 {
82 nType = VT_NULL; // Initialize in case stream fails.
84 }
85 else
86 nType = nStringType & VT_TYPEMASK;
87
88 sal_uInt32 nItemSize(0); // Initialize in case stream fails.
89 ReadUInt32(nItemSize);
90
91 switch( nType )
92 {
93 case VT_LPSTR :
94 {
95 if (nItemSize)
96 {
97 auto nMaxSizePossible = remainingSize();
98 if (nItemSize > nMaxSizePossible)
99 {
100 SAL_WARN("sd.filter", "String of Len " << nItemSize << " claimed, only " << nMaxSizePossible << " possible");
101 nItemSize = nMaxSizePossible;
102 }
103 }
104
105 if (nItemSize)
106 {
107 try
108 {
109 std::unique_ptr<char[]> pString( new char[ nItemSize ] );
110 if ( mnTextEnc == RTL_TEXTENCODING_UCS2 )
111 {
112 nItemSize >>= 1;
113 if ( nItemSize > 1 )
114 {
115 sal_Unicode* pWString = reinterpret_cast<sal_Unicode*>(pString.get());
116 for (sal_uInt32 i = 0; i < nItemSize; ++i)
117 ReadUtf16( pWString[ i ] );
118 rString = OUString(pWString, lcl_getMaxSafeStrLen(nItemSize));
119 }
120 else
121 rString.clear();
122 bRetValue = true;
123 }
124 else
125 {
126 SvMemoryStream::ReadBytes(pString.get(), nItemSize);
127 if ( pString[ nItemSize - 1 ] == 0 )
128 {
129 if ( nItemSize > 1 )
130 rString = OUString(pString.get(), rtl_str_getLength(pString.get()), mnTextEnc);
131 else
132 rString.clear();
133 bRetValue = true;
134 }
135 }
136 }
137 catch( const std::bad_alloc& )
138 {
139 OSL_FAIL( "sd PropItem::Read bad alloc" );
140 }
141 }
142 if ( bAlign )
143 SeekRel( ( 4 - ( nItemSize & 3 ) ) & 3 ); // dword align
144 }
145 break;
146
147 case VT_LPWSTR :
148 {
149 if (nItemSize)
150 {
151 auto nMaxSizePossible = remainingSize() / sizeof(sal_Unicode);
152 if (nItemSize > nMaxSizePossible)
153 {
154 SAL_WARN("sd.filter", "String of Len " << nItemSize << " claimed, only " << nMaxSizePossible << " possible");
155 nItemSize = nMaxSizePossible;
156 }
157 }
158
159 if (nItemSize)
160 {
161 try
162 {
163 std::unique_ptr<sal_Unicode[]> pString( new sal_Unicode[ nItemSize ] );
164 for (sal_uInt32 i = 0; i < nItemSize; ++i)
165 ReadUtf16( pString[ i ] );
166 if ( pString[ nItemSize - 1 ] == 0 )
167 {
168 if ( static_cast<sal_uInt16>(nItemSize) > 1 )
169 rString = OUString(pString.get(), lcl_getMaxSafeStrLen(nItemSize));
170 else
171 rString.clear();
172 bRetValue = true;
173 }
174 }
175 catch( const std::bad_alloc& )
176 {
177 OSL_FAIL( "sd PropItem::Read bad alloc" );
178 }
179 }
180 if ( bAlign && ( nItemSize & 1 ) )
181 SeekRel( 2 ); // dword align
182 }
183 break;
184 }
185 if ( !bRetValue )
186 Seek( nItemPos );
187 return bRetValue;
188}
189
191{
192 if ( this != &rPropItem )
193 {
195 delete[] static_cast<sal_uInt8*>(SwitchBuffer());
196
197 mnTextEnc = rPropItem.mnTextEnc;
198 SvMemoryStream::WriteBytes(rPropItem.GetData(), rPropItem.TellEnd());
199 }
200 return *this;
201}
202
203Section::Section( const Section& rSection )
204 : mnTextEnc(rSection.mnTextEnc)
205{
206 for ( int i = 0; i < 16; i++ )
207 aFMTID[ i ] = rSection.aFMTID[ i ];
208 for(const std::unique_ptr<PropEntry>& rEntry : rSection.maEntries)
209 maEntries.push_back(std::make_unique<PropEntry>(*rEntry));
210}
211
212Section::Section( const sal_uInt8* pFMTID ) : mnTextEnc(RTL_TEXTENCODING_MS_1252)
213{
214 for ( int i = 0; i < 16; i++ )
215 aFMTID[ i ] = pFMTID[ i ];
216}
217
218bool Section::GetProperty( sal_uInt32 nId, PropItem& rPropItem )
219{
220 if ( nId )
221 {
222 auto iter = std::find_if(maEntries.begin(), maEntries.end(),
223 [nId](const std::unique_ptr<PropEntry>& rxEntry) { return rxEntry->mnId == nId; });
224
225 if (iter != maEntries.end())
226 {
227 rPropItem.Clear();
228 rPropItem.SetTextEncoding( mnTextEnc );
229 rPropItem.WriteBytes( (*iter)->mpBuf.get(), (*iter)->mnSize );
230 rPropItem.Seek( STREAM_SEEK_TO_BEGIN );
231 return true;
232 }
233 }
234 return false;
235}
236
237void Section::AddProperty( sal_uInt32 nId, const sal_uInt8* pBuf, sal_uInt32 nBufSize )
238{
239 // just a simple id check
240
241 if ( !nId )
242 return;
243 if ( nId == 0xffffffff )
244 nId = 0;
245
246 // do not allow same PropId's, sort
247 auto iter = std::find_if(maEntries.begin(), maEntries.end(),
248 [nId](const std::unique_ptr<PropEntry>& rxEntry) { return rxEntry->mnId >= nId; });
249 if (iter != maEntries.end())
250 {
251 if ( (*iter)->mnId == nId )
252 (*iter).reset(new PropEntry( nId, pBuf, nBufSize ));
253 else
254 maEntries.insert( iter, std::make_unique<PropEntry>( nId, pBuf, nBufSize ));
255 }
256 else
257 {
258 maEntries.push_back( std::make_unique<PropEntry>( nId, pBuf, nBufSize ) );
259 }
260}
261
263{
264 auto iter = std::find_if(maEntries.begin(), maEntries.end(),
265 [](const std::unique_ptr<PropEntry>& rxEntry) { return rxEntry->mnId == 0; });
266
267 if (iter == maEntries.end())
268 return;
269
270 SvMemoryStream aStream( (*iter)->mpBuf.get(), (*iter)->mnSize, StreamMode::READ );
271 aStream.Seek( STREAM_SEEK_TO_BEGIN );
272 sal_uInt32 nDictCount(0);
273 aStream.ReadUInt32( nDictCount );
274 for (sal_uInt32 i = 0; i < nDictCount; ++i)
275 {
276 sal_uInt32 nId(0), nSize(0);
277 aStream.ReadUInt32(nId).ReadUInt32(nSize);
278 if (!aStream.good() || nSize > aStream.remainingSize())
279 break;
280 if (mnTextEnc == RTL_TEXTENCODING_UCS2)
281 nSize >>= 1;
282 if (!nSize)
283 continue;
284 OUString aString;
285 try
286 {
287 if ( mnTextEnc == RTL_TEXTENCODING_UCS2 )
288 {
289 std::unique_ptr<sal_Unicode[]> pWString( new sal_Unicode[nSize] );
290 for (sal_uInt32 j = 0; j < nSize; ++j)
291 aStream.ReadUtf16(pWString[j]);
292 aString = OUString(pWString.get(), lcl_getMaxSafeStrLen(nSize));
293 }
294 else
295 {
296 std::unique_ptr<char[]> pString( new char[nSize] );
297 aStream.ReadBytes(pString.get(), nSize);
298 aString = OUString(pString.get(), lcl_getMaxSafeStrLen(nSize), mnTextEnc);
299 }
300 }
301 catch( const std::bad_alloc& )
302 {
303 OSL_FAIL( "sd Section::GetDictionary bad alloc" );
304 }
305 if (aString.isEmpty())
306 break;
307 rDict.insert( std::make_pair(aString,nId) );
308 }
309}
310
312{
313 sal_uInt32 nSecOfs = pStrm->Tell();
314 sal_uInt32 nStrmSize = pStrm->remainingSize();
315
316 mnTextEnc = RTL_TEXTENCODING_MS_1252;
317 sal_uInt32 nSecSize(0), nPropCount(0);
318 pStrm->ReadUInt32(nSecSize).ReadUInt32(nPropCount);
319 if (nSecSize > nStrmSize)
320 {
321 SAL_WARN("sd.filter", "Section Len " << nSecSize << " claimed, only " << nStrmSize << " possible");
322 nSecSize = nStrmSize;
323 }
324
325 while (nPropCount--)
326 {
327 sal_uInt32 nPropId(0), nPropOfs(0);
328 pStrm->ReadUInt32(nPropId).ReadUInt32(nPropOfs);
329 if (!pStrm->good())
330 break;
331 auto nCurrent = pStrm->Tell();
332 sal_uInt64 nOffset = nPropOfs + nSecOfs;
333 if (!checkSeek(*pStrm, nOffset))
334 break;
335 if ( nPropId ) // do not read dictionary
336 {
337 sal_uInt32 nPropType(0), nVectorCount(0);
338 pStrm->ReadUInt32(nPropType);
339
340 sal_uInt32 nPropSize = 4;
341 if ( nPropType & VT_VECTOR )
342 {
343 pStrm->ReadUInt32( nVectorCount );
344 nPropType &=~VT_VECTOR;
345 nPropSize += 4;
346 }
347 else
348 nVectorCount = 1;
349
350 bool bVariant = ( nPropType == VT_VARIANT );
351
352 o3tl::sorted_vector<sal_uInt64> aVisitedOffsets;
353
354 for (sal_uInt32 i = 0; nPropSize && i < nVectorCount && pStrm->good(); ++i)
355 {
356 if ( bVariant )
357 {
358 pStrm->ReadUInt32( nPropType );
359 nPropSize += 4;
360 }
361 sal_uInt32 nTemp(0);
362 switch( nPropType )
363 {
364 case VT_UI1 :
365 nPropSize++;
366 break;
367
368 case VT_I2 :
369 case VT_UI2 :
370 case VT_BOOL :
371 nPropSize += 2;
372 break;
373
374 case VT_I4 :
375 case VT_R4 :
376 case VT_UI4 :
377 case VT_ERROR :
378 nPropSize += 4;
379 break;
380
381 case VT_I8 :
382 case VT_R8 :
383 case VT_CY :
384 case VT_UI8 :
385 case VT_DATE :
386 case VT_FILETIME :
387 nPropSize += 8;
388 break;
389
390 case VT_BSTR :
391 pStrm->ReadUInt32( nTemp );
392 nPropSize += ( nTemp + 4 );
393 break;
394
395 case VT_LPSTR :
396 pStrm->ReadUInt32( nTemp );
397 nPropSize += ( nTemp + 4 );
398 break;
399
400 case VT_LPWSTR :
401 {
402 pStrm->ReadUInt32( nTemp );
403 // looks like these are aligned to 4 bytes
404 sal_uInt32 nLength = nPropOfs + nSecOfs + nPropSize + ( nTemp << 1 ) + 4;
405 nPropSize += ( nTemp << 1 ) + 4 + (nLength % 4);
406 }
407 break;
408
409 case VT_BLOB_OBJECT :
410 case VT_BLOB :
411 case VT_CF :
412 pStrm->ReadUInt32( nTemp );
413 nPropSize += ( nTemp + 4 );
414 break;
415
416 case VT_CLSID :
417 case VT_STREAM :
418 case VT_STORAGE :
419 case VT_STREAMED_OBJECT :
420 case VT_STORED_OBJECT :
421 case VT_VARIANT :
422 case VT_VECTOR :
423 default :
424 nPropSize = 0;
425 }
426 if ( nPropSize )
427 {
428 if ( ( nVectorCount - i ) > 1 )
429 {
430 nOffset = nPropOfs + nSecOfs + nPropSize;
431 if (!checkSeek(*pStrm, nOffset))
432 break;
433 // inserts returns false if an equivalent element already existed
434 if (!aVisitedOffsets.insert(nOffset).second)
435 {
436 SAL_WARN("sd.filter", "loop in Section::Read property list");
437 break;
438 }
439 }
440 }
441 else
442 break;
443 }
444 if ( nPropSize )
445 {
446 if ( nPropSize > nStrmSize )
447 {
448 break;
449 }
450 pStrm->Seek( nPropOfs + nSecOfs );
451 // make sure we don't overflow the section size
452 if( nPropSize > nSecSize - nSecOfs )
453 nPropSize = nSecSize - nSecOfs;
454 std::unique_ptr<sal_uInt8[]> pBuf( new sal_uInt8[ nPropSize ] );
455 nPropSize = pStrm->ReadBytes(pBuf.get(), nPropSize);
456 AddProperty( nPropId, pBuf.get(), nPropSize );
457 }
458 if ( nPropId == 1 )
459 {
460 PropItem aPropItem;
461 if ( GetProperty( 1, aPropItem ) )
462 {
463 aPropItem.ReadUInt32( nPropType );
464 if ( nPropType == VT_I2 )
465 {
466 sal_uInt16 nCodePage(0);
467 aPropItem.ReadUInt16(nCodePage);
468
469 if ( nCodePage == 1200 )
470 {
471 mnTextEnc = RTL_TEXTENCODING_UCS2;
472 }
473 else
474 {
475 mnTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage );
476 if ( mnTextEnc == RTL_TEXTENCODING_DONTKNOW )
477 mnTextEnc = RTL_TEXTENCODING_MS_1252;
478 }
479 }
480 else
481 {
482 mnTextEnc = RTL_TEXTENCODING_MS_1252;
483 }
484 }
485 }
486 }
487 else
488 {
489 sal_uInt32 nDictCount(0);
490 pStrm->ReadUInt32(nDictCount);
491 auto nMaxRecordsPossible = pStrm->remainingSize() / (sizeof(sal_uInt32)*2);
492 if (nDictCount > nMaxRecordsPossible)
493 {
494 SAL_WARN("sd.filter", "Dictionary count of " << nDictCount << " claimed, only " << nMaxRecordsPossible << " possible");
495 nDictCount = nMaxRecordsPossible;
496 }
497 for (sal_uInt32 i = 0; i < nDictCount; ++i)
498 {
499 sal_uInt32 nSize(0);
500 pStrm->ReadUInt32( nSize ).ReadUInt32( nSize );
501 if (!pStrm->good())
502 break;
503 sal_uInt64 nPos = pStrm->Tell() + nSize;
504 if (!checkSeek(*pStrm, nPos))
505 break;
506 }
507 sal_uInt32 nSize = pStrm->Tell();
508 pStrm->Seek( nPropOfs + nSecOfs );
509 nSize -= pStrm->Tell();
510 if ( nSize > nStrmSize )
511 {
512 break;
513 }
514 std::unique_ptr<sal_uInt8[]> pBuf( new sal_uInt8[ nSize ] );
515 nSize = pStrm->ReadBytes(pBuf.get(), nSize);
516 AddProperty( 0xffffffff, pBuf.get(), nSize );
517 }
518 pStrm->Seek(nCurrent);
519 }
520 pStrm->Seek(nSecOfs + nSecSize);
521}
522
524{
525 if ( this != &rSection )
526 {
527 memcpy( static_cast<void*>(aFMTID), static_cast<void const *>(rSection.aFMTID), 16 );
528
529 for(const std::unique_ptr<PropEntry>& rEntry : rSection.maEntries)
530 maEntries.push_back(std::make_unique<PropEntry>(*rEntry));
531 }
532 return *this;
533}
534
535PropRead::PropRead( SotStorage& rStorage, const OUString& rName ) :
536 mbStatus ( false ),
537 mnByteOrder ( 0xfffe )
538{
539 if ( rStorage.IsStream( rName ) )
540 {
541 mpSvStream = rStorage.OpenSotStream( rName, StreamMode::STD_READ );
542 if ( mpSvStream.is() )
543 {
544 mpSvStream->SetEndian( SvStreamEndian::LITTLE );
545 memset( mApplicationCLSID, 0, 16 );
546 mbStatus = true;
547 }
548 }
549}
550
552{
553 auto it = std::find_if(maSections.begin(), maSections.end(),
554 [&pFMTID](const std::unique_ptr<Section>& rxSection) { return memcmp( rxSection->GetFMTID(), pFMTID, 16 ) == 0; });
555 if (it != maSections.end())
556 return it->get();
557 return nullptr;
558}
559
561{
562 maSections.clear();
563
564 if ( !mbStatus )
565 return;
566
567 sal_uInt16 mnVersionLo;
568 sal_uInt16 mnVersionHi;
569 sal_uInt16 mnFormat;
570 mpSvStream->ReadUInt16( mnByteOrder ).ReadUInt16( mnFormat ).ReadUInt16( mnVersionLo ).ReadUInt16( mnVersionHi );
571 if ( mnByteOrder != 0xfffe )
572 return;
573
574 std::vector<sal_uInt8> aSectCLSID(16);
575 mpSvStream->ReadBytes(mApplicationCLSID, 16);
576 sal_uInt32 nSections(0);
577 mpSvStream->ReadUInt32(nSections);
578 if ( nSections > 2 ) // sj: PowerPoint documents are containing max 2 sections
579 {
580 mbStatus = false;
581 }
582 else
583 for ( sal_uInt32 i = 0; i < nSections; i++ )
584 {
585 mpSvStream->ReadBytes(aSectCLSID.data(), aSectCLSID.size());
586 sal_uInt32 nSectionOfs(0);
587 mpSvStream->ReadUInt32( nSectionOfs );
588 sal_uInt32 nCurrent = mpSvStream->Tell();
589 if (checkSeek(*mpSvStream, nSectionOfs))
590 {
591 Section aSection(aSectCLSID.data());
592 aSection.Read(mpSvStream.get());
593 maSections.push_back(std::make_unique<Section>(aSection));
594 }
595 mpSvStream->Seek( nCurrent );
596 }
597}
598
600{
601 if ( this != &rPropRead )
602 {
603 mbStatus = rPropRead.mbStatus;
604 mpSvStream = rPropRead.mpSvStream;
605
606 mnByteOrder = rPropRead.mnByteOrder;
607 memcpy( mApplicationCLSID, rPropRead.mApplicationCLSID, 16 );
608
609 for(const std::unique_ptr<Section>& rSection : rPropRead.maSections)
610 maSections.push_back(std::make_unique<Section>(*rSection));
611 }
612 return *this;
613}
614
615/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
PropItem & operator=(PropItem &rPropItem)
Definition: propread.cxx:190
void Clear()
Definition: propread.cxx:56
bool Read(OUString &rString, sal_uInt32 nType=VT_EMPTY, bool bDwordAlign=true)
Definition: propread.cxx:73
void SetTextEncoding(sal_uInt16 nTextEnc)
Definition: propread.hxx:108
sal_uInt16 mnTextEnc
Definition: propread.hxx:99
bool mbStatus
Definition: propread.hxx:135
const Section * GetSection(const sal_uInt8 *pFMTID)
Definition: propread.cxx:551
std::vector< std::unique_ptr< Section > > maSections
Definition: propread.hxx:140
PropRead & operator=(const PropRead &rPropRead)
Definition: propread.cxx:599
tools::SvRef< SotStorageStream > mpSvStream
Definition: propread.hxx:136
void Read()
Definition: propread.cxx:560
sal_uInt8 mApplicationCLSID[16]
Definition: propread.hxx:139
sal_uInt16 mnByteOrder
Definition: propread.hxx:138
PropRead(SotStorage &rSvStorage, const OUString &rName)
Definition: propread.cxx:535
Section & operator=(const Section &rSection)
Definition: propread.cxx:523
void GetDictionary(PropDictionary &rDict)
Definition: propread.cxx:262
Section(const sal_uInt8 *pFMTID)
Definition: propread.cxx:212
bool GetProperty(sal_uInt32 nId, PropItem &rPropItem)
Definition: propread.cxx:218
void Read(SotStorageStream *pStrm)
Definition: propread.cxx:311
std::vector< std::unique_ptr< PropEntry > > maEntries
Definition: propread.hxx:116
sal_uInt16 mnTextEnc
Definition: propread.hxx:115
void AddProperty(sal_uInt32 nId, const sal_uInt8 *pBuf, sal_uInt32 nBufSize)
Definition: propread.cxx:237
sal_uInt8 aFMTID[16]
Definition: propread.hxx:118
bool IsStream(const OUString &rEleName) const
tools::SvRef< SotStorageStream > OpenSotStream(const OUString &rEleName, StreamMode=StreamMode::STD_READWRITE)
void * SwitchBuffer()
const void * GetData()
virtual sal_uInt64 TellEnd() override
sal_uInt64 Tell() const
bool good() const
std::size_t WriteBytes(const void *pData, std::size_t nSize)
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
SvStream & ReadUtf16(sal_Unicode &rUtf16)
sal_uInt64 Seek(sal_uInt64 nPos)
std::size_t ReadBytes(void *pData, std::size_t nSize)
sal_uInt64 SeekRel(sal_Int64 nPos)
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
sal_uInt64 remainingSize()
std::pair< const_iterator, bool > insert(Value &&x)
T * get() const
bool is() const
sal_uInt16 mnId
sal_uInt32 mnSize
sal_uInt16 nPos
#define SAL_WARN(area, stream)
int i
sal_Int16 nId
static sal_Int32 lcl_getMaxSafeStrLen(sal_uInt32 nSize)
Definition: propread.cxx:62
#define VT_LPSTR
Definition: propread.hxx:67
#define VT_UI2
Definition: propread.hxx:61
#define VT_DATE
Definition: propread.hxx:53
#define VT_BLOB_OBJECT
Definition: propread.hxx:75
#define VT_EMPTY
Definition: propread.hxx:46
#define VT_R4
Definition: propread.hxx:50
#define VT_UI4
Definition: propread.hxx:62
#define VT_STORED_OBJECT
Definition: propread.hxx:74
#define VT_BSTR
Definition: propread.hxx:54
#define VT_FILETIME
Definition: propread.hxx:69
#define VT_CF
Definition: propread.hxx:76
#define VT_R8
Definition: propread.hxx:51
#define VT_I8
Definition: propread.hxx:63
#define VT_BLOB
Definition: propread.hxx:70
#define VT_VARIANT
Definition: propread.hxx:57
#define VT_VECTOR
Definition: propread.hxx:78
#define VT_STREAM
Definition: propread.hxx:71
#define VT_ERROR
Definition: propread.hxx:55
#define VT_CLSID
Definition: propread.hxx:77
#define VT_UI8
Definition: propread.hxx:64
#define VT_STORAGE
Definition: propread.hxx:72
#define VT_TYPEMASK
Definition: propread.hxx:81
#define VT_STREAMED_OBJECT
Definition: propread.hxx:73
#define VT_NULL
Definition: propread.hxx:47
#define VT_BOOL
Definition: propread.hxx:56
#define VT_CY
Definition: propread.hxx:52
std::map< OUString, sal_uInt32 > PropDictionary
Definition: propread.hxx:83
#define VT_I4
Definition: propread.hxx:49
#define VT_UI1
Definition: propread.hxx:60
#define VT_LPWSTR
Definition: propread.hxx:68
#define VT_I2
Definition: propread.hxx:48
QPRO_FUNC_TYPE nType
#define STREAM_SEEK_TO_BEGIN
TOOLS_DLLPUBLIC bool checkSeek(SvStream &rSt, sal_uInt64 nOffset)
PropEntry(sal_uInt32 nId, const sal_uInt8 *pBuf, sal_uInt32 nBufSize)
Definition: propread.cxx:28
sal_uInt32 mnSize
Definition: propread.hxx:88
sal_uInt32 mnId
Definition: propread.hxx:87
PropEntry & operator=(const PropEntry &rPropEntry)
Definition: propread.cxx:44
std::unique_ptr< sal_uInt8[]> mpBuf
Definition: propread.hxx:89
unsigned char sal_uInt8
#define SAL_MAX_INT32
sal_uInt16 sal_Unicode
sal_Int32 nLength