sot: prevent some null pointer crashes
This commit is contained in:
parent
c75e2ed27d
commit
10dc090b31
13 changed files with 393 additions and 165 deletions
|
@ -91,7 +91,8 @@ const SvStream* OLEStorageBase::GetSvStream_Impl() const
|
|||
OLEStorageBase::OLEStorageBase( StgIo* p, StgDirEntry* pe, StreamMode& nMode )
|
||||
: nStreamMode( nMode ), pIo( p ), pEntry( pe )
|
||||
{
|
||||
p->IncRef();
|
||||
if ( p )
|
||||
p->IncRef();
|
||||
if( pe )
|
||||
pe->nRefCnt++;
|
||||
}
|
||||
|
@ -108,21 +109,28 @@ OLEStorageBase::~OLEStorageBase()
|
|||
else
|
||||
pEntry->Close();
|
||||
}
|
||||
|
||||
pEntry = NULL;
|
||||
}
|
||||
|
||||
|
||||
if( !pIo->DecRef() )
|
||||
if( pIo && !pIo->DecRef() )
|
||||
{
|
||||
delete pIo;
|
||||
pIo = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the instance for I/O
|
||||
|
||||
sal_Bool OLEStorageBase::Validate_Impl( sal_Bool bWrite ) const
|
||||
{
|
||||
if( pEntry
|
||||
if( pIo
|
||||
&& pIo->pTOC
|
||||
&& pEntry
|
||||
&& !pEntry->bInvalid
|
||||
&& ( !bWrite || !pEntry->bDirect || ( nStreamMode & STREAM_WRITE ) ) )
|
||||
return sal_True;
|
||||
return sal_True;
|
||||
return sal_False;
|
||||
}
|
||||
|
||||
|
@ -161,7 +169,7 @@ StorageStream::StorageStream( StgIo* p, StgDirEntry* q, StreamMode m )
|
|||
: OLEStorageBase( p, q, m_nMode ), nPos( 0L )
|
||||
{
|
||||
// The dir entry may be 0; this means that the stream is invalid.
|
||||
if( q )
|
||||
if( q && p )
|
||||
{
|
||||
if( q->nRefCnt == 1 )
|
||||
{
|
||||
|
@ -269,14 +277,21 @@ sal_Bool StorageStream::Commit()
|
|||
|
||||
sal_Bool StorageStream::Revert()
|
||||
{
|
||||
pEntry->Revert();
|
||||
pIo->MoveError( *this );
|
||||
return Good();
|
||||
sal_Bool bResult = sal_False;
|
||||
|
||||
if ( Validate() )
|
||||
{
|
||||
pEntry->Revert();
|
||||
pIo->MoveError( *this );
|
||||
bResult = Good();
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
sal_Bool StorageStream::CopyTo( BaseStorageStream* pDest )
|
||||
{
|
||||
if( !Validate() || !pDest->Validate( sal_True ) || Equals( *pDest ) )
|
||||
if( !Validate() || !pDest || !pDest->Validate( sal_True ) || Equals( *pDest ) )
|
||||
return sal_False;
|
||||
pEntry->Copy( *pDest );
|
||||
pDest->Commit();
|
||||
|
@ -328,14 +343,20 @@ sal_Bool Storage::IsStorageFile( const String & rFileName )
|
|||
|
||||
sal_Bool Storage::IsStorageFile( SvStream* pStream )
|
||||
{
|
||||
StgHeader aHdr;
|
||||
sal_uLong nPos = pStream->Tell();
|
||||
sal_Bool bRet = ( aHdr.Load( *pStream ) && aHdr.Check() );
|
||||
sal_Bool bRet = sal_False;
|
||||
|
||||
if ( pStream )
|
||||
{
|
||||
StgHeader aHdr;
|
||||
sal_uLong nPos = pStream->Tell();
|
||||
bRet = ( aHdr.Load( *pStream ) && aHdr.Check() );
|
||||
|
||||
// It's not a stream error if it is too small for a OLE storage header
|
||||
if ( pStream->GetErrorCode() == ERRCODE_IO_CANTSEEK )
|
||||
pStream->ResetError();
|
||||
pStream->Seek( nPos );
|
||||
}
|
||||
|
||||
// It's not a stream error if it is too small for a OLE storage header
|
||||
if ( pStream->GetErrorCode() == ERRCODE_IO_CANTSEEK )
|
||||
pStream->ResetError();
|
||||
pStream->Seek( nPos );
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
@ -450,7 +471,9 @@ void Storage::Init( sal_Bool bCreate )
|
|||
pEntry = NULL;
|
||||
sal_Bool bHdrLoaded = sal_False;
|
||||
bIsRoot = sal_True;
|
||||
if( pIo->Good() )
|
||||
|
||||
OSL_ENSURE( pIo, "The pointer may not be empty at this point!" );
|
||||
if( pIo->Good() && pIo->GetStrm() )
|
||||
{
|
||||
sal_uLong nSize = pIo->GetStrm()->Seek( STREAM_SEEK_TO_END );
|
||||
pIo->GetStrm()->Seek( 0L );
|
||||
|
@ -471,7 +494,7 @@ void Storage::Init( sal_Bool bCreate )
|
|||
// the file is empty
|
||||
if( !bHdrLoaded )
|
||||
pIo->Init();
|
||||
if( pIo->Good() )
|
||||
if( pIo->Good() && pIo->pTOC )
|
||||
{
|
||||
pEntry = pIo->pTOC->GetRoot();
|
||||
pEntry->nRefCnt++;
|
||||
|
@ -526,7 +549,7 @@ const String& Storage::GetName() const
|
|||
|
||||
void Storage::FillInfoList( SvStorageInfoList* pList ) const
|
||||
{
|
||||
if( Validate() )
|
||||
if( Validate() && pList )
|
||||
{
|
||||
StgIterator aIter( *pEntry );
|
||||
StgDirEntry* p = aIter.First();
|
||||
|
@ -709,21 +732,24 @@ sal_Bool Storage::CopyTo( const String& rElem, BaseStorage* pDest, const String&
|
|||
BaseStorage* p1 = OpenStorage( rElem, INTERNAL_MODE );
|
||||
BaseStorage* p2 = pDest->OpenOLEStorage( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pEntry->bDirect );
|
||||
|
||||
sal_uLong nTmpErr = p2->GetError();
|
||||
if( !nTmpErr )
|
||||
if ( p2 )
|
||||
{
|
||||
p2->SetClassId( p1->GetClassId() );
|
||||
p1->CopyTo( p2 );
|
||||
SetError( p1->GetError() );
|
||||
|
||||
nTmpErr = p2->GetError();
|
||||
sal_uLong nTmpErr = p2->GetError();
|
||||
if( !nTmpErr )
|
||||
p2->Commit();
|
||||
{
|
||||
p2->SetClassId( p1->GetClassId() );
|
||||
p1->CopyTo( p2 );
|
||||
SetError( p1->GetError() );
|
||||
|
||||
nTmpErr = p2->GetError();
|
||||
if( !nTmpErr )
|
||||
p2->Commit();
|
||||
else
|
||||
pDest->SetError( nTmpErr );
|
||||
}
|
||||
else
|
||||
pDest->SetError( nTmpErr );
|
||||
}
|
||||
else
|
||||
pDest->SetError( nTmpErr );
|
||||
|
||||
delete p1;
|
||||
delete p2;
|
||||
|
@ -735,20 +761,23 @@ sal_Bool Storage::CopyTo( const String& rElem, BaseStorage* pDest, const String&
|
|||
BaseStorageStream* p1 = OpenStream( rElem, INTERNAL_MODE );
|
||||
BaseStorageStream* p2 = pDest->OpenStream( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pEntry->bDirect );
|
||||
|
||||
sal_uLong nTmpErr = p2->GetError();
|
||||
if( !nTmpErr )
|
||||
if ( p2 )
|
||||
{
|
||||
p1->CopyTo( p2 );
|
||||
SetError( p1->GetError() );
|
||||
|
||||
nTmpErr = p2->GetError();
|
||||
sal_uLong nTmpErr = p2->GetError();
|
||||
if( !nTmpErr )
|
||||
p2->Commit();
|
||||
{
|
||||
p1->CopyTo( p2 );
|
||||
SetError( p1->GetError() );
|
||||
|
||||
nTmpErr = p2->GetError();
|
||||
if( !nTmpErr )
|
||||
p2->Commit();
|
||||
else
|
||||
pDest->SetError( nTmpErr );
|
||||
}
|
||||
else
|
||||
pDest->SetError( nTmpErr );
|
||||
}
|
||||
else
|
||||
pDest->SetError( nTmpErr );
|
||||
|
||||
delete p1;
|
||||
delete p2;
|
||||
|
@ -999,17 +1028,23 @@ sal_Bool Storage::ValidateFAT()
|
|||
|
||||
void Storage::SetDirty()
|
||||
{
|
||||
pEntry->SetDirty();
|
||||
if ( pEntry )
|
||||
pEntry->SetDirty();
|
||||
}
|
||||
|
||||
void Storage::SetClassId( const ClsId& rId )
|
||||
{
|
||||
pEntry->aEntry.SetClassId( rId );
|
||||
if ( pEntry )
|
||||
pEntry->aEntry.SetClassId( rId );
|
||||
}
|
||||
|
||||
const ClsId& Storage::GetClassId() const
|
||||
{
|
||||
return pEntry->aEntry.GetClassId();
|
||||
if ( pEntry )
|
||||
return pEntry->aEntry.GetClassId();
|
||||
|
||||
static ClsId aDummyId = {0,0,0,0,0,0,0,0,0,0,0};
|
||||
return aDummyId;
|
||||
}
|
||||
|
||||
const SvStream* Storage::GetSvStream() const
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
||||
*/
|
||||
|
||||
#include <osl/diagnose.h>
|
||||
#include "stgavl.hxx"
|
||||
|
||||
StgAvlNode::StgAvlNode()
|
||||
|
@ -33,13 +34,16 @@ StgAvlNode::~StgAvlNode()
|
|||
|
||||
StgAvlNode* StgAvlNode::Find( StgAvlNode* pFind )
|
||||
{
|
||||
StgAvlNode* p = this;
|
||||
while( p )
|
||||
if ( pFind )
|
||||
{
|
||||
short nRes = p->Compare( pFind );
|
||||
if( !nRes )
|
||||
return p;
|
||||
else p = ( nRes < 0 ) ? p->pLeft : p->pRight;
|
||||
StgAvlNode* p = this;
|
||||
while( p )
|
||||
{
|
||||
short nRes = p->Compare( pFind );
|
||||
if( !nRes )
|
||||
return p;
|
||||
else p = ( nRes < 0 ) ? p->pLeft : p->pRight;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -53,23 +57,28 @@ short StgAvlNode::Locate
|
|||
{
|
||||
short nRes = 0;
|
||||
StgAvlNode* pCur = this;
|
||||
|
||||
OSL_ENSURE( pPivot && pParent && pPrev, "The pointers may not be NULL!" );
|
||||
*pParent = *pPrev = NULL;
|
||||
*pPivot = this;
|
||||
|
||||
// search tree for insertion point
|
||||
|
||||
while( pCur != NULL )
|
||||
if ( pFind )
|
||||
{
|
||||
// check for pPivot
|
||||
if( pCur->nBalance != 0 )
|
||||
*pPivot = pCur, *pParent = *pPrev;
|
||||
// save pPrev location and see what direction to go
|
||||
*pPrev = pCur;
|
||||
nRes = pCur->Compare( pFind );
|
||||
if( nRes == 0 )
|
||||
break;
|
||||
else pCur = ( nRes < 0 ) ? pCur->pLeft : pCur->pRight;
|
||||
while( pCur != NULL )
|
||||
{
|
||||
// check for pPivot
|
||||
if( pCur->nBalance != 0 )
|
||||
*pPivot = pCur, *pParent = *pPrev;
|
||||
// save pPrev location and see what direction to go
|
||||
*pPrev = pCur;
|
||||
nRes = pCur->Compare( pFind );
|
||||
if( nRes == 0 )
|
||||
break;
|
||||
else pCur = ( nRes < 0 ) ? pCur->pLeft : pCur->pRight;
|
||||
}
|
||||
}
|
||||
|
||||
return( nRes );
|
||||
}
|
||||
|
||||
|
@ -81,8 +90,10 @@ short StgAvlNode::Adjust( StgAvlNode** pHeavy, StgAvlNode* pNew )
|
|||
StgAvlNode* pCur = this;
|
||||
short nDelta;
|
||||
// no traversing
|
||||
if( pCur == pNew )
|
||||
OSL_ENSURE( pHeavy && pNew, "The pointers is not allowed to be NULL!" );
|
||||
if( pCur == pNew || !pNew )
|
||||
return nBalance;
|
||||
|
||||
short nRes = Compare( pNew );
|
||||
if( nRes > 0 )
|
||||
{
|
||||
|
@ -119,6 +130,7 @@ short StgAvlNode::Adjust( StgAvlNode** pHeavy, StgAvlNode* pNew )
|
|||
|
||||
StgAvlNode* StgAvlNode::RotLL()
|
||||
{
|
||||
OSL_ENSURE( pLeft, "The pointer is not allowed to be NULL!" );
|
||||
StgAvlNode *pHeavy = pLeft;
|
||||
pLeft = pHeavy->pRight;
|
||||
pHeavy->pRight = this;
|
||||
|
@ -130,7 +142,7 @@ StgAvlNode* StgAvlNode::RotLL()
|
|||
|
||||
StgAvlNode* StgAvlNode::RotLR()
|
||||
{
|
||||
|
||||
OSL_ENSURE( pLeft && pLeft->pRight, "The pointer is not allowed to be NULL!" );
|
||||
StgAvlNode* pHeavy = pLeft;
|
||||
StgAvlNode* pNewRoot = pHeavy->pRight;
|
||||
|
||||
|
@ -162,6 +174,7 @@ StgAvlNode* StgAvlNode::RotLR()
|
|||
|
||||
StgAvlNode* StgAvlNode::RotRR()
|
||||
{
|
||||
OSL_ENSURE( pRight, "The pointer is not allowed to be NULL!" );
|
||||
StgAvlNode* pHeavy = pRight;
|
||||
pRight = pHeavy->pLeft;
|
||||
pHeavy->pLeft = this;
|
||||
|
@ -173,6 +186,7 @@ StgAvlNode* StgAvlNode::RotRR()
|
|||
|
||||
StgAvlNode* StgAvlNode::RotRL()
|
||||
{
|
||||
OSL_ENSURE( pRight && pRight->pLeft, "The pointer is not allowed to be NULL!" );
|
||||
StgAvlNode* pHeavy = pRight;
|
||||
StgAvlNode* pNewRoot = pHeavy->pLeft;
|
||||
pHeavy->pLeft = pNewRoot->pRight;
|
||||
|
@ -202,7 +216,7 @@ StgAvlNode* StgAvlNode::RotRL()
|
|||
|
||||
StgAvlNode* StgAvlNode::Rem( StgAvlNode** p, StgAvlNode* pDel, sal_Bool bPtrs )
|
||||
{
|
||||
if( *p )
|
||||
if( p && *p && pDel )
|
||||
{
|
||||
StgAvlNode* pCur = *p;
|
||||
short nRes = bPtrs ? short( pCur == pDel ) : short(pCur->Compare( pDel ));
|
||||
|
@ -256,14 +270,11 @@ StgAvlNode* StgAvlNode::Rem( StgAvlNode** p, StgAvlNode* pDel, sal_Bool bPtrs )
|
|||
|
||||
void StgAvlNode::StgEnum( short& n )
|
||||
{
|
||||
if( this )
|
||||
{
|
||||
if( pLeft )
|
||||
pLeft->StgEnum( n );
|
||||
nId = n++;
|
||||
if( pRight )
|
||||
pRight->StgEnum( n );
|
||||
}
|
||||
if( pLeft )
|
||||
pLeft->StgEnum( n );
|
||||
nId = n++;
|
||||
if( pRight )
|
||||
pRight->StgEnum( n );
|
||||
}
|
||||
|
||||
// Add node to AVL tree.
|
||||
|
@ -272,6 +283,9 @@ void StgAvlNode::StgEnum( short& n )
|
|||
sal_Bool StgAvlNode::Insert( StgAvlNode** pRoot, StgAvlNode* pIns )
|
||||
{
|
||||
StgAvlNode* pPivot, *pHeavy, *pNewRoot, *pParent, *pPrev;
|
||||
if ( !pRoot )
|
||||
return sal_False;
|
||||
|
||||
// special case - empty tree
|
||||
if( *pRoot == NULL )
|
||||
{
|
||||
|
@ -282,6 +296,8 @@ sal_Bool StgAvlNode::Insert( StgAvlNode** pRoot, StgAvlNode* pIns )
|
|||
short nRes = (*pRoot)->Locate( pIns, &pPivot, &pParent, &pPrev );
|
||||
if( !nRes )
|
||||
return sal_False;
|
||||
OSL_ENSURE( pPivot && pPrev, "The pointers may not be NULL!" );
|
||||
|
||||
// add new node
|
||||
if( nRes < 0 )
|
||||
pPrev->pLeft = pIns;
|
||||
|
@ -319,6 +335,9 @@ sal_Bool StgAvlNode::Insert( StgAvlNode** pRoot, StgAvlNode* pIns )
|
|||
|
||||
sal_Bool StgAvlNode::Remove( StgAvlNode** pRoot, StgAvlNode* pDel, sal_Bool bDel )
|
||||
{
|
||||
if ( !pRoot )
|
||||
return sal_False;
|
||||
|
||||
// special case - empty tree
|
||||
if( *pRoot == NULL )
|
||||
return sal_False;
|
||||
|
@ -349,6 +368,9 @@ sal_Bool StgAvlNode::Remove( StgAvlNode** pRoot, StgAvlNode* pDel, sal_Bool bDel
|
|||
sal_Bool StgAvlNode::Move
|
||||
( StgAvlNode** pRoot1, StgAvlNode** pRoot2, StgAvlNode* pMove )
|
||||
{
|
||||
if ( !pRoot1 )
|
||||
return sal_False;
|
||||
|
||||
// special case - empty tree
|
||||
if( *pRoot1 == NULL )
|
||||
return sal_False;
|
||||
|
|
|
@ -60,6 +60,7 @@ typedef boost::unordered_map
|
|||
|
||||
StgPage::StgPage( StgCache* p, short n )
|
||||
{
|
||||
OSL_ENSURE( n >= 512, "Unexpected page size is provided!" );
|
||||
pCache = p;
|
||||
nData = n;
|
||||
bDirty = sal_False;
|
||||
|
@ -123,11 +124,15 @@ StgCache::~StgCache()
|
|||
|
||||
void StgCache::SetPhysPageSize( short n )
|
||||
{
|
||||
nPageSize = n;
|
||||
sal_uLong nPos = pStrm->Tell();
|
||||
sal_uLong nFileSize = pStrm->Seek( STREAM_SEEK_TO_END );
|
||||
nPages = lcl_GetPageCount( nFileSize, nPageSize );
|
||||
pStrm->Seek( nPos );
|
||||
OSL_ENSURE( n >= 512, "Unexpecte page size is provided!" );
|
||||
if ( n >= 512 )
|
||||
{
|
||||
nPageSize = n;
|
||||
sal_uLong nPos = pStrm->Tell();
|
||||
sal_uLong nFileSize = pStrm->Seek( STREAM_SEEK_TO_END );
|
||||
nPages = lcl_GetPageCount( nFileSize, nPageSize );
|
||||
pStrm->Seek( nPos );
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new cache element
|
||||
|
@ -181,19 +186,24 @@ StgPage* StgCache::Create( sal_Int32 nPg )
|
|||
|
||||
void StgCache::Erase( StgPage* pElem )
|
||||
{
|
||||
//remove from LRU
|
||||
pElem->pNext1->pLast1 = pElem->pLast1;
|
||||
pElem->pLast1->pNext1 = pElem->pNext1;
|
||||
if( pCur == pElem )
|
||||
pCur = ( pElem->pNext1 == pElem ) ? NULL : pElem->pNext1;
|
||||
if( pLRUCache )
|
||||
((UsrStgPagePtr_Impl*)pLRUCache)->erase( pElem->nPage );
|
||||
// remove from Sorted
|
||||
pElem->pNext2->pLast2 = pElem->pLast2;
|
||||
pElem->pLast2->pNext2 = pElem->pNext2;
|
||||
if( pElem1 == pElem )
|
||||
pElem1 = ( pElem->pNext2 == pElem ) ? NULL : pElem->pNext2;
|
||||
delete pElem;
|
||||
OSL_ENSURE( pElem, "The pointer should not be NULL!" );
|
||||
if ( pElem )
|
||||
{
|
||||
OSL_ENSURE( pElem->pNext1 && pElem->pLast1, "The pointers may not be NULL!" );
|
||||
//remove from LRU
|
||||
pElem->pNext1->pLast1 = pElem->pLast1;
|
||||
pElem->pLast1->pNext1 = pElem->pNext1;
|
||||
if( pCur == pElem )
|
||||
pCur = ( pElem->pNext1 == pElem ) ? NULL : pElem->pNext1;
|
||||
if( pLRUCache )
|
||||
((UsrStgPagePtr_Impl*)pLRUCache)->erase( pElem->nPage );
|
||||
// remove from Sorted
|
||||
pElem->pNext2->pLast2 = pElem->pLast2;
|
||||
pElem->pLast2->pNext2 = pElem->pNext2;
|
||||
if( pElem1 == pElem )
|
||||
pElem1 = ( pElem->pNext2 == pElem ) ? NULL : pElem->pNext2;
|
||||
delete pElem;
|
||||
}
|
||||
}
|
||||
|
||||
// remove all cache elements without flushing them
|
||||
|
@ -225,9 +235,11 @@ StgPage* StgCache::Find( sal_Int32 nPage )
|
|||
{
|
||||
// page found
|
||||
StgPage* pFound = (*aIt).second;
|
||||
OSL_ENSURE( pFound, "The pointer may not be NULL!" );
|
||||
|
||||
if( pFound != pCur )
|
||||
{
|
||||
OSL_ENSURE( pFound->pNext1 && pFound->pLast1, "The pointers may not be NULL!" );
|
||||
// remove from LRU
|
||||
pFound->pNext1->pLast1 = pFound->pLast1;
|
||||
pFound->pLast1->pNext1 = pFound->pNext1;
|
||||
|
@ -274,7 +286,10 @@ StgPage* StgCache::Copy( sal_Int32 nNew, sal_Int32 nOld )
|
|||
// old page: we must have this data!
|
||||
StgPage* q = Get( nOld, sal_True );
|
||||
if( q )
|
||||
{
|
||||
OSL_ENSURE( p->nData == q->nData, "Unexpected page size!" );
|
||||
memcpy( p->pData, q->pData, p->nData );
|
||||
}
|
||||
}
|
||||
p->SetDirty();
|
||||
return p;
|
||||
|
@ -449,8 +464,12 @@ sal_Bool StgCache::Write( sal_Int32 nPage, void* pBuf, sal_Int32 nPg )
|
|||
if( Good() )
|
||||
{
|
||||
sal_uLong nPos = Page2Pos( nPage );
|
||||
sal_uLong nBytes = nPg * nPageSize;
|
||||
sal_uLong nBytes = 0;
|
||||
if ( SAL_MAX_INT32 / nPg > nPageSize )
|
||||
nBytes = nPg * nPageSize;
|
||||
|
||||
// fixed address and size for the header
|
||||
// nPageSize must be >= 512, otherwise the header can not be written here, we check it on import
|
||||
if( nPage == -1 )
|
||||
nPos = 0L, nBytes = 512;
|
||||
if( pStrm->Tell() != nPos )
|
||||
|
|
|
@ -62,7 +62,7 @@ public:
|
|||
SvStream* GetStrm() { return pStrm; }
|
||||
void SetStrm( SvStream*, sal_Bool );
|
||||
void SetStrm( UCBStorageStream* );
|
||||
sal_Bool IsWritable() { return pStrm->IsWritable(); }
|
||||
sal_Bool IsWritable() { return ( pStrm && pStrm->IsWritable() ); }
|
||||
sal_Bool Good() { return sal_Bool( nError == SVSTREAM_OK ); }
|
||||
sal_Bool Bad() { return sal_Bool( nError != SVSTREAM_OK ); }
|
||||
sal_uLong GetError() { return nError; }
|
||||
|
|
|
@ -44,9 +44,9 @@
|
|||
// Problem der Implementation: Keine Hierarchischen commits. Daher nur
|
||||
// insgesamt transaktionsorientert oder direkt.
|
||||
|
||||
StgDirEntry::StgDirEntry( const void* pFrom, sal_Bool * pbOk ) : StgAvlNode()
|
||||
StgDirEntry::StgDirEntry( const void* pBuffer, sal_uInt32 nBufferLen, sal_Bool * pbOk ) : StgAvlNode()
|
||||
{
|
||||
*pbOk = aEntry.Load( pFrom );
|
||||
*pbOk = aEntry.Load( pBuffer, nBufferLen );
|
||||
|
||||
InitMembers();
|
||||
}
|
||||
|
@ -93,8 +93,13 @@ StgDirEntry::~StgDirEntry()
|
|||
|
||||
short StgDirEntry::Compare( const StgAvlNode* p ) const
|
||||
{
|
||||
const StgDirEntry* pEntry = (const StgDirEntry*) p;
|
||||
return aEntry.Compare( pEntry->aEntry );
|
||||
short nResult = -1;
|
||||
if ( p )
|
||||
{
|
||||
const StgDirEntry* pEntry = (const StgDirEntry*) p;
|
||||
nResult = aEntry.Compare( pEntry->aEntry );
|
||||
}
|
||||
return nResult;
|
||||
}
|
||||
|
||||
// Enumerate the entry numbers.
|
||||
|
@ -254,9 +259,9 @@ void StgDirEntry::OpenStream( StgIo& rIo, sal_Bool bForceBig )
|
|||
sal_Int32 nThreshold = (sal_uInt16) rIo.aHdr.GetThreshold();
|
||||
delete pStgStrm;
|
||||
if( !bForceBig && aEntry.GetSize() < nThreshold )
|
||||
pStgStrm = new StgSmallStrm( rIo, this );
|
||||
pStgStrm = new StgSmallStrm( rIo, *this );
|
||||
else
|
||||
pStgStrm = new StgDataStrm( rIo, this );
|
||||
pStgStrm = new StgDataStrm( rIo, *this );
|
||||
if( bInvalid && aEntry.GetSize() )
|
||||
{
|
||||
// This entry has invalid data, so delete that data
|
||||
|
@ -314,6 +319,10 @@ sal_Bool StgDirEntry::SetSize( sal_Int32 nNewSize )
|
|||
}
|
||||
else
|
||||
{
|
||||
OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" );
|
||||
if ( !pStgStrm )
|
||||
return sal_False;
|
||||
|
||||
sal_Bool bRes = sal_False;
|
||||
StgIo& rIo = pStgStrm->GetIo();
|
||||
sal_Int32 nThreshold = rIo.aHdr.GetThreshold();
|
||||
|
@ -393,6 +402,10 @@ sal_Int32 StgDirEntry::Seek( sal_Int32 nNew )
|
|||
}
|
||||
else
|
||||
{
|
||||
OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" );
|
||||
if ( !pStgStrm )
|
||||
return nPos;
|
||||
|
||||
sal_Int32 nSize = aEntry.GetSize();
|
||||
|
||||
if( nNew < 0 )
|
||||
|
@ -412,6 +425,7 @@ sal_Int32 StgDirEntry::Seek( sal_Int32 nNew )
|
|||
pStgStrm->Pos2Page( nNew );
|
||||
nNew = pStgStrm->GetPos();
|
||||
}
|
||||
|
||||
return nPos = nNew;
|
||||
}
|
||||
|
||||
|
@ -426,7 +440,14 @@ sal_Int32 StgDirEntry::Read( void* p, sal_Int32 nLen )
|
|||
else if( pCurStrm )
|
||||
nLen = pCurStrm->Read( p, nLen );
|
||||
else
|
||||
{
|
||||
OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" );
|
||||
if ( !pStgStrm )
|
||||
return 0;
|
||||
|
||||
nLen = pStgStrm->Read( p, nLen );
|
||||
}
|
||||
|
||||
nPos += nLen;
|
||||
return nLen;
|
||||
}
|
||||
|
@ -444,6 +465,11 @@ sal_Int32 StgDirEntry::Write( const void* p, sal_Int32 nLen )
|
|||
// Is this stream opened in transacted mode? Do we have to make a copy?
|
||||
if( !bDirect && !pTmpStrm && !Strm2Tmp() )
|
||||
return 0;
|
||||
|
||||
OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" );
|
||||
if ( !pStgStrm )
|
||||
return 0;
|
||||
|
||||
if( pTmpStrm )
|
||||
{
|
||||
nLen = pTmpStrm->Write( p, nLen );
|
||||
|
@ -600,6 +626,10 @@ sal_Bool StgDirEntry::Strm2Tmp()
|
|||
{
|
||||
if( n )
|
||||
{
|
||||
OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" );
|
||||
if ( !pStgStrm )
|
||||
return sal_False;
|
||||
|
||||
sal_uInt8 aTempBytes[ 4096 ];
|
||||
void* p = static_cast<void*>( aTempBytes );
|
||||
pStgStrm->Pos2Page( 0L );
|
||||
|
@ -621,9 +651,13 @@ sal_Bool StgDirEntry::Strm2Tmp()
|
|||
else
|
||||
n = 1;
|
||||
}
|
||||
|
||||
if( n )
|
||||
{
|
||||
pStgStrm->GetIo().SetError( pTmpStrm->GetError() );
|
||||
OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" );
|
||||
if ( pStgStrm )
|
||||
pStgStrm->GetIo().SetError( pTmpStrm->GetError() );
|
||||
|
||||
delete pTmpStrm;
|
||||
pTmpStrm = NULL;
|
||||
return sal_False;
|
||||
|
@ -641,6 +675,9 @@ sal_Bool StgDirEntry::Tmp2Strm()
|
|||
pTmpStrm = pCurStrm, pCurStrm = NULL;
|
||||
if( pTmpStrm )
|
||||
{
|
||||
OSL_ENSURE( pStgStrm, "The pointer may not be NULL!" );
|
||||
if ( !pStgStrm )
|
||||
return sal_False;
|
||||
sal_uLong n = pTmpStrm->GetSize();
|
||||
StgStrm* pNewStrm;
|
||||
StgIo& rIo = pStgStrm->GetIo();
|
||||
|
@ -777,7 +814,7 @@ void StgDirStrm::SetupEntry( sal_Int32 n, StgDirEntry* pUpper )
|
|||
if( p )
|
||||
{
|
||||
sal_Bool bOk(sal_False);
|
||||
StgDirEntry* pCur = new StgDirEntry( p, &bOk );
|
||||
StgDirEntry* pCur = new StgDirEntry( p, STGENTRY_SIZE, &bOk );
|
||||
|
||||
if( !bOk )
|
||||
{
|
||||
|
@ -854,6 +891,9 @@ void StgDirStrm::SetupEntry( sal_Int32 n, StgDirEntry* pUpper )
|
|||
sal_Bool StgDirStrm::SetSize( sal_Int32 nBytes )
|
||||
{
|
||||
// Always allocate full pages
|
||||
if ( nBytes < 0 )
|
||||
nBytes = 0;
|
||||
|
||||
nBytes = ( ( nBytes + nPageSize - 1 ) / nPageSize ) * nPageSize;
|
||||
return StgStrm::SetSize( nBytes );
|
||||
}
|
||||
|
@ -862,7 +902,7 @@ sal_Bool StgDirStrm::SetSize( sal_Int32 nBytes )
|
|||
|
||||
sal_Bool StgDirStrm::Store()
|
||||
{
|
||||
if( !pRoot->IsDirty() )
|
||||
if( !pRoot || !pRoot->IsDirty() )
|
||||
return sal_True;
|
||||
if( !pRoot->StoreStreams( rIo ) )
|
||||
return sal_False;
|
||||
|
|
|
@ -62,7 +62,7 @@ public:
|
|||
sal_Bool bDirect; // sal_True: direct mode
|
||||
sal_Bool bZombie; // sal_True: Removed From StgIo
|
||||
sal_Bool bInvalid; // sal_True: invalid entry
|
||||
StgDirEntry( const void*, sal_Bool * pbOk );
|
||||
StgDirEntry( const void* pBuffer, sal_uInt32 nBufferLen, sal_Bool * pbOk );
|
||||
StgDirEntry( const StgEntry& );
|
||||
~StgDirEntry();
|
||||
|
||||
|
|
|
@ -70,21 +70,44 @@ SvStream& operator <<( SvStream& r, const ClsId& rId )
|
|||
///////////////////////////// class StgHeader ////////////////////////////
|
||||
|
||||
StgHeader::StgHeader()
|
||||
: nVersion( 0 )
|
||||
, nByteOrder( 0 )
|
||||
, nPageSize( 0 )
|
||||
, nDataPageSize( 0 )
|
||||
, bDirty( 0 )
|
||||
, nFATSize( 0 )
|
||||
, nTOCstrm( 0 )
|
||||
, nReserved( 0 )
|
||||
, nThreshold( 0 )
|
||||
, nDataFAT( 0 )
|
||||
, nDataFATSize( 0 )
|
||||
, nMasterChain( 0 )
|
||||
, nMaster( 0 )
|
||||
{
|
||||
memset( this, 0, sizeof( StgHeader ) );
|
||||
memset( cSignature, 0, sizeof( cSignature ) );
|
||||
memset( &aClsId, 0, sizeof( ClsId ) );
|
||||
memset( cReserved, 0, sizeof( cReserved ) );
|
||||
memset( nMasterFAT, 0, sizeof( nMasterFAT ) );
|
||||
}
|
||||
|
||||
void StgHeader::Init()
|
||||
{
|
||||
memset( this, 0, sizeof( StgHeader ) );
|
||||
memcpy( cSignature, cStgSignature, 8 );
|
||||
memset( &aClsId, 0, sizeof( ClsId ) );
|
||||
nVersion = 0x0003003B;
|
||||
nByteOrder = 0xFFFE;
|
||||
nPageSize = 9; // 512 bytes
|
||||
nDataPageSize = 6; // 64 bytes
|
||||
bDirty = 0;
|
||||
memset( cReserved, 0, sizeof( cReserved ) );
|
||||
nFATSize = 0;
|
||||
nTOCstrm = 0;
|
||||
nReserved = 0;
|
||||
nThreshold = 4096;
|
||||
nDataFAT = 0;
|
||||
nDataFATSize = 0;
|
||||
nMasterChain = STG_EOF;
|
||||
|
||||
SetTOCStart( STG_EOF );
|
||||
SetDataFATStart( STG_EOF );
|
||||
for( short i = 0; i < 109; i++ )
|
||||
|
@ -93,9 +116,15 @@ void StgHeader::Init()
|
|||
|
||||
sal_Bool StgHeader::Load( StgIo& rIo )
|
||||
{
|
||||
SvStream& r = *rIo.GetStrm();
|
||||
Load( r );
|
||||
return rIo.Good();
|
||||
sal_Bool bResult = sal_False;
|
||||
if ( rIo.GetStrm() )
|
||||
{
|
||||
SvStream& r = *rIo.GetStrm();
|
||||
bResult = Load( r );
|
||||
bResult = ( bResult && rIo.Good() );
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
sal_Bool StgHeader::Load( SvStream& r )
|
||||
|
@ -118,7 +147,8 @@ sal_Bool StgHeader::Load( SvStream& r )
|
|||
>> nMaster; // 48 # of additional master blocks
|
||||
for( short i = 0; i < 109; i++ )
|
||||
r >> nMasterFAT[ i ];
|
||||
return r.GetErrorCode() == ERRCODE_NONE;
|
||||
|
||||
return ( r.GetErrorCode() == ERRCODE_NONE && Check() );
|
||||
}
|
||||
|
||||
sal_Bool StgHeader::Store( StgIo& rIo )
|
||||
|
@ -157,8 +187,15 @@ sal_Bool StgHeader::Check()
|
|||
{
|
||||
return sal_Bool( memcmp( cSignature, cStgSignature, 8 ) == 0
|
||||
&& (short) ( nVersion >> 16 ) == 3 )
|
||||
&& nPageSize == 9
|
||||
&& lcl_wontoverflow(nPageSize)
|
||||
&& lcl_wontoverflow(nDataPageSize);
|
||||
&& lcl_wontoverflow(nDataPageSize)
|
||||
&& nFATSize > 0
|
||||
&& nTOCstrm >= 0
|
||||
&& nThreshold > 0
|
||||
&& ( nDataFAT == -2 || ( nDataFAT >= 0 && nDataFATSize > 0 ) )
|
||||
&& ( nMasterChain == -2 || ( nMasterChain >=0 && nMaster > 109 ) )
|
||||
&& nMaster >= 0;
|
||||
}
|
||||
|
||||
sal_Int32 StgHeader::GetFATPage( short n ) const
|
||||
|
@ -213,7 +250,21 @@ void StgHeader::SetMasters( sal_Int32 n )
|
|||
|
||||
sal_Bool StgEntry::Init()
|
||||
{
|
||||
memset( this, 0, sizeof (StgEntry) - sizeof( String ) );
|
||||
memset( nName, 0, sizeof( nName ) );
|
||||
nNameLen = 0;
|
||||
cType = 0;
|
||||
cFlags = 0;
|
||||
nLeft = 0;
|
||||
nRight = 0;
|
||||
nChild = 0;
|
||||
memset( &aClsId, 0, sizeof( aClsId ) );
|
||||
nFlags = 0;
|
||||
nMtime[0] = 0; nMtime[1] = 0;
|
||||
nAtime[0] = 0; nAtime[1] = 0;
|
||||
nPage1 = 0;
|
||||
nSize = 0;
|
||||
nUnknown = 0;
|
||||
|
||||
SetLeaf( STG_LEFT, STG_FREE );
|
||||
SetLeaf( STG_RIGHT, STG_FREE );
|
||||
SetLeaf( STG_CHILD, STG_FREE );
|
||||
|
@ -306,9 +357,12 @@ short StgEntry::Compare( const StgEntry& r ) const
|
|||
// These load/store operations are a bit more complicated,
|
||||
// since they have to copy their contents into a packed structure.
|
||||
|
||||
sal_Bool StgEntry::Load( const void* pFrom )
|
||||
sal_Bool StgEntry::Load( const void* pFrom, sal_uInt32 nBufSize )
|
||||
{
|
||||
SvMemoryStream r( (sal_Char*) pFrom, 128, STREAM_READ );
|
||||
if ( nBufSize < 128 )
|
||||
return sal_False;
|
||||
|
||||
SvMemoryStream r( (sal_Char*) pFrom, nBufSize, STREAM_READ );
|
||||
for( short i = 0; i < 32; i++ )
|
||||
r >> nName[ i ]; // 00 name as WCHAR
|
||||
r >> nNameLen // 40 size of name in bytes including 00H
|
||||
|
@ -334,7 +388,7 @@ sal_Bool StgEntry::Load( const void* pFrom )
|
|||
if (n > nMaxLegalStr)
|
||||
return sal_False;
|
||||
|
||||
if (nSize < 0 && cType != STG_STORAGE)
|
||||
if ((nSize < 0 && cType != STG_STORAGE) || (nPage1 < 0 && nPage1 != -2))
|
||||
{
|
||||
// the size makes no sense for the substorage
|
||||
// TODO/LATER: actually the size should be an unsigned value, but in this case it would mean a stream of more than 2Gb
|
||||
|
|
|
@ -55,6 +55,7 @@ class StgHeader
|
|||
sal_Int32 nMasterFAT[ 109 ]; // 4C first 109 master FAT pages
|
||||
public:
|
||||
StgHeader();
|
||||
|
||||
void Init(); // initialize the header
|
||||
sal_Bool Load( StgIo& );
|
||||
sal_Bool Load( SvStream& );
|
||||
|
@ -128,7 +129,7 @@ public:
|
|||
void GetName( String& rName ) const;
|
||||
// fill in the name
|
||||
short Compare( const StgEntry& ) const; // compare two entries
|
||||
sal_Bool Load( const void* );
|
||||
sal_Bool Load( const void* pBuffer, sal_uInt32 nBufSize );
|
||||
void Store( void* );
|
||||
StgEntryType GetType() const { return (StgEntryType) cType; }
|
||||
sal_Int32 GetStartPage() const { return nPage1; }
|
||||
|
|
|
@ -60,6 +60,8 @@ sal_Bool StgIo::Load()
|
|||
else
|
||||
return sal_False;
|
||||
}
|
||||
else
|
||||
return sal_False;
|
||||
}
|
||||
return Good();
|
||||
}
|
||||
|
@ -93,7 +95,7 @@ void StgIo::SetupStreams()
|
|||
if( pRoot )
|
||||
{
|
||||
pDataFAT = new StgDataStrm( *this, aHdr.GetDataFATStart(), -1 );
|
||||
pDataStrm = new StgDataStrm( *this, pRoot );
|
||||
pDataStrm = new StgDataStrm( *this, *pRoot );
|
||||
pDataFAT->SetIncrement( 1 << aHdr.GetPageSize() );
|
||||
pDataStrm->SetIncrement( GetDataPageSize() );
|
||||
pDataStrm->SetEntry( *pRoot );
|
||||
|
@ -115,7 +117,7 @@ short StgIo::GetDataPageSize()
|
|||
sal_Bool StgIo::CommitAll()
|
||||
{
|
||||
// Store the data (all streams and the TOC)
|
||||
if( pTOC->Store() )
|
||||
if( pTOC && pTOC->Store() && pDataFAT )
|
||||
{
|
||||
if( Commit() )
|
||||
{
|
||||
|
@ -152,7 +154,11 @@ public:
|
|||
|
||||
sal_Int32 GetPageSize() { return nPageSize; }
|
||||
sal_Int32 Count() { return nPages; }
|
||||
sal_Int32 operator[]( sal_Int32 nOffset ) { return pFat[ nOffset ]; }
|
||||
sal_Int32 operator[]( sal_Int32 nOffset )
|
||||
{
|
||||
OSL_ENSURE( nOffset >= 0 && nOffset < nPages, "Unexpected offset!" );
|
||||
return nOffset >= 0 && nOffset < nPages ? pFat[ nOffset ] : -2;
|
||||
}
|
||||
|
||||
sal_uLong Mark( sal_Int32 nPage, sal_Int32 nCount, sal_Int32 nExpect );
|
||||
sal_Bool HasUnrefChains();
|
||||
|
@ -200,6 +206,8 @@ sal_uLong EasyFat::Mark( sal_Int32 nPage, sal_Int32 nCount, sal_Int32 nExpect )
|
|||
sal_Int32 nCurPage = nPage;
|
||||
while( nCount != 0 )
|
||||
{
|
||||
if( nCurPage < 0 || nCurPage >= nPages )
|
||||
return FAT_OUTOFBOUNDS;
|
||||
pFree[ nCurPage ] = sal_False;
|
||||
nCurPage = pFat[ nCurPage ];
|
||||
//Stream zu lang
|
||||
|
@ -213,9 +221,6 @@ sal_uLong EasyFat::Mark( sal_Int32 nPage, sal_Int32 nCount, sal_Int32 nExpect )
|
|||
nCount = 1;
|
||||
if( nCount != -1 )
|
||||
nCount--;
|
||||
// Naechster Block nicht in der FAT
|
||||
if( nCount && ( nCurPage < 0 || nCurPage >= nPages ) )
|
||||
return FAT_OUTOFBOUNDS;
|
||||
}
|
||||
return FAT_OK;
|
||||
}
|
||||
|
@ -259,6 +264,9 @@ sal_uLong Validator::ValidateMasterFATs()
|
|||
{
|
||||
sal_Int32 nCount = rIo.aHdr.GetFATSize();
|
||||
sal_uLong nErr;
|
||||
if ( !rIo.pFAT )
|
||||
return FAT_INMEMORYERROR;
|
||||
|
||||
for( sal_Int32 i = 0; i < nCount; i++ )
|
||||
{
|
||||
if( ( nErr = aFat.Mark(rIo.pFAT->GetPage( short(i), sal_False ), aFat.GetPageSize(), -3 )) != FAT_OK )
|
||||
|
@ -267,11 +275,15 @@ sal_uLong Validator::ValidateMasterFATs()
|
|||
if( rIo.aHdr.GetMasters() )
|
||||
if( ( nErr = aFat.Mark(rIo.aHdr.GetFATChain( ), aFat.GetPageSize(), -4 )) != FAT_OK )
|
||||
return nErr;
|
||||
|
||||
return FAT_OK;
|
||||
}
|
||||
|
||||
sal_uLong Validator::MarkAll( StgDirEntry *pEntry )
|
||||
{
|
||||
if ( !pEntry )
|
||||
return FAT_INMEMORYERROR;
|
||||
|
||||
StgIterator aIter( *pEntry );
|
||||
sal_uLong nErr = FAT_OK;
|
||||
for( StgDirEntry* p = aIter.First(); p ; p = aIter.Next() )
|
||||
|
@ -298,6 +310,9 @@ sal_uLong Validator::MarkAll( StgDirEntry *pEntry )
|
|||
|
||||
sal_uLong Validator::ValidateDirectoryEntries()
|
||||
{
|
||||
if ( !rIo.pTOC )
|
||||
return FAT_INMEMORYERROR;
|
||||
|
||||
// Normale DirEntries
|
||||
sal_uLong nErr = MarkAll( rIo.pTOC->GetRoot() );
|
||||
if( nErr != FAT_OK )
|
||||
|
@ -347,7 +362,11 @@ sal_uLong StgIo::ValidateFATs()
|
|||
Validator *pV = new Validator( *this );
|
||||
sal_Bool bRet1 = !pV->IsError(), bRet2 = sal_True ;
|
||||
delete pV;
|
||||
|
||||
SvFileStream *pFileStrm = ( SvFileStream *) GetStrm();
|
||||
if ( !pFileStrm )
|
||||
return FAT_INMEMORYERROR;
|
||||
|
||||
StgIo aIo;
|
||||
if( aIo.Open( pFileStrm->GetFileName(),
|
||||
STREAM_READ | STREAM_SHARE_DENYNONE) &&
|
||||
|
|
|
@ -115,23 +115,28 @@ sal_Bool StgCompObjStream::Load()
|
|||
*this >> aClsId;
|
||||
sal_Int32 nLen1 = 0;
|
||||
*this >> nLen1;
|
||||
// higher bits are ignored
|
||||
nLen1 &= 0xFFFF;
|
||||
sal_Char* p = new sal_Char[ (sal_uInt16) nLen1 ];
|
||||
if( Read( p, nLen1 ) == (sal_uLong) nLen1 )
|
||||
if ( nLen1 > 0 )
|
||||
{
|
||||
//The encoding here is "ANSI", which is pretty useless seeing as
|
||||
//the actual codepage used doesn't seem to be specified/stored
|
||||
//anywhere :-(. Might as well pick 1252 and be consistent on
|
||||
//all platforms and envs
|
||||
//http://www.openoffice.org/nonav/issues/showattachment.cgi/68668/Orginal%20Document.doc
|
||||
//for a good edge-case example
|
||||
aUserName = nLen1 ? String( p, RTL_TEXTENCODING_MS_1252 ) : String();
|
||||
nCbFormat = ReadClipboardFormat( *this );
|
||||
// higher bits are ignored
|
||||
sal_uLong nStrLen = ::std::min( nLen1, (sal_Int32)0xFFFE );
|
||||
|
||||
sal_Char* p = new sal_Char[ nStrLen+1 ];
|
||||
p[nStrLen] = 0;
|
||||
if( Read( p, nStrLen ) == nStrLen )
|
||||
{
|
||||
//The encoding here is "ANSI", which is pretty useless seeing as
|
||||
//the actual codepage used doesn't seem to be specified/stored
|
||||
//anywhere :-(. Might as well pick 1252 and be consistent on
|
||||
//all platforms and envs
|
||||
//http://www.openoffice.org/nonav/issues/showattachment.cgi/68668/Orginal%20Document.doc
|
||||
//for a good edge-case example
|
||||
aUserName = nStrLen ? String( p, RTL_TEXTENCODING_MS_1252 ) : String();
|
||||
nCbFormat = ReadClipboardFormat( *this );
|
||||
}
|
||||
else
|
||||
SetError( SVSTREAM_GENERALERROR );
|
||||
delete [] p;
|
||||
}
|
||||
else
|
||||
SetError( SVSTREAM_GENERALERROR );
|
||||
delete [] p;
|
||||
}
|
||||
return sal_Bool( GetError() == SVSTREAM_OK );
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ sal_Int32 StgFAT::GetNextPage( sal_Int32 nPg )
|
|||
{
|
||||
if( nPg >= 0 )
|
||||
{
|
||||
StgPage* pPg = GetPhysPage( nPg << 2 );
|
||||
StgPage* pPg = GetPhysPage( nPg << 2 );
|
||||
nPg = pPg ? pPg->GetPage( nOffset >> 2 ) : STG_EOF;
|
||||
}
|
||||
return nPg;
|
||||
|
@ -260,19 +260,22 @@ sal_Int32 StgFAT::AllocPages( sal_Int32 nBgn, sal_Int32 nPgs )
|
|||
sal_Bool StgFAT::InitNew( sal_Int32 nPage1 )
|
||||
{
|
||||
sal_Int32 n = ( ( rStrm.GetSize() >> 2 ) - nPage1 ) / nEntries;
|
||||
while( n-- )
|
||||
if ( n > 0 )
|
||||
{
|
||||
StgPage* pPg = NULL;
|
||||
// Position within the underlying stream
|
||||
// use the Pos2Page() method of the stream
|
||||
rStrm.Pos2Page( nPage1 << 2 );
|
||||
// Initialize the page
|
||||
pPg = rStrm.GetIo().Copy( rStrm.GetPage(), STG_FREE );
|
||||
if ( !pPg )
|
||||
return sal_False;
|
||||
for( short i = 0; i < nEntries; i++ )
|
||||
pPg->SetPage( i, STG_FREE );
|
||||
nPage1++;
|
||||
while( n-- )
|
||||
{
|
||||
StgPage* pPg = NULL;
|
||||
// Position within the underlying stream
|
||||
// use the Pos2Page() method of the stream
|
||||
rStrm.Pos2Page( nPage1 << 2 );
|
||||
// Initialize the page
|
||||
pPg = rStrm.GetIo().Copy( rStrm.GetPage(), STG_FREE );
|
||||
if ( !pPg )
|
||||
return sal_False;
|
||||
for( short i = 0; i < nEntries; i++ )
|
||||
pPg->SetPage( i, STG_FREE );
|
||||
nPage1++;
|
||||
}
|
||||
}
|
||||
return sal_True;
|
||||
}
|
||||
|
@ -365,6 +368,9 @@ void StgStrm::scanBuildPageChainCache(sal_Int32 *pOptionalCalcSize)
|
|||
// behind the EOF.
|
||||
sal_Bool StgStrm::Pos2Page( sal_Int32 nBytePos )
|
||||
{
|
||||
if ( !pFat )
|
||||
return sal_False;
|
||||
|
||||
// Values < 0 seek to the end
|
||||
if( nBytePos < 0 || nBytePos >= nSize )
|
||||
nBytePos = nSize;
|
||||
|
@ -447,6 +453,9 @@ StgPage* StgStrm::GetPhysPage( sal_Int32 nBytePos, sal_Bool bForce )
|
|||
|
||||
sal_Bool StgStrm::Copy( sal_Int32 nFrom, sal_Int32 nBytes )
|
||||
{
|
||||
if ( !pFat )
|
||||
return sal_False;
|
||||
|
||||
m_aPagesCache.clear();
|
||||
|
||||
sal_Int32 nTo = nStart;
|
||||
|
@ -475,6 +484,9 @@ sal_Bool StgStrm::Copy( sal_Int32 nFrom, sal_Int32 nBytes )
|
|||
|
||||
sal_Bool StgStrm::SetSize( sal_Int32 nBytes )
|
||||
{
|
||||
if ( nBytes < 0 || !pFat )
|
||||
return sal_False;
|
||||
|
||||
m_aPagesCache.clear();
|
||||
|
||||
// round up to page size
|
||||
|
@ -548,6 +560,7 @@ sal_Bool StgFATStrm::Pos2Page( sal_Int32 nBytePos )
|
|||
|
||||
StgPage* StgFATStrm::GetPhysPage( sal_Int32 nBytePos, sal_Bool bForce )
|
||||
{
|
||||
OSL_ENSURE( nBytePos >= 0, "The value may not be negative!" );
|
||||
return rIo.Get( nBytePos / ( nPageSize >> 2 ), bForce );
|
||||
}
|
||||
|
||||
|
@ -555,6 +568,7 @@ StgPage* StgFATStrm::GetPhysPage( sal_Int32 nBytePos, sal_Bool bForce )
|
|||
|
||||
sal_Int32 StgFATStrm::GetPage( short nOff, sal_Bool bMake, sal_uInt16 *pnMasterAlloc )
|
||||
{
|
||||
OSL_ENSURE( nOff >= 0, "The offset may not be negative!" );
|
||||
if( pnMasterAlloc ) *pnMasterAlloc = 0;
|
||||
if( nOff < rIo.aHdr.GetFAT1Size() )
|
||||
return rIo.aHdr.GetFATPage( nOff );
|
||||
|
@ -631,6 +645,7 @@ sal_Int32 StgFATStrm::GetPage( short nOff, sal_Bool bMake, sal_uInt16 *pnMasterA
|
|||
|
||||
sal_Bool StgFATStrm::SetPage( short nOff, sal_Int32 nNewPage )
|
||||
{
|
||||
OSL_ENSURE( nOff >= 0, "The offset may not be negative!" );
|
||||
m_aPagesCache.clear();
|
||||
|
||||
sal_Bool bRes = sal_True;
|
||||
|
@ -682,6 +697,9 @@ sal_Bool StgFATStrm::SetPage( short nOff, sal_Int32 nNewPage )
|
|||
|
||||
sal_Bool StgFATStrm::SetSize( sal_Int32 nBytes )
|
||||
{
|
||||
if ( nBytes < 0 )
|
||||
return sal_False;
|
||||
|
||||
m_aPagesCache.clear();
|
||||
|
||||
// Set the number of entries to a multiple of the page size
|
||||
|
@ -710,6 +728,7 @@ sal_Bool StgFATStrm::SetSize( sal_Int32 nBytes )
|
|||
|
||||
// find a free page using the FAT allocator
|
||||
sal_Int32 n = 1;
|
||||
OSL_ENSURE( pFat, "The pointer is always initializer here!" );
|
||||
sal_Int32 nNewPage = pFat->FindBlock( n );
|
||||
if( nNewPage == STG_EOF )
|
||||
{
|
||||
|
@ -782,21 +801,25 @@ StgDataStrm::StgDataStrm( StgIo& r, sal_Int32 nBgn, sal_Int32 nLen ) : StgStrm(
|
|||
Init( nBgn, nLen );
|
||||
}
|
||||
|
||||
StgDataStrm::StgDataStrm( StgIo& r, StgDirEntry* p ) : StgStrm( r )
|
||||
StgDataStrm::StgDataStrm( StgIo& r, StgDirEntry& p ) : StgStrm( r )
|
||||
{
|
||||
pEntry = p;
|
||||
Init( p->aEntry.GetLeaf( STG_DATA ),
|
||||
p->aEntry.GetSize() );
|
||||
pEntry = &p;
|
||||
Init( p.aEntry.GetLeaf( STG_DATA ),
|
||||
p.aEntry.GetSize() );
|
||||
}
|
||||
|
||||
void StgDataStrm::Init( sal_Int32 nBgn, sal_Int32 nLen )
|
||||
{
|
||||
pFat = new StgFAT( *rIo.pFAT, sal_True );
|
||||
if ( rIo.pFAT )
|
||||
pFat = new StgFAT( *rIo.pFAT, sal_True );
|
||||
|
||||
OSL_ENSURE( pFat, "The pointer should not be empty!" );
|
||||
|
||||
nStart = nPage = nBgn;
|
||||
nSize = nLen;
|
||||
nIncr = 1;
|
||||
nOffset = 0;
|
||||
if( nLen < 0 )
|
||||
if( nLen < 0 && pFat )
|
||||
{
|
||||
// determine the actual size of the stream by scanning
|
||||
// the FAT chain and counting the # of pages allocated
|
||||
|
@ -808,6 +831,9 @@ void StgDataStrm::Init( sal_Int32 nBgn, sal_Int32 nLen )
|
|||
|
||||
sal_Bool StgDataStrm::SetSize( sal_Int32 nBytes )
|
||||
{
|
||||
if ( !pFat )
|
||||
return sal_False;
|
||||
|
||||
nBytes = ( ( nBytes + nIncr - 1 ) / nIncr ) * nIncr;
|
||||
sal_Int32 nOldSz = nSize;
|
||||
if( ( nOldSz != nBytes ) )
|
||||
|
@ -913,12 +939,15 @@ sal_Int32 StgDataStrm::Read( void* pBuf, sal_Int32 n )
|
|||
|
||||
sal_Int32 StgDataStrm::Write( const void* pBuf, sal_Int32 n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return 0;
|
||||
|
||||
sal_Int32 nDone = 0;
|
||||
if( ( nPos + n ) > nSize )
|
||||
{
|
||||
sal_Int32 nOld = nPos;
|
||||
if( !SetSize( nPos + n ) )
|
||||
return sal_False;
|
||||
return 0;
|
||||
Pos2Page( nOld );
|
||||
}
|
||||
while( n )
|
||||
|
@ -983,17 +1012,20 @@ StgSmallStrm::StgSmallStrm( StgIo& r, sal_Int32 nBgn, sal_Int32 nLen ) : StgStrm
|
|||
Init( nBgn, nLen );
|
||||
}
|
||||
|
||||
StgSmallStrm::StgSmallStrm( StgIo& r, StgDirEntry* p ) : StgStrm( r )
|
||||
StgSmallStrm::StgSmallStrm( StgIo& r, StgDirEntry& p ) : StgStrm( r )
|
||||
{
|
||||
pEntry = p;
|
||||
Init( p->aEntry.GetLeaf( STG_DATA ),
|
||||
p->aEntry.GetSize() );
|
||||
pEntry = &p;
|
||||
Init( p.aEntry.GetLeaf( STG_DATA ),
|
||||
p.aEntry.GetSize() );
|
||||
}
|
||||
|
||||
void StgSmallStrm::Init( sal_Int32 nBgn, sal_Int32 nLen )
|
||||
{
|
||||
pFat = new StgFAT( *rIo.pDataFAT, sal_False );
|
||||
if ( rIo.pDataFAT )
|
||||
pFat = new StgFAT( *rIo.pDataFAT, sal_False );
|
||||
pData = rIo.pDataStrm;
|
||||
OSL_ENSURE( pFat && pData, "The pointers should not be empty!" );
|
||||
|
||||
nPageSize = rIo.GetDataPageSize();
|
||||
nStart =
|
||||
nPage = nBgn;
|
||||
|
@ -1018,7 +1050,7 @@ sal_Int32 StgSmallStrm::Read( void* pBuf, sal_Int32 n )
|
|||
nBytes = (short) n;
|
||||
if( nBytes )
|
||||
{
|
||||
if( !pData->Pos2Page( nPage * nPageSize + nOffset ) )
|
||||
if( !pData || !pData->Pos2Page( nPage * nPageSize + nOffset ) )
|
||||
break;
|
||||
// all reading thru the stream
|
||||
short nRes = (short) pData->Read( (sal_uInt8*)pBuf + nDone, nBytes );
|
||||
|
@ -1058,9 +1090,10 @@ sal_Int32 StgSmallStrm::Write( const void* pBuf, sal_Int32 n )
|
|||
{
|
||||
// all writing goes thru the stream
|
||||
sal_Int32 nDataPos = nPage * nPageSize + nOffset;
|
||||
if( pData->GetSize() < ( nDataPos + nBytes ) )
|
||||
if( !pData->SetSize( nDataPos + nBytes ) )
|
||||
break;
|
||||
if ( !pData
|
||||
|| ( pData->GetSize() < ( nDataPos + nBytes )
|
||||
&& !pData->SetSize( nDataPos + nBytes ) ) )
|
||||
break;
|
||||
if( !pData->Pos2Page( nDataPos ) )
|
||||
break;
|
||||
short nRes = (short) pData->Write( (sal_uInt8*)pBuf + nDone, nBytes );
|
||||
|
|
|
@ -117,7 +117,7 @@ class StgDataStrm : public StgStrm // a physical data stream
|
|||
void Init( sal_Int32 nBgn, sal_Int32 nLen );
|
||||
public:
|
||||
StgDataStrm( StgIo&, sal_Int32 nBgn, sal_Int32 nLen=-1 );
|
||||
StgDataStrm( StgIo&, StgDirEntry* );
|
||||
StgDataStrm( StgIo&, StgDirEntry& );
|
||||
void* GetPtr( sal_Int32 nPos, sal_Bool bForce, sal_Bool bDirty );
|
||||
void SetIncrement( short n ) { nIncr = n ; }
|
||||
virtual sal_Bool SetSize( sal_Int32 );
|
||||
|
@ -136,7 +136,7 @@ class StgSmallStrm : public StgStrm // a logical data stream
|
|||
void Init( sal_Int32 nBgn, sal_Int32 nLen );
|
||||
public:
|
||||
StgSmallStrm( StgIo&, sal_Int32 nBgn, sal_Int32 nLen );
|
||||
StgSmallStrm( StgIo&, StgDirEntry* );
|
||||
StgSmallStrm( StgIo&, StgDirEntry& );
|
||||
virtual sal_Int32 Read( void*, sal_Int32 );
|
||||
virtual sal_Int32 Write( const void*, sal_Int32 );
|
||||
virtual sal_Bool IsSmallStrm() const { return sal_True; }
|
||||
|
|
|
@ -35,8 +35,8 @@ sal_uLong ReadClipboardFormat( SvStream & rStm )
|
|||
if( nLen > 0 )
|
||||
{
|
||||
// get a string name
|
||||
sal_Char * p = new sal_Char[ nLen ];
|
||||
if( rStm.Read( p, nLen ) == (sal_uLong) nLen )
|
||||
sal_Char * p = new( ::std::nothrow ) sal_Char[ nLen ];
|
||||
if( p && rStm.Read( p, nLen ) == (sal_uLong) nLen )
|
||||
{
|
||||
nFormat = SotExchange::RegisterFormatName(rtl::OUString(p, nLen-1, RTL_TEXTENCODING_ASCII_US));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue