diff options
Diffstat (limited to 'tools/source/ref')
-rw-r--r-- | tools/source/ref/errinf.cxx | 465 | ||||
-rw-r--r-- | tools/source/ref/globname.cxx | 456 | ||||
-rw-r--r-- | tools/source/ref/makefile.mk | 57 | ||||
-rw-r--r-- | tools/source/ref/pstm.cxx | 918 | ||||
-rw-r--r-- | tools/source/ref/ref.cxx | 54 |
5 files changed, 1950 insertions, 0 deletions
diff --git a/tools/source/ref/errinf.cxx b/tools/source/ref/errinf.cxx new file mode 100644 index 000000000000..25d894f4b925 --- /dev/null +++ b/tools/source/ref/errinf.cxx @@ -0,0 +1,465 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: errinf.cxx,v $ + * $Revision: 1.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_tools.hxx" + +#include <limits.h> +#include <tools/shl.hxx> +#include <tools/debug.hxx> +#include <tools/errinf.hxx> +#include <tools/string.hxx> + +class ErrorHandler; + +namespace { + +typedef void (* DisplayFnPtr)(); + +} + +struct EDcrData +{ + public: + + ErrorHandler *pFirstHdl; + ErrorContext *pFirstCtx; + DisplayFnPtr pDsp; + BOOL bIsWindowDsp; + + + DynamicErrorInfo *ppDcr[ERRCODE_DYNAMIC_COUNT]; + USHORT nNextDcr; + EDcrData(); + +static EDcrData *GetData(); + +}; + +class EDcr_Impl +{ + ULONG lErrId; + USHORT nMask; + + void RegisterEDcr(DynamicErrorInfo *); + void UnRegisterEDcr(DynamicErrorInfo *); + static ErrorInfo *GetDynamicErrorInfo(ULONG lId); + +friend class DynamicErrorInfo; +friend class ErrorInfo; +}; + + +EDcrData::EDcrData() +{ + for(USHORT n=0;n<ERRCODE_DYNAMIC_COUNT;n++) + ppDcr[n]=0; + nNextDcr=0; + pFirstHdl=0; + pDsp=0; + pFirstCtx=0; +} + + +EDcrData *EDcrData::GetData() +{ +#ifdef BOOTSTRAP + return 0x0; +#else + EDcrData **ppDat=(EDcrData **)GetAppData(SHL_ERR); + if(!*ppDat) + { + return (*ppDat=new EDcrData); + } + else + return *ppDat; +#endif +} + +void EDcr_Impl::RegisterEDcr(DynamicErrorInfo *pDcr) +{ + //Vergibt eine dynamische Id + + EDcrData* pData=EDcrData::GetData(); + lErrId= (((ULONG)pData->nNextDcr + 1) << ERRCODE_DYNAMIC_SHIFT) + + pDcr->GetErrorCode(); + DynamicErrorInfo **ppDcr=pData->ppDcr; + USHORT nNext=pData->nNextDcr; + + // bei einem Ringbuffer koennen wir uns das ASSERT wohl sparen! + // DBG_ASSERT(ppDcr[nNext]==0,"ErrHdl: Alle Errors belegt"); + if(ppDcr[nNext]) + { + delete ppDcr[nNext]; + } + ppDcr[nNext]=pDcr; + if(++pData->nNextDcr>=ERRCODE_DYNAMIC_COUNT) + pData->nNextDcr=0; +} + + +void EDcr_Impl::UnRegisterEDcr(DynamicErrorInfo *pDcr) +{ + + EDcrData* pData=EDcrData::GetData(); + DynamicErrorInfo **ppDcr=pData->ppDcr; + ULONG lIdx=( + ((ULONG)(*pDcr) & ERRCODE_DYNAMIC_MASK)>>ERRCODE_DYNAMIC_SHIFT)-1; + DBG_ASSERT(ppDcr[lIdx]==pDcr,"ErrHdl: Error nicht gefunden"); + if(ppDcr[lIdx]==pDcr) + ppDcr[lIdx]=0; +} + +TYPEINIT0(ErrorInfo); +TYPEINIT1(DynamicErrorInfo, ErrorInfo); +TYPEINIT1(StandardErrorInfo, DynamicErrorInfo); +TYPEINIT1(StringErrorInfo, DynamicErrorInfo); +TYPEINIT1(TwoStringErrorInfo, DynamicErrorInfo); +TYPEINIT1(MessageInfo, DynamicErrorInfo); + + +ErrorInfo *ErrorInfo::GetErrorInfo(ULONG lId) +{ + if(lId & ERRCODE_DYNAMIC_MASK) + return EDcr_Impl::GetDynamicErrorInfo(lId); + else + return new ErrorInfo(lId); +} + +DynamicErrorInfo::operator ULONG() const +{ + return pImpl->lErrId; +} + +DynamicErrorInfo::DynamicErrorInfo(ULONG lArgUserId, USHORT nMask) +: ErrorInfo(lArgUserId) +{ + pImpl=new EDcr_Impl; + pImpl->RegisterEDcr(this); + pImpl->nMask=nMask; +} + +DynamicErrorInfo::~DynamicErrorInfo() +{ + pImpl->UnRegisterEDcr(this); + delete pImpl; +} + +ErrorInfo* EDcr_Impl::GetDynamicErrorInfo(ULONG lId) +{ + ULONG lIdx=((lId & ERRCODE_DYNAMIC_MASK)>>ERRCODE_DYNAMIC_SHIFT)-1; + DynamicErrorInfo* pDcr=EDcrData::GetData()->ppDcr[lIdx]; + if(pDcr && (ULONG)(*pDcr)==lId) + return pDcr; + else + return new ErrorInfo(lId & ~ERRCODE_DYNAMIC_MASK); +} + + +USHORT DynamicErrorInfo::GetDialogMask() const +{ + return pImpl->nMask; +} + + +StandardErrorInfo::StandardErrorInfo( + ULONG UserId, ULONG lArgExtId, USHORT nFlags) +: DynamicErrorInfo(UserId, nFlags), lExtId(lArgExtId) +{ +} + + +StringErrorInfo::StringErrorInfo( + ULONG UserId, const String& aStringP, USHORT nFlags) +: DynamicErrorInfo(UserId, nFlags), aString(aStringP) +{ +} + + +class ErrHdl_Impl +{ + public: + + ErrorHandler *pNext; + static BOOL CreateString(const ErrorHandler *pStart, + const ErrorInfo*, String&, USHORT&); +}; + + +static void aDspFunc(const String &rErr, const String &rAction) +{ + ByteString aErr("Aktion: "); + aErr+= ByteString( rAction, RTL_TEXTENCODING_ASCII_US ); + aErr+=" Fehler: "; + aErr+= ByteString( rErr, RTL_TEXTENCODING_ASCII_US ); + DBG_ERROR(aErr.GetBuffer()); +} + + +ErrorContext::ErrorContext(Window *pWinP) +{ + EDcrData *pData=EDcrData::GetData(); + ErrorContext *&pHdl=pData->pFirstCtx; + pWin=pWinP; + pNext=pHdl; + pHdl=this; +} + +ErrorContext::~ErrorContext() +{ + ErrorContext **ppCtx=&(EDcrData::GetData()->pFirstCtx); + while(*ppCtx && *ppCtx!=this) + ppCtx=&((*ppCtx)->pNext); + if(*ppCtx) + *ppCtx=(*ppCtx)->pNext; +} + +ErrorContext *ErrorContext::GetContext() +{ + return EDcrData::GetData()->pFirstCtx; +} + +ErrorHandler::ErrorHandler() +{ + pImpl=new ErrHdl_Impl; + EDcrData *pData=EDcrData::GetData(); + ErrorHandler *&pHdl=pData->pFirstHdl; + pImpl->pNext=pHdl; + pHdl=this; + if(!pData->pDsp) + RegisterDisplay(&aDspFunc); +} + +ErrorHandler::~ErrorHandler() +{ + ErrorHandler **ppHdl=&(EDcrData::GetData()->pFirstHdl); + while(*ppHdl && *ppHdl!=this) + ppHdl=&((*ppHdl)->pImpl->pNext); + if(*ppHdl) + *ppHdl=(*ppHdl)->pImpl->pNext; + delete pImpl; +} + +void ErrorHandler::RegisterDisplay(WindowDisplayErrorFunc *aDsp) +{ + EDcrData *pData=EDcrData::GetData(); + pData->bIsWindowDsp=TRUE; + pData->pDsp = reinterpret_cast< DisplayFnPtr >(aDsp); +} + +void ErrorHandler::RegisterDisplay(BasicDisplayErrorFunc *aDsp) +{ + EDcrData *pData=EDcrData::GetData(); + pData->bIsWindowDsp=FALSE; + pData->pDsp = reinterpret_cast< DisplayFnPtr >(aDsp); +} + +USHORT ErrorHandler::HandleError_Impl( + ULONG lId, USHORT nFlags, BOOL bJustCreateString, String & rError) +{ + +/* [Beschreibung] + Handelt einen Fehler ab. lId ist die FehlerId, nFlags sind die + ErrorFlags. Werden nFlags nicht abgegeben, so werden die in + der DynamicErrorInfo angegebenen Flags bzw. die aus der Resource + verwendet. + + Also: + + 1. nFlags, + 2. Resource Flags + 3. Dynamic Flags + 4. Default ERRCODE_BUTTON_OK, ERRCODE_MSG_ERROR + + + */ + + String aErr; + String aAction; + if(!lId || lId == ERRCODE_ABORT) + return 0; + EDcrData *pData=EDcrData::GetData(); + ErrorInfo *pInfo=ErrorInfo::GetErrorInfo(lId); + ErrorContext *pCtx=ErrorContext::GetContext(); + if(pCtx) + pCtx->GetString(pInfo->GetErrorCode(), aAction); + Window *pParent=0; + //Nimm den Parent aus dem Konext + for(;pCtx;pCtx=pCtx->pNext) + if(pCtx->GetParent()) + { + pParent=pCtx->GetParent(); + break; + } + + BOOL bWarning = ((lId & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK); + USHORT nErrFlags = ERRCODE_BUTTON_DEF_OK | ERRCODE_BUTTON_OK; + if (bWarning) + nErrFlags |= ERRCODE_MSG_WARNING; + else + nErrFlags |= ERRCODE_MSG_ERROR; + + DynamicErrorInfo* pDynPtr=PTR_CAST(DynamicErrorInfo,pInfo); + if(pDynPtr) + { + USHORT nDynFlags = pDynPtr->GetDialogMask(); + if( nDynFlags ) + nErrFlags = nDynFlags; + } + + if(ErrHdl_Impl::CreateString(pData->pFirstHdl,pInfo,aErr,nErrFlags)) + { + if (bJustCreateString) + { + rError = aErr; + return 1; + } + else + { + if(!pData->pDsp) + { + ByteString aStr("Action: "); + aStr += ByteString( aAction, RTL_TEXTENCODING_ASCII_US ); + aStr += ByteString("\nFehler: "); + aStr += ByteString( aErr, RTL_TEXTENCODING_ASCII_US ); + DBG_ERROR( aStr.GetBuffer() ); + } + else + { + delete pInfo; + if(!pData->bIsWindowDsp) + { + (*(BasicDisplayErrorFunc*)pData->pDsp)(aErr,aAction); + return 0; + } + else + { + if( nFlags != USHRT_MAX ) + nErrFlags = nFlags; + return (*(WindowDisplayErrorFunc*)pData->pDsp)( + pParent, nErrFlags, aErr, aAction); + } + } + } + } + DBG_ERROR("Error nicht behandelt"); + // Error 1 ist General Error im Sfx + if(pInfo->GetErrorCode()!=1) { + HandleError_Impl(1, USHRT_MAX, bJustCreateString, rError); + } + else { + DBG_ERROR("Error 1 nicht gehandeled"); + } + delete pInfo; + return 0; +} + +// static +BOOL ErrorHandler::GetErrorString(ULONG lId, String& rStr) +{ + return (BOOL)HandleError_Impl( lId, USHRT_MAX, TRUE, rStr ); +} + +USHORT ErrorHandler::HandleError(ULONG lId, USHORT nFlags) +{ + +/* [Beschreibung] + Handelt einen Fehler ab. lId ist die FehlerId, nFlags sind die + ErrorFlags. Werden nFlags nicht abgegeben, so werden die in + der DynamicErrorInfo angegebenen Flags bzw. die aus der Resource + verwendet. + + Also: + + 1. nFlags, + 2. Resource Flags + 3. Dynamic Flags + 4. Default ERRCODE_BUTTON_OK, ERRCODE_MSG_ERROR + + + */ + + String aDummy; + return HandleError_Impl( lId, nFlags, FALSE, aDummy ); +} + +BOOL ErrorHandler::ForwCreateString(const ErrorInfo* pInfo, String& rStr, USHORT &rFlags) const +{ + return ErrHdl_Impl::CreateString(this->pImpl->pNext, pInfo, rStr, rFlags); +} + +BOOL ErrHdl_Impl::CreateString( const ErrorHandler *pStart, + const ErrorInfo* pInfo, String& pStr, + USHORT &rFlags) +{ + for(const ErrorHandler *pHdl=pStart;pHdl;pHdl=pHdl->pImpl->pNext) + { + if(pHdl->CreateString( pInfo, pStr, rFlags)) + return TRUE; + } + return FALSE; +} + +BOOL SimpleErrorHandler::CreateString( + const ErrorInfo *pInfo, String &rStr, USHORT &) const +{ + ULONG nId = pInfo->GetErrorCode(); + ByteString aStr; + aStr="Id "; + aStr+=ByteString::CreateFromInt32(nId); + aStr+=" only handled by SimpleErrorHandler"; + aStr+="\nErrorCode: "; + aStr+=ByteString::CreateFromInt32(nId & ((1L << ERRCODE_CLASS_SHIFT) - 1 )); + aStr+="\nErrorClass: "; + aStr+=ByteString::CreateFromInt32((nId & ERRCODE_CLASS_MASK) >> ERRCODE_CLASS_SHIFT); + aStr+="\nErrorArea: "; + aStr+=ByteString::CreateFromInt32((nId & ERRCODE_ERROR_MASK & + ~((1 << ERRCODE_AREA_SHIFT ) -1 ) ) >> ERRCODE_AREA_SHIFT); + DynamicErrorInfo *pDyn=PTR_CAST(DynamicErrorInfo,pInfo); + if(pDyn) + { + aStr+="\nDId "; + aStr+=ByteString::CreateFromInt32((ULONG)*pDyn); + } + StandardErrorInfo *pStd=PTR_CAST(StandardErrorInfo,pInfo); + if(pStd) + { + aStr+="\nXId "; + aStr+=ByteString::CreateFromInt32(pStd->GetExtendedErrorCode()); + } + rStr = String( aStr, RTL_TEXTENCODING_ASCII_US ); + return TRUE; +} + +SimpleErrorHandler::SimpleErrorHandler() + : ErrorHandler() +{ +} + diff --git a/tools/source/ref/globname.cxx b/tools/source/ref/globname.cxx new file mode 100644 index 000000000000..50d028acacc4 --- /dev/null +++ b/tools/source/ref/globname.cxx @@ -0,0 +1,456 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: globname.cxx,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_tools.hxx" + +#include <ctype.h> +#include <stdio.h> +#include <string.h> + +#include <tools/stream.hxx> +#include <tools/globname.hxx> + +/************** class ImpSvGlobalName ************************************/ +ImpSvGlobalName::ImpSvGlobalName( const ImpSvGlobalName & rObj ) +{ + nRefCount = 0; + memcpy( szData, rObj.szData, sizeof( szData ) ); +} + +/************** class ImpSvGlobalName ************************************/ +ImpSvGlobalName::ImpSvGlobalName( int ) +{ + nRefCount = 1; + memset( szData, 0, sizeof( szData ) ); +} + +/************************************************************************* +|* ImpSvGlobalName::operator ==() +*************************************************************************/ +BOOL ImpSvGlobalName::operator == ( const ImpSvGlobalName & rObj ) const +{ + return !memcmp( szData, rObj.szData, sizeof( szData ) ); +} + +/************************************************************************* +|* SvGlobalName::SvGlobalName() +*************************************************************************/ +SvGlobalName::SvGlobalName() +{ + static ImpSvGlobalName aNoName( 0 ); + + pImp = &aNoName; + pImp->nRefCount++; +} + +// locker die Struktur von Windows kopiert +#ifdef WNT +struct _GUID +#else +struct GUID +#endif +{ + UINT32 Data1; + UINT16 Data2; + UINT16 Data3; + BYTE Data4[8]; +}; +SvGlobalName::SvGlobalName( const CLSID & rId ) +{ + pImp = new ImpSvGlobalName(); + pImp->nRefCount++; + memcpy( pImp->szData, &rId, sizeof( pImp->szData ) ); +} + +SvGlobalName::SvGlobalName( UINT32 n1, USHORT n2, USHORT n3, + BYTE b8, BYTE b9, BYTE b10, BYTE b11, + BYTE b12, BYTE b13, BYTE b14, BYTE b15 ) +{ + pImp = new ImpSvGlobalName(); + pImp->nRefCount++; + + *(UINT32 *)pImp->szData = n1; + *(USHORT *)&pImp->szData[ 4 ] = n2; + *(USHORT *)&pImp->szData[ 6 ] = n3; + pImp->szData[ 8 ] = b8; + pImp->szData[ 9 ] = b9; + pImp->szData[ 10 ] = b10; + pImp->szData[ 11 ] = b11; + pImp->szData[ 12 ] = b12; + pImp->szData[ 13 ] = b13; + pImp->szData[ 14 ] = b14; + pImp->szData[ 15 ] = b15; +} + +/************************************************************************* +|* SvGlobalName::~SvGlobalName() +*************************************************************************/ +SvGlobalName::~SvGlobalName() +{ + pImp->nRefCount--; + if( !pImp->nRefCount ) + delete pImp; +} + +/************************************************************************* +|* SvGlobalName::operator = () +*************************************************************************/ +SvGlobalName & SvGlobalName::operator = ( const SvGlobalName & rObj ) +{ + rObj.pImp->nRefCount++; + pImp->nRefCount--; + if( !pImp->nRefCount ) + delete pImp; + pImp = rObj.pImp; + return *this; +} + +/************************************************************************* +|* SvGlobalName::NewImp() +*************************************************************************/ +void SvGlobalName::NewImp() +{ + if( pImp->nRefCount > 1 ) + { + pImp->nRefCount--; + pImp = new ImpSvGlobalName( *pImp ); + pImp->nRefCount++; + } +} + +/************************************************************************* +|* SvGlobalName::operator << () +|* SvGlobalName::operator >> () +*************************************************************************/ +SvStream& operator << ( SvStream& rOStr, const SvGlobalName & rObj ) +{ + rOStr << *(UINT32 *)rObj.pImp->szData; + rOStr << *(USHORT *)&rObj.pImp->szData[ 4 ]; + rOStr << *(USHORT *)&rObj.pImp->szData[ 6 ]; + rOStr.Write( (sal_Char *)&rObj.pImp->szData[ 8 ], 8 ); + return rOStr; +} + +SvStream& operator >> ( SvStream& rStr, SvGlobalName & rObj ) +{ + rObj.NewImp(); // kopieren, falls noetig + rStr >> *(UINT32 *)rObj.pImp->szData; + rStr >> *(USHORT *)&rObj.pImp->szData[ 4 ]; + rStr >> *(USHORT *)&rObj.pImp->szData[ 6 ]; + rStr.Read( (sal_Char *)&rObj.pImp->szData[ 8 ], 8 ); + return rStr; +} + + +/************************************************************************* +|* SvGlobalName::operator < () +*************************************************************************/ +BOOL SvGlobalName::operator < ( const SvGlobalName & rObj ) const +{ + int n = memcmp( pImp->szData +6, rObj.pImp->szData +6, + sizeof( pImp->szData ) -6); + if( n < 0 ) + return TRUE; + else if( n > 0 ) + return FALSE; + else if( *(USHORT *)&pImp->szData[ 4 ] < *(USHORT *)&rObj.pImp->szData[ 4 ] ) + return TRUE; + else if( *(USHORT *)&pImp->szData[ 4 ] == *(USHORT *)&rObj.pImp->szData[ 4 ] ) + return *(UINT32 *)pImp->szData < *(UINT32 *)rObj.pImp->szData; + else + return FALSE; + +} + +/************************************************************************* +|* SvGlobalName::operator +=() +*************************************************************************/ +SvGlobalName & SvGlobalName::operator += ( UINT32 n ) +{ + NewImp(); + UINT32 nOld = (*(UINT32 *)pImp->szData); + (*(UINT32 *)pImp->szData) += n; + if( nOld > *(UINT32 *)pImp->szData ) + // ueberlauf + (*(USHORT *)&pImp->szData[ 4 ])++; + return *this; +} + +/************************************************************************* +|* SvGlobalName::operator ==() +*************************************************************************/ +BOOL SvGlobalName::operator == ( const SvGlobalName & rObj ) const +{ + return *pImp == *rObj.pImp; +} + +void SvGlobalName::MakeFromMemory( void * pData ) +{ + NewImp(); + memcpy( pImp->szData, pData, sizeof( pImp->szData ) ); +} + +/************************************************************************* +|* SvGlobalName::MakeId() +*************************************************************************/ +BOOL SvGlobalName::MakeId( const String & rIdStr ) +{ + ByteString aStr( rIdStr, RTL_TEXTENCODING_ASCII_US ); + sal_Char * pStr = (sal_Char *)aStr.GetBuffer(); + if( rIdStr.Len() == 36 + && '-' == pStr[ 8 ] && '-' == pStr[ 13 ] + && '-' == pStr[ 18 ] && '-' == pStr[ 23 ] ) + { + UINT32 nFirst = 0; + int i = 0; + for( i = 0; i < 8; i++ ) + { + if( isxdigit( *pStr ) ) + if( isdigit( *pStr ) ) + nFirst = nFirst * 16 + (*pStr - '0'); + else + nFirst = nFirst * 16 + (toupper( *pStr ) - 'A' + 10 ); + else + return FALSE; + pStr++; + } + + UINT16 nSec = 0; + pStr++; + for( i = 0; i < 4; i++ ) + { + if( isxdigit( *pStr ) ) + if( isdigit( *pStr ) ) + nSec = nSec * 16 + (*pStr - '0'); + else + nSec = nSec * 16 + (UINT16)(toupper( *pStr ) - 'A' + 10 ); + else + return FALSE; + pStr++; + } + + UINT16 nThird = 0; + pStr++; + for( i = 0; i < 4; i++ ) + { + if( isxdigit( *pStr ) ) + if( isdigit( *pStr ) ) + nThird = nThird * 16 + (*pStr - '0'); + else + nThird = nThird * 16 + (UINT16)(toupper( *pStr ) - 'A' + 10 ); + else + return FALSE; + pStr++; + } + + BYTE szRemain[ 8 ]; + memset( szRemain, 0, sizeof( szRemain ) ); + pStr++; + for( i = 0; i < 16; i++ ) + { + if( isxdigit( *pStr ) ) + if( isdigit( *pStr ) ) + szRemain[i/2] = szRemain[i/2] * 16 + (*pStr - '0'); + else + szRemain[i/2] = szRemain[i/2] * 16 + (BYTE)(toupper( *pStr ) - 'A' + 10 ); + else + return FALSE; + pStr++; + if( i == 3 ) + pStr++; + } + + NewImp(); + *(UINT32 *)pImp->szData = nFirst; + *(USHORT *)&pImp->szData[ 4 ] = nSec; + *(USHORT *)&pImp->szData[ 6 ] = nThird; + memcpy( &pImp->szData[ 8 ], szRemain, 8 ); + return TRUE; + } + return FALSE; +} + +/************************************************************************* +|* SvGlobalName::GetctorName() +*************************************************************************/ +String SvGlobalName::GetctorName() const +{ + ByteString aRet; + + sal_Char buf[ 20 ]; + sprintf( buf, "0x%8.8lX", (ULONG)*(UINT32 *)pImp->szData ); + aRet += buf; + USHORT i; + for( i = 4; i < 8; i += 2 ) + { + aRet += ','; + sprintf( buf, "0x%4.4X", *(USHORT *)&pImp->szData[ i ] ); + aRet += buf; + } + for( i = 8; i < 16; i++ ) + { + aRet += ','; + sprintf( buf, "0x%2.2x", pImp->szData[ i ] ); + aRet += buf; + } + return String( aRet, RTL_TEXTENCODING_ASCII_US ); +} + +/************************************************************************* +|* SvGlobalName::GetHexName() +*************************************************************************/ +String SvGlobalName::GetHexName() const +{ + ByteString aRet; + + sal_Char buf[ 10 ]; + sprintf( buf, "%8.8lX", (ULONG)*(UINT32 *)pImp->szData ); + aRet += buf; + aRet += '-'; + USHORT i ; + for( i = 4; i < 8; i += 2 ) + { + sprintf( buf, "%4.4X", *(USHORT *)&pImp->szData[ i ] ); + aRet += buf; + aRet += '-'; + } + for( i = 8; i < 10; i++ ) + { + sprintf( buf, "%2.2x", pImp->szData[ i ] ); + aRet += buf; + } + aRet += '-'; + for( i = 10; i < 16; i++ ) + { + sprintf( buf, "%2.2x", pImp->szData[ i ] ); + aRet += buf; + } + return String( aRet, RTL_TEXTENCODING_ASCII_US ); +} + +/************** SvGlobalNameList ****************************************/ +/************************************************************************/ +/************************************************************************* +|* SvGlobalNameList::SvGlobalNameList() +*************************************************************************/ +SvGlobalNameList::SvGlobalNameList() + : aList( 1, 1 ) +{ +} + +/************************************************************************* +|* SvGlobalNameList::~SvGlobalNameList() +*************************************************************************/ +SvGlobalNameList::~SvGlobalNameList() +{ + for( ULONG i = Count(); i > 0; i-- ) + { + ImpSvGlobalName * pImp = (ImpSvGlobalName *)aList.GetObject( i -1 ); + pImp->nRefCount--; + if( !pImp->nRefCount ) + delete pImp; + } +} + +/************************************************************************* +|* SvGlobalNameList::Append() +*************************************************************************/ +void SvGlobalNameList::Append( const SvGlobalName & rName ) +{ + rName.pImp->nRefCount++; + aList.Insert( rName.pImp, LIST_APPEND ); +} + +/************************************************************************* +|* SvGlobalNameList::GetObject() +*************************************************************************/ +SvGlobalName SvGlobalNameList::GetObject( ULONG nPos ) +{ + return SvGlobalName( (ImpSvGlobalName *)aList.GetObject( nPos ) ); +} + +/************************************************************************* +|* SvGlobalNameList::IsEntry() +*************************************************************************/ +BOOL SvGlobalNameList::IsEntry( const SvGlobalName & rName ) +{ + for( ULONG i = Count(); i > 0; i-- ) + { + if( *rName.pImp == *(ImpSvGlobalName *)aList.GetObject( i -1 ) ) + return TRUE; + } + return FALSE; +} + +com::sun::star::uno::Sequence < sal_Int8 > SvGlobalName::GetByteSequence() const +{ + // platform independent representation of a "GlobalName" + // maybe transported remotely + com::sun::star::uno::Sequence< sal_Int8 > aResult( 16 ); + + aResult[0] = (sal_Int8) (*(UINT32 *)pImp->szData >> 24); + aResult[1] = (sal_Int8) ((*(UINT32 *)pImp->szData << 8 ) >> 24); + aResult[2] = (sal_Int8) ((*(UINT32 *)pImp->szData << 16 ) >> 24); + aResult[3] = (sal_Int8) ((*(UINT32 *)pImp->szData << 24 ) >> 24); + aResult[4] = (sal_Int8) (*(USHORT *)&pImp->szData[ 4 ] >> 8); + aResult[5] = (sal_Int8) ((*(USHORT *)&pImp->szData[ 4 ] << 8 ) >> 8); + aResult[6] = (sal_Int8) (*(USHORT *)&pImp->szData[ 6 ] >> 8); + aResult[7] = (sal_Int8) ((*(USHORT *)&pImp->szData[ 6 ] << 8 ) >> 8); + aResult[8] = pImp->szData[ 8 ]; + aResult[9] = pImp->szData[ 9 ]; + aResult[10] = pImp->szData[ 10 ]; + aResult[11] = pImp->szData[ 11 ]; + aResult[12] = pImp->szData[ 12 ]; + aResult[13] = pImp->szData[ 13 ]; + aResult[14] = pImp->szData[ 14 ]; + aResult[15] = pImp->szData[ 15 ]; + + return aResult; +} + +SvGlobalName::SvGlobalName( const com::sun::star::uno::Sequence < sal_Int8 >& aSeq ) +{ + // create SvGlobalName from a platform independent representation + GUID aResult; + memset( &aResult, 0, sizeof( aResult ) ); + if ( aSeq.getLength() == 16 ) + { + aResult.Data1 = ( ( ( ( ( ( sal_uInt8 )aSeq[0] << 8 ) + ( sal_uInt8 )aSeq[1] ) << 8 ) + ( sal_uInt8 )aSeq[2] ) << 8 ) + ( sal_uInt8 )aSeq[3]; + aResult.Data2 = ( ( sal_uInt8 )aSeq[4] << 8 ) + ( sal_uInt8 )aSeq[5]; + aResult.Data3 = ( ( sal_uInt8 )aSeq[6] << 8 ) + ( sal_uInt8 )aSeq[7]; + for( int nInd = 0; nInd < 8; nInd++ ) + aResult.Data4[nInd] = ( sal_uInt8 )aSeq[nInd+8]; + } + + pImp = new ImpSvGlobalName(); + pImp->nRefCount++; + memcpy( pImp->szData, &aResult, sizeof( pImp->szData ) ); +} diff --git a/tools/source/ref/makefile.mk b/tools/source/ref/makefile.mk new file mode 100644 index 000000000000..2c22027532b0 --- /dev/null +++ b/tools/source/ref/makefile.mk @@ -0,0 +1,57 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.7 $ +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=tools +TARGET=ref +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES= $(SLO)$/ref.obj \ + $(SLO)$/pstm.obj \ + $(SLO)$/globname.obj \ + $(SLO)$/errinf.obj + +OBJFILES= $(OBJ)$/ref.obj \ + $(OBJ)$/pstm.obj \ + $(OBJ)$/globname.obj \ + $(OBJ)$/errinf.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/tools/source/ref/pstm.cxx b/tools/source/ref/pstm.cxx new file mode 100644 index 000000000000..a336bbaab360 --- /dev/null +++ b/tools/source/ref/pstm.cxx @@ -0,0 +1,918 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: pstm.cxx,v $ + * $Revision: 1.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_tools.hxx" + +#include <tools/debug.hxx> +#include <tools/pstm.hxx> + +#define STOR_NO_OPTIMIZE + +/***********************************************************************/ +/************************************************************************ +|* SvClassManager::Register() +*************************************************************************/ +void SvClassManager::Register( USHORT nClassId, SvCreateInstancePersist pFunc ) +{ +#ifdef DBG_UTIL + SvCreateInstancePersist p; + p = Get( nClassId ); + DBG_ASSERT( !p || p == pFunc, "register class with same id" ); +#endif + aAssocTable.insert(Map::value_type(nClassId, pFunc)); +} + +/************************************************************************ +|* SvClassManager::Get() +*************************************************************************/ +SvCreateInstancePersist SvClassManager::Get( USHORT nClassId ) +{ + Map::const_iterator i(aAssocTable.find(nClassId)); + return i == aAssocTable.end() ? 0 : i->second; +} + +/****************** SvRttiBase *******************************************/ +TYPEINIT0( SvRttiBase ); + +/****************** SvPersistBaseMemberList ******************************/ + +SvPersistBaseMemberList::SvPersistBaseMemberList(){} +SvPersistBaseMemberList::SvPersistBaseMemberList( + USHORT nInitSz, USHORT nResize ) + : SuperSvPersistBaseMemberList( nInitSz, nResize ){} + +#define PERSIST_LIST_VER (BYTE)0 +#define PERSIST_LIST_DBGUTIL (BYTE)0x80 + +/************************************************************************ +|* SvPersistBaseMemberList::WriteOnlyStreamedObjects() +*************************************************************************/ +void SvPersistBaseMemberList::WriteObjects( SvPersistStream & rStm, + BOOL bOnlyStreamed ) const +{ +#ifdef STOR_NO_OPTIMIZE + rStm << (BYTE)(PERSIST_LIST_VER | PERSIST_LIST_DBGUTIL); + UINT32 nObjPos = rStm.WriteDummyLen(); +#else + BYTE bTmp = PERSIST_LIST_VER; + rStm << bTmp; +#endif + UINT32 nCountMember = Count(); + ULONG nCountPos = rStm.Tell(); + UINT32 nWriteCount = 0; + rStm << nCountMember; + //bloss die Liste nicht veraendern, + //wegen Seiteneffekten beim Save + for( ULONG n = 0; n < nCountMember; n++ ) + { + SvPersistBase * pObj = GetObject( n ); + if( !bOnlyStreamed || rStm.IsStreamed( pObj ) ) + { // Objekt soll geschrieben werden + rStm << GetObject( n ); + nWriteCount++; + } + } + if( nWriteCount != nCountMember ) + { + // nicht alle Objekte geschrieben, Count anpassen + ULONG nPos = rStm.Tell(); + rStm.Seek( nCountPos ); + rStm << nWriteCount; + rStm.Seek( nPos ); + } +#ifdef STOR_NO_OPTIMIZE + rStm.WriteLen( nObjPos ); +#endif +} + +/************************************************************************ +|* operator << () +*************************************************************************/ +SvPersistStream& operator << ( SvPersistStream & rStm, + const SvPersistBaseMemberList & rLst ) +{ + rLst.WriteObjects( rStm ); + return rStm; +} + +/************************************************************************ +|* operator >> () +*************************************************************************/ +SvPersistStream& operator >> ( SvPersistStream & rStm, + SvPersistBaseMemberList & rLst ) +{ + BYTE nVer; + rStm >> nVer; + + if( (nVer & ~PERSIST_LIST_DBGUTIL) != PERSIST_LIST_VER ) + { + rStm.SetError( SVSTREAM_GENERALERROR ); + DBG_ERROR( "persist list, false version" ); + } + + UINT32 nObjLen(0), nObjPos(0); + if( nVer & PERSIST_LIST_DBGUTIL ) + nObjLen = rStm.ReadLen( &nObjPos ); + + sal_uInt32 nCount; + rStm >> nCount; + for( ULONG n = 0; n < nCount && rStm.GetError() == SVSTREAM_OK; n++ ) + { + SvPersistBase * pObj; + rStm >> pObj; + if( pObj ) + rLst.Append( pObj ); + } +#ifdef DBG_UTIL + if( nObjLen + nObjPos != rStm.Tell() ) + { + ByteString aStr( "false list len: read = " ); + aStr += ByteString::CreateFromInt32( (long)(rStm.Tell() - nObjPos) ); + aStr += ", should = "; + aStr += ByteString::CreateFromInt64(nObjLen); + DBG_ERROR( aStr.GetBuffer() ); + } +#endif + return rStm; +} + +//========================================================================= +SvPersistStream::SvPersistStream +( + SvClassManager & rMgr, /* Alle Factorys, deren Objekt geladen und + gespeichert werdn k"onnen */ + SvStream * pStream, /* Dieser Stream wird als Medium genommen, auf + dem der PersistStream arbeitet */ + UINT32 nStartIdxP /* Ab diesem Index werden die Id's f"ur + die Objekte vergeben, er muss gr"osser + als Null sein. */ +) + : rClassMgr( rMgr ) + , pStm( pStream ) + , aPUIdx( nStartIdxP ) + , nStartIdx( nStartIdxP ) + , pRefStm( NULL ) + , nFlags( 0 ) +/* [Beschreibung] + + Der Konstruktor der Klasse SvPersistStream. Die Objekte rMgr und + pStream d"urfen nicht ver"andert werden, solange sie in einem + SvPersistStream eingesetzt sind. Eine Aussnahme gibt es f"ur + pStream (siehe <SvPersistStream::SetStream>). +*/ +{ + DBG_ASSERT( nStartIdx != 0, "zero index not allowed" ); + bIsWritable = TRUE; + if( pStm ) + { + SetVersion( pStm->GetVersion() ); + SetError( pStm->GetError() ); + SyncSvStream( pStm->Tell() ); + } +} + +//========================================================================= +SvPersistStream::SvPersistStream +( + SvClassManager & rMgr, /* Alle Factorys, deren Objekt geladen und + gespeichert werdn k"onnen */ + SvStream * pStream, /* Dieser Stream wird als Medium genommen, auf + dem der PersistStream arbeitet */ + const SvPersistStream & rPersStm + /* Wenn PersistStream's verschachtelt werden, + dann ist dies der Parent-Stream. */ +) + : rClassMgr( rMgr ) + , pStm( pStream ) + // Bereiche nicht ueberschneiden, deshalb nur groessere Indexe + , aPUIdx( rPersStm.GetCurMaxIndex() +1 ) + , nStartIdx( rPersStm.GetCurMaxIndex() +1 ) + , pRefStm( &rPersStm ) + , nFlags( 0 ) +/* [Beschreibung] + + Der Konstruktor der Klasse SvPersistStream. Die Objekte rMgr und + pStream d"urfen nicht ver"andert werden, solange sie in einem + SvPersistStream eingesetzt sind. Eine Aussnahme gibt es f"ur + pStream (siehe <SvPersistStream::SetStream>). + Durch diesen Konstruktor wird eine Hierarchiebildung unterst"utzt. + Alle Objekte aus einer Hierarchie m"ussen erst geladen werden, + wenn das erste aus dieser Hierarchie benutzt werden soll. +*/ +{ + bIsWritable = TRUE; + if( pStm ) + { + SetVersion( pStm->GetVersion() ); + SetError( pStm->GetError() ); + SyncSvStream( pStm->Tell() ); + } +} + +//========================================================================= +SvPersistStream::~SvPersistStream() +/* [Beschreibung] + + Der Detruktor ruft die Methode <SvPersistStream::SetStream> + mit NULL. +*/ +{ + SetStream( NULL ); +} + +//========================================================================= +void SvPersistStream::SetStream +( + SvStream * pStream /* auf diesem Stream arbeitet der PersistStream */ + +) +/* [Beschreibung] + + Es wird ein Medium (pStream) eingesetzt, auf dem PersistStream arbeitet. + Dieses darf nicht von aussen modifiziert werden, solange es + eingesetzt ist. Es sei denn, w"ahrend auf dem Medium gearbeitet + wird, wird keine Methode von SvPersistStream gerufen, bevor + nicht <SvPersistStream::SetStream> mit demselben Medium gerufen + wurde. +*/ +{ + if( pStm != pStream ) + { + if( pStm ) + { + SyncSysStream(); + pStm->SetError( GetError() ); + } + pStm = pStream; + } + if( pStm ) + { + SetVersion( pStm->GetVersion() ); + SetError( pStm->GetError() ); + SyncSvStream( pStm->Tell() ); + } +} + +//========================================================================= +USHORT SvPersistStream::IsA() const +/* [Beschreibung] + + Gibt den Identifier dieses Streamklasse zur"uck. + + [R"uckgabewert] + + USHORT ID_PERSISTSTREAM wird zur"uckgegeben. + + + [Querverweise] + + <SvStream::IsA> +*/ +{ + return ID_PERSISTSTREAM; +} + + +/************************************************************************* +|* SvPersistStream::ResetError() +*************************************************************************/ +void SvPersistStream::ResetError() +{ + SvStream::ResetError(); + DBG_ASSERT( pStm, "stream not set" ); + pStm->ResetError(); +} + +/************************************************************************* +|* SvPersistStream::GetData() +*************************************************************************/ +ULONG SvPersistStream::GetData( void* pData, ULONG nSize ) +{ + DBG_ASSERT( pStm, "stream not set" ); + ULONG nRet = pStm->Read( pData, nSize ); + SetError( pStm->GetError() ); + return nRet; +} + +/************************************************************************* +|* SvPersistStream::PutData() +*************************************************************************/ +ULONG SvPersistStream::PutData( const void* pData, ULONG nSize ) +{ + DBG_ASSERT( pStm, "stream not set" ); + ULONG nRet = pStm->Write( pData, nSize ); + SetError( pStm->GetError() ); + return nRet; +} + +/************************************************************************* +|* SvPersistStream::Seek() +*************************************************************************/ +ULONG SvPersistStream::SeekPos( ULONG nPos ) +{ + DBG_ASSERT( pStm, "stream not set" ); + ULONG nRet = pStm->Seek( nPos ); + SetError( pStm->GetError() ); + return nRet; +} + +/************************************************************************* +|* SvPersistStream::FlushData() +*************************************************************************/ +void SvPersistStream::FlushData() +{ +} + +/************************************************************************* +|* SvPersistStream::GetCurMaxIndex() +*************************************************************************/ +ULONG SvPersistStream::GetCurMaxIndex( const SvPersistUIdx & rIdx ) const +{ + // const bekomme ich nicht den hoechsten Index + SvPersistUIdx * p = (SvPersistUIdx *)&rIdx; + // alten merken + ULONG nCurIdx = p->GetCurIndex(); + p->Last(); + // Bereiche nicht ueberschneiden, deshalb nur groessere Indexe + ULONG nMaxIdx = p->GetCurIndex(); + // wieder herstellen + p->Seek( nCurIdx ); + return nMaxIdx; +} + +/************************************************************************* +|* SvPersistStream::GetIndex() +*************************************************************************/ +ULONG SvPersistStream::GetIndex( SvPersistBase * pObj ) const +{ + ULONG nId = (ULONG)aPTable.Get( (ULONG)pObj ); + if( !nId && pRefStm ) + return pRefStm->GetIndex( pObj ); + return nId; +} + +/************************************************************************* +|* SvPersistStream::GetObject) +*************************************************************************/ +SvPersistBase * SvPersistStream::GetObject( ULONG nIdx ) const +{ + if( nIdx >= nStartIdx ) + return aPUIdx.Get( nIdx ); + else if( pRefStm ) + return pRefStm->GetObject( nIdx ); + return NULL; +} + +//========================================================================= +#define LEN_1 0x80 +#define LEN_2 0x40 +#define LEN_4 0x20 +#define LEN_5 0x10 +UINT32 SvPersistStream::ReadCompressed +( + SvStream & rStm /* Aus diesem Stream werden die komprimierten Daten + gelesen */ +) +/* [Beschreibung] + + Ein im Stream komprimiert abgelegtes Wort wird gelesen. In welchem + Format komprimiert wird, siehe <SvPersistStream::WriteCompressed>. + + [R"uckgabewert] + + UINT32 Das nicht komprimierte Wort wird zur"uckgegeben. + + [Querverweise] + +*/ +{ + UINT32 nRet(0); + BYTE nMask; + rStm >> nMask; + if( nMask & LEN_1 ) + nRet = ~LEN_1 & nMask; + else if( nMask & LEN_2 ) + { + nRet = ~LEN_2 & nMask; + nRet <<= 8; + rStm >> nMask; + nRet |= nMask; + } + else if( nMask & LEN_4 ) + { + nRet = ~LEN_4 & nMask; + nRet <<= 8; + rStm >> nMask; + nRet |= nMask; + nRet <<= 16; + USHORT n; + rStm >> n; + nRet |= n; + } + else if( nMask & LEN_5 ) + { + if( nMask & 0x0F ) + { + rStm.SetError( SVSTREAM_FILEFORMAT_ERROR ); + DBG_ERROR( "format error" ); + } + rStm >> nRet; + } + else + { + rStm.SetError( SVSTREAM_FILEFORMAT_ERROR ); + DBG_ERROR( "format error" ); + } + return nRet; +} + +//========================================================================= +void SvPersistStream::WriteCompressed +( + SvStream & rStm,/* Aus diesem Stream werden die komprimierten Daten + gelesen */ + UINT32 nVal /* Dieser Wert wird komprimiert geschrieben */ +) +/* [Beschreibung] + + Das "ubergebene Wort wird komprimiert und in den Stream + geschrieben. Folgendermassen wir komprimiert. + nVal < 0x80 => 0x80 + nVal ist 1 Byte gross. + nVal < 0x4000 => 0x4000 + nVal ist 2 Byte gross. + nVal < 0x20000000 => 0x20000000 + nVal ist 4 Byte gross. + nVal > 0x1FFFFFFF => 0x1000000000+ nVal ist 5 Byte gross. + + [Querverweise] + + <SvPersistStream::ReadCompressed> +*/ +{ +#ifdef STOR_NO_OPTIMIZE + if( nVal < 0x80 ) + rStm << (BYTE)(LEN_1 | nVal); + else if( nVal < 0x4000 ) + { + rStm << (BYTE)(LEN_2 | (nVal >> 8)); + rStm << (BYTE)nVal; + } + else if( nVal < 0x20000000 ) + { + // hoechstes BYTE + rStm << (BYTE)(LEN_4 | (nVal >> 24)); + // 2. hoechstes BYTE + rStm << (BYTE)(nVal >> 16); + rStm << (USHORT)(nVal); + } + else +#endif + { + rStm << (BYTE)LEN_5; + rStm << nVal; + } +} + +//========================================================================= +UINT32 SvPersistStream::WriteDummyLen() +/* [Beschreibung] + + Die Methode schreibt 4 Byte in den Stream und gibt die Streamposition + zur"uck. + + [R"uckgabewert] + + UINT32 Die Position hinter der L"angenangabe wird zur"uckgegeben. + + [Beispiel] + + UINT32 nObjPos = rStm.WriteDummyLen(); + ... + // Daten schreiben + ... + rStm.WriteLen( nObjPos ); + + [Querverweise] + + <SvPersistStream::ReadLen>, <SvPersistStream::WriteLen> + +*/ +{ +#ifdef DBG_UTIL + UINT32 nPos = Tell(); +#endif + UINT32 n0 = 0; + *this << n0; // wegen Sun sp + // keine Assertion bei Streamfehler + DBG_ASSERT( GetError() != SVSTREAM_OK + || (sizeof( UINT32 ) == Tell() -nPos), + "keine 4-Byte fuer Langenangabe" ); + return Tell(); +} + +//========================================================================= +void SvPersistStream::WriteLen +( + UINT32 nObjPos /* die Position + 4, an der die L"ange geschrieben + wird. */ +) +/* [Beschreibung] + + Die Methode schreibt die Differenz zwischen der aktuellen und + nObjPos als UINT32 an die Position nObjPos -4 im Stream. Danach + wird der Stream wieder auf die alte Position gestellt. + + [Beispiel] + + Die Differenz enth"alt nicht die L"angenangabe. + + UINT32 nObjPos = rStm.WriteDummyLen(); + ... + // Daten schreiben + ... + rStm.WriteLen( nObjPos ); + // weitere Daten schreiben + + [Querverweise] + + <SvPersistStream::ReadLen>, <SvPersistStream::WriteDummyLen> +*/ +{ + UINT32 nPos = Tell(); + UINT32 nLen = nPos - nObjPos; + // die Laenge mu� im stream 4-Byte betragen + Seek( nObjPos - sizeof( UINT32 ) ); + // Laenge schreiben + *this << nLen; + Seek( nPos ); +} + +//========================================================================= +UINT32 SvPersistStream::ReadLen +( + UINT32 * pTestPos /* Die Position des Streams, nach dem Lesen der + L"ange, wird zur"uckgegeben. Es darf auch NULL + "ubergeben werden. */ +) +/* [Beschreibung] + + Liest die L"ange die vorher mit <SvPersistStream::WriteDummyLen> + und <SvPersistStream::WriteLen> geschrieben wurde. +*/ +{ + UINT32 nLen; + *this >> nLen; + if( pTestPos ) + *pTestPos = Tell(); + return nLen; +} + +//========================================================================= +// Dateirormat abw"arts kompatibel +#ifdef STOR_NO_OPTIMIZE +#define P_VER (BYTE)0x00 +#else +#define P_VER (BYTE)0x01 +#endif +#define P_VER_MASK (BYTE)0x0F +#define P_ID_0 (BYTE)0x80 +#define P_OBJ (BYTE)0x40 +#define P_DBGUTIL (BYTE)0x20 +#define P_ID (BYTE)0x10 +#ifdef STOR_NO_OPTIMIZE +#define P_STD P_DBGUTIL +#else +#define P_STD 0 +#endif + +static void WriteId +( + SvStream & rStm, + BYTE nHdr, + UINT32 nId, + USHORT nClassId +) +{ +#ifdef STOR_NO_OPTIMIZE + nHdr |= P_ID; +#endif + nHdr |= P_VER; + if( nHdr & P_ID ) + { + if( (nHdr & P_OBJ) || nId != 0 ) + { // Id nur bei Zeiger, oder DBGUTIL + rStm << (BYTE)(nHdr); + SvPersistStream::WriteCompressed( rStm, nId ); + } + else + { // NULL Pointer + rStm << (BYTE)(nHdr | P_ID_0); + return; + } + } + else + rStm << nHdr; + + if( (nHdr & P_DBGUTIL) || (nHdr & P_OBJ) ) + // Objekte haben immer eine Klasse, + // Pointer nur bei DBG_UTIL und != NULL + SvPersistStream::WriteCompressed( rStm, nClassId ); +} + +//========================================================================= +static void ReadId +( + SvStream & rStm, + BYTE & nHdr, + UINT32 & nId, + USHORT & nClassId +) +{ + nClassId = 0; + rStm >> nHdr; + if( nHdr & P_ID_0 ) + nId = 0; + else + { + if( (nHdr & P_VER_MASK) == 0 ) + { + if( (nHdr & P_DBGUTIL) || !(nHdr & P_OBJ) ) + nId = SvPersistStream::ReadCompressed( rStm ); + else + nId = 0; + } + else if( nHdr & P_ID ) + nId = SvPersistStream::ReadCompressed( rStm ); + + if( (nHdr & P_DBGUTIL) || (nHdr & P_OBJ) ) + nClassId = (USHORT)SvPersistStream::ReadCompressed( rStm ); + } +} + +//========================================================================= +void SvPersistStream::WriteObj +( + BYTE nHdr, + SvPersistBase * pObj +) +{ +#ifdef STOR_NO_OPTIMIZE + UINT32 nObjPos = 0; + if( nHdr & P_DBGUTIL ) + // Position fuer Laenge merken + nObjPos = WriteDummyLen(); +#endif + pObj->Save( *this ); +#ifdef STOR_NO_OPTIMIZE + if( nHdr & P_DBGUTIL ) + WriteLen( nObjPos ); +#endif +} + +//========================================================================= +SvPersistStream& SvPersistStream::WritePointer +( + SvPersistBase * pObj +) +{ + BYTE nP = P_STD; + + if( pObj ) + { + ULONG nId = GetIndex( pObj ); + if( nId ) + nP |= P_ID; + else + { + nId = aPUIdx.Insert( pObj ); + aPTable.Insert( (ULONG)pObj, (void *)nId ); + nP |= P_OBJ; + } + WriteId( *this, nP, nId, pObj->GetClassId() ); + if( nP & P_OBJ ) + WriteObj( nP, pObj ); + } + else + { // NULL Pointer + WriteId( *this, nP | P_ID, 0, 0 ); + } + return *this; +} + +//========================================================================= +UINT32 SvPersistStream::ReadObj +( + SvPersistBase * & rpObj, + BOOL bRegister +) +{ + BYTE nHdr; + UINT32 nId = 0; + USHORT nClassId; + + rpObj = NULL; // Spezifikation: Im Fehlerfall 0. + ReadId( *this, nHdr, nId, nClassId ); + + // reine Versionsnummer durch maskieren + if( P_VER < (nHdr & P_VER_MASK) ) + { + SetError( SVSTREAM_FILEFORMAT_ERROR ); + DBG_ERROR( "false version" ); + } + + if( !(nHdr & P_ID_0) && GetError() == SVSTREAM_OK ) + { + if( P_OBJ & nHdr ) + { // read object, nId nur bei P_DBGUTIL gesetzt + DBG_ASSERT( !(nHdr & P_DBGUTIL) || NULL == aPUIdx.Get( nId ), + "object already exist" ); + SvCreateInstancePersist pFunc = rClassMgr.Get( nClassId ); + + UINT32 nObjLen(0), nObjPos(0); + if( nHdr & P_DBGUTIL ) + nObjLen = ReadLen( &nObjPos ); + if( !pFunc ) + { +#ifdef DBG_UTIL + ByteString aStr( "no class with id: " ); + aStr += ByteString::CreateFromInt32( nClassId ); + aStr += " registered"; + DBG_WARNING( aStr.GetBuffer() ); +#endif + SetError( ERRCODE_IO_NOFACTORY ); + return 0; + } + pFunc( &rpObj ); + // Sichern + rpObj->AddRef(); + + if( bRegister ) + { + // unbedingt erst in Tabelle eintragen + ULONG nNewId = aPUIdx.Insert( rpObj ); + // um den gleichen Zustand, wie nach dem Speichern herzustellen + aPTable.Insert( (ULONG)rpObj, (void *)nNewId ); + DBG_ASSERT( !(nHdr & P_DBGUTIL) || nId == nNewId, + "read write id conflict: not the same" ); + } + // und dann Laden + rpObj->Load( *this ); +#ifdef DBG_UTIL + if( nObjLen + nObjPos != Tell() ) + { + ByteString aStr( "false object len: read = " ); + aStr += ByteString::CreateFromInt32( (long)(Tell() - nObjPos) ); + aStr += ", should = "; + aStr += ByteString::CreateFromInt32( nObjLen ); + DBG_ERROR( aStr.GetBuffer() ); + } +#endif + rpObj->RestoreNoDelete(); + rpObj->ReleaseRef(); + } + else + { + rpObj = GetObject( nId ); + DBG_ASSERT( rpObj != NULL, "object does not exist" ); + DBG_ASSERT( rpObj->GetClassId() == nClassId, "class mismatch" ); + } + } + return nId; +} + +//========================================================================= +SvPersistStream& SvPersistStream::ReadPointer +( + SvPersistBase * & rpObj +) +{ + ReadObj( rpObj, TRUE ); + return *this; +} + +//========================================================================= +SvPersistStream& operator << +( + SvPersistStream & rStm, + SvPersistBase * pObj +) +{ + return rStm.WritePointer( pObj ); +} + +//========================================================================= +SvPersistStream& operator >> +( + SvPersistStream & rStm, + SvPersistBase * & rpObj +) +{ + return rStm.ReadPointer( rpObj ); +} + +//========================================================================= +SvStream& operator << +( + SvStream & rStm, + SvPersistStream & rThis +) +{ + SvStream * pOldStm = rThis.GetStream(); + rThis.SetStream( &rStm ); + + BYTE bTmp = 0; + rThis << bTmp; // Version + UINT32 nCount = (UINT32)rThis.aPUIdx.Count(); + rThis << nCount; + SvPersistBase * pEle = rThis.aPUIdx.First(); + for( UINT32 i = 0; i < nCount; i++ ) + { + BYTE nP = P_OBJ | P_ID | P_STD; + WriteId( rThis, nP, rThis.aPUIdx.GetCurIndex(), + pEle->GetClassId() ); + rThis.WriteObj( nP, pEle ); + pEle = rThis.aPUIdx.Next(); + } + rThis.SetStream( pOldStm ); + return rStm; +} + +//========================================================================= +SvStream& operator >> +( + SvStream & rStm, + SvPersistStream & rThis +) +{ + SvStream * pOldStm = rThis.GetStream(); + rThis.SetStream( &rStm ); + + BYTE nVers; + rThis >> nVers; // Version + if( 0 == nVers ) + { + UINT32 nCount = 0; + rThis >> nCount; + for( UINT32 i = 0; i < nCount; i++ ) + { + SvPersistBase * pEle; + // Lesen, ohne in die Tabellen einzutragen + UINT32 nId = rThis.ReadObj( pEle, FALSE ); + if( rThis.GetError() ) + break; + + // Die Id eines Objektes wird nie modifiziert + rThis.aPUIdx.Insert( nId, pEle ); + rThis.aPTable.Insert( (ULONG)pEle, (void *)nId ); + } + } + else + rThis.SetError( SVSTREAM_FILEFORMAT_ERROR ); + + rThis.SetStream( pOldStm ); + return rStm; +} + +//========================================================================= +ULONG SvPersistStream::InsertObj( SvPersistBase * pObj ) +{ + ULONG nId = aPUIdx.Insert( pObj ); + aPTable.Insert( (ULONG)pObj, (void *)nId ); + return nId; +} + +//========================================================================= +ULONG SvPersistStream::RemoveObj( SvPersistBase * pObj ) +{ + ULONG nIdx = GetIndex( pObj ); + aPUIdx.Remove( nIdx ); + aPTable.Remove( (ULONG)pObj ); + return nIdx; +} + diff --git a/tools/source/ref/ref.cxx b/tools/source/ref/ref.cxx new file mode 100644 index 000000000000..c99a043fe92d --- /dev/null +++ b/tools/source/ref/ref.cxx @@ -0,0 +1,54 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ref.cxx,v $ + * $Revision: 1.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_tools.hxx" + +#include <tools/ref.hxx> + +/****************** SvRefBaseMemberList **********************************/ +SV_IMPL_REF_LIST( SvRefBase,SvRefBase* ) + +/************************************************************************** +#* SvRefBase::~SvRefBase() +**************************************************************************/ +SvRefBase::~SvRefBase() +{ +} + +/************************************************************************** +#* SvRefBase::QueryDelete() +**************************************************************************/ +void SvRefBase::QueryDelete() +{ + nRefCount = SV_NO_DELETE_REFCOUNT / 2; + delete this; +} + |