21#include <rtl/tencinfo.h>
22#include <rtl/textenc.h>
25#include <osl/diagnose.h>
33 memcpy(
mpBuf.get(), pBuf, nBufSize );
46 if (
this != &rPropEntry )
70 return static_cast< sal_Int32
>( nSize );
75 sal_uInt32
nType, nItemPos;
76 bool bRetValue =
false;
88 sal_uInt32 nItemSize(0);
98 if (nItemSize > nMaxSizePossible)
100 SAL_WARN(
"sd.filter",
"String of Len " << nItemSize <<
" claimed, only " << nMaxSizePossible <<
" possible");
101 nItemSize = nMaxSizePossible;
109 std::unique_ptr<char[]> pString(
new char[ nItemSize ] );
110 if (
mnTextEnc == RTL_TEXTENCODING_UCS2 )
116 for (sal_uInt32
i = 0;
i < nItemSize; ++
i)
127 if ( pString[ nItemSize - 1 ] == 0 )
130 rString = OUString(pString.get(), rtl_str_getLength(pString.get()),
mnTextEnc);
137 catch(
const std::bad_alloc& )
139 OSL_FAIL(
"sd PropItem::Read bad alloc" );
143 SeekRel( ( 4 - ( nItemSize & 3 ) ) & 3 );
152 if (nItemSize > nMaxSizePossible)
154 SAL_WARN(
"sd.filter",
"String of Len " << nItemSize <<
" claimed, only " << nMaxSizePossible <<
" possible");
155 nItemSize = nMaxSizePossible;
163 std::unique_ptr<sal_Unicode[]> pString(
new sal_Unicode[ nItemSize ] );
164 for (sal_uInt32
i = 0;
i < nItemSize; ++
i)
166 if ( pString[ nItemSize - 1 ] == 0 )
168 if (
static_cast<sal_uInt16
>(nItemSize) > 1 )
175 catch(
const std::bad_alloc& )
177 OSL_FAIL(
"sd PropItem::Read bad alloc" );
180 if ( bAlign && ( nItemSize & 1 ) )
192 if (
this != &rPropItem )
204 : mnTextEnc(rSection.mnTextEnc)
206 for (
int i = 0;
i < 16;
i++ )
208 for(
const std::unique_ptr<PropEntry>& rEntry : rSection.
maEntries)
209 maEntries.push_back(std::make_unique<PropEntry>(*rEntry));
214 for (
int i = 0;
i < 16;
i++ )
223 [
nId](
const std::unique_ptr<PropEntry>& rxEntry) { return rxEntry->mnId == nId; });
229 rPropItem.
WriteBytes( (*iter)->mpBuf.get(), (*iter)->mnSize );
243 if (
nId == 0xffffffff )
248 [
nId](
const std::unique_ptr<PropEntry>& rxEntry) { return rxEntry->mnId >= nId; });
251 if ( (*iter)->mnId ==
nId )
254 maEntries.insert( iter, std::make_unique<PropEntry>(
nId, pBuf, nBufSize ));
258 maEntries.push_back( std::make_unique<PropEntry>(
nId, pBuf, nBufSize ) );
265 [](
const std::unique_ptr<PropEntry>& rxEntry) { return rxEntry->mnId == 0; });
270 SvMemoryStream aStream( (*iter)->mpBuf.get(), (*iter)->mnSize, StreamMode::READ );
272 sal_uInt32 nDictCount(0);
274 for (sal_uInt32
i = 0;
i < nDictCount; ++
i)
276 sal_uInt32
nId(0), nSize(0);
287 if (
mnTextEnc == RTL_TEXTENCODING_UCS2 )
289 std::unique_ptr<sal_Unicode[]> pWString(
new sal_Unicode[nSize] );
290 for (sal_uInt32 j = 0; j < nSize; ++j)
296 std::unique_ptr<char[]> pString(
new char[nSize] );
301 catch(
const std::bad_alloc& )
303 OSL_FAIL(
"sd Section::GetDictionary bad alloc" );
305 if (aString.isEmpty())
307 rDict.insert( std::make_pair(aString,
nId) );
313 sal_uInt32 nSecOfs = pStrm->Tell();
314 sal_uInt32 nStrmSize = pStrm->remainingSize();
317 sal_uInt32 nSecSize(0), nPropCount(0);
318 pStrm->ReadUInt32(nSecSize).ReadUInt32(nPropCount);
319 if (nSecSize > nStrmSize)
321 SAL_WARN(
"sd.filter",
"Section Len " << nSecSize <<
" claimed, only " << nStrmSize <<
" possible");
322 nSecSize = nStrmSize;
327 sal_uInt32 nPropId(0), nPropOfs(0);
328 pStrm->ReadUInt32(nPropId).ReadUInt32(nPropOfs);
331 auto nCurrent = pStrm->Tell();
332 sal_uInt64 nOffset = nPropOfs + nSecOfs;
337 sal_uInt32 nPropType(0), nVectorCount(0);
338 pStrm->ReadUInt32(nPropType);
340 sal_uInt32 nPropSize = 4;
343 pStrm->ReadUInt32( nVectorCount );
344 nPropType &=~VT_VECTOR;
354 for (sal_uInt32
i = 0; nPropSize &&
i < nVectorCount && pStrm->good(); ++
i)
358 pStrm->ReadUInt32( nPropType );
391 pStrm->ReadUInt32( nTemp );
392 nPropSize += ( nTemp + 4 );
396 pStrm->ReadUInt32( nTemp );
397 nPropSize += ( nTemp + 4 );
402 pStrm->ReadUInt32( nTemp );
404 sal_uInt32
nLength = nPropOfs + nSecOfs + nPropSize + ( nTemp << 1 ) + 4;
405 nPropSize += ( nTemp << 1 ) + 4 + (
nLength % 4);
412 pStrm->ReadUInt32( nTemp );
413 nPropSize += ( nTemp + 4 );
428 if ( ( nVectorCount -
i ) > 1 )
430 nOffset = nPropOfs + nSecOfs + nPropSize;
434 if (!aVisitedOffsets.
insert(nOffset).second)
436 SAL_WARN(
"sd.filter",
"loop in Section::Read property list");
446 if ( nPropSize > nStrmSize )
450 pStrm->Seek( nPropOfs + nSecOfs );
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);
464 if ( nPropType ==
VT_I2 )
466 sal_uInt16 nCodePage(0);
469 if ( nCodePage == 1200 )
475 mnTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage );
476 if (
mnTextEnc == RTL_TEXTENCODING_DONTKNOW )
489 sal_uInt32 nDictCount(0);
490 pStrm->ReadUInt32(nDictCount);
491 auto nMaxRecordsPossible = pStrm->remainingSize() / (
sizeof(sal_uInt32)*2);
492 if (nDictCount > nMaxRecordsPossible)
494 SAL_WARN(
"sd.filter",
"Dictionary count of " << nDictCount <<
" claimed, only " << nMaxRecordsPossible <<
" possible");
495 nDictCount = nMaxRecordsPossible;
497 for (sal_uInt32
i = 0;
i < nDictCount; ++
i)
500 pStrm->ReadUInt32( nSize ).ReadUInt32( nSize );
503 sal_uInt64
nPos = pStrm->Tell() + nSize;
507 sal_uInt32 nSize = pStrm->Tell();
508 pStrm->Seek( nPropOfs + nSecOfs );
509 nSize -= pStrm->Tell();
510 if ( nSize > nStrmSize )
514 std::unique_ptr<sal_uInt8[]> pBuf(
new sal_uInt8[ nSize ] );
515 nSize = pStrm->ReadBytes(pBuf.get(), nSize);
518 pStrm->Seek(nCurrent);
520 pStrm->Seek(nSecOfs + nSecSize);
525 if (
this != &rSection )
527 memcpy(
static_cast<void*
>(
aFMTID),
static_cast<void const *
>(rSection.
aFMTID), 16 );
529 for(
const std::unique_ptr<PropEntry>& rEntry : rSection.
maEntries)
530 maEntries.push_back(std::make_unique<PropEntry>(*rEntry));
537 mnByteOrder ( 0xfffe )
544 mpSvStream->SetEndian( SvStreamEndian::LITTLE );
554 [&pFMTID](
const std::unique_ptr<Section>& rxSection) { return memcmp( rxSection->GetFMTID(), pFMTID, 16 ) == 0; });
567 sal_uInt16 mnVersionLo;
568 sal_uInt16 mnVersionHi;
570 mpSvStream->ReadUInt16(
mnByteOrder ).ReadUInt16( mnFormat ).ReadUInt16( mnVersionLo ).ReadUInt16( mnVersionHi );
574 std::vector<sal_uInt8> aSectCLSID(16);
576 sal_uInt32 nSections(0);
583 for ( sal_uInt32
i = 0;
i < nSections;
i++ )
585 mpSvStream->ReadBytes(aSectCLSID.data(), aSectCLSID.size());
586 sal_uInt32 nSectionOfs(0);
591 Section aSection(aSectCLSID.data());
593 maSections.push_back(std::make_unique<Section>(aSection));
601 if (
this != &rPropRead )
609 for(
const std::unique_ptr<Section>& rSection : rPropRead.
maSections)
610 maSections.push_back(std::make_unique<Section>(*rSection));
PropItem & operator=(PropItem &rPropItem)
bool Read(OUString &rString, sal_uInt32 nType=VT_EMPTY, bool bDwordAlign=true)
void SetTextEncoding(sal_uInt16 nTextEnc)
const Section * GetSection(const sal_uInt8 *pFMTID)
std::vector< std::unique_ptr< Section > > maSections
PropRead & operator=(const PropRead &rPropRead)
tools::SvRef< SotStorageStream > mpSvStream
sal_uInt8 mApplicationCLSID[16]
PropRead(SotStorage &rSvStorage, const OUString &rName)
Section & operator=(const Section &rSection)
void GetDictionary(PropDictionary &rDict)
Section(const sal_uInt8 *pFMTID)
bool GetProperty(sal_uInt32 nId, PropItem &rPropItem)
void Read(SotStorageStream *pStrm)
std::vector< std::unique_ptr< PropEntry > > maEntries
void AddProperty(sal_uInt32 nId, const sal_uInt8 *pBuf, sal_uInt32 nBufSize)
bool IsStream(const OUString &rEleName) const
tools::SvRef< SotStorageStream > OpenSotStream(const OUString &rEleName, StreamMode=StreamMode::STD_READWRITE)
virtual sal_uInt64 TellEnd() override
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)
#define SAL_WARN(area, stream)
static sal_Int32 lcl_getMaxSafeStrLen(sal_uInt32 nSize)
#define VT_STREAMED_OBJECT
std::map< OUString, sal_uInt32 > PropDictionary
#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)
PropEntry & operator=(const PropEntry &rPropEntry)
std::unique_ptr< sal_uInt8[]> mpBuf