From cbedb240486a21c5d5676e7a7f4e2ba17a55dbab Mon Sep 17 00:00:00 2001 From: Vladimir Glazounov Date: Fri, 13 Mar 2009 15:52:34 +0000 Subject: CWS-TOOLING: integrate CWS mhu17 2009-01-23 14:08:09 +0100 mhu r266816 : CWS-TOOLING: rebase CWS mhu17 to trunk@266428 (milestone: DEV300:m39) 2009-01-16 17:49:37 +0100 mhu r266442 : #i98151# Migration to subversion. 2009-01-16 17:48:53 +0100 mhu r266441 : #i98151# Migration to subversion. 2009-01-16 17:47:56 +0100 mhu r266440 : #i98151# Migration to subversion. --- sal/inc/internal/once.h | 2 + sal/inc/osl/file.h | 60 ++ sal/osl/unx/file.cxx | 195 +++- sal/osl/w32/dllentry.c | 4 + sal/osl/w32/file.cxx | 202 ++++- sal/rtl/source/alloc_cache.h | 2 +- sal/rtl/source/locale.c | 76 +- sal/rtl/source/makefile.mk | 18 +- sal/util/sal.map | 6 + store/inc/store/filelckb.hxx | 162 ---- store/inc/store/lockbyte.hxx | 122 --- store/inc/store/memlckb.hxx | 152 ---- store/inc/store/object.hxx | 134 --- store/source/filelckb.cxx | 699 -------------- store/source/fileos2.hxx | 255 ------ store/source/filestd.hxx | 242 ----- store/source/fileunx.hxx | 339 ------- store/source/filew32.hxx | 274 ------ store/source/lockbyte.cxx | 979 ++++++++++++++++++++ store/source/lockbyte.hxx | 222 +++++ store/source/makefile.mk | 16 +- store/source/memlckb.cxx | 344 ------- store/source/object.cxx | 16 +- store/source/object.hxx | 146 +++ store/source/storbase.cxx | 2060 +++--------------------------------------- store/source/storbase.hxx | 1175 ++++++++++++------------ store/source/storbios.cxx | 1570 ++++++++++++++++++++++++++++++++ store/source/storbios.hxx | 302 +++++++ store/source/storcach.cxx | 928 +++++++++---------- store/source/storcach.hxx | 179 +--- store/source/stordata.cxx | 1522 +++++++++++-------------------- store/source/stordata.hxx | 561 ++++++------ store/source/stordir.cxx | 249 +++++ store/source/stordir.hxx | 157 ++++ store/source/store.cxx | 91 +- store/source/storlckb.cxx | 526 ++--------- store/source/storlckb.hxx | 158 +--- store/source/storpage.cxx | 1362 ++++++++++------------------ store/source/storpage.hxx | 115 ++- store/source/stortree.cxx | 575 +++++++----- store/source/stortree.hxx | 250 ++--- store/util/makefile.mk | 24 - store/util/sto.dxp | 25 - store/util/sto.map | 30 - store/util/sto.mxp.map | 204 ----- store/util/store.mxp.map | 204 ----- store/workben/makefile.mk | 40 +- store/workben/t_base.cxx | 166 +--- store/workben/t_file.cxx | 108 ++- store/workben/t_leak.cxx | 19 + store/workben/t_page.cxx | 1574 ++++++++++++++++++++++++++++++++ store/workben/t_store.cxx | 40 +- 52 files changed, 8996 insertions(+), 9885 deletions(-) delete mode 100644 store/inc/store/filelckb.hxx delete mode 100644 store/inc/store/lockbyte.hxx delete mode 100644 store/inc/store/memlckb.hxx delete mode 100644 store/inc/store/object.hxx delete mode 100644 store/source/filelckb.cxx delete mode 100644 store/source/fileos2.hxx delete mode 100644 store/source/filestd.hxx delete mode 100644 store/source/fileunx.hxx delete mode 100644 store/source/filew32.hxx create mode 100644 store/source/lockbyte.cxx create mode 100644 store/source/lockbyte.hxx delete mode 100644 store/source/memlckb.cxx create mode 100644 store/source/object.hxx create mode 100644 store/source/storbios.cxx create mode 100644 store/source/storbios.hxx create mode 100644 store/source/stordir.cxx create mode 100644 store/source/stordir.hxx delete mode 100644 store/util/sto.dxp delete mode 100644 store/util/sto.map delete mode 100644 store/util/sto.mxp.map delete mode 100644 store/util/store.mxp.map create mode 100644 store/workben/t_leak.cxx create mode 100644 store/workben/t_page.cxx diff --git a/sal/inc/internal/once.h b/sal/inc/internal/once.h index 08a0a254e7bc..c0595ef2a135 100644 --- a/sal/inc/internal/once.h +++ b/sal/inc/internal/once.h @@ -47,7 +47,9 @@ typedef pthread_once_t sal_once_type; #elif defined(SAL_W32) #define WIN32_LEAN_AND_MEAN +#pragma warning(push,1) /* disable warnings within system headers */ #include +#pragma warning(pop) typedef struct sal_once_st sal_once_type; struct sal_once_st diff --git a/sal/inc/osl/file.h b/sal/inc/osl/file.h index dec8ac88a11f..3e7a85dfe662 100644 --- a/sal/inc/osl/file.h +++ b/sal/inc/osl/file.h @@ -808,6 +808,37 @@ oslFileError SAL_CALL osl_setFileSize( oslFileHandle Handle, sal_uInt64 uSize ); oslFileError SAL_CALL osl_getFileSize( oslFileHandle Handle, sal_uInt64 *pSize ); +/** Map flags. + + @since UDK 3.2.10 + */ +#define osl_File_MapFlag_RandomAccess ((sal_uInt32)(0x1)) + +/** Map a shared file into memory. + + @since UDK 3.2.10 + */ +oslFileError +SAL_CALL osl_mapFile ( + oslFileHandle Handle, + void** ppAddr, + sal_uInt64 uLength, + sal_uInt64 uOffset, + sal_uInt32 uFlags +); + + +/** Unmap a shared file from memory. + + @since UDK 3.2.10 + */ +oslFileError +SAL_CALL osl_unmapFile ( + void* pAddr, + sal_uInt64 uLength +); + + /** Read a number of bytes from a file. Reads a number of bytes from a file. The internal file pointer is @@ -913,6 +944,35 @@ oslFileError SAL_CALL osl_isEndOfFile( oslFileHandle Handle, sal_Bool *pIsEOF ); oslFileError SAL_CALL osl_writeFile( oslFileHandle Handle, const void *pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64 *pBytesWritten ); +/** Read a number of bytes from a specified offset in a file. + + The current position of the internal file pointer may or may not be changed. + + @since UDK 3.2.10 + */ +oslFileError SAL_CALL osl_readFileAt( + oslFileHandle Handle, + sal_uInt64 uOffset, + void* pBuffer, + sal_uInt64 uBytesRequested, + sal_uInt64* pBytesRead +); + + +/** Write a number of bytes to a specified offset in a file. + + The current position of the internal file pointer may or may not be changed. + + @since UDK 3.2.10 + */ +oslFileError SAL_CALL osl_writeFileAt( + oslFileHandle Handle, + sal_uInt64 uOffset, + const void* pBuffer, + sal_uInt64 uBytesToWrite, + sal_uInt64* pBytesWritten +); + /** Read a line from a file. diff --git a/sal/osl/unx/file.cxx b/sal/osl/unx/file.cxx index 0ff212fe6cd8..9296cb1ef966 100644 --- a/sal/osl/unx/file.cxx +++ b/sal/osl/unx/file.cxx @@ -696,7 +696,10 @@ oslFileError osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal flags = fcntl(fd, F_GETFL, NULL); flags &= ~O_NONBLOCK; if( 0 > fcntl(fd, F_GETFL, flags) ) + { + close(fd); return oslTranslateFileError(OSL_FET_ERROR, errno); + } #endif if( NULL == pFileLockEnvVar ) aflock.l_type = 0; @@ -1164,6 +1167,93 @@ oslFileError osl_setFileTime( rtl_uString* ustrFileURL, const TimeValue* pCreati * *****************************************************************************/ +/******************************************* + osl_mapFile +********************************************/ +oslFileError +SAL_CALL osl_mapFile ( + oslFileHandle Handle, + void** ppAddr, + sal_uInt64 uLength, + sal_uInt64 uOffset, + sal_uInt32 uFlags +) +{ + oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle; + + if ((0 == pHandleImpl) || (-1 == pHandleImpl->fd) || (0 == ppAddr)) + return osl_File_E_INVAL; + *ppAddr = 0; + + static sal_uInt64 const g_limit_size_t = std::numeric_limits< size_t >::max(); + if (g_limit_size_t < uLength) + return osl_File_E_OVERFLOW; + size_t const nLength = sal::static_int_cast< size_t >(uLength); + + static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max(); + if (g_limit_off_t < uOffset) + return osl_File_E_OVERFLOW; + off_t const nOffset = sal::static_int_cast< off_t >(uOffset); + + void* p = mmap(NULL, nLength, PROT_READ, MAP_SHARED, pHandleImpl->fd, nOffset); + if (MAP_FAILED == p) + return oslTranslateFileError(OSL_FET_ERROR, errno); + *ppAddr = p; + + if (uFlags & osl_File_MapFlag_RandomAccess) + { + // Determine memory pagesize. +#if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX) + size_t const nPageSize = getpagesize(); +#else /* POSIX */ + size_t const nPageSize = sysconf(_SC_PAGESIZE); +#endif /* xBSD || POSIX */ + if (size_t(-1) != nPageSize) + { + /* + * Pagein, touching first byte of every memory page. + * Note: volatile disables optimizing the loop away. + */ + sal_uInt8 * pData (reinterpret_cast(*ppAddr)); + size_t nSize (nLength); + + volatile sal_uInt8 c = 0; + while (nSize > nPageSize) + { + c ^= pData[0]; + pData += nPageSize; + nSize -= nPageSize; + } + if (nSize > 0) + { + c^= pData[0]; + pData += nSize; + nSize -= nSize; + } + } + } + return osl_File_E_None; +} + +/******************************************* + osl_unmapFile +********************************************/ +oslFileError +SAL_CALL osl_unmapFile (void* pAddr, sal_uInt64 uLength) +{ + if (0 == pAddr) + return osl_File_E_INVAL; + + static sal_uInt64 const g_limit_size_t = std::numeric_limits< size_t >::max(); + if (g_limit_size_t < uLength) + return osl_File_E_OVERFLOW; + size_t const nLength = sal::static_int_cast< size_t >(uLength); + + if (-1 == munmap(static_cast(pAddr), nLength)) + return oslTranslateFileError(OSL_FET_ERROR, errno); + + return osl_File_E_None; +} /******************************************* osl_readFile @@ -1227,7 +1317,110 @@ oslFileError osl_writeFile(oslFileHandle Handle, const void* pBuffer, sal_uInt64 } /******************************************* - osl_writeFile + osl_readFileAt +********************************************/ +oslFileError +SAL_CALL osl_readFileAt ( + oslFileHandle Handle, + sal_uInt64 uOffset, + void* pBuffer, + sal_uInt64 uBytesRequested, + sal_uInt64* pBytesRead) +{ + oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle; + + if ((0 == pHandleImpl) || (pHandleImpl->fd < 0) || (0 == pBuffer) || (0 == pBytesRead)) + return osl_File_E_INVAL; + + static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max(); + if (g_limit_off_t < uOffset) + return osl_File_E_OVERFLOW; + off_t const nOffset = sal::static_int_cast< off_t >(uOffset); + + static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max(); + if (g_limit_ssize_t < uBytesRequested) + return osl_File_E_OVERFLOW; + size_t const nBytesRequested = sal::static_int_cast< size_t >(uBytesRequested); + +#if defined(LINUX) || defined(SOLARIS) + + ssize_t nBytes = ::pread(pHandleImpl->fd, pBuffer, nBytesRequested, nOffset); + if ((-1 == nBytes) && (EOVERFLOW == errno)) + { + /* + * Workaround for 'pread()' failure at end-of-file: + * + * Some 'pread()'s fail with EOVERFLOW when reading at (or past) + * end-of-file, different from 'lseek() + read()' behaviour. + * Returning '0 bytes read' and 'osl_File_E_None' instead. + */ + nBytes = 0; + } + +#else /* LINUX || SOLARIS */ + + if (-1 == ::lseek (pHandleImpl->fd, nOffset, SEEK_SET)) + return oslTranslateFileError(OSL_FET_ERROR, errno); + + ssize_t nBytes = ::read(pHandleImpl->fd, pBuffer, nBytesRequested); + +#endif /* LINUX || SOLARIS */ + + if (-1 == nBytes) + return oslTranslateFileError(OSL_FET_ERROR, errno); + + *pBytesRead = nBytes; + return osl_File_E_None; +} + +/******************************************* + osl_writeFileAt +********************************************/ +oslFileError +SAL_CALL osl_writeFileAt ( + oslFileHandle Handle, + sal_uInt64 uOffset, + const void* pBuffer, + sal_uInt64 uBytesToWrite, + sal_uInt64* pBytesWritten) +{ + oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle; + + if ((0 == pHandleImpl) || (pHandleImpl->fd < 0) || (0 == pBuffer) || (0 == pBytesWritten)) + return osl_File_E_INVAL; + + static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max(); + if (g_limit_off_t < uOffset) + return osl_File_E_OVERFLOW; + off_t const nOffset = sal::static_int_cast< off_t >(uOffset); + + static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max(); + if (g_limit_ssize_t < uBytesToWrite) + return osl_File_E_OVERFLOW; + size_t const nBytesToWrite = sal::static_int_cast< size_t >(uBytesToWrite); + +#if defined(LINUX) || defined(SOLARIS) + + ssize_t nBytes = ::pwrite(pHandleImpl->fd, pBuffer, nBytesToWrite, nOffset); + +#else /* LINUX || SOLARIS */ + + if (-1 == ::lseek(pHandleImpl->fd, nOffset, SEEK_SET)) + return oslTranslateFileError(OSL_FET_ERROR, errno); + + ssize_t nBytes = ::write(pHandleImpl->fd, pBuffer, nBytesToWrite); + +#endif /* LINUX || SOLARIS */ + + if (-1 == nBytes) + return oslTranslateFileError(OSL_FET_ERROR, errno); + + *pBytesWritten = nBytes; + return osl_File_E_None; +} + +/******************************************* + osl_setFilePos ********************************************/ oslFileError osl_setFilePos( oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uPos ) diff --git a/sal/osl/w32/dllentry.c b/sal/osl/w32/dllentry.c index ad14d3e2908b..11928a3b6458 100644 --- a/sal/osl/w32/dllentry.c +++ b/sal/osl/w32/dllentry.c @@ -56,6 +56,7 @@ extern CRITICAL_SECTION g_ThreadKeyListCS; extern oslMutex g_Mutex; extern oslMutex g_CurrentDirectoryMutex; +extern void rtl_locale_fini (void); extern void rtl_memory_fini (void); extern void rtl_cache_fini (void); extern void rtl_arena_fini (void); @@ -258,6 +259,9 @@ void do_cleanup( void ) __try #endif { + /* cleanup locale hashtable */ + rtl_locale_fini(); + /* finalize memory management */ rtl_memory_fini(); rtl_cache_fini(); diff --git a/sal/osl/w32/file.cxx b/sal/osl/w32/file.cxx index cb104f7d95aa..b25ed7735d36 100644 --- a/sal/osl/w32/file.cxx +++ b/sal/osl/w32/file.cxx @@ -55,12 +55,19 @@ #define WIN32_LEAN_AND_MEAN #include #include + #ifdef __MINGW32__ #include #include #endif + #include #include +#include + +#ifdef max /* conflict w/ std::numeric_limits::max() */ +#undef max +#endif //##################################################### // BEGIN global @@ -2588,16 +2595,13 @@ oslFileError SAL_CALL osl_isEndOfFile(oslFileHandle Handle, sal_Bool *pIsEOF) //############################################# oslFileError SAL_CALL osl_setFilePos(oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uPos) { - oslFileError error; - HANDLE hFile = (HANDLE)Handle; + HANDLE hFile = (HANDLE)Handle; + if (!IsValidHandle(hFile)) + return osl_File_E_INVAL; - if ( IsValidHandle(hFile) ) + DWORD dwMoveMethod = 0; + switch ( uHow ) { - DWORD dwMoveMethod; - LONG lDistanceToMove, lDistanceToMoveHigh; - - switch ( uHow ) - { case osl_Pos_Current: dwMoveMethod = FILE_CURRENT; break; @@ -2608,21 +2612,20 @@ oslFileError SAL_CALL osl_setFilePos(oslFileHandle Handle, sal_uInt32 uHow, sal_ default: dwMoveMethod = FILE_BEGIN; break; - } - - lDistanceToMove = (LONG)(uPos & 0xFFFFFFFF); - lDistanceToMoveHigh = (LONG)(uPos >> 32); - + } - SetLastError(0); - SetFilePointer( hFile, lDistanceToMove, &lDistanceToMoveHigh, dwMoveMethod ); + LONG nOffsetLo = sal::static_int_cast(uPos & 0xFFFFFFFF); + LONG nOffsetHi = sal::static_int_cast(uPos >> 32); - error = MapError( GetLastError() ); + SetLastError(0); + DWORD dwPosLo = SetFilePointer( hFile, nOffsetLo, &nOffsetHi, dwMoveMethod ); + if (INVALID_SET_FILE_POINTER == dwPosLo) + { + DWORD dwError = GetLastError(); + if (NO_ERROR != dwError) + return MapError( dwError ); } - else - error = osl_File_E_INVAL; - - return error; + return osl_File_E_None; } //############################################# @@ -2685,6 +2688,99 @@ oslFileError SAL_CALL osl_setFileSize(oslFileHandle Handle, sal_uInt64 uSize) return error; } +//############################################# +oslFileError SAL_CALL osl_mapFile( + oslFileHandle Handle, + void** ppAddr, + sal_uInt64 uLength, + sal_uInt64 uOffset, + sal_uInt32 uFlags) +{ + struct FileMapping + { + HANDLE m_handle; + + explicit FileMapping (HANDLE hMap) + : m_handle (hMap) + {} + + ~FileMapping() + { + (void)::CloseHandle(m_handle); + } + }; + + HANDLE hFile = (HANDLE)(Handle); + if (!IsValidHandle(hFile) || (0 == ppAddr)) + return osl_File_E_INVAL; + *ppAddr = 0; + + static SIZE_T const nLimit = std::numeric_limits< SIZE_T >::max(); + if (uLength > nLimit) + return osl_File_E_OVERFLOW; + SIZE_T const nLength = sal::static_int_cast< SIZE_T >(uLength); + + OSVERSIONINFO osinfo; + osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + (void)::GetVersionEx(&osinfo); + + if (VER_PLATFORM_WIN32_NT != osinfo.dwPlatformId) + return osl_File_E_NOSYS; // Unsupported + + FileMapping aMap( ::CreateFileMapping (hFile, NULL, SEC_COMMIT | PAGE_READONLY, 0, 0, NULL) ); + if (!IsValidHandle(aMap.m_handle)) + return MapError( GetLastError() ); + + DWORD const dwOffsetHi = sal::static_int_cast(uOffset >> 32); + DWORD const dwOffsetLo = sal::static_int_cast(uOffset & 0xFFFFFFFF); + + *ppAddr = ::MapViewOfFile( aMap.m_handle, FILE_MAP_READ, dwOffsetHi, dwOffsetLo, nLength ); + if (0 == *ppAddr) + return MapError( GetLastError() ); + + if (uFlags & osl_File_MapFlag_RandomAccess) + { + // Determine memory pagesize. + SYSTEM_INFO info; + ::GetSystemInfo( &info ); + DWORD const dwPageSize = info.dwPageSize; + + /* + * Pagein, touching first byte of each memory page. + * Note: volatile disables optimizing the loop away. + */ + BYTE * pData (reinterpret_cast(*ppAddr)); + SIZE_T nSize (nLength); + + volatile BYTE c = 0; + while (nSize > dwPageSize) + { + c ^= pData[0]; + pData += dwPageSize; + nSize -= dwPageSize; + } + if (nSize > 0) + { + c ^= pData[0]; + pData += nSize; + nSize -= nSize; + } + } + return osl_File_E_None; +} + +//############################################# +oslFileError SAL_CALL osl_unmapFile(void* pAddr, sal_uInt64 /* uLength */) +{ + if (0 == pAddr) + return osl_File_E_INVAL; + + if (!::UnmapViewOfFile (pAddr)) + return MapError( GetLastError() ); + + return osl_File_E_None; +} + //############################################# oslFileError SAL_CALL osl_readFile( oslFileHandle Handle, @@ -2743,6 +2839,72 @@ oslFileError SAL_CALL osl_writeFile( return error; } +//############################################# +oslFileError SAL_CALL osl_readFileAt( + oslFileHandle Handle, + sal_uInt64 uOffset, + void* pBuffer, + sal_uInt64 uBytesRequested, + sal_uInt64* pBytesRead) +{ + HANDLE hFile = (HANDLE)(Handle); + if (!IsValidHandle(hFile) || (0 == pBuffer)) + return osl_File_E_INVAL; + + static sal_uInt64 const g_limit_dword = std::numeric_limits< DWORD >::max(); + if (g_limit_dword < uBytesRequested) + return osl_File_E_OVERFLOW; + DWORD const dwBytes = sal::static_int_cast< DWORD >(uBytesRequested); + + if (0 == pBytesRead) + return osl_File_E_INVAL; + *pBytesRead = 0; + + oslFileError error = osl_setFilePos(Handle, osl_Pos_Absolut, uOffset); + if (osl_File_E_None != error) + return error; + + DWORD dwDone = 0; + if (!::ReadFile(hFile, pBuffer, dwBytes, &dwDone, NULL)) + return MapError( GetLastError() ); + + *pBytesRead = dwDone; + return osl_File_E_None; +} + +//############################################# +oslFileError SAL_CALL osl_writeFileAt( + oslFileHandle Handle, + sal_uInt64 uOffset, + const void* pBuffer, + sal_uInt64 uBytesToWrite, + sal_uInt64* pBytesWritten) +{ + HANDLE hFile = (HANDLE)(Handle); + if (!IsValidHandle(hFile) || (0 == pBuffer)) + return osl_File_E_INVAL; + + static sal_uInt64 const g_limit_dword = std::numeric_limits< DWORD >::max(); + if (g_limit_dword < uBytesToWrite) + return osl_File_E_OVERFLOW; + DWORD const dwBytes = sal::static_int_cast< DWORD >(uBytesToWrite); + + if (0 == pBytesWritten) + return osl_File_E_INVAL; + *pBytesWritten = 0; + + oslFileError error = osl_setFilePos(Handle, osl_Pos_Absolut, uOffset); + if (osl_File_E_None != error) + return error; + + DWORD dwDone = 0; + if (!::WriteFile(hFile, pBuffer, dwBytes, &dwDone, NULL)) + return MapError( GetLastError() ); + + *pBytesWritten = dwDone; + return osl_File_E_None; +} + //############################################# oslFileError SAL_CALL osl_removeFile( rtl_uString* strPath ) { diff --git a/sal/rtl/source/alloc_cache.h b/sal/rtl/source/alloc_cache.h index e6a43e97e980..8efef9daac14 100644 --- a/sal/rtl/source/alloc_cache.h +++ b/sal/rtl/source/alloc_cache.h @@ -86,7 +86,7 @@ struct rtl_cache_slab_st /** rtl_cache_magazine_type * @internal */ -#define RTL_CACHE_MAGAZINE_SIZE 64 +#define RTL_CACHE_MAGAZINE_SIZE 61 typedef struct rtl_cache_magazine_st rtl_cache_magazine_type; struct rtl_cache_magazine_st diff --git a/sal/rtl/source/locale.c b/sal/rtl/source/locale.c index a64c8721d01d..b87318203d55 100644 --- a/sal/rtl/source/locale.c +++ b/sal/rtl/source/locale.c @@ -28,10 +28,12 @@ * ************************************************************************/ -#include -#include -#include -#include +#include "rtl/locale.h" + +#include "osl/diagnose.h" +#include "rtl/alloc.h" + +#include "internal/once.h" static sal_Int32 RTL_HASHTABLE_SIZE[] = { @@ -54,11 +56,14 @@ typedef struct rtl_hashtable RTL_HASHENTRY** Table; } RTL_HASHTABLE; -static RTL_HASHTABLE* pLocaleTable = NULL; +static RTL_HASHTABLE* g_pLocaleTable = NULL; -static rtl_Locale* pDefaultLocale = NULL; +static rtl_Locale* g_pDefaultLocale = NULL; +static int rtl_locale_init (void); +/************************************************************************* + */ void rtl_hashentry_destroy(RTL_HASHENTRY* entry) { rtl_uString_release(entry->Entry->Language); @@ -68,6 +73,7 @@ void rtl_hashentry_destroy(RTL_HASHENTRY* entry) rtl_hashentry_destroy(entry->Next); rtl_freeMemory(entry->Entry); + rtl_freeMemory(entry); } void rtl_hashtable_destroy(RTL_HASHTABLE* table) @@ -199,14 +205,14 @@ sal_Bool rtl_hashtable_grow(RTL_HASHTABLE** table) return sal_True; } -sal_Bool rtl_hashtable_find(sal_Int32 key, sal_Int32 hashCode, rtl_Locale** pValue) +sal_Bool rtl_hashtable_find(RTL_HASHTABLE * table, sal_Int32 key, sal_Int32 hashCode, rtl_Locale** pValue) { - if (!pLocaleTable) + if (!table) return sal_False; - if (pLocaleTable->Table[key]) + if (table->Table[key]) { - RTL_HASHENTRY *pEntry = pLocaleTable->Table[key]; + RTL_HASHENTRY *pEntry = table->Table[key]; while (pEntry && hashCode != pEntry->Entry->HashCode) pEntry = pEntry->Next; @@ -221,6 +227,41 @@ sal_Bool rtl_hashtable_find(sal_Int32 key, sal_Int32 hashCode, rtl_Locale** pVal return sal_True; } +/************************************************************************* + * rtl_locale_init + */ +static void rtl_locale_once_init (void) +{ + OSL_ASSERT(g_pLocaleTable == 0); + rtl_hashtable_init(&g_pLocaleTable, 1); +} + +static int rtl_locale_init (void) +{ + static sal_once_type g_once = SAL_ONCE_INIT; + SAL_ONCE(&g_once, rtl_locale_once_init); + return (g_pLocaleTable != 0); +} + +/************************************************************************* + * rtl_locale_fini + */ +#if defined(__GNUC__) +static void rtl_locale_fini (void) __attribute__((destructor)); +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +#pragma fini(rtl_locale_fini) +static void rtl_locale_fini (void); +#endif /* __GNUC__ || __SUNPRO_C */ + +void rtl_locale_fini (void) +{ + if (g_pLocaleTable != 0) + { + rtl_hashtable_destroy (g_pLocaleTable); + g_pLocaleTable = 0; + } +} + /************************************************************************* * rtl_locale_register */ @@ -239,13 +280,13 @@ rtl_Locale * SAL_CALL rtl_locale_register( const sal_Unicode * language, const s if ( !variant ) variant = &c; - if (!pLocaleTable) - rtl_hashtable_init(&pLocaleTable, 1); + if (!rtl_locale_init()) + return NULL; hashCode = rtl_ustr_hashCode(language) ^ rtl_ustr_hashCode(country) ^ rtl_ustr_hashCode(variant); - key = rtl_hashfunc(pLocaleTable, hashCode); + key = rtl_hashfunc(g_pLocaleTable, hashCode); - if (rtl_hashtable_find(key, hashCode, &newLocale)) + if (rtl_hashtable_find(g_pLocaleTable, key, hashCode, &newLocale)) return newLocale; rtl_uString_newFromStr(&sLanguage, language); @@ -259,7 +300,7 @@ rtl_Locale * SAL_CALL rtl_locale_register( const sal_Unicode * language, const s newLocale->Variant = sVariant; newLocale->HashCode = hashCode; - rtl_hashtable_add(&pLocaleTable, newLocale); + rtl_hashtable_add(&g_pLocaleTable, newLocale); return newLocale; } @@ -269,7 +310,7 @@ rtl_Locale * SAL_CALL rtl_locale_register( const sal_Unicode * language, const s */ rtl_Locale * SAL_CALL rtl_locale_getDefault() { - return pDefaultLocale; + return g_pDefaultLocale; } /************************************************************************* @@ -277,7 +318,7 @@ rtl_Locale * SAL_CALL rtl_locale_getDefault() */ void SAL_CALL rtl_locale_setDefault( const sal_Unicode * language, const sal_Unicode * country, const sal_Unicode * variant ) { - pDefaultLocale = rtl_locale_register(language, country, variant); + g_pDefaultLocale = rtl_locale_register(language, country, variant); } /************************************************************************* @@ -322,4 +363,3 @@ sal_Int32 SAL_CALL rtl_locale_equals( rtl_Locale * This, rtl_Locale * obj ) { return This == obj; } - diff --git a/sal/rtl/source/makefile.mk b/sal/rtl/source/makefile.mk index 0d6447d64758..c2397485aa12 100644 --- a/sal/rtl/source/makefile.mk +++ b/sal/rtl/source/makefile.mk @@ -72,9 +72,6 @@ ALWAYSDBGTARGET=do_it_alwaysdebug .ENDIF SLOFILES= \ - $(SLO)$/alloc_global.obj \ - $(SLO)$/alloc_cache.obj \ - $(SLO)$/alloc_arena.obj \ $(SLO)$/memory.obj \ $(SLO)$/cipher.obj \ $(SLO)$/crc.obj \ @@ -96,8 +93,11 @@ SLOFILES= \ $(SLO)$/unload.obj \ $(SLO)$/logfile.obj \ $(SLO)$/tres.obj \ - $(SLO)$/debugprint.obj \ - $(SLO)$/math.obj + $(SLO)$/debugprint.obj \ + $(SLO)$/math.obj \ + $(SLO)$/alloc_global.obj\ + $(SLO)$/alloc_cache.obj \ + $(SLO)$/alloc_arena.obj .IF "$(OS)"=="MACOSX" SLOFILES+=$(SLO)$/memory_fini.obj @@ -106,9 +106,6 @@ SLOFILES+=$(SLO)$/memory_fini.obj #.IF "$(UPDATER)"=="YES" OBJFILES= \ - $(OBJ)$/alloc_global.obj \ - $(OBJ)$/alloc_cache.obj \ - $(OBJ)$/alloc_arena.obj \ $(OBJ)$/memory.obj \ $(OBJ)$/cipher.obj \ $(OBJ)$/crc.obj \ @@ -130,7 +127,10 @@ OBJFILES= \ $(OBJ)$/unload.obj \ $(OBJ)$/logfile.obj \ $(OBJ)$/tres.obj \ - $(OBJ)$/math.obj + $(OBJ)$/math.obj \ + $(OBJ)$/alloc_global.obj\ + $(OBJ)$/alloc_cache.obj \ + $(OBJ)$/alloc_arena.obj .IF "$(OS)"=="MACOSX" OBJFILES+=$(OBJ)$/memory_fini.obj diff --git a/sal/util/sal.map b/sal/util/sal.map index 36576439c7f8..03af5c114aa1 100755 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -577,6 +577,12 @@ UDK_3.8 { # OOo 3.0 UDK_3.9 { # OOo 3.1 global: + osl_mapFile; + osl_unmapFile; + + osl_readFileAt; + osl_writeFileAt; + rtl_math_expm1; rtl_math_log1p; rtl_math_atanh; diff --git a/store/inc/store/filelckb.hxx b/store/inc/store/filelckb.hxx deleted file mode 100644 index 77f6702e5bca..000000000000 --- a/store/inc/store/filelckb.hxx +++ /dev/null @@ -1,162 +0,0 @@ -/************************************************************************* - * - * 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: filelckb.hxx,v $ - * $Revision: 1.5 $ - * - * 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 - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef _STORE_FILELCKB_HXX_ -#define _STORE_FILELCKB_HXX_ "$Revision: 1.5 $" - -#include -#include -#include -#include -#include - -namespace store -{ - -class OFileLockBytes_Impl; - -/*======================================================================== - * - * OFileLockBytes interface. - * - *======================================================================*/ -class OFileLockBytes : - public store::OStoreObject, - public store::ILockBytes -{ -public: - /** Construction. - */ - OFileLockBytes (void); - - /** create. - @param pFilename [in] - @param eAccessMode [in] - @return store_E_None upon success - */ - storeError create ( - rtl_uString *pFilename, - storeAccessMode eAccessMode); - - /** Read at Offset into Buffer. - @param nOffset [in] - @param pBuffer [out] - @param nBytes [in] - @param rnDone [out] - @return store_E_None upon success - */ - virtual storeError readAt ( - sal_uInt32 nOffset, - void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone); - - /** Write at Offset from Buffer. - @param nOffset [in] - @param pBuffer [in] - @param nBytes [in] - @param rnDone [out] - @return store_E_None upon success - */ - virtual storeError writeAt ( - sal_uInt32 nOffset, - const void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone); - - /** flush. - @return store_E_None upon success - */ - virtual storeError flush (void); - - /** setSize. - @param nSize [in] - @return store_E_None upon success - */ - virtual storeError setSize (sal_uInt32 nSize); - - /** stat. - @param rnSize [out] - @return store_E_None upon success - */ - virtual storeError stat (sal_uInt32 &rnSize); - - /** Lock range at Offset. - @param nOffset [in] - @param nBytes [in] - @return store_E_None upon success - store_E_LockingViolation - */ - virtual storeError lockRange ( - sal_uInt32 nOffset, - sal_uInt32 nBytes); - - /** Unlock range at Offset. - @param nOffset [in] - @param nBytes [in] - @return store_E_None upon success - store_E_LockingViolation - */ - virtual storeError unlockRange ( - sal_uInt32 nOffset, - sal_uInt32 nBytes); - - /** Delegate multiple inherited IReference. - */ - virtual oslInterlockedCount SAL_CALL acquire (void); - virtual oslInterlockedCount SAL_CALL release (void); - -protected: - /** Destruction. - */ - virtual ~OFileLockBytes (void); - -private: - /** Representation. - */ - osl::Mutex m_aMutex; - OFileLockBytes_Impl *m_pImpl; - - /** Not implemented. - */ - OFileLockBytes (const OFileLockBytes&); - OFileLockBytes& operator= (const OFileLockBytes&); -}; - -/*======================================================================== - * - * The End. - * - *======================================================================*/ - -} // namespace store - -#endif /* !_STORE_FILELCKB_HXX_ */ - diff --git a/store/inc/store/lockbyte.hxx b/store/inc/store/lockbyte.hxx deleted file mode 100644 index a7e8c9751e4e..000000000000 --- a/store/inc/store/lockbyte.hxx +++ /dev/null @@ -1,122 +0,0 @@ -/************************************************************************* - * - * 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: lockbyte.hxx,v $ - * $Revision: 1.6 $ - * - * 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 - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef _STORE_LOCKBYTE_HXX_ -#define _STORE_LOCKBYTE_HXX_ "$Revision: 1.6 $" - -#include -#include -#include - -namespace store -{ - -/*======================================================================== - * - * ILockBytes interface. - * - *======================================================================*/ -class ILockBytes : public rtl::IReference -{ -public: - /** - @param nOffset [in] - @param pBuffer [out] - @param nBytes [in] - @param rnDone [out] - @return store_E_None upon success - */ - virtual storeError readAt ( - sal_uInt32 nOffset, - void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone) = 0; - - /** - @param nOffset [in] - @param pBuffer [in] - @param nBytes [in] - @param rnDone [out] - @return store_E_None upon success - */ - virtual storeError writeAt ( - sal_uInt32 nOffset, - const void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone) = 0; - - /** - @return store_E_None upon success - */ - virtual storeError flush (void) = 0; - - /** - @param nSize [in] - @return store_E_None upon success - */ - virtual storeError setSize (sal_uInt32 nSize) = 0; - - /** - @param rnSize [out] - @return store_E_None upon success - */ - virtual storeError stat (sal_uInt32 &rnSize) = 0; - - /** - @param nOffset [in] - @param nBytes [in] - @return store_E_None upon success - store_E_LockingViolation - */ - virtual storeError lockRange ( - sal_uInt32 nOffset, - sal_uInt32 nBytes) = 0; - - /** - @param nOffset [in] - @param nBytes [in] - @return store_E_None upon success - store_E_LockingViolation - */ - virtual storeError unlockRange ( - sal_uInt32 nOffset, - sal_uInt32 nBytes) = 0; -}; - -/*======================================================================== - * - * The End. - * - *======================================================================*/ - -} // namespace store - -#endif /* !_STORE_LOCKBYTE_HXX_ */ - diff --git a/store/inc/store/memlckb.hxx b/store/inc/store/memlckb.hxx deleted file mode 100644 index 213a6ffe75f7..000000000000 --- a/store/inc/store/memlckb.hxx +++ /dev/null @@ -1,152 +0,0 @@ -/************************************************************************* - * - * 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: memlckb.hxx,v $ - * $Revision: 1.5 $ - * - * 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 - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef _STORE_MEMLCKB_HXX_ -#define _STORE_MEMLCKB_HXX_ "$Revision: 1.5 $" - -#include -#include -#include -#include - -namespace store -{ - -class OMemoryLockBytes_Impl; - -/*======================================================================== - * - * OMemoryLockBytes interface. - * - *======================================================================*/ -class OMemoryLockBytes : - public store::OStoreObject, - public store::ILockBytes -{ -public: - /** Construction. - */ - OMemoryLockBytes (void); - - /** Read at Offset into Buffer. - @param nOffset [in] - @param pBuffer [out] - @param nBytes [in] - @param rnDone [out] - @return store_E_None upon success - */ - virtual storeError readAt ( - sal_uInt32 nOffset, - void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone); - - /** Write at Offset from Buffer. - @param nOffset [in] - @param pBuffer [in] - @param nBytes [in] - @param rnDone [out] - @return store_E_None upon success - */ - virtual storeError writeAt ( - sal_uInt32 nOffset, - const void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone); - - /** flush. - @return store_E_None upon success - */ - virtual storeError flush (void); - - /** setSize. - @param nSize [in] - @return store_E_None upon success - */ - virtual storeError setSize (sal_uInt32 nSize); - - /** stat. - @param rnSize [out] - @return store_E_None upon success - */ - virtual storeError stat (sal_uInt32 &rnSize); - - /** Lock range at Offset. - @param nOffset [in] - @param nBytes [in] - @return store_E_None upon success - store_E_LockingViolation - */ - virtual storeError lockRange ( - sal_uInt32 nOffset, - sal_uInt32 nBytes); - - /** Unlock range at Offset. - @param nOffset [in] - @param nBytes [in] - @return store_E_None upon success - store_E_LockingViolation - */ - virtual storeError unlockRange ( - sal_uInt32 nOffset, - sal_uInt32 nBytes); - - /** Delegate multiple inherited IReference. - */ - virtual oslInterlockedCount SAL_CALL acquire (void); - virtual oslInterlockedCount SAL_CALL release (void); - -protected: - /** Destruction. - */ - virtual ~OMemoryLockBytes (void); - -private: - /** Representation. - */ - osl::Mutex m_aMutex; - OMemoryLockBytes_Impl *m_pImpl; - - /** Not implemented. - */ - OMemoryLockBytes (const OMemoryLockBytes&); - OMemoryLockBytes& operator= (const OMemoryLockBytes&); -}; - -/*======================================================================== - * - * The End. - * - *======================================================================*/ - -} // namespace store - -#endif /* !_STORE_MEMLCKB_HXX_ */ - diff --git a/store/inc/store/object.hxx b/store/inc/store/object.hxx deleted file mode 100644 index 5e8b41bba7cc..000000000000 --- a/store/inc/store/object.hxx +++ /dev/null @@ -1,134 +0,0 @@ -/************************************************************************* - * - * 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: object.hxx,v $ - * $Revision: 1.6 $ - * - * 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 - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef _STORE_OBJECT_HXX_ -#define _STORE_OBJECT_HXX_ "$Revision: 1.6 $" - -#include -#include -#include - -namespace store -{ - -/*======================================================================== - * - * IStoreHandle interface. - * - *======================================================================*/ -class IStoreHandle : public rtl::IReference -{ -public: - /** Replaces dynamic_cast type checking. - */ - virtual sal_Bool SAL_CALL isKindOf (sal_uInt32 nTypeId) = 0; -}; - - -/** Template helper function as dynamic_cast replacement. - */ -template -store_handle_type * SAL_CALL query ( - IStoreHandle * pHandle, store_handle_type *); - -/*======================================================================== - * - * OStoreObject interface. - * - *======================================================================*/ -class OStoreObject : public store::IStoreHandle -{ - /** Template function specialization as dynamic_cast replacement. - */ - friend OStoreObject* - SAL_CALL query<> (IStoreHandle *pHandle, OStoreObject*); - -public: - /** Construction. - */ - OStoreObject (void); - - /** Allocation. - */ - static void* operator new (size_t n); - static void operator delete (void *p); - - /** IStoreHandle. - */ - virtual sal_Bool SAL_CALL isKindOf (sal_uInt32 nTypeId); - - /** IReference. - */ - virtual oslInterlockedCount SAL_CALL acquire (void); - virtual oslInterlockedCount SAL_CALL release (void); - -protected: - /** Destruction. - */ - virtual ~OStoreObject (void); - -private: - /** The IStoreHandle TypeId. - */ - static const sal_uInt32 m_nTypeId; - - /** Representation. - */ - oslInterlockedCount m_nRefCount; - - /** Not implemented. - */ - OStoreObject (const OStoreObject&); - OStoreObject& operator= (const OStoreObject&); -}; - -/** Template function specialization as dynamic_cast replacement. - */ -template<> inline OStoreObject* -SAL_CALL query (IStoreHandle *pHandle, OStoreObject*) -{ - if (pHandle && pHandle->isKindOf (OStoreObject::m_nTypeId)) - { - // Handle is kind of OStoreObject. - return static_cast(pHandle); - } - return 0; -} - -/*======================================================================== - * - * The End. - * - *======================================================================*/ - -} // namespace store - -#endif /* !_STORE_OBJECT_HXX_ */ - diff --git a/store/source/filelckb.cxx b/store/source/filelckb.cxx deleted file mode 100644 index 11be82912194..000000000000 --- a/store/source/filelckb.cxx +++ /dev/null @@ -1,699 +0,0 @@ -/************************************************************************* - * - * 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: filelckb.cxx,v $ - * $Revision: 1.17 $ - * - * 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 - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_store.hxx" - -#include - -#ifndef INCLUDED_STDDEF_H -#include -#define INCLUDED_STDDEF_H -#endif - -#ifndef INCLUDED_STRING_H -#include -#define INCLUDED_STRING_H -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace store; - -/*======================================================================== - * - * OFileLockBytes internals. - * - *======================================================================*/ - -/* - * __store_memcpy. - */ -inline void __store_memcpy (void * dst, const void * src, sal_uInt32 n) -{ - ::memcpy (dst, src, n); -} - -/* - * __store_errcode_mapping. - */ -struct __store_errcode_mapping_st -{ - sal_uInt32 m_nErrno; - storeError m_nCode; -}; - -static storeError __store_errnoToErrCode (sal_uInt32 nErrno); -#define ERROR_FROM_NATIVE(e) __store_errnoToErrCode((sal_uInt32)(e)) - -/* - * __store_file (basic file I/O; platform specific; inline). - */ -#define store_File_OpenRead 0x01L -#define store_File_OpenWrite 0x02L -#define store_File_OpenNoCreate 0x04L -#define store_File_OpenTruncate 0x08L - -#if defined(SAL_OS2) -#include -#elif defined(SAL_UNX) -#include -#elif defined(SAL_W32) -#include -#else /* !(OS2 | UNX | W32) */ -#include -#endif /* !(OS2 | UNX | W32) */ - -/* - * __store_errnoToErrCode. - */ -static storeError __store_errnoToErrCode (sal_uInt32 nErrno) -{ - int i, n = sizeof(__store_errcode_map) / sizeof(__store_errcode_map[0]); - for (i = 0; i < n; i++) - { - if (__store_errcode_map[i].m_nErrno == nErrno) - return __store_errcode_map[i].m_nCode; - } - return store_E_Unknown; -} - -/*======================================================================== - * - * FileMapping_Impl. - * - *======================================================================*/ -namespace // unnamed -{ - -struct FileMapping_Impl -{ - /** Representation. - */ - sal_uInt32 m_nAlignment; - sal_uInt32 m_nSize; - HSTORE m_hMap; - - /** Construction. - */ - FileMapping_Impl (void); - ~FileMapping_Impl (void); - - /** Create readonly file mapping. - */ - storeError create (HSTORE hFile); -}; - -/* - * FileMapping_Impl. - */ -inline FileMapping_Impl::FileMapping_Impl (void) - : m_nAlignment (__store_malign()), m_nSize (0), m_hMap (0) -{ -} - -/* - * ~FileMapping_Impl. - */ -inline FileMapping_Impl::~FileMapping_Impl (void) -{ - if (m_hMap != 0) - __store_funmap (m_hMap); -} - -/* - * create. - */ -inline storeError FileMapping_Impl::create (HSTORE hFile) -{ - if (m_nAlignment == (sal_uInt32)(-1)) - return store_E_Unknown; // E_Unsupported - - if ((m_hMap = __store_fmap (hFile)) == 0) - return ERROR_FROM_NATIVE(__store_errno()); - - return __store_fsize (hFile, m_nSize); -} - -} // unnamed namespace - -/*======================================================================== - * - * MemoryMapping_Impl. - * - *======================================================================*/ -namespace // unnamed -{ - -struct MemoryMapping_Impl -{ - /** Representation. - */ - sal_uInt32 m_nOffset; - sal_uInt32 m_nSize; - sal_uInt8 *m_pData; - - /** Construction. - */ - MemoryMapping_Impl (void); - ~MemoryMapping_Impl (void); - - /** Check for a valid memory mapping. - */ - bool isValid (void) const { return (m_pData != 0); } - - /** Create a readonly memory mapping. - */ - storeError create ( - const FileMapping_Impl & fmap, - sal_uInt32 nOffset, - sal_uInt32 nSize); - - /** Cleanup (unmap) memory mapping. - */ - void cleanup (void); -}; - -/* - * MemoryMapping_Impl. - */ -inline MemoryMapping_Impl::MemoryMapping_Impl (void) - : m_nOffset (0), m_nSize (0), m_pData (0) -{ -} - -/* - * ~MemoryMapping_Impl. - */ -inline MemoryMapping_Impl::~MemoryMapping_Impl (void) -{ - if (m_pData != 0) - { - __store_munmap (m_pData, m_nSize); - m_pData = 0, m_nSize = 0; - } -} - -/* - * create. - */ -inline storeError MemoryMapping_Impl::create ( - const FileMapping_Impl & fmap, sal_uInt32 nOffset, sal_uInt32 nSize) -{ - storeError result = store_E_None; - sal_uInt32 nAlign = (nOffset % fmap.m_nAlignment); - - nOffset -= nAlign; - nSize += nAlign; - - if ((nOffset + nSize) > fmap.m_nSize) - nSize = fmap.m_nSize - nOffset; - - m_pData = __store_mmap (fmap.m_hMap, nOffset, nSize); - if (m_pData == 0) - result = ERROR_FROM_NATIVE(__store_errno()); - else - m_nOffset = nOffset, m_nSize = nSize; - return (result); -} - -/* - * cleanup. - */ -inline void MemoryMapping_Impl::cleanup (void) -{ - if (m_pData != 0) - { - __store_munmap (m_pData, m_nSize); - m_pData = 0, m_nSize = 0; - } -} - -} // unnamed namespace - -/*======================================================================== - * - * OFileLockBytes_Impl interface. - * - *======================================================================*/ -namespace store -{ - -class OFileLockBytes_Impl -{ - /** Representation. - */ - HSTORE m_hFile; - MemoryMapping_Impl m_aMemmap; - bool m_bWriteable; - -public: - /** Allocation. - */ - static void * operator new (size_t n) SAL_THROW(()) - { - return rtl_allocateMemory (sal_uInt32(n)); - } - static void operator delete (void * p, size_t) SAL_THROW(()) - { - rtl_freeMemory (p); - } - - /** Construction. - */ - OFileLockBytes_Impl (void); - ~OFileLockBytes_Impl (void); - - /** Check for a valid file handle. - */ - bool isValid (void) const { return (m_hFile != 0); } - - /** Operation. - */ - storeError close (void); - - storeError create ( - const sal_Char *pszFilename, - storeAccessMode eAccessMode); - storeError create ( - rtl_uString *pFilename, - storeAccessMode eAccessMode); - - storeError resize (sal_uInt32 nSize); - - storeError readAt ( - sal_uInt32 nOffset, - void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone); - storeError writeAt ( - sal_uInt32 nOffset, - const void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone); - - storeError sync (void); - storeError stat (sal_uInt32 &rnSize); -}; - -} // namespace store - -/*======================================================================== - * - * OFileLockBytes_Impl (inline) implementation. - * - *======================================================================*/ -/* - * OFileLockBytes_Impl. - */ -inline OFileLockBytes_Impl::OFileLockBytes_Impl (void) - : m_hFile (0), - m_bWriteable (false) -{ -} - -/* - * ~OFileLockBytes_Impl. - */ -inline OFileLockBytes_Impl::~OFileLockBytes_Impl (void) -{ - m_aMemmap.cleanup(); - if (m_hFile) - { - (void)__store_fclose (m_hFile); - m_hFile = 0; - } -} - -/* - * close. - */ -inline storeError OFileLockBytes_Impl::close (void) -{ - m_aMemmap.cleanup(); - if (m_hFile) - { - (void)__store_fclose (m_hFile); - m_hFile = 0; - } - return store_E_None; -} - -/* - * create(sal_Char*). - */ -inline storeError OFileLockBytes_Impl::create ( - const sal_Char *pszFilename, storeAccessMode eAccessMode) -{ - m_aMemmap.cleanup(); - if (m_hFile) - { - (void)__store_fclose (m_hFile); - m_hFile = 0; - } - - m_bWriteable = (!(eAccessMode == store_AccessReadOnly)); - - sal_uInt32 nMode = store_File_OpenRead; - if (m_bWriteable) - nMode |= store_File_OpenWrite; - else - nMode |= store_File_OpenNoCreate; - - if (eAccessMode == store_AccessCreate) - nMode |= store_File_OpenTruncate; - if (eAccessMode == store_AccessReadWrite) - nMode |= store_File_OpenNoCreate; - - storeError eErrCode = __store_fopen (pszFilename, nMode, m_hFile); - if (eErrCode == store_E_None) - { - if (!m_bWriteable) - { - // Readonly, try Memory mapped I/O, ignore errors. - FileMapping_Impl fmap; - if (fmap.create (m_hFile) == store_E_None) - { - // Try to map the entire file into memory. - m_aMemmap.create (fmap, 0, fmap.m_nSize); - } - } - } - return eErrCode; -} - -/* - * create(rtl_uString*). - */ -inline storeError OFileLockBytes_Impl::create ( - rtl_uString *pFilename, storeAccessMode eAccessMode) -{ - // Path conversion result. - oslFileError result; - - // Convert into system path. - rtl::OUString aSystemPath; - result = osl_getSystemPathFromFileURL (pFilename, &(aSystemPath.pData)); - if (!(result == osl_File_E_None)) - { - // Not FileUrl. Maybe a system path, already. - result = osl_getFileURLFromSystemPath ( - pFilename, &(aSystemPath.pData)); - if (!(result == osl_File_E_None)) - { - // Invalid path. - return store_E_InvalidParameter; - } - - rtl_uString_assign (&(aSystemPath.pData), pFilename); - } - - // Convert into system text encoding. - rtl::OString aFilename ( - aSystemPath.pData->buffer, - aSystemPath.pData->length, - osl_getThreadTextEncoding()); - - // Open file. - return create (aFilename.pData->buffer, eAccessMode); -} - -/* - * readAt. - */ -inline storeError OFileLockBytes_Impl::readAt ( - sal_uInt32 nOffset, - void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone) -{ - if (m_aMemmap.isValid()) - { - // Memory mapped I/O. - if (!(nOffset < m_aMemmap.m_nSize)) - return store_E_None; - - nBytes = SAL_MIN(nOffset + nBytes, m_aMemmap.m_nSize) - nOffset; - if (!(nBytes > 0)) - return store_E_None; - - __store_memcpy (pBuffer, m_aMemmap.m_pData + nOffset, nBytes); - rnDone = nBytes; - - return store_E_None; - } - else - { - // File I/O. - return __store_fread (m_hFile, nOffset, pBuffer, nBytes, rnDone); - } -} - -/* - * writeAt. - */ -inline storeError OFileLockBytes_Impl::writeAt ( - sal_uInt32 nOffset, - const void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone) -{ - if (m_bWriteable) - return __store_fwrite (m_hFile, nOffset, pBuffer, nBytes, rnDone); - else - return store_E_AccessViolation; -} - -/* - * resize. - */ -inline storeError OFileLockBytes_Impl::resize (sal_uInt32 nSize) -{ - if (m_bWriteable) - return __store_ftrunc (m_hFile, nSize); - else - return store_E_AccessViolation; -} - -/* - * sync. - */ -inline storeError OFileLockBytes_Impl::sync (void) -{ - if (m_bWriteable) - return __store_fsync (m_hFile); - else - return store_E_None; -} - -/* - * stat. - */ -inline storeError OFileLockBytes_Impl::stat (sal_uInt32 &rnSize) -{ - if (m_aMemmap.isValid()) - { - // Memory mapped I/O. - rnSize = m_aMemmap.m_nSize; - return store_E_None; - } - return __store_fsize (m_hFile, rnSize); -} - -/*======================================================================== - * - * OFileLockBytes implementation. - * - *======================================================================*/ -/* - * OFileLockBytes. - */ -OFileLockBytes::OFileLockBytes (void) - : m_pImpl (new OFileLockBytes_Impl()) -{ -} - -/* - * ~OFileLockBytes. - */ -OFileLockBytes::~OFileLockBytes (void) -{ - delete m_pImpl; -} - -/* - * acquire. - */ -oslInterlockedCount SAL_CALL OFileLockBytes::acquire (void) -{ - return OStoreObject::acquire(); -} - -/* - * release. - */ -oslInterlockedCount SAL_CALL OFileLockBytes::release (void) -{ - return OStoreObject::release(); -} - -/* - * create. - */ -storeError OFileLockBytes::create ( - rtl_uString *pFilename, - storeAccessMode eAccessMode) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - if (pFilename) - return m_pImpl->create (pFilename, eAccessMode); - else - return store_E_InvalidParameter; -} - -/* - * readAt. - */ -storeError OFileLockBytes::readAt ( - sal_uInt32 nOffset, - void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone) -{ - // Initialize [out] param. - rnDone = 0; - - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - if (m_pImpl->isValid()) - return m_pImpl->readAt (nOffset, pBuffer, nBytes, rnDone); - else - return store_E_InvalidHandle; -} - -/* - * writeAt. - */ -storeError OFileLockBytes::writeAt ( - sal_uInt32 nOffset, - const void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone) -{ - // Initialize [out] param. - rnDone = 0; - - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - if (m_pImpl->isValid()) - return m_pImpl->writeAt (nOffset, pBuffer, nBytes, rnDone); - else - return store_E_InvalidHandle; -} - -/* - * flush. - */ -storeError OFileLockBytes::flush (void) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - if (m_pImpl->isValid()) - return m_pImpl->sync(); - else - return store_E_InvalidHandle; -} - -/* - * setSize. - */ -storeError OFileLockBytes::setSize (sal_uInt32 nSize) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - if (m_pImpl->isValid()) - return m_pImpl->resize (nSize); - else - return store_E_InvalidHandle; -} - -/* - * stat. - */ -storeError OFileLockBytes::stat (sal_uInt32 &rnSize) -{ - // Initialize [out] param. - rnSize = 0; - - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - if (m_pImpl->isValid()) - return m_pImpl->stat (rnSize); - else - return store_E_InvalidHandle; -} - -/* - * lockRange. - */ -storeError OFileLockBytes::lockRange ( - sal_uInt32 /* nOffset */, sal_uInt32 /* nBytes */) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - if (m_pImpl->isValid()) - return store_E_None; // E_Unsupported - else - return store_E_InvalidHandle; -} - -/* - * unlockRange. - */ -storeError OFileLockBytes::unlockRange ( - sal_uInt32 /* nOffset */, sal_uInt32 /* nBytes */) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - if (m_pImpl->isValid()) - return store_E_None; // E_Unsupported - else - return store_E_InvalidHandle; -} diff --git a/store/source/fileos2.hxx b/store/source/fileos2.hxx deleted file mode 100644 index 891cee459cd9..000000000000 --- a/store/source/fileos2.hxx +++ /dev/null @@ -1,255 +0,0 @@ -/************************************************************************* - * - * 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: fileos2.hxx,v $ - * $Revision: 1.6 $ - * - * 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 - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef INCLUDED_STORE_FILEOS2_HXX -#define INCLUDED_STORE_FILEOS2_HXX - -#define INCL_DOS -#define INCL_DOSERRORS -#include - -typedef HFILE HSTORE; - -/*======================================================================== - * - * File I/O (inline) implementation. - * - *======================================================================*/ -/* - * __store_errcode_map. - */ -static const __store_errcode_mapping_st __store_errcode_map[] = -{ - { NO_ERROR, store_E_None }, - { ERROR_FILE_NOT_FOUND, store_E_NotExists }, - { ERROR_PATH_NOT_FOUND, store_E_NotExists }, - { ERROR_ACCESS_DENIED, store_E_AccessViolation }, - { ERROR_SHARING_VIOLATION, store_E_AccessViolation }, - { ERROR_LOCK_VIOLATION, store_E_LockingViolation }, - { ERROR_INVALID_ACCESS, store_E_InvalidAccess }, - { ERROR_INVALID_HANDLE, store_E_InvalidHandle }, - { ERROR_INVALID_PARAMETER, store_E_InvalidParameter }, - { ERROR_FILENAME_EXCED_RANGE, store_E_NameTooLong }, - { ERROR_TOO_MANY_OPEN_FILES, store_E_NoMoreFiles } -}; - -/* - * __store_errno. - */ -inline sal_Int32 __store_errno (void) -{ - return (sal_Int32)errno; -} - -/* - * __store_malign (unsupported). - */ -inline sal_uInt32 __store_malign (void) -{ - return (sal_uInt32)(-1); -} - -/* - * __store_fmap (readonly, unsupported). - */ -inline HSTORE __store_fmap (HSTORE hFile) -{ - return ((HSTORE)0); -} - -/* - * __store_funmap. - */ -inline void __store_funmap (HSTORE hMap) -{ -} - -/* - * __store_mmap (readonly, unsupported). - */ -inline sal_uInt8* __store_mmap (HSTORE h, sal_uInt32 k, sal_uInt32 n) -{ - return (sal_uInt8*)NULL; -} - -/* - * __store_munmap (unsupported). - */ -inline void __store_munmap (sal_uInt8 *p, sal_uInt32 n) -{ -} - -/* - * __store_fopen. - */ -inline storeError __store_fopen ( - const sal_Char *pszName, sal_uInt32 nMode, HSTORE &rhFile) -{ - // Initialize [out] param. - rhFile = 0; - - // Access mode. - sal_uInt32 nAccessMode = OPEN_ACCESS_READONLY; - if (nMode & store_File_OpenWrite) - nAccessMode = OPEN_ACCESS_READWRITE; - - if (nAccessMode == OPEN_ACCESS_READONLY) - { - nMode |= store_File_OpenNoCreate; - nMode &= ~store_File_OpenTruncate; - } - - // Share mode. - sal_uInt32 nShareMode = OPEN_SHARE_DENYNONE; - if (nMode & store_File_OpenWrite) - nShareMode = OPEN_SHARE_DENYWRITE; - - // Open action. - sal_uInt32 nOpenAction = 0, nDoneAction = 0; - if (!(nMode & store_File_OpenNoCreate)) - nOpenAction = OPEN_ACTION_CREATE_IF_NEW; // Open always. - else - nOpenAction = OPEN_ACTION_FAIL_IF_NEW; // Open existing. - - if (nMode & store_File_OpenTruncate) - nOpenAction |= OPEN_ACTION_REPLACE_IF_EXISTS; - else - nOpenAction |= OPEN_ACTION_OPEN_IF_EXISTS; - - // Create file handle. - APIRET result = ::DosOpen ( - (PSZ)pszName, - &rhFile, - &nDoneAction, - 0L, - FILE_NORMAL, - nOpenAction, - nAccessMode | nShareMode | OPEN_FLAGS_NOINHERIT, - 0L); - - // Check result. - if (result) - return ERROR_FROM_NATIVE(result); - else - return store_E_None; -} - -/* - * __store_fread. - */ -inline storeError __store_fread ( - HSTORE h, sal_uInt32 offset, void *p, sal_uInt32 n, sal_uInt32 &k) -{ - APIRET result; - if ((result = ::DosSetFilePtr (h, (long)offset, FILE_BEGIN, &k)) != 0) - return ERROR_FROM_NATIVE(result); - if ((result = ::DosRead (h, p, n, &k)) != 0) - return ERROR_FROM_NATIVE(result); - else - return store_E_None; -} - -/* - * __store_fwrite. - */ -inline storeError __store_fwrite ( - HSTORE h, sal_uInt32 offset, const void *p, sal_uInt32 n, sal_uInt32 &k) -{ - APIRET result; - if ((result = ::DosSetFilePtr (h, (long)offset, FILE_BEGIN, &k)) != 0) - return ERROR_FROM_NATIVE(result); - if ((result = ::DosWrite (h, (PVOID)p, n, &k)) != 0) - return ERROR_FROM_NATIVE(result); - else - return store_E_None; -} - -/* - * __store_fseek. - */ -inline storeError __store_fseek (HSTORE h, sal_uInt32 n) -{ - sal_uInt32 k = 0; - APIRET result = ::DosSetFilePtr (h, (long)n, FILE_BEGIN, &k); - if (result) - return ERROR_FROM_NATIVE(result); - else - return store_E_None; -} - -/* - * __store_fsize. - */ -inline storeError __store_fsize (HSTORE h, sal_uInt32 &k) -{ - APIRET result = ::DosSetFilePtr (h, 0L, FILE_END, &k); - if (result) - return ERROR_FROM_NATIVE(result); - else - return store_E_None; -} - -/* - * __store_ftrunc. - */ -inline storeError __store_ftrunc (HSTORE h, sal_uInt32 n) -{ - APIRET result = ::DosSetFileSize (h, n); - if (result) - return ERROR_FROM_NATIVE(result); - else - return store_E_None; -} - -/* - * __store_fsync. - */ -inline storeError __store_fsync (HSTORE h) -{ - APIRET result = ::DosResetBuffer (h); - if (result) - return ERROR_FROM_NATIVE(result); - else - return store_E_None; -} - -/* - * __store_fclose. - */ -inline storeError __store_fclose (HSTORE h) -{ - APIRET result = ::DosClose (h); - if (result) - return ERROR_FROM_NATIVE(result); - else - return store_E_None; -} - -#endif /* INCLUDED_STORE_FILEOS2_HXX */ diff --git a/store/source/filestd.hxx b/store/source/filestd.hxx deleted file mode 100644 index 69e8f89ae48c..000000000000 --- a/store/source/filestd.hxx +++ /dev/null @@ -1,242 +0,0 @@ -/************************************************************************* - * - * 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: filestd.hxx,v $ - * $Revision: 1.5 $ - * - * 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 - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef INCLUDED_STORE_FILESTD_HXX -#define INCLUDED_STORE_FILESTD_HXX - -#ifndef INCLUDED_ERRNO_H -#include -#define INCLUDED_ERRNO_H -#endif - -#ifndef INCLUDED_STDIO_H -#include -#define INCLUDED_STDIO_H -#endif - -typedef FILE* HSTORE; - -/*======================================================================== - * - * File I/O (inline) implementation. - * - *======================================================================*/ -/* - * __store_errcode_map. - */ -static const __store_errcode_mapping_st __store_errcode_map[] = -{ - { 0, store_E_None }, - { ENOENT, store_E_NotExists }, - { EACCES, store_E_AccessViolation }, - { EPERM, store_E_AccessViolation }, - { EAGAIN, store_E_LockingViolation }, - { EDEADLOCK, store_E_LockingViolation }, - { EBADF, store_E_InvalidHandle }, - { EINVAL, store_E_InvalidParameter }, - { ENOSPC, store_E_OutOfSpace }, -}; - -/* - * __store_errno. - */ -inline sal_Int32 __store_errno (void) -{ - return (sal_Int32)errno; -} - -/* - * __store_malign (unsupported). - */ -inline sal_uInt32 __store_malign (void) -{ - return (sal_uInt32)(-1); -} - -/* - * __store_fmap (readonly, unsupported). - */ -inline HSTORE __store_fmap (HSTORE hFile) -{ - return ((HSTORE)0); -} - -/* - * __store_funmap. - */ -inline void __store_funmap (HSTORE hMap) -{ -} - -/* - * __store_mmap (readonly, unsupported). - */ -inline sal_uInt8* __store_mmap (HSTORE h, sal_uInt32 k, sal_uInt32 n) -{ - return (sal_uInt8*)NULL; -} - -/* - * __store_munmap (unsupported). - */ -inline void __store_munmap (sal_uInt8 *p, sal_uInt32 n) -{ -} - -/* - * __store_fopen. - */ -inline storeError __store_fopen ( - const sal_Char *pszName, sal_uInt32 nMode, HSTORE &rhFile) -{ - // Access mode. - if (!(nMode & store_File_OpenWrite)) - { - nMode |= store_File_OpenNoCreate; - nMode &= ~store_File_OpenTruncate; - } - - // Create file handle. - if (nMode & store_File_OpenTruncate) - { - // Create always, truncate existing. - rhFile = fopen (pszName, "wb+"); - } - else if (nMode & store_File_OpenWrite) - { - // Open existing (rw). - rhFile = fopen (pszName, "rb+"); - if (!(rhFile || (nMode & store_File_OpenNoCreate))) - { - // Try create (rw). - rhFile = fopen (pszName, "wb+"); - } - } - else - { - // Open existing (ro). - rhFile = fopen (pszName, "rb"); - } - - // Check result. - if (!rhFile) - return ERROR_FROM_NATIVE(errno); - else - return store_E_None; -} - -/* - * __store_fread. - */ -inline storeError __store_fread ( - HSTORE h, sal_uInt32 offset, void *p, sal_uInt32 n, sal_uInt32 &k) -{ - if (::fseek (h, (long)offset, SEEK_SET) < 0) - return ERROR_FROM_NATIVE(errno); - - k = (sal_uInt32)::fread (p, (size_t)1, (size_t)n, h); - if (k == (sal_uInt32)(-1)) - return ERROR_FROM_NATIVE(errno); - else - return store_E_None; -} - -/* - * __store_fwrite. - */ -inline storeError __store_fwrite ( - HSTORE h, sal_uInt32 offset, const void *p, sal_uInt32 n, sal_uInt32 &k) -{ - if (::fseek (h, (long)offset, SEEK_SET) < 0) - return ERROR_FROM_NATIVE(errno); - - k = (sal_uInt32)::fwrite (p, (size_t)1, (size_t)n, h); - if (k == (sal_uInt32)(-1)) - return ERROR_FROM_NATIVE(errno); - else - return store_E_None; -} - -/* - * __store_fseek. - */ -inline storeError __store_fseek (HSTORE h, sal_uInt32 n) -{ - if (::fseek (h, (long)n, SEEK_SET) < 0) - return ERROR_FROM_NATIVE(errno); - else - return store_E_None; -} - -/* - * __store_fsize. - */ -inline storeError __store_fsize (HSTORE h, sal_uInt32 &k) -{ - if (::fseek (h, 0, SEEK_END) < 0) - return ERROR_FROM_NATIVE(errno); - k = (sal_uInt32)::ftell (h); - if (k == (sal_uInt32)(-1)) - return ERROR_FROM_NATIVE(errno); - else - return store_E_None; -} - -/* - * __store_ftrunc (unsupported). - */ -inline storeError __store_ftrunc (HSTORE h, sal_uInt32 n) -{ - return store_E_None; -} - -/* - * __store_fsync. - */ -inline storeError __store_fsync (HSTORE h) -{ - if (::fflush (h) < 0) - return ERROR_FROM_NATIVE(errno); - else - return store_E_None; -} - -/* - * __store_fclose. - */ -inline storeError __store_fclose (HSTORE h) -{ - if (::fclose (h) < 0) - return ERROR_FROM_NATIVE(errno); - else - return store_E_None; -} - -#endif /* INCLUDED_STORE_FILESTD_HXX */ diff --git a/store/source/fileunx.hxx b/store/source/fileunx.hxx deleted file mode 100644 index 143f062f8482..000000000000 --- a/store/source/fileunx.hxx +++ /dev/null @@ -1,339 +0,0 @@ -/************************************************************************* - * - * 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: fileunx.hxx,v $ - * $Revision: 1.8 $ - * - * 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 - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef INCLUDED_STORE_FILEUNX_HXX -#define INCLUDED_STORE_FILEUNX_HXX - -#define _USE_UNIX98 /* _XOPEN_SOURCE=500 */ -#include - -#include -#include - -#include -#include -#include - -#if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX) -#define EDEADLOCK EDEADLK -#endif /* FREEBSD || NETBSD || MACOSX */ - -typedef int HSTORE; - -/*======================================================================== - * - * File I/O (inline) implementation. - * - *======================================================================*/ -/* - * __store_errcode_map. - */ -static const __store_errcode_mapping_st __store_errcode_map[] = -{ - { 0, store_E_None }, - { ENOENT, store_E_NotExists }, - { EACCES, store_E_AccessViolation }, - { EPERM, store_E_AccessViolation }, - { EAGAIN, store_E_LockingViolation }, -#if defined(EDEADLOCK) - { EDEADLOCK, store_E_LockingViolation }, -#endif /* EDEADLOCK */ - { EBADF, store_E_InvalidHandle }, - { EINVAL, store_E_InvalidParameter }, - { ENOSPC, store_E_OutOfSpace }, -}; - -/* - * __store_errno. - */ -inline sal_Int32 __store_errno (void) -{ - return (sal_Int32)errno; -} - -/* - * __store_malign. - */ -#if defined(FREEBSD) || defined(LINUX) || defined(MACOSX) -inline sal_uInt32 __store_malign (void) -{ - return (sal_uInt32)::getpagesize(); -} -#elif defined(IRIX) || defined(SOLARIS) -inline sal_uInt32 __store_malign (void) -{ - return (sal_uInt32)::sysconf (_SC_PAGESIZE); -} -#else -inline sal_uInt32 __store_malign (void) -{ - return (sal_uInt32)(-1); -} -#endif /* FREEBSD || IRIX || LINUX || SOLARIS || MACOSX*/ - -/* - * __store_fmap (readonly). - */ -inline HSTORE __store_fmap (HSTORE hFile) -{ - // Avoid hMap = dup (hFile); may result in EMFILE. - return hFile; -} - -/* - * __store_funmap. - */ -inline void __store_funmap (HSTORE) -{ - // Nothing to do, see '__store_fmap()'. -} - -/* - * __store_mmap (readonly, shared). - */ -inline sal_uInt8* __store_mmap (HSTORE h, sal_uInt32 k, sal_uInt32 n) -{ - void * p = ::mmap (NULL, (size_t)n, PROT_READ, MAP_SHARED, h, (off_t)k); - return ((p != MAP_FAILED) ? (sal_uInt8*)p : 0); -} - -/* - * __store_munmap. - */ -inline void __store_munmap (sal_uInt8 *p, sal_uInt32 n) -{ - (void)::munmap ((char *)p, (size_t)n); -} - -/* - * __store_fopen. - */ -inline storeError __store_fopen ( - const sal_Char *pszName, sal_uInt32 nMode, HSTORE &rhFile) -{ - // Access mode. - int nAccessMode = O_RDONLY; - - if (nMode & store_File_OpenWrite) - nAccessMode = O_RDWR; - - if (nAccessMode == O_RDONLY) - nMode |= store_File_OpenNoCreate; - - if ((!(nMode & store_File_OpenNoCreate)) && (!(nAccessMode == O_RDONLY))) - nAccessMode |= O_CREAT; - - if (nMode & store_File_OpenTruncate) - nAccessMode |= O_TRUNC; - - // Share mode. - int nShareMode = S_IREAD | S_IROTH | S_IRGRP; - - if (nMode & store_File_OpenWrite) - nShareMode |= (S_IWRITE | S_IWOTH | S_IWGRP); - - // Create file handle. - if ((rhFile = ::open (pszName, nAccessMode, nShareMode)) < 0) - { - rhFile = 0; - return ERROR_FROM_NATIVE(errno); - } - - // Acquire (advisory) Lock (Multiple Reader | Single Writer) - struct flock lock; - - if (nMode & store_File_OpenWrite) - lock.l_type = F_WRLCK; - else - lock.l_type = F_RDLCK; - - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 0; - - if (::fcntl (rhFile, F_SETLK, &lock) < 0) - { - // Save original result. - storeError result; - if ((errno == EACCES) || (errno == EAGAIN)) - result = store_E_LockingViolation; - else - result = ERROR_FROM_NATIVE(errno); - - // Close file handle. - (void)::close (rhFile); rhFile = 0; - - // Finish. - return (result); - } - - int nFlags = ::fcntl (rhFile, F_GETFD, 0); - if (!(nFlags < 0)) - { - // Set close-on-exec flag. - nFlags |= FD_CLOEXEC; - (void)::fcntl (rhFile, F_SETFD, nFlags); - } - return store_E_None; -} - -/* - * __store_fread. - */ -inline storeError __store_fread ( - HSTORE h, sal_uInt32 offset, void *p, sal_uInt32 n, sal_uInt32 &k) -{ -#if defined(LINUX) || defined(SOLARIS) - - k = (sal_uInt32)::pread (h, (char*)p, (size_t)n, (off_t)offset); - if ((k == (sal_uInt32)(-1)) && (errno == EOVERFLOW)) - { - /* - * Workaround for 'pread()' failure at end-of-file: - * - * Some 'pread()'s fail with EOVERFLOW when reading at (or past) - * end-of-file, different from 'lseek() + read()' behaviour. - * Returning '0 bytes read' and 'store_E_None' instead. - */ - k = 0; - } - -#else /* LINUX || SOLARIS */ - - if (::lseek (h, (off_t)offset, SEEK_SET) < 0) - return ERROR_FROM_NATIVE(errno); - - k = (sal_uInt32)::read (h, (char *)p, (size_t)n); - -#endif /* LINUX || SOLARIS */ - - if (k == (sal_uInt32)(-1)) - return ERROR_FROM_NATIVE(errno); - else - return store_E_None; -} - -/* - * __store_fwrite. - */ -inline storeError __store_fwrite ( - HSTORE h, sal_uInt32 offset, const void *p, sal_uInt32 n, sal_uInt32 &k) -{ -#if defined(LINUX) || defined(SOLARIS) - - k = (sal_uInt32)::pwrite (h, (char*)p, (size_t)n, (off_t)offset); - -#else /* LINUX || SOLARIS */ - - if (::lseek (h, (off_t)offset, SEEK_SET) < 0) - return ERROR_FROM_NATIVE(errno); - - k = (sal_uInt32)::write (h, (char *)p, (size_t)n); - -#endif /* LINUX || SOLARIS */ - - if (k == (sal_uInt32)(-1)) - return ERROR_FROM_NATIVE(errno); - else - return store_E_None; -} - -/* - * __store_fsize. - */ -inline storeError __store_fsize (HSTORE h, sal_uInt32 &k) -{ - k = (sal_uInt32)::lseek (h, (off_t)0, SEEK_END); - if (k == (sal_uInt32)(-1)) - return ERROR_FROM_NATIVE(errno); - else - return store_E_None; -} - -/* - * __store_ftrunc. - */ -inline storeError __store_ftrunc (HSTORE h, sal_uInt32 n) -{ - if (::ftruncate (h, (off_t)n) < 0) - { - // Save original result. - storeError result = ERROR_FROM_NATIVE(errno); - - // Check against current size. Fail upon 'shrink'. - sal_uInt32 k = (sal_uInt32)::lseek (h, (off_t)0, SEEK_END); - if (k == (sal_uInt32)(-1)) - return (result); - if (n <= k) - return (result); - - // Try 'expand' via 'lseek()' and 'write()'. - if (::lseek (h, (off_t)(n - 1), SEEK_SET) < 0) - return (result); - if (::write (h, (char*)"", (size_t)1) < 0) - return (result); - } - return store_E_None; -} - -/* - * __store_fsync. - */ -inline storeError __store_fsync (HSTORE h) -{ - if (::fsync (h) == -1) - return ERROR_FROM_NATIVE(errno); - else - return store_E_None; -} - -/* - * __store_fclose. - */ -inline storeError __store_fclose (HSTORE h) -{ - // Release (advisory) Lock (Multiple Reader | Single Writer) - struct flock lock; - - lock.l_type = F_UNLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 0; - - (void)::fcntl (h, F_SETLK, &lock); - - // Close file handle. - if (::close (h) == -1) - return ERROR_FROM_NATIVE(errno); - else - return store_E_None; -} - -#endif /* INCLUDED_STORE_FILEUNX_HXX */ diff --git a/store/source/filew32.hxx b/store/source/filew32.hxx deleted file mode 100644 index d7ccbe2c1cf4..000000000000 --- a/store/source/filew32.hxx +++ /dev/null @@ -1,274 +0,0 @@ -/************************************************************************* - * - * 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: filew32.hxx,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 - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef INCLUDED_STORE_FILEW32_HXX -#define INCLUDED_STORE_FILEW32_HXX - -#ifdef _MSC_VER -#pragma warning(push,1) // disable warnings within system headers -#endif -#define WIN32_LEAN_AND_MEAN -#include -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -typedef HANDLE HSTORE; - -/*======================================================================== - * - * File I/O (inline) implementation. - * - *======================================================================*/ -/* - * __store_errcode_map. - */ -static const __store_errcode_mapping_st __store_errcode_map[] = -{ - { ERROR_SUCCESS, store_E_None }, - { ERROR_FILE_NOT_FOUND, store_E_NotExists }, - { ERROR_ACCESS_DENIED, store_E_AccessViolation }, - { ERROR_LOCK_FAILED, store_E_LockingViolation }, - { ERROR_LOCK_VIOLATION, store_E_LockingViolation }, - { ERROR_INVALID_HANDLE, store_E_InvalidHandle }, - { ERROR_INVALID_PARAMETER, store_E_InvalidParameter }, - { ERROR_DISK_FULL, store_E_OutOfSpace }, - { ERROR_HANDLE_DISK_FULL, store_E_OutOfSpace }, -}; - -/* - * __store_errno. - */ -inline sal_uInt32 __store_errno (void) -{ - return (sal_uInt32)::GetLastError(); -} - -/* - * __store_malign. - */ -inline sal_uInt32 __store_malign (void) -{ - // Check Win32 platform. - OSVERSIONINFO osinfo; - - osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - ::GetVersionEx (&osinfo); - - if (osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - // Determine memory allocation granularity. - SYSTEM_INFO info; - - ::GetSystemInfo (&info); - return ((sal_uInt32)(info.dwAllocationGranularity)); - } - return (sal_uInt32)(-1); -} - -/* - * __store_fmap (readonly). - */ -inline HSTORE __store_fmap (HSTORE hFile) -{ - return ::CreateFileMapping ( - hFile, NULL, SEC_COMMIT | PAGE_READONLY, 0, 0, NULL); -} - -/* - * __store_funmap. - */ -inline void __store_funmap (HSTORE hMap) -{ - ::CloseHandle (hMap); -} - -/* - * __store_mmap (readonly). - */ -inline sal_uInt8* __store_mmap (HSTORE h, sal_uInt32 k, sal_uInt32 n) -{ - return (sal_uInt8*)::MapViewOfFile (h, FILE_MAP_READ, 0, k, n); -} - -/* - * __store_munmap. - */ -inline void __store_munmap (sal_uInt8 *p, sal_uInt32) -{ - ::UnmapViewOfFile (p); -} - -/* - * __store_fopen. - */ -inline storeError __store_fopen ( - const sal_Char *pszName, sal_uInt32 nMode, HSTORE &rhFile) -{ - // Access mode. - DWORD nAccessMode = GENERIC_READ; - - if (nMode & store_File_OpenWrite) - nAccessMode |= GENERIC_WRITE; - - if (nAccessMode == GENERIC_READ) - nMode |= store_File_OpenNoCreate; - - // Share mode. - DWORD nShareMode = FILE_SHARE_READ; - if (!(nMode & store_File_OpenWrite)) - nShareMode |= FILE_SHARE_WRITE; - - // Open action. - DWORD nOpenAction = 0; - if (!(nMode & store_File_OpenNoCreate)) - { - // Open always. - if (nMode & store_File_OpenTruncate) - nOpenAction = CREATE_ALWAYS; - else - nOpenAction = OPEN_ALWAYS; - } - else - { - // Open existing. - if (nMode & store_File_OpenTruncate) - nOpenAction = TRUNCATE_EXISTING; - else - nOpenAction = OPEN_EXISTING; - } - - // Create file handle. - rhFile = ::CreateFile ( - pszName, - nAccessMode, - nShareMode, - (LPSECURITY_ATTRIBUTES)NULL, - nOpenAction, - (FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS), - (HANDLE)NULL); - - // Check result and finish. - if (rhFile == INVALID_HANDLE_VALUE) - { - rhFile = 0; - return ERROR_FROM_NATIVE(::GetLastError()); - } - return store_E_None; -} - -/* - * __store_fread. - */ -inline storeError __store_fread ( - HSTORE h, sal_uInt32 offset, void *p, sal_uInt32 n, sal_uInt32 &k) -{ - if (::SetFilePointer (h, offset, NULL, FILE_BEGIN) == (DWORD)(-1)) - return ERROR_FROM_NATIVE(::GetLastError()); - if (!::ReadFile (h, p, n, &k, NULL)) - return ERROR_FROM_NATIVE(::GetLastError()); - else - return store_E_None; -} - -/* - * __store_fwrite. - */ -inline storeError __store_fwrite ( - HSTORE h, sal_uInt32 offset, const void *p, sal_uInt32 n, sal_uInt32 &k) -{ - if (::SetFilePointer (h, offset, NULL, FILE_BEGIN) == (DWORD)(-1)) - return ERROR_FROM_NATIVE(::GetLastError()); - if (!::WriteFile (h, p, n, &k, NULL)) - return ERROR_FROM_NATIVE(::GetLastError()); - else - return store_E_None; -} - -/* - * __store_fseek. - */ -inline storeError __store_fseek (HSTORE h, sal_uInt32 n) -{ - DWORD k = ::SetFilePointer (h, n, NULL, FILE_BEGIN); - if (k == (DWORD)(-1)) - return ERROR_FROM_NATIVE(::GetLastError()); - else - return store_E_None; -} - -/* - * __store_fsize. - */ -inline storeError __store_fsize (HSTORE h, sal_uInt32 &k) -{ - k = (sal_uInt32)::GetFileSize (h, NULL); - if (k == (sal_uInt32)(-1)) - return ERROR_FROM_NATIVE(::GetLastError()); - else - return store_E_None; -} - -/* - * __store_ftrunc. - */ -inline storeError __store_ftrunc (HSTORE h, sal_uInt32 n) -{ - if (::SetFilePointer (h, n, NULL, FILE_BEGIN) == (DWORD)(-1)) - return ERROR_FROM_NATIVE(::GetLastError()); - if (!::SetEndOfFile (h)) - return ERROR_FROM_NATIVE(::GetLastError()); - else - return store_E_None; -} - -/* - * __store_fsync. - */ -inline storeError __store_fsync (HSTORE h) -{ - if (!::FlushFileBuffers (h)) - return ERROR_FROM_NATIVE(::GetLastError()); - else - return store_E_None; -} - -/* - * __store_fclose. - */ -inline storeError __store_fclose (HSTORE h) -{ - if (!::CloseHandle (h)) - return ERROR_FROM_NATIVE(::GetLastError()); - else - return store_E_None; -} - -#endif /* INCLUDED_STORE_FILEW32_HXX */ diff --git a/store/source/lockbyte.cxx b/store/source/lockbyte.cxx new file mode 100644 index 000000000000..ef97f129538d --- /dev/null +++ b/store/source/lockbyte.cxx @@ -0,0 +1,979 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: lockbyte.cxx,v $ + * + * $Revision: 1.1.2.4 $ + * + * last change: $Author: mhu $ $Date: 2008/11/25 15:44:56 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_store.hxx" + +#include "lockbyte.hxx" + +#include "sal/types.h" +#include "osl/diagnose.h" +#include "osl/file.h" +#include "rtl/alloc.h" +#include "rtl/ustring.hxx" + +#include "object.hxx" +#include "storbase.hxx" + +#ifndef INCLUDED_STRING_H +#include +#define INCLUDED_STRING_H +#endif + +using namespace store; + +/*======================================================================== + * + * ILockBytes (non-virtual interface) implementation. + * + *======================================================================*/ + +storeError ILockBytes::initialize (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize) +{ + OSL_PRECOND((STORE_MINIMUM_PAGESIZE <= nPageSize) && (nPageSize <= STORE_MAXIMUM_PAGESIZE), "invalid PageSize"); + return initialize_Impl (rxAllocator, nPageSize); +} + +storeError ILockBytes::readPageAt (PageHolder & rPage, sal_uInt32 nOffset) +{ + OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::ILockBytes::readPageAt(): invalid Offset"); + if (nOffset == STORE_PAGE_NULL) + return store_E_CantSeek; + + return readPageAt_Impl (rPage, nOffset); +} + +storeError ILockBytes::writePageAt (PageHolder const & rPage, sal_uInt32 nOffset) +{ + // [SECURITY:ValInput] + PageData const * pagedata = rPage.get(); + OSL_PRECOND(!(pagedata == 0), "store::ILockBytes::writePageAt(): invalid Page"); + if (pagedata == 0) + return store_E_InvalidParameter; + + sal_uInt32 const offset = pagedata->location(); + OSL_PRECOND(!(nOffset != offset), "store::ILockBytes::writePageAt(): inconsistent Offset"); + if (nOffset != offset) + return store_E_InvalidParameter; + + OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::ILockBytes::writePageAt(): invalid Offset"); + if (nOffset == STORE_PAGE_NULL) + return store_E_CantSeek; + + return writePageAt_Impl (rPage, nOffset); +} + +storeError ILockBytes::readAt (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes) +{ + // [SECURITY:ValInput] + sal_uInt8 * dst_lo = static_cast(pBuffer); + if (!(dst_lo != 0)) + return store_E_InvalidParameter; + + sal_uInt8 * dst_hi = dst_lo + nBytes; + if (!(dst_lo < dst_hi)) + return (dst_lo > dst_hi) ? store_E_InvalidParameter : store_E_None; + + OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::ILockBytes::readAt(): invalid Offset"); + if (nOffset == STORE_PAGE_NULL) + return store_E_CantSeek; + + sal_uInt64 const src_size = nOffset + nBytes; + if (src_size > SAL_MAX_UINT32) + return store_E_CantSeek; + + return readAt_Impl (nOffset, dst_lo, (dst_hi - dst_lo)); +} + +storeError ILockBytes::writeAt (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes) +{ + // [SECURITY:ValInput] + sal_uInt8 const * src_lo = static_cast(pBuffer); + if (!(src_lo != 0)) + return store_E_InvalidParameter; + + sal_uInt8 const * src_hi = src_lo + nBytes; + if (!(src_lo < src_hi)) + return (src_lo > src_hi) ? store_E_InvalidParameter : store_E_None; + + OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::ILockBytes::writeAt(): invalid Offset"); + if (nOffset == STORE_PAGE_NULL) + return store_E_CantSeek; + + sal_uInt64 const dst_size = nOffset + nBytes; + if (dst_size > SAL_MAX_UINT32) + return store_E_CantSeek; + + return writeAt_Impl (nOffset, src_lo, (src_hi - src_lo)); +} + +storeError ILockBytes::getSize (sal_uInt32 & rnSize) +{ + rnSize = 0; + return getSize_Impl (rnSize); +} + +storeError ILockBytes::setSize (sal_uInt32 nSize) +{ + return setSize_Impl (nSize); +} + +storeError ILockBytes::flush() +{ + return flush_Impl(); +} + +storeError ILockBytes::lockRange (sal_uInt32 nOffset, sal_uInt32 nBytes) +{ + OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::ILockBytes::lockRange(): invalid Offset"); + if (nOffset == STORE_PAGE_NULL) + return store_E_CantSeek; + + sal_uInt64 size = nOffset + nBytes; + if (size > SAL_MAX_UINT32) + return store_E_CantSeek; + +#ifdef STORE_FEATURE_LOCKING + return lockRange_Impl (nOffset, nBytes); +#else + return store_E_None; // E_Unsupported +#endif /* STORE_FEATURE_LOCKING */ +} + +storeError ILockBytes::unlockRange (sal_uInt32 nOffset, sal_uInt32 nBytes) +{ + OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::ILockBytes::unlockRange(): invalid Offset"); + if (nOffset == STORE_PAGE_NULL) + return store_E_CantSeek; + + sal_uInt64 size = nOffset + nBytes; + if (size > SAL_MAX_UINT32) + return store_E_CantSeek; + +#ifdef STORE_FEATURE_LOCKING + return unlockRange_Impl (nOffset, nBytes); +#else + return store_E_None; // E_Unsupported +#endif /* STORE_FEATURE_LOCKING */ +} + +/*======================================================================== + * + * FileLockBytes implementation. + * + *======================================================================*/ +namespace store +{ + +struct FileHandle +{ + oslFileHandle m_handle; + + FileHandle() : m_handle(0) {} + + bool operator != (FileHandle const & rhs) + { + return (m_handle != rhs.m_handle); + } + + static storeError errorFromNative (oslFileError eErrno) + { + switch (eErrno) + { + case osl_File_E_None: + return store_E_None; + + case osl_File_E_NOENT: + return store_E_NotExists; + + case osl_File_E_ACCES: + case osl_File_E_PERM: + return store_E_AccessViolation; + + case osl_File_E_AGAIN: + case osl_File_E_DEADLK: + return store_E_LockingViolation; + + case osl_File_E_BADF: + return store_E_InvalidHandle; + + case osl_File_E_INVAL: + return store_E_InvalidParameter; + + case osl_File_E_NOMEM: + return store_E_OutOfMemory; + + case osl_File_E_NOSPC: + return store_E_OutOfSpace; + + case osl_File_E_OVERFLOW: + return store_E_CantSeek; + + default: + return store_E_Unknown; + } + } + + static sal_uInt32 modeToNative (storeAccessMode eAccessMode) + { + sal_uInt32 nFlags = 0; + switch (eAccessMode) + { + case store_AccessCreate: + case store_AccessReadCreate: + nFlags |= osl_File_OpenFlag_Create; + // fall through + case store_AccessReadWrite: + nFlags |= osl_File_OpenFlag_Write; + // fall through + case store_AccessReadOnly: + nFlags |= osl_File_OpenFlag_Read; + break; + default: + OSL_PRECOND(0, "store::FileHandle: unknown storeAccessMode"); + } + return nFlags; + } + + storeError initialize (rtl_uString * pFilename, storeAccessMode eAccessMode) + { + // Verify arguments. + sal_uInt32 nFlags = modeToNative (eAccessMode); + if (!pFilename || !nFlags) + return store_E_InvalidParameter; + + // Convert into FileUrl. + rtl::OUString aFileUrl; + if (osl_getFileURLFromSystemPath (pFilename, &(aFileUrl.pData)) != osl_File_E_None) + { + // Not system path. Maybe a file url, already. + rtl_uString_assign (&(aFileUrl.pData), pFilename); + } + + // Acquire handle. + oslFileError result = osl_openFile (aFileUrl.pData, &m_handle, nFlags); + if (result == osl_File_E_EXIST) + { + // Already existing (O_CREAT | O_EXCL). + result = osl_openFile (aFileUrl.pData, &m_handle, osl_File_OpenFlag_Write); + if ((result == osl_File_E_None) && (eAccessMode == store_AccessCreate)) + { + // Truncate existing file. + result = osl_setFileSize (m_handle, 0); + } + } + if (result != osl_File_E_None) + return errorFromNative(result); + return store_E_None; + } + + /** @see FileLockBytes destructor + */ + static void closeFile (oslFileHandle hFile) + { + (void) osl_closeFile (hFile); + } + + /** @see ResourceHolder::destructor_type + */ + struct CloseFile + { + void operator()(FileHandle & rFile) const + { + // Release handle. + closeFile (rFile.m_handle); + rFile.m_handle = 0; + } + }; + typedef CloseFile destructor_type; +}; + +class FileLockBytes : + public store::OStoreObject, + public store::ILockBytes +{ + /** Representation. + */ + oslFileHandle m_hFile; + sal_uInt32 m_nSize; + rtl::Reference< PageData::Allocator > m_xAllocator; + + storeError initSize_Impl (sal_uInt32 & rnSize); + + /** ILockBytes implementation. + */ + virtual storeError initialize_Impl (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize); + + virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset); + virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset); + + virtual storeError readAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes); + virtual storeError writeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes); + + virtual storeError getSize_Impl (sal_uInt32 & rnSize); + virtual storeError setSize_Impl (sal_uInt32 nSize); + + virtual storeError flush_Impl(); + + /** Not implemented. + */ + FileLockBytes (FileLockBytes const &); + FileLockBytes & operator= (FileLockBytes const &); + +public: + /** Construction. + */ + explicit FileLockBytes (FileHandle & rFile); + + /** Delegate multiple inherited IReference. + */ + virtual oslInterlockedCount SAL_CALL acquire(); + virtual oslInterlockedCount SAL_CALL release(); + +protected: + /** Destruction. + */ + virtual ~FileLockBytes(); +}; + +} // namespace store + +FileLockBytes::FileLockBytes (FileHandle & rFile) + : m_hFile (rFile.m_handle), m_nSize (SAL_MAX_UINT32), m_xAllocator() +{ +} + +FileLockBytes::~FileLockBytes() +{ + FileHandle::closeFile (m_hFile); +} + +oslInterlockedCount SAL_CALL FileLockBytes::acquire() +{ + return OStoreObject::acquire(); +} + +oslInterlockedCount SAL_CALL FileLockBytes::release() +{ + return OStoreObject::release(); +} + +storeError FileLockBytes::initSize_Impl (sal_uInt32 & rnSize) +{ + /* osl_getFileSize() uses slow 'fstat(h, &size)', + * instead of fast 'size = lseek(h, 0, SEEK_END)'. + * so, init size here, and track changes. + */ + sal_uInt64 uSize = 0; + oslFileError result = osl_getFileSize (m_hFile, &uSize); + if (result != osl_File_E_None) + return FileHandle::errorFromNative(result); + if (uSize > SAL_MAX_UINT32) + return store_E_CantSeek; + + rnSize = sal::static_int_cast(uSize); + return store_E_None; +} + +storeError FileLockBytes::initialize_Impl (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize) +{ + storeError result = initSize_Impl (m_nSize); + if (result != store_E_None) + return (result); + + result = PageData::Allocator::createInstance (rxAllocator, nPageSize); + if (result != store_E_None) + return (result); + + // @see readPageAt_Impl(). + m_xAllocator = rxAllocator; + return store_E_None; +} + +storeError FileLockBytes::readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset) +{ + if (m_xAllocator.is()) + { + PageHolder page (m_xAllocator->construct(), m_xAllocator); + page.swap (rPage); + } + + if (!m_xAllocator.is()) + return store_E_InvalidAccess; + if (!rPage.get()) + return store_E_OutOfMemory; + + PageData * pagedata = rPage.get(); + return readAt_Impl (nOffset, pagedata, pagedata->size()); +} + +storeError FileLockBytes::writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset) +{ + PageData const * pagedata = rPage.get(); + OSL_PRECOND(pagedata != 0, "contract violation"); + return writeAt_Impl (nOffset, pagedata, pagedata->size()); +} + +storeError FileLockBytes::readAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes) +{ + sal_uInt64 nDone = 0; + oslFileError result = osl_readFileAt (m_hFile, nOffset, pBuffer, nBytes, &nDone); + if (result != osl_File_E_None) + return FileHandle::errorFromNative(result); + if (nDone != nBytes) + return (nDone != 0) ? store_E_CantRead : store_E_NotExists; + return store_E_None; +} + +storeError FileLockBytes::writeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes) +{ + sal_uInt64 nDone = 0; + oslFileError result = osl_writeFileAt (m_hFile, nOffset, pBuffer, nBytes, &nDone); + if (result != osl_File_E_None) + return FileHandle::errorFromNative(result); + if (nDone != nBytes) + return store_E_CantWrite; + + sal_uInt64 const uSize = nOffset + nBytes; + OSL_PRECOND(uSize < SAL_MAX_UINT32, "store::ILockBytes::writeAt() contract violation"); + if (uSize > m_nSize) + m_nSize = sal::static_int_cast(uSize); + return store_E_None; +} + +storeError FileLockBytes::getSize_Impl (sal_uInt32 & rnSize) +{ + rnSize = m_nSize; + return store_E_None; +} + +storeError FileLockBytes::setSize_Impl (sal_uInt32 nSize) +{ + oslFileError result = osl_setFileSize (m_hFile, nSize); + if (result != osl_File_E_None) + return FileHandle::errorFromNative(result); + + m_nSize = nSize; + return store_E_None; +} + +storeError FileLockBytes::flush_Impl() +{ + oslFileError result = osl_syncFile (m_hFile); + if (result != osl_File_E_None) + return FileHandle::errorFromNative(result); + return store_E_None; +} + +/*======================================================================== + * + * MappedLockBytes implementation. + * + *======================================================================*/ +namespace store +{ + +struct FileMapping +{ + sal_uInt8 * m_pAddr; + sal_uInt32 m_nSize; + + FileMapping() : m_pAddr(0), m_nSize(0) {} + + bool operator != (FileMapping const & rhs) const + { + return ((m_pAddr != rhs.m_pAddr) || (m_nSize != rhs.m_nSize)); + } + + oslFileError initialize (oslFileHandle hFile) + { + // Determine mapping size. + sal_uInt64 uSize = 0; + oslFileError result = osl_getFileSize (hFile, &uSize); + if (result != osl_File_E_None) + return result; + + // [SECURITY:IntOver] + if (uSize > SAL_MAX_UINT32) + return osl_File_E_OVERFLOW; + m_nSize = sal::static_int_cast(uSize); + + // Acquire mapping. + return osl_mapFile (hFile, reinterpret_cast(&m_pAddr), m_nSize, 0, osl_File_MapFlag_RandomAccess); + } + + /** @see MappedLockBytes::destructor. + */ + static void unmapFile (sal_uInt8 * pAddr, sal_uInt32 nSize) + { + (void) osl_unmapFile (pAddr, nSize); + } + + /** @see ResourceHolder::destructor_type + */ + struct UnmapFile + { + void operator ()(FileMapping & rMapping) const + { + // Release mapping. + unmapFile (rMapping.m_pAddr, rMapping.m_nSize); + rMapping.m_pAddr = 0, rMapping.m_nSize = 0; + } + }; + typedef UnmapFile destructor_type; +}; + +class MappedLockBytes : + public store::OStoreObject, + public store::PageData::Allocator, + public store::ILockBytes +{ + /** Representation. + */ + sal_uInt8 * m_pData; + sal_uInt32 m_nSize; + sal_uInt16 m_nPageSize; + + /** PageData::Allocator implementation. + */ + virtual void allocate_Impl (void ** ppPage, sal_uInt16 * pnSize); + virtual void deallocate_Impl (void * pPage); + + /** ILockBytes implementation. + */ + virtual storeError initialize_Impl (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize); + + virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset); + virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset); + + virtual storeError readAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes); + virtual storeError writeAt_Impl (sal_uInt32 nOffset, const void * pBuffer, sal_uInt32 nBytes); + + virtual storeError getSize_Impl (sal_uInt32 & rnSize); + virtual storeError setSize_Impl (sal_uInt32 nSize); + + virtual storeError flush_Impl(); + + /** Not implemented. + */ + MappedLockBytes (MappedLockBytes const &); + MappedLockBytes & operator= (MappedLockBytes const &); + +public: + /** Construction. + */ + explicit MappedLockBytes (FileMapping & rMapping); + + /** Delegate multiple inherited IReference. + */ + virtual oslInterlockedCount SAL_CALL acquire(); + virtual oslInterlockedCount SAL_CALL release(); + +protected: + /* Destruction. + */ + virtual ~MappedLockBytes(); +}; + +} // namespace store + +MappedLockBytes::MappedLockBytes (FileMapping & rMapping) + : m_pData (rMapping.m_pAddr), m_nSize (rMapping.m_nSize), m_nPageSize(0) +{ +} + +MappedLockBytes::~MappedLockBytes() +{ + FileMapping::unmapFile (m_pData, m_nSize); +} + +oslInterlockedCount SAL_CALL MappedLockBytes::acquire() +{ + return OStoreObject::acquire(); +} + +oslInterlockedCount SAL_CALL MappedLockBytes::release() +{ + return OStoreObject::release(); +} + +void MappedLockBytes::allocate_Impl (void ** ppPage, sal_uInt16 * pnSize) +{ + OSL_PRECOND((ppPage != 0) && (pnSize != 0), "contract violation"); + *ppPage = 0, *pnSize = m_nPageSize; +} + +void MappedLockBytes::deallocate_Impl (void * pPage) +{ + OSL_PRECOND((m_pData <= pPage) && (pPage < m_pData + m_nSize), "contract violation"); + (void)pPage; // UNUSED +} + +storeError MappedLockBytes::initialize_Impl (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize) +{ + rxAllocator = this; + m_nPageSize = nPageSize; + return store_E_None; +} + +storeError MappedLockBytes::readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset) +{ + sal_uInt8 * src_lo = m_pData + nOffset; + if ((m_pData > src_lo) || (src_lo >= m_pData + m_nSize)) + return store_E_NotExists; + + sal_uInt8 * src_hi = src_lo + m_nPageSize; + if ((m_pData > src_hi) || (src_hi > m_pData + m_nSize)) + return store_E_CantRead; + + PageHolder page (reinterpret_cast< PageData* >(src_lo), static_cast< PageData::Allocator* >(this)); + page.swap (rPage); + + return store_E_None; +} + +storeError MappedLockBytes::writePageAt_Impl (PageHolder const & /*rPage*/, sal_uInt32 /*nOffset*/) +{ + return store_E_AccessViolation; +} + +storeError MappedLockBytes::readAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes) +{ + sal_uInt8 const * src_lo = m_pData + nOffset; + if ((m_pData > src_lo) || (src_lo >= m_pData + m_nSize)) + return store_E_NotExists; + + sal_uInt8 const * src_hi = src_lo + nBytes; + if ((m_pData > src_hi) || (src_hi > m_pData + m_nSize)) + return store_E_CantRead; + + memcpy (pBuffer, src_lo, (src_hi - src_lo)); + return store_E_None; +} + +storeError MappedLockBytes::writeAt_Impl (sal_uInt32 /*nOffset*/, void const * /*pBuffer*/, sal_uInt32 /*nBytes*/) +{ + return store_E_AccessViolation; +} + +storeError MappedLockBytes::getSize_Impl (sal_uInt32 & rnSize) +{ + rnSize = m_nSize; + return store_E_None; +} + +storeError MappedLockBytes::setSize_Impl (sal_uInt32 /*nSize*/) +{ + return store_E_AccessViolation; +} + +storeError MappedLockBytes::flush_Impl() +{ + return store_E_None; +} + +/*======================================================================== + * + * MemoryLockBytes implementation. + * + *======================================================================*/ +namespace store +{ + +class MemoryLockBytes : + public store::OStoreObject, + public store::ILockBytes +{ + /** Representation. + */ + sal_uInt8 * m_pData; + sal_uInt32 m_nSize; + rtl::Reference< PageData::Allocator > m_xAllocator; + + /** ILockBytes implementation. + */ + virtual storeError initialize_Impl (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize); + + virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset); + virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset); + + virtual storeError readAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes); + virtual storeError writeAt_Impl (sal_uInt32 nOffset, const void * pBuffer, sal_uInt32 nBytes); + + virtual storeError getSize_Impl (sal_uInt32 & rnSize); + virtual storeError setSize_Impl (sal_uInt32 nSize); + + virtual storeError flush_Impl(); + + /** Not implemented. + */ + MemoryLockBytes (MemoryLockBytes const &); + MemoryLockBytes& operator= (MemoryLockBytes const &); + +public: + /** Construction. + */ + MemoryLockBytes(); + + /** Delegate multiple inherited IReference. + */ + virtual oslInterlockedCount SAL_CALL acquire(); + virtual oslInterlockedCount SAL_CALL release(); + +protected: + /** Destruction. + */ + virtual ~MemoryLockBytes(); +}; + +} // namespace store + +MemoryLockBytes::MemoryLockBytes() + : m_pData (0), m_nSize (0), m_xAllocator() +{} + +MemoryLockBytes::~MemoryLockBytes() +{ + rtl_freeMemory (m_pData); +} + +oslInterlockedCount SAL_CALL MemoryLockBytes::acquire (void) +{ + return OStoreObject::acquire(); +} + +oslInterlockedCount SAL_CALL MemoryLockBytes::release (void) +{ + return OStoreObject::release(); +} + +storeError MemoryLockBytes::initialize_Impl (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize) +{ + storeError result = PageData::Allocator::createInstance (rxAllocator, nPageSize); + if (result == store_E_None) + { + // @see readPageAt_Impl(). + m_xAllocator = rxAllocator; + } + return result; +} + +storeError MemoryLockBytes::readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset) +{ + if (m_xAllocator.is()) + { + PageHolder page (m_xAllocator->construct(), m_xAllocator); + page.swap (rPage); + } + + if (!m_xAllocator.is()) + return store_E_InvalidAccess; + if (!rPage.get()) + return store_E_OutOfMemory; + + PageData * pagedata = rPage.get(); + return readAt_Impl (nOffset, pagedata, pagedata->size()); +} + +storeError MemoryLockBytes::writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset) +{ + PageData const * pagedata = rPage.get(); + OSL_PRECOND(!(pagedata == 0), "contract violation"); + return writeAt_Impl (nOffset, pagedata, pagedata->size()); +} + +storeError MemoryLockBytes::readAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes) +{ + sal_uInt8 const * src_lo = m_pData + nOffset; + if ((m_pData > src_lo) || (src_lo >= m_pData + m_nSize)) + return store_E_NotExists; + + sal_uInt8 const * src_hi = src_lo + nBytes; + if ((m_pData > src_hi) || (src_hi > m_pData + m_nSize)) + return store_E_CantRead; + + memcpy (pBuffer, src_lo, (src_hi - src_lo)); + return store_E_None; +} + +storeError MemoryLockBytes::writeAt_Impl (sal_uInt32 nOffset, const void * pBuffer, sal_uInt32 nBytes) +{ + sal_uInt64 const dst_size = nOffset + nBytes; + OSL_PRECOND(dst_size < SAL_MAX_UINT32, "store::ILockBytes::writeAt() contract violation"); + if (dst_size > m_nSize) + { + storeError eErrCode = setSize_Impl (sal::static_int_cast(dst_size)); + if (eErrCode != store_E_None) + return eErrCode; + } + OSL_POSTCOND(dst_size <= m_nSize, "store::MemoryLockBytes::setSize_Impl() contract violation"); + + sal_uInt8 * dst_lo = m_pData + nOffset; + if (dst_lo >= m_pData + m_nSize) + return store_E_CantSeek; + + sal_uInt8 * dst_hi = dst_lo + nBytes; + if (dst_hi > m_pData + m_nSize) + return store_E_CantWrite; + + memcpy (dst_lo, pBuffer, (dst_hi - dst_lo)); + return store_E_None; +} + +storeError MemoryLockBytes::getSize_Impl (sal_uInt32 & rnSize) +{ + rnSize = m_nSize; + return store_E_None; +} + +storeError MemoryLockBytes::setSize_Impl (sal_uInt32 nSize) +{ + if (nSize != m_nSize) + { + sal_uInt8 * pData = reinterpret_cast(rtl_reallocateMemory (m_pData, nSize)); + if (pData != 0) + { + if (nSize > m_nSize) + memset (pData + m_nSize, 0, sal::static_int_cast(nSize - m_nSize)); + } + else + { + if (nSize != 0) + return store_E_OutOfMemory; + } + m_pData = pData, m_nSize = nSize; + } + return store_E_None; +} + +storeError MemoryLockBytes::flush_Impl() +{ + return store_E_None; +} + +/*======================================================================== + * + * ILockBytes factory implementations. + * + *======================================================================*/ +namespace store +{ + +template< class T > struct ResourceHolder +{ + typedef typename T::destructor_type destructor_type; + + T m_value; + + explicit ResourceHolder (T const & value = T()) : m_value (value) {} + ~ResourceHolder() { reset(); } + + T & get() { return m_value; } + T const & get() const { return m_value; } + + void set (T const & value) { m_value = value; } + void reset (T const & value = T()) + { + T tmp (m_value); + if (tmp != value) + destructor_type()(tmp); + set (value); + } + T release() + { + T tmp (m_value); + set (T()); + return tmp; + } + + ResourceHolder (ResourceHolder & rhs) + { + set (rhs.release()); + } + ResourceHolder & operator= (ResourceHolder & rhs) + { + reset (rhs.release()); + return *this; + } +}; + +storeError +FileLockBytes_createInstance ( + rtl::Reference< ILockBytes > & rxLockBytes, + rtl_uString * pFilename, + storeAccessMode eAccessMode +) +{ + // Acquire file handle. + ResourceHolder xFile; + storeError result = xFile.get().initialize (pFilename, eAccessMode); + if (result != store_E_None) + return (result); + + if (eAccessMode == store_AccessReadOnly) + { + ResourceHolder xMapping; + if (xMapping.get().initialize (xFile.get().m_handle) == osl_File_E_None) + { + rxLockBytes = new MappedLockBytes (xMapping.get()); + if (!rxLockBytes.is()) + return store_E_OutOfMemory; + (void) xMapping.release(); + } + } + if (!rxLockBytes.is()) + { + rxLockBytes = new FileLockBytes (xFile.get()); + if (!rxLockBytes.is()) + return store_E_OutOfMemory; + (void) xFile.release(); + } + + return store_E_None; +} + +storeError +MemoryLockBytes_createInstance ( + rtl::Reference< ILockBytes > & rxLockBytes +) +{ + rxLockBytes = new MemoryLockBytes(); + if (!rxLockBytes.is()) + return store_E_OutOfMemory; + + return store_E_None; +} + +} // namespace store diff --git a/store/source/lockbyte.hxx b/store/source/lockbyte.hxx new file mode 100644 index 000000000000..20a8b0b77073 --- /dev/null +++ b/store/source/lockbyte.hxx @@ -0,0 +1,222 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: lockbyte.hxx,v $ + * + * $Revision: 1.1.2.1 $ + * + * last change: $Author: mhu $ $Date: 2008/09/18 16:10:50 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _STORE_LOCKBYTE_HXX_ +#define _STORE_LOCKBYTE_HXX_ "$Revision: 1.1.2.1 $" + +#ifndef _SAL_TYPES_H_ +#include "sal/types.h" +#endif + +#ifndef _RTL_REF_HXX_ +#include "rtl/ref.hxx" +#endif +#ifndef _RTL_USTRING_H_ +#include "rtl/ustring.h" +#endif + +#ifndef _STORE_TYPES_H_ +#include "store/types.h" +#endif +#ifndef _STORE_STORBASE_HXX_ +#include "storbase.hxx" +#endif + +namespace store +{ + +/*======================================================================== + * + * ILockBytes interface. + * + *======================================================================*/ +class ILockBytes : public rtl::IReference +{ +public: + /** + @param rxAllocator [out] + @param nPageSize [in] + */ + storeError initialize ( + rtl::Reference< PageData::Allocator > & rxAllocator, + sal_uInt16 nPageSize); + + /** + @param rPage [out] + @param nOffset [in] + */ + storeError readPageAt ( + PageHolder & rPage, + sal_uInt32 nOffset); + + /** + @param rPage [in] + @param nOffset [in] + */ + storeError writePageAt ( + PageHolder const & rPage, + sal_uInt32 nOffset); + + /** + @param nOffset [in] + @param pBuffer [out] + @param nBytes [in] + @return store_E_None upon success + */ + storeError readAt ( + sal_uInt32 nOffset, + void *pBuffer, + sal_uInt32 nBytes); + + /** + @param nOffset [in] + @param pBuffer [in] + @param nBytes [in] + @return store_E_None upon success + */ + storeError writeAt ( + sal_uInt32 nOffset, + const void *pBuffer, + sal_uInt32 nBytes); + + /** + @param rnSize [out] + @return store_E_None upon success + */ + storeError getSize (sal_uInt32 & rnSize); + + /** + @param nSize [in] + @return store_E_None upon success + */ + storeError setSize (sal_uInt32 nSize); + + /** + @return store_E_None upon success + */ + storeError flush(); + + /** + @param nOffset [in] + @param nBytes [in] + @return store_E_None upon success + store_E_LockingViolation + */ + storeError lockRange ( + sal_uInt32 nOffset, + sal_uInt32 nBytes); + + /** + @param nOffset [in] + @param nBytes [in] + @return store_E_None upon success + store_E_LockingViolation + */ + storeError unlockRange ( + sal_uInt32 nOffset, + sal_uInt32 nBytes); + +private: + /** Implementation (abstract). + */ + virtual storeError initialize_Impl ( + rtl::Reference< PageData::Allocator > & rxAllocator, + sal_uInt16 nPageSize) = 0; + + virtual storeError readPageAt_Impl ( + PageHolder & rPage, + sal_uInt32 nOffset) = 0; + + virtual storeError writePageAt_Impl ( + PageHolder const & rPage, + sal_uInt32 nOffset) = 0; + + virtual storeError readAt_Impl ( + sal_uInt32 nOffset, + void *pBuffer, + sal_uInt32 nBytes) = 0; + + virtual storeError writeAt_Impl ( + sal_uInt32 nOffset, + const void *pBuffer, + sal_uInt32 nBytes) = 0; + + virtual storeError getSize_Impl ( + sal_uInt32 & rnSize) = 0; + + virtual storeError setSize_Impl ( + sal_uInt32 nSize) = 0; + + virtual storeError flush_Impl() = 0; + +#ifdef STORE_FEATURE_LOCKING + virtual storeError lockRange_Impl ( + sal_uInt32 nOffset, + sal_uInt32 nBytes) = 0; + + virtual storeError unlockRange_Impl ( + sal_uInt32 nOffset, + sal_uInt32 nBytes) = 0; +#endif /* STORE_FEATURE_LOCKING */ +}; + +/*======================================================================== + * + * ILockBytes factories. + * + *======================================================================*/ + +storeError +FileLockBytes_createInstance ( + rtl::Reference< store::ILockBytes > & rxLockBytes, + rtl_uString * pFilename, + storeAccessMode eAccessMode +); + +storeError +MemoryLockBytes_createInstance ( + rtl::Reference< store::ILockBytes > & rxLockBytes +); + +/*======================================================================== + * + * The End. + * + *======================================================================*/ + +} // namespace store + +#endif /* !_STORE_LOCKBYTE_HXX_ */ + diff --git a/store/source/makefile.mk b/store/source/makefile.mk index 73c2ef8eefe4..88b7b4af4c33 100644 --- a/store/source/makefile.mk +++ b/store/source/makefile.mk @@ -33,7 +33,6 @@ PRJ=.. PRJNAME=store TARGET=store -ENABLE_EXCEPTIONS=TRUE # --- Settings --- @@ -42,12 +41,13 @@ ENABLE_EXCEPTIONS=TRUE # --- Files --- SLOFILES= \ - $(SLO)$/object.obj \ - $(SLO)$/memlckb.obj \ - $(SLO)$/filelckb.obj \ + $(SLO)$/object.obj \ + $(SLO)$/lockbyte.obj \ $(SLO)$/storbase.obj \ + $(SLO)$/storbios.obj \ $(SLO)$/storcach.obj \ $(SLO)$/stordata.obj \ + $(SLO)$/stordir.obj \ $(SLO)$/storlckb.obj \ $(SLO)$/stortree.obj \ $(SLO)$/storpage.obj \ @@ -55,16 +55,18 @@ SLOFILES= \ .IF "$(debug)" != "" OBJFILES= \ - $(OBJ)$/object.obj \ - $(OBJ)$/memlckb.obj \ - $(OBJ)$/filelckb.obj \ + $(OBJ)$/object.obj \ + $(OBJ)$/lockbyte.obj \ $(OBJ)$/storbase.obj \ + $(OBJ)$/storbios.obj \ $(OBJ)$/storcach.obj \ $(OBJ)$/stordata.obj \ + $(OBJ)$/stordir.obj \ $(OBJ)$/storlckb.obj \ $(OBJ)$/stortree.obj \ $(OBJ)$/storpage.obj \ $(OBJ)$/store.obj + .ENDIF # debug # --- Targets --- diff --git a/store/source/memlckb.cxx b/store/source/memlckb.cxx deleted file mode 100644 index a1033a114137..000000000000 --- a/store/source/memlckb.cxx +++ /dev/null @@ -1,344 +0,0 @@ -/************************************************************************* - * - * 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: memlckb.cxx,v $ - * $Revision: 1.10 $ - * - * 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 - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_store.hxx" - -#include - -#ifndef INCLUDED_STDDEF_H -#include -#define INCLUDED_STDDEF_H -#endif - -#ifndef INCLUDED_STRING_H -#include -#define INCLUDED_STRING_H -#endif -#include -#include -#include -#include -#include -#include -#include - -using namespace store; - -/*======================================================================== - * - * OMemoryLockBytes internals. - * - *======================================================================*/ - -/* - * __store_memcpy. - */ -inline void __store_memcpy (void * dst, const void * src, sal_uInt32 n) -{ - ::memcpy (dst, src, n); -} - -/* - * __store_memset. - */ -inline void __store_memset (void * dst, int val, sal_uInt32 n) -{ - ::memset (dst, val, n); -} - -/*======================================================================== - * - * OMemoryLockBytes_Impl interface. - * - *======================================================================*/ -namespace store -{ - -class OMemoryLockBytes_Impl -{ - sal_uInt8 *m_pBuffer; - sal_uInt32 m_nSize; - -public: - static void * operator new (size_t n) SAL_THROW(()) - { - return rtl_allocateMemory (sal_uInt32(n)); - } - static void operator delete (void * p, size_t) SAL_THROW(()) - { - rtl_freeMemory (p); - } - - OMemoryLockBytes_Impl (void); - ~OMemoryLockBytes_Impl (void); - - storeError resize (sal_uInt32 nSize); - - storeError readAt ( - sal_uInt32 nOffset, - void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone); - storeError writeAt ( - sal_uInt32 nOffset, - const void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone); - - storeError stat (sal_uInt32 &rnSize); -}; - -} // namespace store - -/*======================================================================== - * - * OMemoryLockBytes_Impl (inline) implementation. - * - *======================================================================*/ -/* - * OMemoryLockBytes_Impl. - */ -inline OMemoryLockBytes_Impl::OMemoryLockBytes_Impl (void) - : m_pBuffer (0), m_nSize (0) -{ -} - -/* - * ~OMemoryLockBytes_Impl. - */ -inline OMemoryLockBytes_Impl::~OMemoryLockBytes_Impl (void) -{ - rtl_freeMemory (m_pBuffer); -} - -/* - * resize. - */ -inline storeError OMemoryLockBytes_Impl::resize (sal_uInt32 nSize) -{ - if (!(nSize == m_nSize)) - { - m_pBuffer = (sal_uInt8*)(rtl_reallocateMemory (m_pBuffer, nSize)); - if (!m_pBuffer) - { - m_nSize = 0; - if (nSize > 0) - return store_E_OutOfMemory; - else - return store_E_None; - } - - if (nSize > m_nSize) - __store_memset (m_pBuffer + m_nSize, 0, nSize - m_nSize); - m_nSize = nSize; - } - return store_E_None; -} - -/* - * readAt. - */ -inline storeError OMemoryLockBytes_Impl::readAt ( - sal_uInt32 nOffset, - void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone) -{ - if (m_pBuffer) - { - if (!(nOffset < m_nSize)) - return store_E_None; - - nBytes = SAL_MIN(nOffset + nBytes, m_nSize) - nOffset; - if (!(nBytes > 0)) - return store_E_None; - - __store_memcpy (pBuffer, m_pBuffer + nOffset, nBytes); - rnDone = nBytes; - } - return store_E_None; -} - -/* - * writeAt. - */ -inline storeError OMemoryLockBytes_Impl::writeAt ( - sal_uInt32 nOffset, - const void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone) -{ - if (m_nSize < (nOffset + nBytes)) - { - storeError eErrCode = resize (nOffset + nBytes); - if (eErrCode != store_E_None) - return eErrCode; - } - - __store_memcpy (m_pBuffer + nOffset, pBuffer, nBytes); - rnDone = nBytes; - - return store_E_None; -} - -/* - * stat. - */ -inline storeError OMemoryLockBytes_Impl::stat (sal_uInt32 &rnSize) -{ - rnSize = m_nSize; - return store_E_None; -} - -/*======================================================================== - * - * OMemoryLockBytes implementation. - * - *======================================================================*/ -/* - * OMemoryLockBytes. - */ -OMemoryLockBytes::OMemoryLockBytes (void) - : m_pImpl (new OMemoryLockBytes_Impl()) -{ -} - -/* - * ~OMemoryLockBytes. - */ -OMemoryLockBytes::~OMemoryLockBytes (void) -{ - delete m_pImpl; -} - -/* - * acquire. - */ -oslInterlockedCount SAL_CALL OMemoryLockBytes::acquire (void) -{ - return OStoreObject::acquire(); -} - -/* - * release. - */ -oslInterlockedCount SAL_CALL OMemoryLockBytes::release (void) -{ - return OStoreObject::release(); -} - -/* - * readAt. - */ -storeError OMemoryLockBytes::readAt ( - sal_uInt32 nOffset, - void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone) -{ - // Initialize [out] param. - rnDone = 0; - - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - return m_pImpl->readAt (nOffset, pBuffer, nBytes, rnDone); -} - -/* - * writeAt. - */ -storeError OMemoryLockBytes::writeAt ( - sal_uInt32 nOffset, - const void *pBuffer, - sal_uInt32 nBytes, - sal_uInt32 &rnDone) -{ - // Initialize [out] param. - rnDone = 0; - - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - return m_pImpl->writeAt (nOffset, pBuffer, nBytes, rnDone); -} - -/* - * flush. - */ -storeError OMemoryLockBytes::flush (void) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - return store_E_None; -} - -/* - * setSize. - */ -storeError OMemoryLockBytes::setSize (sal_uInt32 nSize) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - return m_pImpl->resize (nSize); -} - -/* - * stat. - */ -storeError OMemoryLockBytes::stat (sal_uInt32 &rnSize) -{ - // Initialize [out] param. - rnSize = 0; - - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - return m_pImpl->stat (rnSize); -} - -/* - * lockRange. - */ -storeError OMemoryLockBytes::lockRange (sal_uInt32, sal_uInt32) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - return store_E_None; // E_Unsupported -} - -/* - * unlockRange. - */ -storeError OMemoryLockBytes::unlockRange (sal_uInt32, sal_uInt32) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - return store_E_None; // E_Unsupported -} - diff --git a/store/source/object.cxx b/store/source/object.cxx index 92ab83c20097..38bea6a331f3 100644 --- a/store/source/object.cxx +++ b/store/source/object.cxx @@ -31,13 +31,13 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_store.hxx" -#define _STORE_OBJECT_CXX_ "$Revision: 1.5 $" -#include -#include -#include -#include -#include -#include +#include "object.hxx" + +#include "sal/types.h" +#include "rtl/alloc.h" +#include "rtl/ref.hxx" +#include "osl/diagnose.h" +#include "osl/interlck.h" namespace store { @@ -76,7 +76,7 @@ void* OStoreObject::operator new (size_t n) /* * operator delete. */ -void OStoreObject::operator delete (void *p) +void OStoreObject::operator delete (void *p, size_t) { rtl_freeMemory (p); } diff --git a/store/source/object.hxx b/store/source/object.hxx new file mode 100644 index 000000000000..bc2a9bbcffe8 --- /dev/null +++ b/store/source/object.hxx @@ -0,0 +1,146 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: object.hxx,v $ + * + * $Revision: 1.1.2.1 $ + * + * last change: $Author: mhu $ $Date: 2008/09/18 16:10:51 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _STORE_OBJECT_HXX_ +#define _STORE_OBJECT_HXX_ "$Revision: 1.1.2.1 $" + +#ifndef _SAL_TYPES_H_ +#include "sal/types.h" +#endif + +#ifndef _RTL_REF_HXX_ +#include "rtl/ref.hxx" +#endif + +#ifndef _OSL_INTERLCK_H_ +#include "osl/interlck.h" +#endif + +namespace store +{ + +/*======================================================================== + * + * IStoreHandle interface. + * + *======================================================================*/ +class IStoreHandle : public rtl::IReference +{ +public: + /** Replaces dynamic_cast type checking. + */ + virtual sal_Bool SAL_CALL isKindOf (sal_uInt32 nTypeId) = 0; +}; + + +/** Template helper function as dynamic_cast replacement. + */ +template +store_handle_type * SAL_CALL query ( + IStoreHandle * pHandle, store_handle_type *); + +/*======================================================================== + * + * OStoreObject interface. + * + *======================================================================*/ +class OStoreObject : public store::IStoreHandle +{ + /** Template function specialization as dynamic_cast replacement. + */ + friend OStoreObject* + SAL_CALL query<> (IStoreHandle *pHandle, OStoreObject*); + +public: + /** Construction. + */ + OStoreObject (void); + + /** Allocation. + */ + static void* operator new (size_t n); + static void operator delete (void *p, size_t); + + /** IStoreHandle. + */ + virtual sal_Bool SAL_CALL isKindOf (sal_uInt32 nTypeId); + + /** IReference. + */ + virtual oslInterlockedCount SAL_CALL acquire (void); + virtual oslInterlockedCount SAL_CALL release (void); + +protected: + /** Destruction. + */ + virtual ~OStoreObject (void); + +private: + /** The IStoreHandle TypeId. + */ + static const sal_uInt32 m_nTypeId; + + /** Representation. + */ + oslInterlockedCount m_nRefCount; + + /** Not implemented. + */ + OStoreObject (const OStoreObject&); + OStoreObject& operator= (const OStoreObject&); +}; + +/** Template function specialization as dynamic_cast replacement. + */ +template<> inline OStoreObject* +SAL_CALL query (IStoreHandle *pHandle, OStoreObject*) +{ + if (pHandle && pHandle->isKindOf (OStoreObject::m_nTypeId)) + { + // Handle is kind of OStoreObject. + return static_cast(pHandle); + } + return 0; +} + +/*======================================================================== + * + * The End. + * + *======================================================================*/ + +} // namespace store + +#endif /* !_STORE_OBJECT_HXX_ */ diff --git a/store/source/storbase.cxx b/store/source/storbase.cxx index 4a64fc55567e..747b70df393a 100644 --- a/store/source/storbase.cxx +++ b/store/source/storbase.cxx @@ -1,2039 +1,205 @@ /************************************************************************* * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * OpenOffice.org - a multi-platform office productivity suite * - * Copyright 2008 by Sun Microsystems, Inc. + * $RCSfile: storbase.cxx,v $ * - * OpenOffice.org - a multi-platform office productivity suite + * $Revision: 1.12.8.4 $ * - * $RCSfile: storbase.cxx,v $ - * $Revision: 1.12 $ + * last change: $Author: mhu $ $Date: 2008/10/31 18:28:18 $ * - * This file is part of OpenOffice.org. + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. * - * 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). + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_store.hxx" -#define _STORE_STORBASE_CXX_ "$Revision: 1.12 $" - -#ifndef __ALGORITHM__ -#include -#endif -#ifndef __UTILITY__ -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace store; - -/*======================================================================== - * - * OStorePageGuard. - * - *======================================================================*/ -/* - * CRC polynomial 0xEDB88320. - */ -const sal_uInt32 store::OStorePageGuard::m_pTable[] = -{ - /* 0 */ - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - - /* 1 */ - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, +#include "storbase.hxx" - /* 2 */ - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, +#include "sal/types.h" +#include "rtl/alloc.h" +#include "rtl/ref.hxx" +#include "osl/diagnose.h" - /* 3 */ - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, +#include "store/types.h" +#include "object.hxx" - /* 4 */ - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - - /* 5 */ - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - - /* 6 */ - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - - /* 7 */ - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - - /* 8 */ - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - - /* 9 */ - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - - /* A */ - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - - /* B */ - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - - /* C */ - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - - /* D */ - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - - /* E */ - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - - /* F */ - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; - -/* - * crc32. - */ -sal_uInt32 OStorePageGuard::crc32 ( - sal_uInt32 nCRC32, const void *pData, sal_Size nSize) -{ - if (pData) - { - register const sal_uInt8 *p = (const sal_uInt8*)pData; - register sal_Size n; +#ifndef INCLUDED_STDIO_H +#include +#define INCLUDED_STDIO_H +#endif - nCRC32 = ~nCRC32; - for (n = nSize; n > 0; n--) - nCRC32 = updcrc32 (nCRC32, *(p++)); - nCRC32 = ~nCRC32; - } - return nCRC32; -} +using namespace store; /*======================================================================== * - * OStorePageObject. + * SharedCount::Allocator. * *======================================================================*/ -/* - * ~OStorePageObject. - */ -OStorePageObject::~OStorePageObject (void) -{ -} - -/* - * swap. - */ -void OStorePageObject::swap (const D&) +SharedCount::Allocator & +SharedCount::Allocator::get() { -#ifdef OSL_BIGENDIAN - m_rPage.swap (); -#endif /* OSL_BIGENDIAN */ + static Allocator g_aSharedCountAllocator; + return g_aSharedCountAllocator; } -/* - * guard. - */ -void OStorePageObject::guard (const D&) +SharedCount::Allocator::Allocator() { - m_rPage.guard (); + m_cache = rtl_cache_create ( + "store_shared_count_cache", + sizeof(long), + 0, // objalign + 0, // constructor + 0, // destructor + 0, // reclaim + 0, // userarg + 0, // default source + 0 // flags + ); } -/* - * verify. - */ -storeError OStorePageObject::verify (const D&) +SharedCount::Allocator::~Allocator() { - return m_rPage.verify (); + rtl_cache_destroy (m_cache), m_cache = 0; } /*======================================================================== * - * OStoreSuperBlock. - * - *======================================================================*/ -#define STORE_MAGIC_SUPERBLOCK sal_uInt32(0x484D5343) - -struct OStoreSuperBlock -{ - typedef OStorePageGuard G; - typedef OStorePageDescriptor D; - typedef OStorePageLink L; - - /** Representation. - */ - G m_aGuard; - D m_aDescr; - sal_uInt32 m_nMarked; - L m_aMarked; - sal_uInt32 m_nUnused; - L m_aUnused; - - /** size. - */ - static sal_uInt16 size (void) - { - return sal_uInt16(sizeof(G) + sizeof(D) + - 2 * (sizeof(L) + sizeof(sal_uInt32))); - } - - /** Construction. - */ - OStoreSuperBlock (void) - : m_aGuard (STORE_MAGIC_SUPERBLOCK), - m_nMarked (0), - m_aMarked (0), - m_nUnused (0), - m_aUnused (0) - {} - - OStoreSuperBlock (const OStoreSuperBlock& rOther) - : m_aGuard (rOther.m_aGuard), - m_aDescr (rOther.m_aDescr), - m_nMarked (rOther.m_nMarked), - m_aMarked (rOther.m_aMarked), - m_nUnused (rOther.m_nUnused), - m_aUnused (rOther.m_aUnused) - {} - - OStoreSuperBlock& operator= (const OStoreSuperBlock& rOther) - { - m_aGuard = rOther.m_aGuard; - m_aDescr = rOther.m_aDescr; - m_nMarked = rOther.m_nMarked; - m_aMarked = rOther.m_aMarked; - m_nUnused = rOther.m_nUnused; - m_aUnused = rOther.m_aUnused; - return *this; - } - - /** Comparison. - */ - sal_Bool operator== (const OStoreSuperBlock& rOther) const - { - return ((m_aGuard == rOther.m_aGuard ) && - (m_aDescr == rOther.m_aDescr ) && - (m_nMarked == rOther.m_nMarked) && - (m_aMarked == rOther.m_aMarked) && - (m_nUnused == rOther.m_nUnused) && - (m_aUnused == rOther.m_aUnused) ); - } - - /** create. - */ - void create (const D& rDescr) - { - m_aGuard = G(STORE_MAGIC_SUPERBLOCK); - m_aDescr = rDescr; - - m_nMarked = 0; - m_aMarked = L(0); - - m_nUnused = 0; - m_aUnused = L(0); - } - - /** unused(Count|Head|Insert|Remove|Reset). - */ - sal_uInt32 unusedCount (void) const - { - return m_nUnused; - } - const L& unusedHead (void) const - { - return m_aUnused; - } - void unusedInsert (const L& rLink) - { - m_nUnused++; - m_aUnused = rLink; - } - void unusedRemove (const L& rLink) - { - m_nUnused--; - m_aUnused = rLink; - } - void unusedReset (void) - { - m_nUnused = 0; - m_aUnused = L(0); - } - - /** swap (internal and external representation). - */ - void swap (void) - { -#ifdef OSL_BIGENDIAN - m_aGuard.swap(); - m_aDescr.swap(); - - m_nMarked = OSL_SWAPDWORD(m_nMarked); - m_aMarked.swap(); - - m_nUnused = OSL_SWAPDWORD(m_nUnused); - m_aUnused.swap(); -#endif /* OSL_BIGENDIAN */ - } - - /** guard (external representation). - */ - void guard (void) - { - sal_uInt32 nCRC32 = 0; - nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); - nCRC32 = G::crc32 (nCRC32, &m_aDescr, size() - sizeof(G)); -#ifdef OSL_BIGENDIAN - nCRC32 = OSL_SWAPDWORD(nCRC32); -#endif /* OSL_BIGENDIAN */ - m_aGuard.m_nCRC32 = nCRC32; - } - - /** verify (external representation). - */ - storeError verify (void) - { - sal_uInt32 nMagic = m_aGuard.m_nMagic; -#ifdef OSL_BIGENDIAN - nMagic = OSL_SWAPDWORD(nMagic); -#endif /* OSL_BIGENDIAN */ - if (nMagic != STORE_MAGIC_SUPERBLOCK) - return store_E_WrongFormat; - - sal_uInt32 nCRC32 = 0; - nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); - nCRC32 = G::crc32 (nCRC32, &m_aDescr, size() - sizeof(G)); -#ifdef OSL_BIGENDIAN - nCRC32 = OSL_SWAPDWORD(nCRC32); -#endif /* OSL_BIGENDIAN */ - if (m_aGuard.m_nCRC32 != nCRC32) - return store_E_InvalidChecksum; - else - return store_E_None; - } -}; - -/*======================================================================== - * - * OStoreStateBlock. - * - *======================================================================*/ -struct OStoreStateBlock -{ - enum StateBits - { - STATE_CLEAN = 0, - STATE_CLOSE_WAIT = 1, - STATE_FLUSH_WAIT = 2 - }; - - /** Representation. - */ - sal_uInt32 m_nState; - - /** size. - */ - static sal_uInt16 size (void) - { - return sal_uInt16(sizeof(sal_uInt32)); - } - - /** Construction. - */ - OStoreStateBlock (void) - : m_nState (STATE_CLEAN) - {} - - /** swap (internal and external representation). - */ - void swap (void) - { -#ifdef OSL_BIGENDIAN - m_nState = OSL_SWAPDWORD(m_nState); -#endif /* OSL_BIGENDIAN */ - } - - /** Operation. - */ - bool closePending (void) const - { - return ((m_nState & STATE_CLOSE_WAIT) == STATE_CLOSE_WAIT); - } - void closed (void) - { - m_nState &= ~STATE_CLOSE_WAIT; - } - - bool flushPending (void) const - { - return ((m_nState & STATE_FLUSH_WAIT) == STATE_FLUSH_WAIT); - } - void flushed (void) - { - m_nState &= ~STATE_FLUSH_WAIT; - } - - void modified (void) - { - m_nState |= (STATE_CLOSE_WAIT | STATE_FLUSH_WAIT); - } - void clean (void) - { - m_nState &= ~(STATE_CLOSE_WAIT | STATE_FLUSH_WAIT); - } -}; - -/*======================================================================== - * - * OStoreSuperBlockPage interface. + * PageData::Allocator_Impl (default allocator). * *======================================================================*/ namespace store { -struct OStoreSuperBlockPage +class PageData::Allocator_Impl : + public store::OStoreObject, + public store::PageData::Allocator { - typedef OStoreSuperBlock SuperBlock; - typedef OStoreStateBlock StateBlock; - - /** Representation. - */ - SuperBlock m_aSuperOne; - SuperBlock m_aSuperTwo; - StateBlock m_aState; - - /** size. - */ - static sal_uInt16 size (void) - { - return (2 * SuperBlock::size() + StateBlock::size()); - } - - /** Allocation. - */ - static void * operator new (std::size_t n) SAL_THROW(()) - { - return rtl_allocateMemory (sal_uInt32(n)); - } - - static void operator delete (void * p, std::size_t) SAL_THROW(()) - { - rtl_freeMemory (p); - } - - /** Construction. +public: + /** Construction (two phase). */ - OStoreSuperBlockPage (void) - {} + Allocator_Impl(); - /** swap (internal and external representation). - */ - void swap (void) - { -#ifdef OSL_BIGENDIAN - m_aSuperOne.swap(); - m_aSuperTwo.swap(); - m_aState.swap(); -#endif /* OSL_BIGENDIAN */ - } + storeError initialize (sal_uInt16 nPageSize); - /** load (w/o verification). + /** Delegate multiple inherited rtl::IReference. */ - storeError load (OStorePageBIOS &rBIOS) + virtual oslInterlockedCount SAL_CALL acquire() { - // Read. - storeError eErrCode = rBIOS.read (0, this, size()); - -#ifdef OSL_BIGENDIAN - // Swap to internal representation. - swap(); -#endif /* OSL_BIGENDIAN */ - - // Done. - return eErrCode; + return OStoreObject::acquire(); } - - /** save. - */ - storeError save (OStorePageBIOS &rBIOS) + virtual oslInterlockedCount SAL_CALL release() { -#ifdef OSL_BIGENDIAN - // Swap to external representation. - swap(); -#endif /* OSL_BIGENDIAN */ - - // Guard. - m_aSuperOne.guard(); - m_aSuperTwo.guard(); - - // Write. - storeError eErrCode = rBIOS.write (0, this, size()); - -#ifdef OSL_BIGENDIAN - // Swap back to internal representation. - swap(); -#endif /* OSL_BIGENDIAN */ - - // Done. - return eErrCode; + return OStoreObject::release(); } - /** create. +protected: + /** Destruction. */ - storeError create ( - OStorePageBIOS &rBIOS, - const OStorePageDescriptor &rDescr); + virtual ~Allocator_Impl(); - /** close. - */ - storeError close ( - OStorePageBIOS &rBIOS); - - /** flush. +private: + /** Representation. */ - storeError flush ( - OStorePageBIOS &rBIOS); + rtl_cache_type * m_page_cache; + sal_uInt16 m_page_size; - /** modified. + /** PageData::Allocator implementation. */ - storeError modified ( - OStorePageBIOS &rBIOS); + virtual void allocate_Impl (void ** ppPage, sal_uInt16 * pnSize); + virtual void deallocate_Impl (void * pPage); - /** verify (with repair). + /** Not implemented. */ - storeError verify ( - OStorePageBIOS &rBIOS); + Allocator_Impl (Allocator_Impl const &); + Allocator_Impl & operator= (Allocator_Impl const &); }; } // namespace store -/*======================================================================== - * - * OStoreSuperBlockPage implementation. - * - *======================================================================*/ -/* - * create. - */ -storeError OStoreSuperBlockPage::create ( - OStorePageBIOS &rBIOS, - const OStorePageDescriptor &rDescr) -{ - storeError eErrCode = store_E_OutOfMemory; - void * p = rtl_allocateMemory (rDescr.m_nSize); - if (p != 0) - { - // Setup initial Page. - __store_memset (p, 0, rDescr.m_nSize); - - // Mark as modified. - m_aState.modified(); +PageData::Allocator_Impl::Allocator_Impl() + : m_page_cache(0), m_page_size(0) +{} - // Write initial Page. - eErrCode = rBIOS.write (0, p, rDescr.m_nSize); - if (eErrCode == store_E_None) - { - // Setup 1st and 2nd SuperBlock copy. - m_aSuperOne.create (rDescr); - m_aSuperTwo = m_aSuperOne; - - // Mark as modified. - m_aState.modified(); - - // Save. - eErrCode = save (rBIOS); - } - - // Cleanup and finish. - rtl_freeMemory (p); - } - return eErrCode; -} - -/* - * close. - */ -storeError OStoreSuperBlockPage::close (OStorePageBIOS &rBIOS) +storeError +PageData::Allocator_Impl::initialize (sal_uInt16 nPageSize) { - storeError eErrCode = store_E_None; - if (m_aState.closePending()) - { - // Mark as modified. - m_aState.modified(); - - // Check access mode. - if (rBIOS.isWriteable()) - { - // Save StateBlock. - StateBlock aState (m_aState); - - // Mark as clean. - aState.clean(); - -#ifdef OSL_BIGENDIAN - // Swap to external representation. - aState.swap(); -#endif /* OSL_BIGENDIAN */ + char name[RTL_CACHE_NAME_LENGTH + 1]; + sal_Size size = sal::static_int_cast< sal_Size >(nPageSize); + (void) snprintf (name, sizeof(name), "store_page_alloc_%lu", size); - // Write behind SuperBlock. - sal_uInt32 nAddr = 2 * SuperBlock::size(); - eErrCode = rBIOS.write (nAddr, &aState, StateBlock::size()); - } + m_page_cache = rtl_cache_create (name, size, 0, 0, 0, 0, 0, 0, 0); + if (!m_page_cache) + return store_E_OutOfMemory; - // Mark as clean. - m_aState.clean(); - } - return eErrCode; + m_page_size = nPageSize; + return store_E_None; } -/* - * flush. - */ -storeError OStoreSuperBlockPage::flush (OStorePageBIOS &rBIOS) +PageData::Allocator_Impl::~Allocator_Impl() { - storeError eErrCode = store_E_None; - if (m_aState.flushPending()) - { - // Check access mode. - if (rBIOS.isWriteable()) - { - // Save StateBlock. - StateBlock aState (m_aState); - - // Mark as flushed. - aState.flushed(); - -#ifdef OSL_BIGENDIAN - // Swap to external representation. - aState.swap(); -#endif /* OSL_BIGENDIAN */ - - // Write behind SuperBlock. - sal_uInt32 nAddr = 2 * SuperBlock::size(); - eErrCode = rBIOS.write (nAddr, &aState, StateBlock::size()); - } - - // Mark as flushed. - m_aState.flushed(); - } - return eErrCode; + rtl_cache_destroy(m_page_cache), m_page_cache = 0; } -/* - * modified. - */ -storeError OStoreSuperBlockPage::modified (OStorePageBIOS &rBIOS) +void PageData::Allocator_Impl::allocate_Impl (void ** ppPage, sal_uInt16 * pnSize) { - storeError eErrCode = store_E_None; - if (!m_aState.flushPending()) - { - // Mark as modified. - m_aState.modified(); - - // Check access mode. - if (rBIOS.isWriteable()) - { - // Save StateBlock. - StateBlock aState (m_aState); - -#ifdef OSL_BIGENDIAN - // Swap to external representation. - aState.swap(); -#endif /* OSL_BIGENDIAN */ - - // Write behind SuperBlock. - sal_uInt32 nAddr = 2 * SuperBlock::size(); - eErrCode = rBIOS.write (nAddr, &aState, StateBlock::size()); - } - } - return eErrCode; + OSL_PRECOND((ppPage != 0) && (pnSize != 0), "contract violation"); + *ppPage = rtl_cache_alloc(m_page_cache), *pnSize = m_page_size; } -/* - * verify (with repair). - */ -storeError OStoreSuperBlockPage::verify (OStorePageBIOS &rBIOS) +void PageData::Allocator_Impl::deallocate_Impl (void * pPage) { -#ifdef OSL_BIGENDIAN - // Swap to external representation. - swap(); -#endif /* OSL_BIGENDIAN */ - - // Verify 1st copy. - storeError eErrCode = m_aSuperOne.verify(); - if (eErrCode == store_E_None) - { - // Ok. Verify 2nd copy. - eErrCode = m_aSuperTwo.verify(); - if (eErrCode == store_E_None) - { - // Ok. Ensure identical copies (1st copy wins). - if (!(m_aSuperOne == m_aSuperTwo)) - { - // Different. Replace 2nd copy with 1st copy. - m_aSuperTwo = m_aSuperOne; - - // Write back. - if (rBIOS.isWriteable()) - eErrCode = rBIOS.write (0, this, size()); - else - eErrCode = store_E_None; - } - } - else - { - // Failure. Replace 2nd copy with 1st copy. - m_aSuperTwo = m_aSuperOne; - - // Write back. - if (rBIOS.isWriteable()) - eErrCode = rBIOS.write (0, this, size()); - else - eErrCode = store_E_None; - } - } - else - { - // Failure. Verify 2nd copy. - eErrCode = m_aSuperTwo.verify(); - if (eErrCode == store_E_None) - { - // Ok. Replace 1st copy with 2nd copy. - m_aSuperOne = m_aSuperTwo; - - // Write back. - if (rBIOS.isWriteable()) - eErrCode = rBIOS.write (0, this, size()); - else - eErrCode = store_E_None; - } - else - { - // Double Failure. - OSL_TRACE("OStoreSuperBlockPage::verify(): double failure.\n"); - } - } - -#ifdef OSL_BIGENDIAN - // Swap back to internal representation. - swap(); -#endif /* OSL_BIGENDIAN */ - - // Done. - return eErrCode; + OSL_PRECOND(pPage != 0, "contract violation"); + rtl_cache_free(m_page_cache, pPage); } /*======================================================================== * - * MyAllocator. + * PageData::Allocator factory. * *======================================================================*/ -template -struct MyAllocator +storeError +PageData::Allocator::createInstance (rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize) { - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - typedef T * pointer; - typedef const T * const_pointer; - - typedef T & reference; - typedef const T & const_reference; - - typedef T value_type; - - template - struct rebind - { - typedef MyAllocator other; - }; - - pointer address (reference value) const - { - return &value; - } - const_pointer address (const_reference value) const - { - return &value; - } - - MyAllocator (void) - {} - - template - MyAllocator (const MyAllocator &) - {} - - MyAllocator (const MyAllocator &) - {} - - ~MyAllocator (void) - {} - - size_type max_size() const - { - return size_type(-1)/sizeof(T); - } - - pointer allocate (size_type n, void const * = 0) - { - n *= sizeof(T); - return (pointer)rtl_allocateMemory(sal_uInt32(n)); - } - void deallocate (pointer p, size_type n) - { - n *= sizeof(T); - rtl_freeMemory(p); - } - - void construct (pointer p, const_reference value) - { - new ((void*)p) T(value); - } - void destroy (pointer p) - { - p->~T(); - } -}; + rtl::Reference< PageData::Allocator_Impl > xAllocator (new PageData::Allocator_Impl()); + if (!xAllocator.is()) + return store_E_OutOfMemory; -//---------------------------------------------------------------------------- - -template -inline bool operator== (const MyAllocator &, const MyAllocator &) -{ - return true; -} - -template -inline bool operator!= (const MyAllocator &, const MyAllocator &) -{ - return false; -} - -//---------------------------------------------------------------------------- -// see stlport '_alloc.h' comments why old compilers require the hack below. -//---------------------------------------------------------------------------- - -#ifndef __STL_MEMBER_TEMPLATE_CLASSES -namespace _STL -{ - template - inline MyAllocator & __stl_alloc_rebind (MyAllocator & a, U const *) - { - return (MyAllocator&)(a); - } -} -#endif /* __STL_MEMBER_TEMPLATE_CLASSES */ + rxAllocator = &*xAllocator; + return xAllocator->initialize (nPageSize); +} /*======================================================================== * - * OStorePageACL. - * - *======================================================================*/ -typedef sal_uInt32 key_type; -typedef sal_uInt32 val_type; - -typedef std::hash key_hash; -typedef std::equal_to key_cmp; - -typedef std::hash_map< - key_type, - val_type, - std::hash, - std::equal_to, - MyAllocator -> map_type; - -namespace store -{ - -struct OStorePageACL : public map_type -{ - /** Representation. - */ - sal_uInt32 m_nRefCount; - - /** Allocation. - */ - static void * operator new (std::size_t n) SAL_THROW(()) - { - return rtl_allocateMemory (sal_uInt32(n)); - } - - static void operator delete (void * p, std::size_t) SAL_THROW(()) - { - rtl_freeMemory (p); - } - - /** Construction. - */ - OStorePageACL (void) - : m_nRefCount (0) - {} -}; - -} // namespace store - -/*======================================================================== - * - * OStorePageBIOS implementation. + * OStorePageObject. * *======================================================================*/ /* - * OStorePageBIOS. - */ -OStorePageBIOS::OStorePageBIOS (void) - : m_xLockBytes (NULL), - m_pAcl (NULL), - m_pSuper (NULL), - m_bModified (sal_False), - m_bWriteable (sal_False) -{ -} - -/* - * ~OStorePageBIOS. - */ -OStorePageBIOS::~OStorePageBIOS (void) -{ - OStorePageBIOS::close(); -} - -/* - * verify (SuperBlock with repair). - * Internal: Precond: initialized, exclusive access. - */ -storeError OStorePageBIOS::verify (SuperPage *&rpSuper) -{ - // Check SuperBlock page allocation. - if (rpSuper == 0) - { - // Allocate. - if ((rpSuper = new SuperPage()) == 0) - return store_E_OutOfMemory; - - // Load (w/o verification). - storeError eErrCode = rpSuper->load (*this); - if (eErrCode != store_E_None) - { - // Cleanup and fail. - __STORE_DELETEZ (rpSuper); - return eErrCode; - } - - // Check SuperBlock state. - if (rpSuper->m_aState.closePending()) - OSL_TRACE("OStorePageBIOS::verify(): close pending.\n"); - - if (rpSuper->m_aState.flushPending()) - OSL_TRACE("OStorePageBIOS::verify(): flush pending.\n"); - } - - // Verify SuperBlock page (with repair). - return rpSuper->verify (*this); -} - -/* - * repair (SuperBlock). - * Internal: Precond: initialized, exclusive access. - */ -storeError OStorePageBIOS::repair (SuperPage *&rpSuper) -{ - // Acquire Lock. - storeError eErrCode = acquireLock (0, SuperPage::size()); - if (eErrCode != store_E_None) - return eErrCode; - - // Verify SuperBlock page (with repair). - eErrCode = verify (rpSuper); - if (eErrCode != store_E_None) - { - // Failure. - releaseLock (0, SuperPage::size()); - return eErrCode; - } - - // ReleaseLock. - return releaseLock (0, SuperPage::size()); -} - -/* - * initialize. - * Precond: none. - */ -storeError OStorePageBIOS::initialize ( - ILockBytes *pLockBytes, - storeAccessMode eAccessMode) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - // Check arguments. - storeError eErrCode = store_E_InvalidParameter; - if (pLockBytes) - { - // Cleanup. - __STORE_DELETEZ (m_pAcl); - __STORE_DELETEZ (m_pSuper); - - // Initialize. - m_xLockBytes = pLockBytes; - m_bModified = sal_False; - m_bWriteable = (!(eAccessMode == store_AccessReadOnly)); - - // Check access mode. - if (!(eAccessMode == store_AccessCreate)) - { - // Verify (repair) SuperBlock page. - if (!(eAccessMode == store_AccessReadOnly)) - eErrCode = repair (m_pSuper); - else - eErrCode = verify (m_pSuper); - if (eErrCode != store_E_None) - return eErrCode; - - // Obtain modified state. - m_bModified = m_pSuper->m_aState.flushPending(); - } - else - { - // Truncate to zero length. - eErrCode = m_xLockBytes->setSize(0); - if (eErrCode != store_E_None) - return eErrCode; - -#ifdef STORE_FEATURE_COMMIT - // Commit. - eErrCode = m_xLockBytes->flush(); - if (eErrCode != store_E_None) - return eErrCode; -#endif /* STORE_FEATURE_COMMIT */ - - // Mark not existent. - eErrCode = store_E_NotExists; - } - } - return eErrCode; -} - -/* - * create (SuperBlock). - * Precond: initialized, writeable (store_AccessCreate). - */ -storeError OStorePageBIOS::create (sal_uInt16 nPageSize) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - if (!m_bWriteable) - return store_E_AccessViolation; - - // Check PageSize. - sal_uInt16 nMinSize = SuperPage::size(); - nMinSize = std::max (nMinSize, STORE_MINIMUM_PAGESIZE); - - nPageSize = std::max (nPageSize, nMinSize); - nPageSize = std::min (nPageSize, STORE_MAXIMUM_PAGESIZE); - - sal_uInt16 nRemSize = nPageSize % nMinSize; - if (nRemSize) - nPageSize += (nMinSize - nRemSize); - - // Acquire Lock. - storeError eErrCode = acquireLock (0, SuperPage::size()); - if (eErrCode != store_E_None) - return eErrCode; - - // Check SuperBlock page allocation. - if ((m_pSuper == 0) && ((m_pSuper = new SuperPage()) == 0)) - { - // Cleanup and fail. - releaseLock (0, SuperPage::size()); - return store_E_OutOfMemory; - } - - // Create SuperBlock page. - eErrCode = m_pSuper->create ( - *this, OStorePageDescriptor (nPageSize, nPageSize, nMinSize)); - if (eErrCode != store_E_None) - { - // Cleanup and fail. - __STORE_DELETEZ (m_pSuper); - releaseLock (0, SuperPage::size()); - return eErrCode; - } - - // Flush SuperBlock page. - eErrCode = m_pSuper->flush (*this); - if (eErrCode != store_E_None) - { - // Cleanup and fail. - __STORE_DELETEZ (m_pSuper); - releaseLock (0, SuperPage::size()); - return eErrCode; - } - -#ifdef STORE_FEATURE_COMMIT - // Commit. - eErrCode = m_xLockBytes->flush(); - OSL_POSTCOND( - eErrCode == store_E_None, - "OStorePageBIOS::create(): flush failed"); -#endif /* STORE_FEATURE_COMMIT */ - - // Adjust modified state. - m_bModified = (eErrCode != store_E_None); - - // Release Lock and finish. - return releaseLock (0, SuperPage::size()); -} - -/* - * getPageSize. - * Precond: initialized. - */ -storeError OStorePageBIOS::getPageSize (sal_uInt16 &rnPageSize) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - // Initialize [out] param. - rnPageSize = 0; - - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - - // Load SuperBlock and require good health. - storeError eErrCode = verify (m_pSuper); - if (eErrCode == store_E_None) - { - // Obtain PageSize. - rnPageSize = m_pSuper->m_aSuperOne.m_aDescr.m_nSize; - } - return eErrCode; -} - -/* - * acquireLock. - * Low Level: Precond: initialized, exclusive access. - */ -storeError OStorePageBIOS::acquireLock ( - sal_uInt32 nAddr, - sal_uInt32 -#ifdef STORE_FEATURE_LOCKING - nSize -#endif /* STORE_FEATURE_LOCKING */ -) -{ - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - - // Check Address. - OSL_PRECOND( - nAddr != STORE_PAGE_NULL, - "OStorePageBIOS::acquireLock(): invalid Address"); - if (nAddr == STORE_PAGE_NULL) - return store_E_CantSeek; - - // Acquire Lock. -#ifdef STORE_FEATURE_LOCKING - return m_xLockBytes->lockRegion (nAddr, nSize); -#else - return store_E_None; -#endif /* STORE_FEATURE_LOCKING */ -} - -/* - * releaseLock. - * Low Level: Precond: initialized, exclusive access. - */ -storeError OStorePageBIOS::releaseLock ( - sal_uInt32 nAddr, - sal_uInt32 -#ifdef STORE_FEATURE_LOCKING - nSize -#endif /* STORE_FEATURE_LOCKING */ -) -{ - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - - // Check Address. - OSL_PRECOND( - nAddr != STORE_PAGE_NULL, - "OStorePageBIOS::releaseLock(): invalid Address"); - if (nAddr == STORE_PAGE_NULL) - return store_E_CantSeek; - - // Release Lock. -#ifdef STORE_FEATURE_LOCKING - return m_xLockBytes->unlockRegion (nAddr, nSize); -#else - return store_E_None; -#endif /* STORE_FEATURE_LOCKING */ -} - -/* - * read. - * Low Level: Precond: initialized, exclusive access. - */ -storeError OStorePageBIOS::read ( - sal_uInt32 nAddr, void *pData, sal_uInt32 nSize) -{ - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - - // Check Address. - OSL_PRECOND( - nAddr != STORE_PAGE_NULL, - "OStorePageBIOS::read(): invalid Address"); - if (nAddr == STORE_PAGE_NULL) - return store_E_CantSeek; - - // Check Data. - OSL_PRECOND(pData, "OStorePageBIOS::read(): no Data"); - if (pData == NULL) - return store_E_InvalidParameter; - - // Read Page. - sal_uInt32 nDone = 0; - storeError eErrCode = m_xLockBytes->readAt (nAddr, pData, nSize, nDone); - if ((eErrCode == store_E_None) && (nDone != nSize)) - { - // Page too short. - if (nDone == 0) - eErrCode = store_E_NotExists; - else - eErrCode = store_E_CantRead; - } - return eErrCode; -} - -/* - * write. - * Low Level: Precond: initialized, writeable, exclusive access. - */ -storeError OStorePageBIOS::write ( - sal_uInt32 nAddr, const void *pData, sal_uInt32 nSize) -{ - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - if (!m_bWriteable) - return store_E_AccessViolation; - - // Check Address. - OSL_PRECOND( - nAddr != STORE_PAGE_NULL, - "OStorePageBIOS::write(): invalid Address"); - if (nAddr == STORE_PAGE_NULL) - return store_E_CantSeek; - - // Check Data. - OSL_PRECOND(pData, "OStorePageBIOS::write(): no Data"); - if (pData == NULL) - return store_E_InvalidParameter; - - // Check modified state. - storeError eErrCode = store_E_None; - if (!m_bModified) - { - // Mark as modified. - m_bModified = sal_True; - - // Mark SuperBlock modified. - eErrCode = m_pSuper->modified (*this); - if (eErrCode != store_E_None) - return eErrCode; - } - - // Write Data. - sal_uInt32 nDone = 0; - eErrCode = m_xLockBytes->writeAt (nAddr, pData, nSize, nDone); - if ((eErrCode == store_E_None) && (nDone != nSize)) - { - // Page too short. - eErrCode = store_E_CantWrite; - } - return eErrCode; -} - -/* - * acquirePage. - * Precond: initialized. - */ -storeError OStorePageBIOS::acquirePage ( - const OStorePageDescriptor& rDescr, storeAccessMode eMode) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - - // Check access mode. - if (!(m_bWriteable || (eMode == store_AccessReadOnly))) - return store_E_AccessViolation; - - // Check access control list. - if ((m_pAcl == 0) && ((m_pAcl = new OStorePageACL()) == 0)) - return store_E_OutOfMemory; - - // Find access control list entry. - map_type::iterator it = m_pAcl->find (rDescr.m_nAddr); - if (it != m_pAcl->end()) - { - // Acquire existing entry (with ShareDenyWrite). - if (eMode == store_AccessReadOnly) - (*it).second += 1; - else - return store_E_AccessViolation; - } - else - { - // Insert new entry. - typedef std::pair map_entry; - m_pAcl->insert (map_entry (rDescr.m_nAddr, 1)); - } - - // Increment total referer count and finish. - m_pAcl->m_nRefCount += 1; - return store_E_None; -} - -/* - * releasePage. - * Precond: initialized. - */ -storeError OStorePageBIOS::releasePage (const OStorePageDescriptor& rDescr) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - - // Check access control list. - if (!m_pAcl) - return store_E_NotExists; - - // Find access control list entry. - map_type::iterator it = m_pAcl->find (rDescr.m_nAddr); - if (it == m_pAcl->end()) - return store_E_NotExists; - - // Release existing entry. - if ((*it).second > 1) - (*it).second -= 1; - else - m_pAcl->erase(it); - - // Decrement total referer count and finish. - m_pAcl->m_nRefCount -= 1; - return store_E_None; -} - -/* - * getRefererCount. - * Precond: none. - */ -sal_uInt32 OStorePageBIOS::getRefererCount (void) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - // Obtain total referer count. - if (m_pAcl) - return m_pAcl->m_nRefCount; - else - return 0; -} - -/* - * allocate. - * Precond: initialized, writeable. - */ -storeError OStorePageBIOS::allocate ( - OStorePageObject& rPage, Allocation eAlloc) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - if (!m_bWriteable) - return store_E_AccessViolation; - - // Acquire SuperBlock Lock. - storeError eErrCode = acquireLock (0, SuperPage::size()); - if (eErrCode != store_E_None) - return eErrCode; - - // Load SuperBlock and require good health. - eErrCode = verify (m_pSuper); - if (eErrCode != store_E_None) - { - releaseLock (0, SuperPage::size()); - return eErrCode; - } - - // Check allocation. - if (eAlloc != ALLOCATE_EOF) - { - // Check FreeList. - OStorePageLink aListHead (m_pSuper->m_aSuperTwo.unusedHead()); - if (aListHead.m_nAddr) - { - // Allocate from FreeList. - OStorePageData aPageHead (OStorePageData::size()); - aPageHead.location (aListHead.m_nAddr); - - // Load PageHead. - eErrCode = peek (aPageHead); - if (eErrCode != store_E_None) - { - releaseLock (0, SuperPage::size()); - return eErrCode; - } - - // Verify FreeList head. - OSL_PRECOND( - aPageHead.m_aUnused.m_nAddr != STORE_PAGE_NULL, - "OStorePageBIOS::allocate(): page not free"); - if (aPageHead.m_aUnused.m_nAddr == STORE_PAGE_NULL) - { - // Recovery: Reset FreeList. - m_pSuper->m_aSuperTwo.unusedReset(); - m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo; - - // Save SuperBlock page. - eErrCode = m_pSuper->save (*this); - - // Release SuperBlock Lock. - releaseLock (0, SuperPage::size()); - - // Recovery: Allocate from EOF. - if (eErrCode == store_E_None) - return allocate (rPage, ALLOCATE_EOF); - else - return store_E_Unknown; - } - - // Assign location. - OStorePageData &rData = rPage.getData(); - rData.location (aPageHead.m_aDescr.m_nAddr); - - // Pop from FreeList. - aListHead.m_nAddr = aPageHead.m_aUnused.m_nAddr; - rData.m_aUnused.m_nAddr = STORE_PAGE_NULL; - - // Save page. - eErrCode = poke (rPage); - if (eErrCode != store_E_None) - { - releaseLock (0, SuperPage::size()); - return eErrCode; - } - - // Save SuperBlock page. - m_pSuper->m_aSuperTwo.unusedRemove (aListHead); - m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo; - - eErrCode = m_pSuper->save (*this); - OSL_POSTCOND( - eErrCode == store_E_None, - "OStorePageBIOS::allocate(): SuperBlock save failed"); - - // Release SuperBlock Lock and finish. - return releaseLock (0, SuperPage::size()); - } - } - - // Allocate from logical EOF. Determine physical EOF. - sal_uInt32 nAddr = STORE_PAGE_NULL; - eErrCode = m_xLockBytes->stat (nAddr); - if (eErrCode != store_E_None) - { - releaseLock (0, SuperPage::size()); - return eErrCode; - } - - // Obtain logical EOF. - OStorePageDescriptor aDescr (m_pSuper->m_aSuperTwo.m_aDescr); - if (aDescr.m_nAddr == 0) - aDescr.m_nAddr = nAddr; /* backward compatibility */ - - if (!(aDescr.m_nAddr < nAddr)) - { - // Check modified state. - if (!m_bModified) - { - // Mark modified. - m_bModified = sal_True; - - // Mark SuperBlock modified. - eErrCode = m_pSuper->modified (*this); - if (eErrCode != store_E_None) - { - releaseLock (0, SuperPage::size()); - return eErrCode; - } - } - - // Resize. - sal_uInt32 nAlign = STORE_MAXIMUM_PAGESIZE; - - nAlign = std::min (nAddr, nAlign); - nAddr = ((nAddr + nAlign) / nAlign) * nAlign; - - eErrCode = m_xLockBytes->setSize (nAddr); - if (eErrCode != store_E_None) - { - releaseLock (0, SuperPage::size()); - return eErrCode; - } - } - - // Save page. - rPage.location (aDescr.m_nAddr); - eErrCode = poke (rPage); - if (eErrCode != store_E_None) - { - releaseLock (0, SuperPage::size()); - return eErrCode; - } - - // Save SuperBlock page. - aDescr.m_nAddr += aDescr.m_nSize; - - m_pSuper->m_aSuperTwo.m_aDescr = aDescr; - m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo; - - eErrCode = m_pSuper->save (*this); - OSL_POSTCOND( - eErrCode == store_E_None, - "OStorePageBIOS::allocate(): SuperBlock save failed"); - - // Release SuperBlock Lock and finish. - return releaseLock (0, SuperPage::size()); -} - -/* - * free. - * Precond: initialized, writeable. - */ -storeError OStorePageBIOS::free (OStorePageObject& rPage) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - if (!m_bWriteable) - return store_E_AccessViolation; - - // Acquire SuperBlock Lock. - storeError eErrCode = acquireLock (0, SuperPage::size()); - if (eErrCode != store_E_None) - return eErrCode; - - // Load SuperBlock and require good health. - eErrCode = verify (m_pSuper); - if (eErrCode != store_E_None) - { - releaseLock (0, SuperPage::size()); - return eErrCode; - } - - // Load PageHead. - OStorePageData &rData = rPage.getData(); - - eErrCode = peek (rData); - if (eErrCode != store_E_None) - { - releaseLock (0, SuperPage::size()); - return eErrCode; - } - - // Push onto FreeList. - OStorePageLink aListHead (m_pSuper->m_aSuperTwo.unusedHead()); - - rData.m_aUnused.m_nAddr = aListHead.m_nAddr; - aListHead.m_nAddr = rData.m_aDescr.m_nAddr; - - // Save PageHead. - eErrCode = poke (rData); - if (eErrCode != store_E_None) - { - releaseLock (0, SuperPage::size()); - return eErrCode; - } - - // Save SuperBlock page. - m_pSuper->m_aSuperTwo.unusedInsert (aListHead); - m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo; - - eErrCode = m_pSuper->save (*this); - OSL_POSTCOND( - eErrCode == store_E_None, - "OStorePageBIOS::free(): SuperBlock save failed"); - - // Release SuperBlock Lock and finish. - return releaseLock (0, SuperPage::size()); -} - -/* - * load. - * Precond: initialized, readable. - */ -storeError OStorePageBIOS::load (OStorePageObject& rPage) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - - // Save PageDescriptor. - OStorePageData &rData = rPage.getData(); - OStorePageDescriptor aDescr (rData.m_aDescr); - - // Read page. - storeError eErrCode = read (aDescr.m_nAddr, &rData, aDescr.m_nSize); - if (eErrCode != store_E_None) - { - // Restore PageDescriptor. - rData.m_aDescr = aDescr; - return eErrCode; - } - - // Verify page. - eErrCode = rPage.verify (aDescr); - if (eErrCode != store_E_None) - { - // Restore PageDescriptor. - rData.m_aDescr = aDescr; - return eErrCode; - } - -#ifdef OSL_BIGENDIAN - // Swap to internal representation. - rPage.swap (aDescr); -#endif /* OSL_BIGENDIAN */ - - // Verify PageDescriptor. - if (!((aDescr == rData.m_aDescr) || - (aDescr <= rData.m_aDescr) )) - return store_E_InvalidAccess; - - // Mark page as clean. - rPage.clean(); - - // Done. - return store_E_None; -} - -/* - * save. - * Precond: initialized, writeable. - */ -storeError OStorePageBIOS::save (OStorePageObject& rPage) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - if (!m_bWriteable) - return store_E_AccessViolation; - - // Save Page. - return poke (rPage); -} - -/* - * close. - * Precond: none. - */ -storeError OStorePageBIOS::close (void) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - // Check access control list. - if (m_pAcl) - { - // Check referer count. - if (m_pAcl->m_nRefCount) - { - // Report remaining referer count. - sal_uInt32 k = m_pAcl->m_nRefCount; - OSL_TRACE("OStorePageBIOS::close(): referer count: %d\n", k); - } - __STORE_DELETEZ (m_pAcl); - } - - // Check SuperBlock page. - storeError eErrCode = store_E_None; - if (m_pSuper) - { - // Release SuperBlock page. - eErrCode = m_pSuper->close (*this); - __STORE_DELETEZ (m_pSuper); - } - - // Check LockBytes. - if (m_xLockBytes.is()) - { -#ifdef STORE_FEATURE_COMMIT - // Commit. - storeError result = m_xLockBytes->flush(); - if (eErrCode == store_E_None) - { - // Previous result(s) okay. Propagate next result. - eErrCode = result; - } -#endif /* STORE_FEATURE_COMMIT */ - - // Release LockBytes. - m_xLockBytes.clear(); - } - - // Done. - return eErrCode; -} - -/* - * flush. - * Precond: initialized. - */ -storeError OStorePageBIOS::flush (void) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - - // Check mode and state. - storeError eErrCode = store_E_None; - if (!(m_bWriteable && m_bModified)) - return eErrCode; - - // Flush SuperBlock page. - eErrCode = m_pSuper->flush (*this); - - // Flush LockBytes. - storeError result = m_xLockBytes->flush(); - if (eErrCode == store_E_None) - { - // Previous result(s) okay. Propagate next result. - eErrCode = result; - } - - // Adjust modified state. - m_bModified = (eErrCode != store_E_None); - - // Done. - return eErrCode; -} - -/* - * size. - * Precond: initialized. - */ -storeError OStorePageBIOS::size (sal_uInt32 &rnSize) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - // Initialize [out] param. - rnSize = 0; - - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - - // Obtain LockBytes size. - return m_xLockBytes->stat (rnSize); -} - -/* - * scanBegin. - * Precond: initialized. - */ -storeError OStorePageBIOS::scanBegin ( - ScanContext &rCtx, sal_uInt32 nMagic) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - // Initialize [out] param. - rCtx.m_aDescr = OStorePageDescriptor(0, 0, 0); - rCtx.m_nSize = 0; - rCtx.m_nMagic = nMagic; - - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - - // Check SuperBlock page. - storeError eErrCode = verify (m_pSuper); - if (eErrCode != store_E_None) - { - // Damaged. Determine page size (NYI). - OSL_TRACE ("OStorePageBIOS::scanBegin(): damaged.\n"); - return eErrCode; - } - - // Setup Context descriptor. - rCtx.m_aDescr = m_pSuper->m_aSuperOne.m_aDescr; - rCtx.m_aDescr.m_nAddr = rCtx.m_aDescr.m_nSize; - - // Setup Context size. - eErrCode = size (rCtx.m_nSize); - if (eErrCode != store_E_None) - rCtx.m_nSize = ((sal_uInt32)(~0)); - - // Done. - return store_E_None; -} - -/* - * scanNext. - * Precond: initialized. - */ -storeError OStorePageBIOS::scanNext ( - ScanContext &rCtx, OStorePageObject &rPage) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard (m_aMutex); - - // Check precond. - if (!m_xLockBytes.is()) - return store_E_InvalidAccess; - - // Setup PageHead. - OStorePageData aPageHead (OStorePageData::size()); - - // Check context. - while (rCtx.isValid()) - { - // Assign next location. - aPageHead.location (rCtx.m_aDescr.m_nAddr); - rCtx.m_aDescr.m_nAddr += rCtx.m_aDescr.m_nSize; - - // Load PageHead. - storeError eErrCode = peek (aPageHead); - if (eErrCode != store_E_None) - continue; - - // Check PageHead Magic number. - if (aPageHead.m_aGuard.m_nMagic != rCtx.m_nMagic) - continue; - - // Check PageHead Unused link. - if (aPageHead.m_aUnused.m_nAddr != STORE_PAGE_NULL) - continue; - - // Load page. - rPage.location (aPageHead.location()); - eErrCode = OStorePageBIOS::load (rPage); - if (eErrCode != store_E_None) - continue; - - // Deliver page. - return store_E_None; - } - - // Done. - return store_E_CantSeek; -} - -/* - * peek (PageHead). - * Internal: Precond: initialized, readable, exclusive access. - */ -storeError OStorePageBIOS::peek (OStorePageData &rData) -{ - // Save PageDescriptor. - OStorePageDescriptor aDescr (rData.m_aDescr); - - // Read PageHead. - storeError eErrCode = read (aDescr.m_nAddr, &rData, rData.size()); - if (eErrCode != store_E_None) - { - // Restore PageDescriptor. - rData.m_aDescr = aDescr; - return eErrCode; - } - - // Verify PageHead. - eErrCode = rData.verify (); - if (eErrCode != store_E_None) - { - // Restore PageDescriptor. - rData.m_aDescr = aDescr; - return eErrCode; - } - -#ifdef OSL_BIGENDIAN - // Swap to internal representation. - rData.swap (); -#endif /* OSL_BIGENDIAN */ - - // Verify PageDescriptor. - if (!((aDescr == rData.m_aDescr) || - (aDescr <= rData.m_aDescr) )) - return store_E_InvalidAccess; - else - return store_E_None; -} - -/* - * poke (PageHead). - * Internal: Precond: initialized, writeable, exclusive access. - */ -storeError OStorePageBIOS::poke (OStorePageData &rData) -{ - // Save PageDescriptor. - OStorePageDescriptor aDescr (rData.m_aDescr); - -#ifdef OSL_BIGENDIAN - // Swap to external representation. - rData.swap (); -#endif /* OSL_BIGENDIAN */ - - // Guard PageHead. - rData.guard (); - - // Write PageHead. - storeError eErrCode = write (aDescr.m_nAddr, &rData, rData.size()); - -#ifdef OSL_BIGENDIAN - // Swap back to internal representation. - rData.swap (); -#endif /* OSL_BIGENDIAN */ - - // Done. - return eErrCode; -} - -/* - * poke (PageObject). - * Internal: Precond: initialized, writeable, exclusive access. + * ~OStorePageObject. */ -storeError OStorePageBIOS::poke (OStorePageObject &rPage) +OStorePageObject::~OStorePageObject (void) { - // Save PageDescriptor. - OStorePageData &rData = rPage.getData(); - OStorePageDescriptor aDescr (rData.m_aDescr); - -#ifdef OSL_BIGENDIAN - // Swap to external representation. - rPage.swap (aDescr); -#endif /* OSL_BIGENDIAN */ - - // Guard page. - rPage.guard (aDescr); - - // Write page. - storeError eErrCode = write (aDescr.m_nAddr, &rData, aDescr.m_nSize); - -#ifdef OSL_BIGENDIAN - // Swap back to internal representation. - rPage.swap (aDescr); -#endif /* OSL_BIGENDIAN */ - - // Mark page as clean. - if (eErrCode == store_E_None) - rPage.clean(); - - // Done. - return eErrCode; } - diff --git a/store/source/storbase.hxx b/store/source/storbase.hxx index 325d1a097590..167302d7bedd 100644 --- a/store/source/storbase.hxx +++ b/store/source/storbase.hxx @@ -29,26 +29,27 @@ ************************************************************************/ #ifndef _STORE_STORBASE_HXX_ -#define _STORE_STORBASE_HXX_ "$Revision: 1.10 $" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef INCLUDED_CSTDDEF -#include -#define INCLUDED_CSTDDEF +#define _STORE_STORBASE_HXX_ "$Revision: 1.10.8.4 $" + +#include "sal/types.h" + +#include "rtl/alloc.h" +#include "rtl/crc.h" +#include "rtl/ref.hxx" + +#include "osl/diagnose.h" +#include "osl/endian.h" + +#include "store/types.h" + +#ifndef INCLUDED_STDDEF_H +#include +#define INCLUDED_STDDEF_H #endif -#ifndef INCLUDED_CSTRING -#include -#define INCLUDED_CSTRING +#ifndef INCLUDED_STRING_H +#include +#define INCLUDED_STRING_H #endif /*======================================================================== @@ -56,43 +57,139 @@ * store common internals. * *======================================================================*/ -/* MSVC 6.0 still has std functions in global namespace */ -#if defined(_MSC_VER) && (_MSC_VER <= 1310) -#define __STORE_CSTD -#else -#define __STORE_CSTD std -#endif /* _MSC_VER */ -#ifndef __STORE_DELETEZ -#define __STORE_DELETEZ(p) (delete p, p = 0) +#ifndef STORE_IMPL_ISP2 +#define STORE_IMPL_ISP2(value) (((value) & ((value) - 1)) == 0) #endif -/* - * __store_memcpy. - */ -inline void __store_memcpy (void * dst, const void * src, sal_Size n) +#ifndef STORE_IMPL_CONCAT +#define STORE_IMPL_CONCAT(x, y) STORE_IMPL_CONCAT2(x,y) +#define STORE_IMPL_CONCAT2(x, y) x##y +#endif + +#ifndef STORE_STATIC_ASSERT /* Compile time assertion */ +namespace store { - __STORE_CSTD::memcpy (dst, src, n); -} + template< bool x > struct STATIC_ASSERTION_FAILURE; + template<> struct STATIC_ASSERTION_FAILURE< true > { enum { value = 1 }; }; -/* - * __store_memmove. - */ -inline void __store_memmove (void * dst, const void * src, sal_Size n) + template< int x > struct static_assert_test{}; +} // namespace store + +#define STORE_STATIC_ASSERT(pred) \ +typedef \ +store::static_assert_test< sizeof( store::STATIC_ASSERTION_FAILURE< (bool)(pred) > ) > \ +STORE_IMPL_CONCAT(static_assert_typedef_, __LINE__) + +#endif /* !STORE_STATIC_ASSERT */ + +namespace store { - __STORE_CSTD::memmove (dst, src, n); -} -/* - * __store_memset. +#ifdef htons +#undef htons +#endif +#ifdef ntohs +#undef ntohs +#endif + +#ifdef htonl +#undef htonl +#endif +#ifdef ntohl +#undef ntohl +#endif + +#ifdef OSL_BIGENDIAN +inline sal_uInt16 htons (sal_uInt16 h) { return OSL_SWAPWORD(h); } +inline sal_uInt16 ntohs (sal_uInt16 n) { return OSL_SWAPWORD(n); } + +inline sal_uInt32 htonl (sal_uInt32 h) { return OSL_SWAPDWORD(h); } +inline sal_uInt32 ntohl (sal_uInt32 n) { return OSL_SWAPDWORD(n); } +#else +inline sal_uInt16 htons (sal_uInt16 h) { return (h); } +inline sal_uInt16 ntohs (sal_uInt16 n) { return (n); } + +inline sal_uInt32 htonl (sal_uInt32 h) { return (h); } +inline sal_uInt32 ntohl (sal_uInt32 n) { return (n); } +#endif /* OSL_BIGENDIAN */ + +/** swap. */ -inline void __store_memset (void * dst, int val, sal_Size n) +template< typename T > void swap (T & lhs, T & rhs) { - __STORE_CSTD::memset (dst, val, n); + T tmp = lhs; lhs = rhs; rhs = tmp; } -namespace store +/*======================================================================== + * + * SharedCount. + * + *======================================================================*/ +class SharedCount { + long * m_pCount; + + class Allocator + { + rtl_cache_type * m_cache; + + public: + static Allocator & get(); + + long * alloc() + { + return static_cast(rtl_cache_alloc (m_cache)); + } + void free (long * pCount) + { + rtl_cache_free (m_cache, pCount); + } + + protected: + Allocator(); + ~Allocator(); + }; + +public: + SharedCount() + : m_pCount(Allocator::get().alloc()) + { + if (m_pCount != 0) (*m_pCount) = 1; + } + + ~SharedCount() + { + if (m_pCount != 0) + { + long new_count = --(*m_pCount); + if (new_count == 0) + Allocator::get().free(m_pCount); + } + } + + void swap (SharedCount & rhs) // nothrow + { + store::swap(m_pCount, rhs.m_pCount); + } + + SharedCount (SharedCount const & rhs) // nothrow + : m_pCount (rhs.m_pCount) + { + if (m_pCount != 0) ++(*m_pCount); + } + SharedCount & operator= (SharedCount const & rhs) // nothrow + { + SharedCount tmp(rhs); + swap(tmp); + return *this; + } + + bool operator== (long count) const + { + return (m_pCount != 0) ? *m_pCount == count : false; + } +}; /*======================================================================== * @@ -108,52 +205,36 @@ struct OStorePageGuard /** Construction. */ - OStorePageGuard (sal_uInt32 nMagic = 0, sal_uInt32 nCRC32 = 0) - : m_nMagic (nMagic), - m_nCRC32 (nCRC32) + explicit OStorePageGuard (sal_uInt32 nMagic = 0, sal_uInt32 nCRC32 = 0) + : m_nMagic (store::htonl(nMagic)), + m_nCRC32 (store::htonl(nCRC32)) {} - OStorePageGuard (const OStorePageGuard& rOther) - : m_nMagic (rOther.m_nMagic), - m_nCRC32 (rOther.m_nCRC32) - {} - - OStorePageGuard& operator= (const OStorePageGuard& rOther) + void swap (OStorePageGuard & rhs) { - m_nMagic = rOther.m_nMagic; - m_nCRC32 = rOther.m_nCRC32; - return *this; + store::swap(m_nMagic, rhs.m_nMagic); + store::swap(m_nCRC32, rhs.m_nCRC32); } - /** Comparison. - */ - sal_Bool operator== (const OStorePageGuard& rOther) const - { - return ((m_nMagic == rOther.m_nMagic) && - (m_nCRC32 == rOther.m_nCRC32) ); - } + OStorePageGuard (OStorePageGuard const & rhs) + : m_nMagic (rhs.m_nMagic), + m_nCRC32 (rhs.m_nCRC32) + {} - /** swap (internal and external representation). - */ - void swap (void) + OStorePageGuard& operator= (const OStorePageGuard& rhs) { -#ifdef OSL_BIGENDIAN - m_nMagic = OSL_SWAPDWORD(m_nMagic); - m_nCRC32 = OSL_SWAPDWORD(m_nCRC32); -#endif /* OSL_BIGENDIAN */ + m_nMagic = rhs.m_nMagic; + m_nCRC32 = rhs.m_nCRC32; + return *this; } - /** CRC polynomial 0xEDB88320. + /** Comparison. */ - static const sal_uInt32 m_pTable[256]; - - static sal_uInt32 updcrc32 (sal_uInt32 crc, sal_uInt8 octet) + bool operator== (const OStorePageGuard& rhs) const { - return m_pTable[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8); + return ((m_nMagic == rhs.m_nMagic) && + (m_nCRC32 == rhs.m_nCRC32) ); } - - static sal_uInt32 crc32 ( - sal_uInt32 nCRC32, const void *pData, sal_Size nSize); }; /*======================================================================== @@ -173,60 +254,56 @@ struct OStorePageDescriptor /** Construction. */ - OStorePageDescriptor ( + explicit OStorePageDescriptor ( sal_uInt32 nAddr = STORE_PAGE_NULL, sal_uInt16 nSize = 0, sal_uInt16 nUsed = 0) - : m_nAddr (nAddr), - m_nSize (nSize), - m_nUsed (nUsed) + : m_nAddr (store::htonl(nAddr)), + m_nSize (store::htons(nSize)), + m_nUsed (store::htons(nUsed)) {} - OStorePageDescriptor (const OStorePageDescriptor& rOther) - : m_nAddr (rOther.m_nAddr), - m_nSize (rOther.m_nSize), - m_nUsed (rOther.m_nUsed) + void swap (OStorePageDescriptor & rhs) + { + store::swap(m_nAddr, rhs.m_nAddr); + store::swap(m_nSize, rhs.m_nSize); + store::swap(m_nUsed, rhs.m_nUsed); + } + + OStorePageDescriptor (const OStorePageDescriptor & rhs) + : m_nAddr (rhs.m_nAddr), + m_nSize (rhs.m_nSize), + m_nUsed (rhs.m_nUsed) {} - OStorePageDescriptor& operator= (const OStorePageDescriptor& rOther) + OStorePageDescriptor & operator= (const OStorePageDescriptor & rhs) { - m_nAddr = rOther.m_nAddr; - m_nSize = rOther.m_nSize; - m_nUsed = rOther.m_nUsed; + m_nAddr = rhs.m_nAddr; + m_nSize = rhs.m_nSize; + m_nUsed = rhs.m_nUsed; return *this; } /** Comparison. */ - sal_Bool operator== (const OStorePageDescriptor& rOther) const + bool operator== (const OStorePageDescriptor & rhs) const { - return ((m_nAddr == rOther.m_nAddr) && - (m_nSize == rOther.m_nSize) ); + return ((m_nAddr == rhs.m_nAddr) && + (m_nSize == rhs.m_nSize) ); } - sal_Bool operator<= (const OStorePageDescriptor& rOther) const + bool operator<= (const OStorePageDescriptor & rhs) const { - return ((m_nAddr == rOther.m_nAddr) && - (m_nSize <= rOther.m_nSize) ); + return ((m_nAddr == rhs.m_nAddr ) && + (store::ntohs(m_nSize) <= store::ntohs(rhs.m_nSize)) ); } - sal_Bool operator< (const OStorePageDescriptor& rOther) const + bool operator< (const OStorePageDescriptor & rhs) const { - if (m_nAddr == rOther.m_nAddr) - return (m_nSize < rOther.m_nSize); + if (m_nAddr == rhs.m_nAddr) + return (store::ntohs(m_nSize) < store::ntohs(rhs.m_nSize)); else - return (m_nAddr < rOther.m_nAddr); - } - - /** swap (internal and external representation). - */ - void swap (void) - { -#ifdef OSL_BIGENDIAN - m_nAddr = OSL_SWAPDWORD(m_nAddr); - m_nSize = OSL_SWAPWORD(m_nSize); - m_nUsed = OSL_SWAPWORD(m_nUsed); -#endif /* OSL_BIGENDIAN */ + return (store::ntohl(m_nAddr) < store::ntohl(rhs.m_nAddr)); } }; @@ -244,45 +321,42 @@ struct OStorePageKey /** Construction. */ - OStorePageKey (sal_uInt32 nLow = 0, sal_uInt32 nHigh = 0) - : m_nLow (nLow), m_nHigh (nHigh) + explicit OStorePageKey (sal_uInt32 nLow = 0, sal_uInt32 nHigh = 0) + : m_nLow (store::htonl(nLow)), + m_nHigh (store::htonl(nHigh)) {} - OStorePageKey (const OStorePageKey& rOther) - : m_nLow (rOther.m_nLow), m_nHigh (rOther.m_nHigh) + void swap (OStorePageKey & rhs) + { + store::swap(m_nLow, rhs.m_nLow); + store::swap(m_nHigh, rhs.m_nHigh); + } + + OStorePageKey (const OStorePageKey & rhs) + : m_nLow (rhs.m_nLow), m_nHigh (rhs.m_nHigh) {} - OStorePageKey& operator= (const OStorePageKey& rOther) + OStorePageKey & operator= (const OStorePageKey & rhs) { - m_nLow = rOther.m_nLow; - m_nHigh = rOther.m_nHigh; + m_nLow = rhs.m_nLow; + m_nHigh = rhs.m_nHigh; return *this; } /** Comparison. */ - sal_Bool operator== (const OStorePageKey& rOther) const + bool operator== (const OStorePageKey & rhs) const { - return ((m_nLow == rOther.m_nLow ) && - (m_nHigh == rOther.m_nHigh) ); + return ((m_nLow == rhs.m_nLow ) && + (m_nHigh == rhs.m_nHigh) ); } - sal_Bool operator< (const OStorePageKey& rOther) const + bool operator< (const OStorePageKey & rhs) const { - if (m_nHigh == rOther.m_nHigh) - return (m_nLow < rOther.m_nLow); + if (m_nHigh == rhs.m_nHigh) + return (store::ntohl(m_nLow) < store::ntohl(rhs.m_nLow)); else - return (m_nHigh < rOther.m_nHigh); - } - - /** swap (internal and external representation). - */ - void swap (void) - { -#ifdef OSL_BIGENDIAN - m_nLow = OSL_SWAPDWORD(m_nLow); - m_nHigh = OSL_SWAPDWORD(m_nHigh); -#endif /* OSL_BIGENDIAN */ + return (store::ntohl(m_nHigh) < store::ntohl(rhs.m_nHigh)); } }; @@ -299,36 +373,53 @@ struct OStorePageLink /** Construction. */ - OStorePageLink (sal_uInt32 nAddr = STORE_PAGE_NULL) - : m_nAddr (nAddr) + explicit OStorePageLink (sal_uInt32 nAddr = STORE_PAGE_NULL) + : m_nAddr (store::htonl(nAddr)) {} - OStorePageLink (const OStorePageLink& rOther) - : m_nAddr (rOther.m_nAddr) + void swap (OStorePageLink & rhs) + { + store::swap(m_nAddr, rhs.m_nAddr); + } + + OStorePageLink (const OStorePageLink & rhs) + : m_nAddr (rhs.m_nAddr) {} - OStorePageLink& operator= (const OStorePageLink& rOther) + OStorePageLink & operator= (const OStorePageLink & rhs) { - m_nAddr = rOther.m_nAddr; + m_nAddr = rhs.m_nAddr; + return *this; + } + + OStorePageLink & operator= (sal_uInt32 nAddr) + { + m_nAddr = store::htonl(nAddr); return *this; } /** Comparison. */ - sal_Bool operator== (const OStorePageLink& rOther) const + bool operator== (const OStorePageLink & rhs) const { - return (m_nAddr == rOther.m_nAddr); + return (m_nAddr == rhs.m_nAddr); } - sal_Bool operator< (const OStorePageLink& rOther) const + bool operator< (const OStorePageLink& rhs) const { - return (m_nAddr < rOther.m_nAddr); + return (store::ntohl(m_nAddr) < store::ntohl(rhs.m_nAddr)); } /** Operation. */ - void link (OStorePageLink& rPred) + sal_uInt32 location() const + { + return store::ntohl(m_nAddr); + } + + void link (OStorePageLink & rPred) { + // @@@ swap (rPred); @@@ OStorePageLink tmp (rPred); rPred = *this; *this = tmp; @@ -339,568 +430,537 @@ struct OStorePageLink rPred = *this; *this = OStorePageLink(); } - - /** swap (internal and external representation). - */ - void swap (void) - { -#ifdef OSL_BIGENDIAN - m_nAddr = OSL_SWAPDWORD(m_nAddr); -#endif /* OSL_BIGENDIAN */ - } }; /*======================================================================== * - * OStorePageNameBlock. + * PageData. * *======================================================================*/ -struct OStorePageNameBlock +typedef struct PageData OStorePageData; // backward compat. +struct PageData { - typedef OStorePageGuard G; - typedef OStorePageKey K; + typedef OStorePageGuard G; + typedef OStorePageDescriptor D; + typedef OStorePageLink L; /** Representation. - */ - G m_aGuard; - K m_aKey; - sal_uInt32 m_nAttrib; - sal_Char m_pData[STORE_MAXIMUM_NAMESIZE]; + */ + G m_aGuard; + D m_aDescr; + L m_aMarked; + L m_aUnused; - /** size. - */ - static sal_uInt16 size (void) + /** theSize. + */ + static const size_t theSize = sizeof(G) + sizeof(D) + 2 * sizeof(L); + static const sal_uInt16 thePageSize = theSize; + STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= thePageSize); + + /** location. + */ + sal_uInt32 location() const + { + return store::ntohl(m_aDescr.m_nAddr); + } + void location (sal_uInt32 nAddr) { - return sal_uInt16(sizeof(G) + sizeof(K) + sizeof(sal_uInt32) + - sizeof(sal_Char[STORE_MAXIMUM_NAMESIZE])); + m_aDescr.m_nAddr = store::htonl(nAddr); } - /** initialize. - */ - void initialize (void) + /** size. + */ + sal_uInt16 size() const { - m_aGuard = G(); - m_aKey = K(); - m_nAttrib = 0; - __store_memset (m_pData, 0, sizeof(m_pData)); + return store::ntohs(m_aDescr.m_nSize); } - /** Construction. - */ - OStorePageNameBlock (void) - : m_nAttrib (0) + /** type. + */ + sal_uInt32 type() const { - __store_memset (m_pData, 0, sizeof(m_pData)); + return store::ntohl(m_aGuard.m_nMagic); } - /** Comparison. - */ - sal_Bool operator== (const OStorePageNameBlock& rOther) const + /** Allocation. + */ + class Allocator_Impl; + class Allocator : public rtl::IReference + { + public: + template< class T > T * construct() + { + void * page = 0; sal_uInt16 size = 0; + if (allocate (&page, &size)) + { + return new(page) T(size); + } + return 0; + } + + bool allocate (void ** ppPage, sal_uInt16 * pnSize) + { + allocate_Impl (ppPage, pnSize); + return ((*ppPage != 0) && (*pnSize != 0)); + } + + void deallocate (void * pPage) + { + if (pPage != 0) + deallocate_Impl (pPage); + } + + static storeError createInstance ( + rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize); + + private: + /** Implementation (abstract). + */ + virtual void allocate_Impl (void ** ppPage, sal_uInt16 * pnSize) = 0; + virtual void deallocate_Impl (void * pPage) = 0; + }; + + static void* operator new (size_t, void * p) { return p; } + static void operator delete (void * , void *) {} + + /** Construction. + */ + explicit PageData (sal_uInt16 nPageSize = thePageSize) + : m_aGuard(), + m_aDescr(STORE_PAGE_NULL, nPageSize, thePageSize), + m_aMarked(), + m_aUnused() + {} + + void swap (PageData & rhs) // nothrow { - return (m_aGuard == rOther.m_aGuard); + m_aGuard.swap(rhs.m_aGuard); + m_aDescr.swap(rhs.m_aDescr); + m_aMarked.swap(rhs.m_aMarked); + m_aUnused.swap(rhs.m_aUnused); } - /** swap (internal and external representation). - */ - void swap (void) + PageData (PageData const & rhs) // nothrow + : m_aGuard (rhs.m_aGuard), + m_aDescr (rhs.m_aDescr), + m_aMarked(rhs.m_aMarked), + m_aUnused(rhs.m_aUnused) + {} + + PageData & operator= (PageData const & rhs) // nothrow { -#ifdef OSL_BIGENDIAN - m_aGuard.swap(); - m_aKey.swap(); - m_nAttrib = OSL_SWAPDWORD(m_nAttrib); -#endif /* OSL_BIGENDIAN */ + PageData tmp (rhs); + swap (tmp); + return *this; } /** guard (external representation). - */ - void guard (void) + */ + void guard() { sal_uInt32 nCRC32 = 0; - nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); - nCRC32 = G::crc32 (nCRC32, &m_aKey, size() - sizeof(G)); -#ifdef OSL_BIGENDIAN - nCRC32 = OSL_SWAPDWORD(nCRC32); -#endif /* OSL_BIGENDIAN */ - m_aGuard.m_nCRC32 = nCRC32; + nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); + nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G)); + m_aGuard.m_nCRC32 = store::htonl(nCRC32); + } + void guard (sal_uInt32 nAddr) + { + sal_uInt32 nCRC32 = 0; + nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); + m_aDescr.m_nAddr = store::htonl(nAddr); + nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G)); + m_aGuard.m_nCRC32 = store::htonl(nCRC32); } /** verify (external representation). - */ - storeError verify (void) + */ + storeError verify() const { sal_uInt32 nCRC32 = 0; - nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); - nCRC32 = G::crc32 (nCRC32, &m_aKey, size() - sizeof(G)); -#ifdef OSL_BIGENDIAN - nCRC32 = OSL_SWAPDWORD(nCRC32); -#endif /* OSL_BIGENDIAN */ - if (m_aGuard.m_nCRC32 != nCRC32) + nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); + nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G)); + if (m_aGuard.m_nCRC32 != store::htonl(nCRC32)) return store_E_InvalidChecksum; else return store_E_None; } - - /** namei. - */ - static storeError namei ( - const rtl_String *pPath, const rtl_String *pName, K &rKey) + storeError verify (sal_uInt32 nAddr) const { - // Check parameter. - if (!(pPath && pName)) - return store_E_InvalidParameter; - - // Check name length. - if (!(pName->length < STORE_MAXIMUM_NAMESIZE)) - return store_E_NameTooLong; - - // Transform pathname into key. - rKey.m_nLow = G::crc32 (0, pName->buffer, pName->length); - rKey.m_nHigh = G::crc32 (0, pPath->buffer, pPath->length); - - // Done. + sal_uInt32 nCRC32 = 0; + nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); + nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G)); + if (m_aGuard.m_nCRC32 != store::htonl(nCRC32)) + return store_E_InvalidChecksum; + if (m_aDescr.m_nAddr != store::htonl(nAddr)) + return store_E_InvalidAccess; return store_E_None; } + + storeError verifyVersion (sal_uInt32 nMagic) const + { + if (m_aGuard.m_nMagic != store::htonl(nMagic)) + return store_E_WrongVersion; + else + return store_E_None; + } }; /*======================================================================== * - * OStorePageData. + * PageHolder. * *======================================================================*/ -struct OStorePageData +class PageHolder { - typedef OStorePageGuard G; - typedef OStorePageDescriptor D; - typedef OStorePageLink L; + SharedCount m_refcount; + PageData * m_pagedata; - /** Representation. - */ - G m_aGuard; - D m_aDescr; - L m_aMarked; - L m_aUnused; + typedef rtl::Reference< PageData::Allocator > allocator_type; + allocator_type m_allocator; - /** size. - */ - static sal_uInt16 size (void) +public: + explicit PageHolder (PageData * pagedata = 0, allocator_type const & allocator = allocator_type()) + : m_refcount (), + m_pagedata (pagedata), + m_allocator(allocator) { - return sal_uInt16(sizeof(G) + sizeof(D) + 2 * sizeof(L)); + OSL_ENSURE((m_pagedata == 0) || m_allocator.is(), "store::PageHolder::ctor(): pagedata w/o allocator."); } - /** location. - */ - sal_uInt32 location (void) const + ~PageHolder() { - return m_aDescr.m_nAddr; + if ((m_refcount == 1) && (m_pagedata != 0)) + { + // free pagedata. + OSL_ENSURE(m_allocator.is(), "store::PageHolder::dtor(): pagedata w/o allocator."); + m_allocator->deallocate (m_pagedata); + } } - void location (sal_uInt32 nAddr) + void swap (PageHolder & rhs) // nothrow { - m_aDescr.m_nAddr = nAddr; + m_refcount.swap(rhs.m_refcount); + store::swap(m_pagedata, rhs.m_pagedata); + store::swap(m_allocator, rhs.m_allocator); } - /** Allocation. - */ - static void* operator new (size_t n) - { - return rtl_allocateMemory (n); - } + PageHolder (PageHolder const & rhs) // nothrow + : m_refcount (rhs.m_refcount), + m_pagedata (rhs.m_pagedata), + m_allocator(rhs.m_allocator) + {} - static void* operator new (size_t, sal_uInt16 nPageSize) + PageHolder & operator= (PageHolder const & rhs) // nothrow { - return rtl_allocateMemory (nPageSize); + PageHolder tmp (rhs); + swap(tmp); + return *this; } - static void operator delete (void *p) + PageData * get() { return m_pagedata; } + PageData const * get() const { return m_pagedata; } + + PageData * operator->() { - rtl_freeMemory (p); + OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator->(): Null pointer"); + return m_pagedata; } - - static void operator delete (void *p, sal_uInt16) + PageData const * operator->() const { - rtl_freeMemory (p); + OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator->(): Null pointer"); + return m_pagedata; } - /** Construction. - */ - OStorePageData (sal_uInt16 nPageSize) + PageData & operator*() { - m_aDescr.m_nSize = nPageSize; - m_aDescr.m_nUsed = size(); + OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator*(): Null pointer"); + return *m_pagedata; } - - OStorePageData& operator= (const OStorePageData& rOther) + PageData const & operator*() const { - m_aGuard = rOther.m_aGuard; - m_aDescr = rOther.m_aDescr; - m_aMarked = rOther.m_aMarked; - m_aUnused = rOther.m_aUnused; - return *this; + OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator*(): Null pointer"); + return *m_pagedata; } +}; - /** Comparison. +/*======================================================================== + * + * PageHolderObject. + * + *======================================================================*/ +template< class T > +class PageHolderObject +{ + /** Representation. */ - sal_Bool operator== (const OStorePageData& rOther) const - { - return ((m_aGuard == rOther.m_aGuard ) && - (m_aDescr == rOther.m_aDescr ) && - (m_aMarked == rOther.m_aMarked) && - (m_aUnused == rOther.m_aUnused) ); - } + PageHolder m_xPage; - /** swap (internal and external representation). + /** Checked cast. */ - void swap () + template< class U > + static bool isA (PageData const * p) { -#ifdef OSL_BIGENDIAN - m_aGuard.swap(); - m_aDescr.swap(); - m_aMarked.swap(); - m_aUnused.swap(); -#endif /* OSL_BIGENDIAN */ + return ((p != 0) && (p->type() == U::theTypeId)); } - /** guard (external representation). - */ - void guard () + template< class U > + static U * dynamic_page_cast (PageData * p) { - sal_uInt32 nCRC32 = 0; - nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); - nCRC32 = G::crc32 (nCRC32, &m_aDescr, size() - sizeof(G)); -#ifdef OSL_BIGENDIAN - nCRC32 = OSL_SWAPDWORD(nCRC32); -#endif /* OSL_BIGENDIAN */ - m_aGuard.m_nCRC32 = nCRC32; + return isA(p) ? static_cast(p) : 0; } - /** verify (external representation). - */ - storeError verify () + template< class U > + static U const * dynamic_page_cast (PageData const * p) { - sal_uInt32 nCRC32 = 0; - nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); - nCRC32 = G::crc32 (nCRC32, &m_aDescr, size() - sizeof(G)); -#ifdef OSL_BIGENDIAN - nCRC32 = OSL_SWAPDWORD(nCRC32); -#endif /* OSL_BIGENDIAN */ - if (m_aGuard.m_nCRC32 != nCRC32) - return store_E_InvalidChecksum; - else - return store_E_None; + return isA(p) ? static_cast(p) : 0; } -}; - -/*======================================================================== - * - * OStorePageObject. - * - *======================================================================*/ -class OStorePageObject -{ - typedef OStorePageData page; - typedef OStorePageDescriptor D; public: - /** Allocation. - */ - static void * operator new (std::size_t n) SAL_THROW(()) + bool construct (rtl::Reference< PageData::Allocator > const & rxAllocator) { - return rtl_allocateMemory (sal_uInt32(n)); + if ((m_xPage.get() == 0) && rxAllocator.is()) + { + PageHolder tmp (rxAllocator->construct(), rxAllocator); + m_xPage.swap (tmp); + } + return (m_xPage.get() != 0); } - static void operator delete (void * p, std::size_t) SAL_THROW(()) + + static PageHolderObject createInstance (rtl::Reference< PageData::Allocator > const & rxAllocator) { - rtl_freeMemory (p); + PageHolderObject tmp; + (void) tmp.construct (rxAllocator); + return tmp; } - /** Construction. - */ - inline OStorePageObject (page& rPage); + explicit PageHolderObject (PageHolder const & rxPage = PageHolder()) + : m_xPage (rxPage) + {} - /** Destruction. - */ - virtual ~OStorePageObject (void); + void swap (PageHolderObject & rhs) + { + m_xPage.swap (rhs.m_xPage); + } - /** External representation. - */ - virtual void swap (const D& rDescr); - virtual void guard (const D& rDescr); - virtual storeError verify (const D& rDescr); + PageHolderObject (PageHolderObject const & rhs) + : m_xPage (rhs.m_xPage) + {} - /** Data. - */ - inline OStorePageData& getData (void); + PageHolderObject & operator= (PageHolderObject const & rhs) + { + PageHolderObject tmp (rhs); + this->swap (tmp); + return *this; + } - /** State. - */ - inline sal_Bool dirty (void) const; - inline void clean (void); - inline void touch (void); + bool is() const + { + return (m_xPage.get() != 0); + } - /** Location. - */ - inline sal_uInt32 location (void) const; - inline void location (sal_uInt32 nAddr); +#if 1 /* EXP */ + PageHolder & get() { return m_xPage; } + PageHolder const & get() const { return m_xPage; } +#endif /* EXP */ -private: - /** Representation. - */ - page &m_rPage; - sal_Bool m_bDirty; -}; + T * operator->() + { + T * pImpl = dynamic_page_cast(m_xPage.get()); + OSL_PRECOND(pImpl != 0, "store::PageHolder::operator*(): Null pointer"); + return pImpl; + } + T const * operator->() const + { + T const * pImpl = dynamic_page_cast(m_xPage.get()); + OSL_PRECOND(pImpl != 0, "store::PageHolder::operator*(): Null pointer"); + return pImpl; + } -inline OStorePageObject::OStorePageObject (page& rPage) - : m_rPage (rPage), m_bDirty (sal_False) -{ -} + T & operator*() + { + T * pImpl = dynamic_page_cast(m_xPage.get()); + OSL_PRECOND(pImpl != 0, "store::PageHolder::operator*(): Null pointer"); + return (*pImpl); + } + T const & operator*() const + { + T const * pImpl = dynamic_page_cast(m_xPage.get()); + OSL_PRECOND(pImpl != 0, "store::PageHolder::operator*(): Null pointer"); + return (*pImpl); + } -inline OStorePageData& OStorePageObject::getData (void) -{ - return m_rPage; -} + static storeError guard (PageHolder & rxPage, sal_uInt32 nAddr) + { + PageData * pHead = rxPage.get(); + if (!pHead) + return store_E_InvalidAccess; + pHead->guard(nAddr); -inline sal_Bool OStorePageObject::dirty (void) const -{ - return m_bDirty; -} + T * pImpl = dynamic_page_cast(pHead); + OSL_PRECOND(pImpl != 0, "store::PageHolder::guard(): Null pointer"); + pImpl->guard(); -inline void OStorePageObject::clean (void) -{ - m_bDirty = sal_False; -} + return store_E_None; + } + static storeError verify (PageHolder const & rxPage, sal_uInt32 nAddr) + { + PageData const * pHead = rxPage.get(); + if (!pHead) + return store_E_InvalidAccess; -inline void OStorePageObject::touch (void) -{ - m_bDirty = sal_True; -} + storeError eErrCode = pHead->verify(nAddr); + if (eErrCode != store_E_None) + return eErrCode; -inline sal_uInt32 OStorePageObject::location (void) const -{ - return m_rPage.location(); -} + T const * pImpl = dynamic_page_cast(pHead); + if (!pImpl) + return store_E_WrongVersion; -inline void OStorePageObject::location (sal_uInt32 nAddr) -{ - m_rPage.location (nAddr); - touch(); -} - -#define STORE_METHOD_ENTER(pMutex) \ - if ((pMutex)) (pMutex)->acquire() - -#define STORE_METHOD_LEAVE(pMutex, eErrCode) \ -{ \ - if ((pMutex)) (pMutex)->release(); \ - return (eErrCode); \ -} + return pImpl->verify(); + } +}; /*======================================================================== * - * OStorePageBIOS. + * PageObject. * *======================================================================*/ -struct OStoreSuperBlockPage; -struct OStorePageACL; - -class OStorePageBIOS : public store::OStoreObject +#if 1 /* EXP */ +class PageObject { public: - /** Construction. - */ - OStorePageBIOS (void); - - /** Conversion into Mutex& - */ - inline operator osl::Mutex& (void) const; - - /** Initialization. - * @param pLockBytes [in] - * @param eAccessMode [in] - * @return store_E_None upon success - */ - virtual storeError initialize ( - ILockBytes *pLockBytes, - storeAccessMode eAccessMode); - - /** getPageSize. - */ - storeError getPageSize (sal_uInt16 &rnPageSize); - - /** acquireLock. - */ - storeError acquireLock ( - sal_uInt32 nAddr, sal_uInt32 nSize); - - /** releaseLock. - */ - storeError releaseLock ( - sal_uInt32 nAddr, sal_uInt32 nSize); - - /** read. - */ - storeError read ( - sal_uInt32 nAddr, void *pData, sal_uInt32 nSize); - - /** write. - */ - storeError write ( - sal_uInt32 nAddr, const void *pData, sal_uInt32 nSize); - - /** isModified. - */ - inline sal_Bool isModified (void) const; - - /** isWriteable. - */ - inline sal_Bool isWriteable (void) const; - - /** isValid. - */ - inline sal_Bool isValid (void) const; + explicit PageObject (PageHolder const & rxPage = PageHolder()) + : m_xPage (rxPage), m_bDirty (false) + {} - /** Page Access. - */ - storeError acquirePage ( - const OStorePageDescriptor& rDescr, storeAccessMode eMode); + virtual ~PageObject() + {} - storeError releasePage (const OStorePageDescriptor& rDescr); + PageHolder & get() { return m_xPage; } + PageHolder const & get() const { return m_xPage; } - sal_uInt32 getRefererCount (void); + void clean() { m_bDirty = false; } + void touch() { m_bDirty = true; } - /** Page Allocation. - */ - enum Allocation + sal_uInt32 location() const { - ALLOCATE_FIRST = 0, - ALLOCATE_BEST = 1, - ALLOCATE_EOF = 2 - }; + PageData const * pagedata = m_xPage.get(); + return (pagedata != 0) ? pagedata->location() : STORE_PAGE_NULL; + } + void location (sal_uInt32 nAddr) + { + PageData * pagedata = m_xPage.get(); + if (pagedata != 0) + pagedata->location (nAddr); + } - storeError allocate ( - OStorePageObject& rPage, Allocation eAllocation = ALLOCATE_FIRST); +protected: + PageHolder m_xPage; + bool m_bDirty; - virtual storeError free ( - OStorePageObject& rPage); + virtual storeError guard (sal_uInt32 nAddr) = 0; + virtual storeError verify (sal_uInt32 nAddr) const = 0; +}; +#endif /* EXP */ - /** Page I/O. - */ - virtual storeError load ( - OStorePageObject& rPage); +class OStorePageBIOS; - virtual storeError save ( - OStorePageObject& rPage); +class OStorePageObject +{ + typedef OStorePageData page; - /** close. - * @return store_E_None upon success. +public: + /** Allocation. */ - virtual storeError close (void); + static void * operator new (size_t n) SAL_THROW(()) + { + return rtl_allocateMemory (sal_uInt32(n)); + } + static void operator delete (void * p, size_t) SAL_THROW(()) + { + rtl_freeMemory (p); + } - /** flush. - * @return store_E_None upon success. + /** State. */ - virtual storeError flush (void); + inline bool dirty (void) const; + inline void clean (void); + inline void touch (void); - /** size. + /** Location. */ - storeError size (sal_uInt32 &rnSize); + inline sal_uInt32 location (void) const; + inline void location (sal_uInt32 nAddr); - /** ScanContext. +protected: + /** Representation. */ - struct ScanContext - { - /** Representation. - */ - OStorePageDescriptor m_aDescr; - sal_uInt32 m_nSize; - sal_uInt32 m_nMagic; - - /** Construction. - */ - inline ScanContext (void); - - /** isValid. - */ - inline sal_Bool isValid (void) const; - }; + PageHolder m_xPage; + bool m_bDirty; - /** scanBegin. + /** Construction. */ - storeError scanBegin ( - ScanContext &rCtx, - sal_uInt32 nMagic = 0); + explicit OStorePageObject (PageHolder const & rxPage = PageHolder()) + : m_xPage (rxPage), m_bDirty (false) + {} - /** scanNext. + /** Destruction. */ - storeError scanNext ( - ScanContext &rCtx, - OStorePageObject &rPage); + virtual ~OStorePageObject (void); -protected: - /** Destruction (OReference). - */ - virtual ~OStorePageBIOS (void); +public: + template< class U > + PageHolderObject get() const + { + return PageHolderObject(m_xPage); + } - /** create (SuperBlock). - */ - storeError create ( - sal_uInt16 nPageSize = STORE_DEFAULT_PAGESIZE); + template< class U > + storeError construct (rtl::Reference< PageData::Allocator > const & rxAllocator) + { + if (!rxAllocator.is()) + return store_E_InvalidAccess; - /** Page Maintenance. - */ - storeError peek ( - OStorePageData &rData); - storeError poke ( - OStorePageData &rData); - storeError poke ( - OStorePageObject &rPage); - -private: - /** Representation. - */ - rtl::Reference m_xLockBytes; - osl::Mutex m_aMutex; - OStorePageACL *m_pAcl; + PageHolder tmp (rxAllocator->construct(), rxAllocator); + if (!tmp.get()) + return store_E_OutOfMemory; - typedef OStoreSuperBlockPage SuperPage; - SuperPage *m_pSuper; + m_xPage.swap (tmp); + return store_E_None; + } - sal_Bool m_bModified : 1; - sal_Bool m_bWriteable : 1; - /** SuperBlock verification and repair. - */ - storeError verify (SuperPage *&rpSuper); - storeError repair (SuperPage *&rpSuper); + PageHolder & get() { return m_xPage; } + PageHolder const & get() const { return m_xPage; } - /** Not implemented. - */ - OStorePageBIOS (const OStorePageBIOS&); - OStorePageBIOS& operator= (const OStorePageBIOS&); + virtual storeError guard (sal_uInt32 nAddr) = 0; + virtual storeError verify (sal_uInt32 nAddr) const = 0; }; -inline OStorePageBIOS::operator osl::Mutex& (void) const +inline bool OStorePageObject::dirty (void) const { - return (osl::Mutex&)m_aMutex; -} -inline sal_Bool OStorePageBIOS::isModified (void) const -{ - return m_bModified; + return m_bDirty; } -inline sal_Bool OStorePageBIOS::isWriteable (void) const + +inline void OStorePageObject::clean (void) { - return m_bWriteable; + m_bDirty = false; } -inline sal_Bool OStorePageBIOS::isValid (void) const + +inline void OStorePageObject::touch (void) { - return m_xLockBytes.is(); + m_bDirty = true; } -inline OStorePageBIOS::ScanContext::ScanContext (void) - : m_aDescr (0, 0, 0), m_nSize (0), m_nMagic (0) +inline sal_uInt32 OStorePageObject::location (void) const { + return m_xPage->location(); } -inline sal_Bool OStorePageBIOS::ScanContext::isValid (void) const + +inline void OStorePageObject::location (sal_uInt32 nAddr) { - return (m_aDescr.m_nAddr < m_nSize); + m_xPage->location(nAddr); + touch(); } /*======================================================================== @@ -912,4 +972,3 @@ inline sal_Bool OStorePageBIOS::ScanContext::isValid (void) const } // namespace store #endif /* !_STORE_STORBASE_HXX_ */ - diff --git a/store/source/storbios.cxx b/store/source/storbios.cxx new file mode 100644 index 000000000000..d1f15dcda247 --- /dev/null +++ b/store/source/storbios.cxx @@ -0,0 +1,1570 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: storbios.cxx,v $ + * + * $Revision: 1.1.2.3 $ + * + * last change: $Author: mhu $ $Date: 2008/10/31 18:28:18 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_store.hxx" + +#include "storbios.hxx" + +#include "sal/types.h" +#include "sal/macros.h" + +#include "rtl/alloc.h" +#include "rtl/ref.hxx" + +#include "osl/diagnose.h" +#include "osl/mutex.hxx" + +#include "store/types.h" +#include "object.hxx" +#include "lockbyte.hxx" +#include "storcach.hxx" + +using namespace store; + +/*======================================================================== + * + * OStoreSuperBlock. + * + *======================================================================*/ +#define STORE_MAGIC_SUPERBLOCK sal_uInt32(0x484D5343) + +struct OStoreSuperBlock +{ + typedef OStorePageGuard G; + typedef OStorePageDescriptor D; + typedef OStorePageLink L; + + /** Representation. + */ + G m_aGuard; + D m_aDescr; + sal_uInt32 m_nMarked; + L m_aMarked; + sal_uInt32 m_nUnused; + L m_aUnused; + + /** theSize. + */ + static const size_t theSize = sizeof(G) + sizeof(D) + 2 * (sizeof(L) + sizeof(sal_uInt32)); + + /** Construction. + */ + explicit OStoreSuperBlock (sal_uInt16 nPageSize) + : m_aGuard (STORE_MAGIC_SUPERBLOCK), + m_aDescr (nPageSize, nPageSize, STORE_MINIMUM_PAGESIZE), + m_nMarked (store::htonl(0)), + m_aMarked (0), + m_nUnused (store::htonl(0)), + m_aUnused (0) + {} + + OStoreSuperBlock (const OStoreSuperBlock& rOther) + : m_aGuard (rOther.m_aGuard), + m_aDescr (rOther.m_aDescr), + m_nMarked (rOther.m_nMarked), + m_aMarked (rOther.m_aMarked), + m_nUnused (rOther.m_nUnused), + m_aUnused (rOther.m_aUnused) + {} + + OStoreSuperBlock& operator= (const OStoreSuperBlock& rOther) + { + m_aGuard = rOther.m_aGuard; + m_aDescr = rOther.m_aDescr; + m_nMarked = rOther.m_nMarked; + m_aMarked = rOther.m_aMarked; + m_nUnused = rOther.m_nUnused; + m_aUnused = rOther.m_aUnused; + return *this; + } + + /** Comparison. + */ + sal_Bool operator== (const OStoreSuperBlock& rOther) const + { + return ((m_aGuard == rOther.m_aGuard ) && + (m_aDescr == rOther.m_aDescr ) && + (m_nMarked == rOther.m_nMarked) && + (m_aMarked == rOther.m_aMarked) && + (m_nUnused == rOther.m_nUnused) && + (m_aUnused == rOther.m_aUnused) ); + } + + /** unused(Count|Head|Insert|Remove|Reset). + */ + sal_uInt32 unusedCount (void) const + { + return store::ntohl(m_nUnused); + } + const L& unusedHead (void) const + { + return m_aUnused; + } + void unusedInsert (const L& rLink) + { + sal_uInt32 nUnused = unusedCount(); + m_nUnused = store::htonl(nUnused + 1); + m_aUnused = rLink; + } + void unusedRemove (const L& rLink) + { + sal_uInt32 nUnused = unusedCount(); + m_nUnused = store::htonl(nUnused - 1); + m_aUnused = rLink; + } + void unusedReset (void) + { + m_nUnused = store::htonl(0); + m_aUnused = L(0); + } + + /** guard (external representation). + */ + void guard() + { + sal_uInt32 nCRC32 = 0; + nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); + nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G)); + m_aGuard.m_nCRC32 = store::htonl(nCRC32); + } + + /** verify (external representation). + */ + storeError verify() const + { + sal_uInt32 nMagic = store::ntohl(m_aGuard.m_nMagic); + if (nMagic != STORE_MAGIC_SUPERBLOCK) + return store_E_WrongFormat; + + sal_uInt32 nCRC32 = 0; + nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); + nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G)); + if (m_aGuard.m_nCRC32 != store::htonl(nCRC32)) + return store_E_InvalidChecksum; + else + return store_E_None; + } +}; + +/*======================================================================== + * + * OStoreStateBlock. + * + *======================================================================*/ +struct OStoreStateBlock +{ + enum StateBits + { + STATE_CLEAN = 0, + STATE_CLOSE_WAIT = 1, + STATE_FLUSH_WAIT = 2 + }; + + /** Representation. + */ + sal_uInt32 m_nState; + + /** theSize. + */ + static const size_t theSize = sizeof(sal_uInt32); + + /** Construction. + */ + OStoreStateBlock() + : m_nState (store::htonl(STATE_CLEAN)) + {} + + /** Operation. + */ + bool closePending (void) const + { + sal_uInt32 nState = store::ntohl(m_nState); + return ((nState & STATE_CLOSE_WAIT) == STATE_CLOSE_WAIT); + } + void closed (void) + { + sal_uInt32 nState = store::ntohl(m_nState); + nState &= ~STATE_CLOSE_WAIT; + m_nState = store::htonl(nState); + } + + bool flushPending (void) const + { + sal_uInt32 nState = store::ntohl(m_nState); + return ((nState & STATE_FLUSH_WAIT) == STATE_FLUSH_WAIT); + } + void flushed (void) + { + sal_uInt32 nState = store::ntohl(m_nState); + nState &= ~STATE_FLUSH_WAIT; + m_nState = store::htonl(nState); + } + + void modified (void) + { + sal_uInt32 nState = store::ntohl(m_nState); + nState |= (STATE_CLOSE_WAIT | STATE_FLUSH_WAIT); + m_nState = store::htonl(nState); + } + void clean (void) + { + sal_uInt32 nState = store::ntohl(m_nState); + nState &= ~(STATE_CLOSE_WAIT | STATE_FLUSH_WAIT); + m_nState = store::htonl(nState); + } +}; + +/*======================================================================== + * + * OStoreSuperBlockPage interface. + * + *======================================================================*/ +namespace store +{ + +struct OStoreSuperBlockPage +{ + typedef OStoreSuperBlock SuperBlock; + typedef OStoreStateBlock StateBlock; + + /** Representation. + */ + SuperBlock m_aSuperOne; + SuperBlock m_aSuperTwo; + StateBlock m_aState; + + /** theSize. + */ + static const size_t theSize = 2 * SuperBlock::theSize + StateBlock::theSize; + static const sal_uInt16 thePageSize = theSize; + STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= thePageSize); + + /** Allocation. + */ + static void * operator new (size_t n) SAL_THROW(()) + { + return rtl_allocateMemory (sal::static_int_cast(n)); + } + static void operator delete (void * p, size_t) SAL_THROW(()) + { + rtl_freeMemory (p); + } + + static void * operator new (size_t, sal_uInt16 nPageSize) SAL_THROW(()) + { + return rtl_allocateZeroMemory (sal::static_int_cast(nPageSize)); + } + static void operator delete (void * p, sal_uInt16) SAL_THROW(()) + { + rtl_freeMemory (p); + } + + /** Construction. + */ + explicit OStoreSuperBlockPage (sal_uInt16 nPageSize = thePageSize) + : m_aSuperOne(nPageSize), + m_aSuperTwo(nPageSize), + m_aState() + {} + + /** guard (external representation). + */ + void guard() + { + m_aSuperOne.guard(); + m_aSuperTwo.guard(); + } + + /** save. + */ + storeError save (OStorePageBIOS &rBIOS) + { + // Guard. + guard(); + + // Write. + return rBIOS.write (0, this, theSize); + } + + /** close. + */ + storeError close ( + OStorePageBIOS &rBIOS); + + /** flush. + */ + storeError flush ( + OStorePageBIOS &rBIOS); + + /** modified. + */ + storeError modified ( + OStorePageBIOS &rBIOS); + + /** verify (with repair). + */ + storeError verify ( + OStorePageBIOS &rBIOS); +}; + +} // namespace store + +/*======================================================================== + * + * OStoreSuperBlockPage implementation. + * + *======================================================================*/ +/* + * close. + */ +storeError OStoreSuperBlockPage::close (OStorePageBIOS &rBIOS) +{ + storeError eErrCode = store_E_None; + if (m_aState.closePending()) + { + // Mark as modified. + m_aState.modified(); + + // Check access mode. + if (rBIOS.isWriteable()) + { + // Save StateBlock. + StateBlock aState (m_aState); + + // Mark as clean. + aState.clean(); + + // Write behind SuperBlock. + sal_uInt32 nAddr = 2 * SuperBlock::theSize; + eErrCode = rBIOS.write (nAddr, &aState, StateBlock::theSize); + } + + // Mark as clean. + m_aState.clean(); + } + return eErrCode; +} + +/* + * flush. + */ +storeError OStoreSuperBlockPage::flush (OStorePageBIOS &rBIOS) +{ + storeError eErrCode = store_E_None; + if (m_aState.flushPending()) + { + // Check access mode. + if (rBIOS.isWriteable()) + { + // Save StateBlock. + StateBlock aState (m_aState); + + // Mark as flushed. + aState.flushed(); + + // Write behind SuperBlock. + sal_uInt32 nAddr = 2 * SuperBlock::theSize; + eErrCode = rBIOS.write (nAddr, &aState, StateBlock::theSize); + } + + // Mark as flushed. + m_aState.flushed(); + } + return eErrCode; +} + +/* + * modified. + */ +storeError OStoreSuperBlockPage::modified (OStorePageBIOS &rBIOS) +{ + storeError eErrCode = store_E_None; + if (!m_aState.flushPending()) + { + // Mark as modified. + m_aState.modified(); + + // Check access mode. + if (rBIOS.isWriteable()) + { + // Save StateBlock. + StateBlock aState (m_aState); + + // Write behind SuperBlock. + sal_uInt32 nAddr = 2 * SuperBlock::theSize; + eErrCode = rBIOS.write (nAddr, &aState, StateBlock::theSize); + } + } + return eErrCode; +} + +/* + * verify (with repair). + */ +storeError OStoreSuperBlockPage::verify (OStorePageBIOS &rBIOS) +{ + // Verify 1st copy. + storeError eErrCode = m_aSuperOne.verify(); + if (eErrCode == store_E_None) + { + // Ok. Verify 2nd copy. + eErrCode = m_aSuperTwo.verify(); + if (eErrCode == store_E_None) + { + // Ok. Ensure identical copies (1st copy wins). + if (!(m_aSuperOne == m_aSuperTwo)) + { + // Different. Replace 2nd copy with 1st copy. + m_aSuperTwo = m_aSuperOne; + + // Write back. + if (rBIOS.isWriteable()) + eErrCode = rBIOS.write (0, this, theSize); + else + eErrCode = store_E_None; + } + } + else + { + // Failure. Replace 2nd copy with 1st copy. + m_aSuperTwo = m_aSuperOne; + + // Write back. + if (rBIOS.isWriteable()) + eErrCode = rBIOS.write (0, this, theSize); + else + eErrCode = store_E_None; + } + } + else + { + // Failure. Verify 2nd copy. + eErrCode = m_aSuperTwo.verify(); + if (eErrCode == store_E_None) + { + // Ok. Replace 1st copy with 2nd copy. + m_aSuperOne = m_aSuperTwo; + + // Write back. + if (rBIOS.isWriteable()) + eErrCode = rBIOS.write (0, this, theSize); + else + eErrCode = store_E_None; + } + else + { + // Double Failure. + OSL_TRACE("OStoreSuperBlockPage::verify(): double failure.\n"); + } + } + + // Done. + return eErrCode; +} + +/*======================================================================== + * + * OStorePageBIOS::Ace implementation. + * + *======================================================================*/ +OStorePageBIOS::Ace::Ace() + : m_next (this), m_prev (this), m_addr (STORE_PAGE_NULL), m_used (0) +{} + +OStorePageBIOS::Ace::~Ace() +{ + m_next->m_prev = m_prev, m_prev->m_next = m_next; +} + +int +SAL_CALL OStorePageBIOS::Ace::constructor (void * obj, void * /* arg */) +{ + Ace * ace = static_cast(obj); + ace->m_next = ace->m_prev = ace; + return 1; +} + +OStorePageBIOS::Ace * +OStorePageBIOS::Ace::find (OStorePageBIOS::Ace * head, sal_uInt32 addr) +{ + OStorePageBIOS::Ace * entry; + for (entry = head->m_next; entry != head; entry = entry->m_next) + { + if (entry->m_addr >= addr) + return entry; + } + return head; +} + +void +OStorePageBIOS::Ace::insert (OStorePageBIOS::Ace * head, OStorePageBIOS::Ace * entry) +{ + // insert entry at queue tail (before head). + entry->m_next = head; + entry->m_prev = head->m_prev; + head->m_prev = entry; + entry->m_prev->m_next = entry; +} + +/*======================================================================== + * + * OStorePageBIOS::AceCache interface. + * + *======================================================================*/ +namespace store +{ + +class OStorePageBIOS::AceCache +{ + rtl_cache_type * m_ace_cache; + +public: + static AceCache & get(); + + OStorePageBIOS::Ace * + create (sal_uInt32 addr, sal_uInt32 used = 1); + + void + destroy (OStorePageBIOS::Ace * ace); + +protected: + AceCache(); + ~AceCache(); +}; + +} // namespace store + +/*======================================================================== + * + * OStorePageBIOS::AceCache implementation. + * + *======================================================================*/ +extern "C" typedef int (SAL_CALL * ace_constructor_type)(void*,void*); + +OStorePageBIOS::AceCache & +OStorePageBIOS::AceCache::get() +{ + static AceCache g_ace_cache; + return g_ace_cache; +} + +OStorePageBIOS::AceCache::AceCache() +{ + m_ace_cache = rtl_cache_create ( + "store_ace_cache", + sizeof (OStorePageBIOS::Ace), + 0, // objalign + reinterpret_cast( OStorePageBIOS::Ace::constructor), + 0, // destructor, + 0, // reclaim, + 0, // userarg, + 0, // default source, + 0 // flags + ); +} + +OStorePageBIOS::AceCache::~AceCache() +{ + rtl_cache_destroy (m_ace_cache), m_ace_cache = 0; +} + +OStorePageBIOS::Ace * +OStorePageBIOS::AceCache::create (sal_uInt32 addr, sal_uInt32 used) +{ + Ace * ace = static_cast(rtl_cache_alloc (m_ace_cache)); + if (ace != 0) + { + // verify invariant state. + OSL_ASSERT((ace->m_next == ace) && (ace->m_prev == ace)); + + // initialize. + ace->m_addr = addr; + ace->m_used = used; + } + return ace; +} + +void +OStorePageBIOS::AceCache::destroy (OStorePageBIOS::Ace * ace) +{ + if (ace != 0) + { + // remove from queue (if any). + ace->m_next->m_prev = ace->m_prev, ace->m_prev->m_next = ace->m_next; + + // restore invariant state. + ace->m_next = ace->m_prev = ace; + + // return to cache. + rtl_cache_free (m_ace_cache, ace); + } +} + +/*======================================================================== + * + * OStorePageBIOS implementation. + * + *======================================================================*/ +/* + * OStorePageBIOS. + */ +OStorePageBIOS::OStorePageBIOS (void) + : m_xLockBytes (NULL), + m_pSuper (NULL), + m_bModified (sal_False), + m_bWriteable (sal_False) +{ +} + +/* + * ~OStorePageBIOS. + */ +OStorePageBIOS::~OStorePageBIOS (void) +{ + OStorePageBIOS::close(); +} + +/* + * verify (SuperBlock with repair). + * Internal: Precond: initialized, exclusive access. + */ +storeError OStorePageBIOS::verify (SuperPage *&rpSuper) +{ + // Check SuperBlock page allocation. + if (rpSuper == 0) + { + // Allocate. + if ((rpSuper = new SuperPage()) == 0) + return store_E_OutOfMemory; + + // Load (w/o verification). + storeError eErrCode = read (0, rpSuper, SuperPage::theSize); + if (eErrCode != store_E_None) + { + // Cleanup and fail. + delete rpSuper, rpSuper = 0; + return eErrCode; + } + + // Check SuperBlock state. + if (rpSuper->m_aState.closePending()) + OSL_TRACE("OStorePageBIOS::verify(): close pending.\n"); + + if (rpSuper->m_aState.flushPending()) + OSL_TRACE("OStorePageBIOS::verify(): flush pending.\n"); + } + + // Verify SuperBlock page (with repair). + return rpSuper->verify (*this); +} + +/* + * repair (SuperBlock). + * Internal: Precond: initialized, exclusive access. + */ +storeError OStorePageBIOS::repair (SuperPage *&rpSuper) +{ + // Acquire Lock. + storeError eErrCode = acquireLock (0, SuperPage::theSize); + if (eErrCode != store_E_None) + return eErrCode; + + // Verify SuperBlock page (with repair). + eErrCode = verify (rpSuper); + if (eErrCode != store_E_None) + { + // Failure. + releaseLock (0, SuperPage::theSize); + return eErrCode; + } + + // ReleaseLock. + return releaseLock (0, SuperPage::theSize); +} + +/* + * create (SuperBlock). + * Internal: Precond: initialized, exclusive access. + */ +storeError OStorePageBIOS::create (sal_uInt16 nPageSize) +{ + // Check (internal) precond. + OSL_PRECOND(m_xLockBytes.is(), "store::PageBIOS::create(): contract violation"); + + // Check PageSize. + if ((STORE_MINIMUM_PAGESIZE > nPageSize) || (nPageSize > STORE_MAXIMUM_PAGESIZE)) + return store_E_InvalidParameter; + nPageSize = ((nPageSize + STORE_MINIMUM_PAGESIZE - 1) & ~(STORE_MINIMUM_PAGESIZE - 1)); + + // Acquire Lock. + storeError eErrCode = acquireLock (0, nPageSize); + if (eErrCode != store_E_None) + return eErrCode; + + // Allocate SuperBlock page. + delete m_pSuper, m_pSuper = 0; + if ((m_pSuper = new(nPageSize) SuperPage(nPageSize)) == 0) + { + // Cleanup and fail. + releaseLock (0, nPageSize); + return store_E_OutOfMemory; + } + m_pSuper->guard(); + + // Create initial page (w/ SuperBlock). + eErrCode = m_xLockBytes->writeAt (0, m_pSuper, nPageSize); + if (eErrCode != store_E_None) + { + // Cleanup and fail. + releaseLock (0, nPageSize); + return eErrCode; + } + +#ifdef STORE_FEATURE_COMMIT + // Commit. + eErrCode = m_xLockBytes->flush(); + OSL_POSTCOND( + eErrCode == store_E_None, + "OStorePageBIOS::create(): flush failed"); +#endif /* STORE_FEATURE_COMMIT */ + + // Adjust modified state. + m_bModified = (eErrCode != store_E_None); + + // Release Lock and finish. + return releaseLock (0, nPageSize); +} + +/* + * initialize. + * Precond: none. + */ +storeError OStorePageBIOS::initialize ( + ILockBytes * pLockBytes, + storeAccessMode eAccessMode, + sal_uInt16 & rnPageSize) +{ + // Acquire exclusive access. + osl::MutexGuard aGuard (m_aMutex); + + // Check arguments. + storeError eErrCode = store_E_InvalidParameter; + if (!pLockBytes) + return eErrCode; + + // Cleanup. +#if 0 /* OLD */ + __STORE_DELETEZ (m_pAcl); /* @@@ */ +#endif /* OLD */ + delete m_pSuper, m_pSuper = 0; + + // Initialize. + m_xLockBytes = pLockBytes; + m_bModified = sal_False; + m_bWriteable = (!(eAccessMode == store_AccessReadOnly)); + + // Check access mode. + if (eAccessMode == store_AccessReadOnly) + { + // Verify SuperBlock page. + eErrCode = verify (m_pSuper); + } + else if (eAccessMode != store_AccessCreate) + { + // Verify (w/ repair) SuperBlock page. + eErrCode = repair (m_pSuper); + } + else + { + // Truncate to zero length. + eErrCode = m_xLockBytes->setSize(0); + if (eErrCode != store_E_None) + return eErrCode; + +#ifdef STORE_FEATURE_COMMIT + // Commit. + eErrCode = m_xLockBytes->flush(); + if (eErrCode != store_E_None) + return eErrCode; +#endif /* STORE_FEATURE_COMMIT */ + + // Mark as not existing. + eErrCode = store_E_NotExists; + } + + if (eErrCode != store_E_None) + { + // Check reason. + if (eErrCode != store_E_NotExists) + return eErrCode; + + // Check mode. + if (eAccessMode == store_AccessReadOnly) + return store_E_NotExists; + if (eAccessMode == store_AccessReadWrite) + return store_E_NotExists; + + // Create SuperBlock page. + eErrCode = create (rnPageSize); + } + if (eErrCode == store_E_None) + { + // Obtain modified state. + m_bModified = m_pSuper->m_aState.flushPending(); + + // Obtain page size. + rnPageSize = store::ntohs(m_pSuper->m_aSuperOne.m_aDescr.m_nSize); + + // Create page allocator. + eErrCode = m_xLockBytes->initialize (m_xAllocator, rnPageSize); + if (eErrCode != store_E_None) + return eErrCode; + + // Create page cache. + eErrCode = PageCache_createInstance (m_xCache, rnPageSize); + } + return eErrCode; +} + +/* + * acquireLock. + * Low Level: Precond: initialized, exclusive access. + */ +storeError OStorePageBIOS::acquireLock ( + sal_uInt32 nAddr, sal_uInt32 nSize) +{ + // Check precond. + if (!m_xLockBytes.is()) + return store_E_InvalidAccess; + + // Acquire Lock. + return m_xLockBytes->lockRange (nAddr, nSize); +} + +/* + * releaseLock. + * Low Level: Precond: initialized, exclusive access. + */ +storeError OStorePageBIOS::releaseLock ( + sal_uInt32 nAddr, sal_uInt32 nSize) +{ + // Check precond. + if (!m_xLockBytes.is()) + return store_E_InvalidAccess; + + // Release Lock. + return m_xLockBytes->unlockRange (nAddr, nSize); +} + +/* + * read. + * Low Level: Precond: initialized, exclusive access. + */ +storeError OStorePageBIOS::read ( + sal_uInt32 nAddr, void *pData, sal_uInt32 nSize) +{ + // Check precond. + if (!m_xLockBytes.is()) + return store_E_InvalidAccess; + + // Read Page. + return m_xLockBytes->readAt (nAddr, pData, nSize); +} + +/* + * write. + * Low Level: Precond: initialized, writeable, exclusive access. + */ +storeError OStorePageBIOS::write ( + sal_uInt32 nAddr, const void *pData, sal_uInt32 nSize) +{ + // Check precond. + if (!m_xLockBytes.is()) + return store_E_InvalidAccess; + if (!m_bWriteable) + return store_E_AccessViolation; + + // Check modified state. + if (!m_bModified) + { + // Mark as modified. + m_bModified = sal_True; + + // Mark SuperBlock modified. + storeError eErrCode = m_pSuper->modified (*this); + if (eErrCode != store_E_None) + return eErrCode; + } + + // Write Data. + return m_xLockBytes->writeAt (nAddr, pData, nSize); +} + +/* + * acquirePage. + * Precond: initialized. + */ +storeError OStorePageBIOS::acquirePage ( + const OStorePageDescriptor& rDescr, storeAccessMode eMode) +{ + // Acquire exclusive access. + osl::MutexGuard aGuard (m_aMutex); + + // Check precond. + if (!m_xLockBytes.is()) + return store_E_InvalidAccess; + + // Check access mode. + if (!(m_bWriteable || (eMode == store_AccessReadOnly))) + return store_E_AccessViolation; + + // Find access control list entry. + Ace * ace = Ace::find (&m_ace_head, rDescr.m_nAddr); + if (ace->m_addr == rDescr.m_nAddr) + { + // Acquire existing entry (with ShareDenyWrite). + if (eMode == store_AccessReadOnly) + ace->m_used += 1; + else + return store_E_AccessViolation; + } + else + { + // Insert new entry. + Ace * entry = AceCache::get().create (rDescr.m_nAddr, 1); + if (!entry) + return store_E_OutOfMemory; + Ace::insert (ace, entry); + } + + // Increment total referer count and finish. + m_ace_head.m_used += 1; + return store_E_None; +} + +/* + * releasePage. + * Precond: initialized. + */ +storeError OStorePageBIOS::releasePage ( + const OStorePageDescriptor& rDescr, storeAccessMode /* eMode */) +{ + // Acquire exclusive access. + osl::MutexGuard aGuard (m_aMutex); + + // Check precond. + if (!m_xLockBytes.is()) + return store_E_InvalidAccess; + + // Find access control list entry. + Ace * ace = Ace::find (&m_ace_head, rDescr.m_nAddr); + if (ace->m_addr != rDescr.m_nAddr) + return store_E_NotExists; + + // Release existing entry. + if (ace->m_used > 1) + ace->m_used -= 1; + else + AceCache::get().destroy (ace); + + // Decrement total referer count and finish. + m_ace_head.m_used -= 1; + return store_E_None; +} + +/* + * getRefererCount. + * Precond: none. + */ +sal_uInt32 OStorePageBIOS::getRefererCount (void) +{ + // Acquire exclusive access. + osl::MutexGuard aGuard (m_aMutex); + + // Obtain total referer count. + return m_ace_head.m_used; +} + +/* + * allocate. + * Precond: initialized, writeable. + */ +storeError OStorePageBIOS::allocate ( + OStorePageObject& rPage, Allocation eAlloc) +{ + // Acquire exclusive access. + osl::MutexGuard aGuard (m_aMutex); + + // Check precond. + if (!m_xLockBytes.is()) + return store_E_InvalidAccess; + if (!m_bWriteable) + return store_E_AccessViolation; + + // Acquire SuperBlock Lock. + storeError eErrCode = acquireLock (0, SuperPage::theSize); + if (eErrCode != store_E_None) + return eErrCode; + + // Load SuperBlock and require good health. + eErrCode = verify (m_pSuper); + if (eErrCode != store_E_None) + { + releaseLock (0, SuperPage::theSize); + return eErrCode; + } + + // Check allocation. + if (eAlloc != ALLOCATE_EOF) + { + // Check FreeList. + OStorePageLink aListHead (m_pSuper->m_aSuperTwo.unusedHead()); + if (aListHead.location()) + { + // Allocate from FreeList. + OStorePageData aPageHead (OStorePageData::theSize); + aPageHead.location (aListHead.location()); + + // Load PageHead. + eErrCode = peek (aPageHead); + if (eErrCode != store_E_None) + { + releaseLock (0, SuperPage::theSize); + return eErrCode; + } + + // Verify FreeList head. + OSL_PRECOND( + aPageHead.m_aUnused.m_nAddr != STORE_PAGE_NULL, + "OStorePageBIOS::allocate(): page not free"); + if (aPageHead.m_aUnused.location() == STORE_PAGE_NULL) + { + // Recovery: Reset FreeList. + m_pSuper->m_aSuperTwo.unusedReset(); + m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo; + + // Save SuperBlock page. + eErrCode = m_pSuper->save (*this); + + // Release SuperBlock Lock. + releaseLock (0, SuperPage::theSize); + + // Recovery: Allocate from EOF. + if (eErrCode == store_E_None) + return allocate (rPage, ALLOCATE_EOF); + else + return store_E_Unknown; + } + + // Pop from FreeList. + aListHead = aPageHead.m_aUnused.location(); + rPage.get()->m_aUnused = STORE_PAGE_NULL; + + // Save page at PageHead location. + eErrCode = saveObjectAt_Impl (rPage, aPageHead.location()); + if (eErrCode != store_E_None) + { + releaseLock (0, SuperPage::theSize); + return eErrCode; + } + + // Save SuperBlock page. + m_pSuper->m_aSuperTwo.unusedRemove (aListHead); + m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo; + + eErrCode = m_pSuper->save (*this); + OSL_POSTCOND( + eErrCode == store_E_None, + "OStorePageBIOS::allocate(): SuperBlock save failed"); + + // Release SuperBlock Lock and finish. + return releaseLock (0, SuperPage::theSize); + } + } + + // Allocate from logical EOF. Determine physical EOF. + sal_uInt32 nPhysLen = STORE_PAGE_NULL; + eErrCode = m_xLockBytes->getSize (nPhysLen); + if (eErrCode != store_E_None) + { + releaseLock (0, SuperPage::theSize); + return eErrCode; + } + + // Obtain logical EOF. + OStorePageDescriptor aDescr (m_pSuper->m_aSuperTwo.m_aDescr); + sal_uInt32 nLogLen = store::ntohl(aDescr.m_nAddr); + if (nLogLen == 0) + nLogLen = nPhysLen; /* backward compatibility */ + + if (!(nLogLen < nPhysLen)) + { + // Check modified state. + if (!m_bModified) + { + // Mark modified. + m_bModified = sal_True; + + // Mark SuperBlock modified. + eErrCode = m_pSuper->modified (*this); + if (eErrCode != store_E_None) + { + releaseLock (0, SuperPage::theSize); + return eErrCode; + } + } + + // Resize. + sal_uInt32 nAlign = SAL_MIN (nPhysLen, STORE_MAXIMUM_PAGESIZE); + nPhysLen = ((nPhysLen + nAlign) / nAlign) * nAlign; + + eErrCode = m_xLockBytes->setSize (nPhysLen); + if (eErrCode != store_E_None) + { + releaseLock (0, SuperPage::theSize); + return eErrCode; + } + } + + // Save page at logical EOF. + eErrCode = saveObjectAt_Impl (rPage, nLogLen); + if (eErrCode != store_E_None) + { + releaseLock (0, SuperPage::theSize); + return eErrCode; + } + + // Save SuperBlock page. + nLogLen += store::ntohs(aDescr.m_nSize); + aDescr.m_nAddr = store::htonl(nLogLen); + + m_pSuper->m_aSuperTwo.m_aDescr = aDescr; + m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo; + + eErrCode = m_pSuper->save (*this); + OSL_POSTCOND( + eErrCode == store_E_None, + "OStorePageBIOS::allocate(): SuperBlock save failed"); + + // Release SuperBlock Lock and finish. + return releaseLock (0, SuperPage::theSize); +} + +/* + * free. + * Precond: initialized, writeable. + */ +storeError OStorePageBIOS::free (OStorePageData & /* rData */, sal_uInt32 nAddr) +{ + // Acquire exclusive access. + osl::MutexGuard aGuard (m_aMutex); + + // Check precond. + if (!m_xLockBytes.is()) + return store_E_InvalidAccess; + if (!m_bWriteable) + return store_E_AccessViolation; + + // Acquire SuperBlock Lock. + storeError eErrCode = acquireLock (0, SuperPage::theSize); + if (eErrCode != store_E_None) + return eErrCode; + + // Load SuperBlock and require good health. + eErrCode = verify (m_pSuper); + if (eErrCode != store_E_None) + { + releaseLock (0, SuperPage::theSize); + return eErrCode; + } + + // Load PageHead. + OStorePageData aPageHead(OStorePageData::theSize); + aPageHead.location (nAddr); + + eErrCode = peek (aPageHead); + if (eErrCode != store_E_None) + { + releaseLock (0, SuperPage::theSize); + return eErrCode; + } + + // Invalidate cache. + (void) m_xCache->removePageAt (nAddr); + + // Push onto FreeList. + OStorePageLink aListHead (m_pSuper->m_aSuperTwo.unusedHead()); + + aPageHead.m_aUnused.m_nAddr = aListHead.m_nAddr; + aListHead.m_nAddr = aPageHead.m_aDescr.m_nAddr; + + // Save PageHead. + eErrCode = poke (aPageHead); + if (eErrCode != store_E_None) + { + releaseLock (0, SuperPage::theSize); + return eErrCode; + } + + // Save SuperBlock page. + m_pSuper->m_aSuperTwo.unusedInsert (aListHead); + m_pSuper->m_aSuperOne = m_pSuper->m_aSuperTwo; + + eErrCode = m_pSuper->save (*this); + OSL_POSTCOND( + eErrCode == store_E_None, + "OStorePageBIOS::free(): SuperBlock save failed"); + + // Release SuperBlock Lock and finish. + return releaseLock (0, SuperPage::theSize); +} + +/* + * loadObjectAt. + * Precond: initialized, readable. + */ +storeError OStorePageBIOS::loadObjectAt (OStorePageObject & rPage, sal_uInt32 nAddr) +{ + // Acquire exclusive access. + osl::MutexGuard aGuard (m_aMutex); + + // Check precond. + if (!m_xLockBytes.is()) + return store_E_InvalidAccess; + + return loadObjectAt_Impl (rPage, nAddr); +} + +/* + * loadObjectAt_Impl. + * Internal: Precond: initialized, readable, exclusive access. + */ +storeError OStorePageBIOS::loadObjectAt_Impl (OStorePageObject & rPage, sal_uInt32 nAddr) +{ + storeError eErrCode = m_xCache->lookupPageAt (rPage.get(), nAddr); + if (eErrCode != store_E_NotExists) + return eErrCode; + + // Read page. + eErrCode = m_xLockBytes->readPageAt (rPage.get(), nAddr); + if (eErrCode != store_E_None) + return eErrCode; + + // Verify page. + eErrCode = rPage.verify (nAddr); + if (eErrCode != store_E_None) + return eErrCode; + + // Mark page as clean. + rPage.clean(); + + // Cache page. + return m_xCache->insertPageAt (rPage.get(), nAddr); +} + +/* + * saveObjectAt. + * Precond: initialized, writeable. + */ +storeError OStorePageBIOS::saveObjectAt (OStorePageObject & rPage, sal_uInt32 nAddr) +{ + // Acquire exclusive access. + osl::MutexGuard aGuard (m_aMutex); + + // Check precond. + if (!m_xLockBytes.is()) + return store_E_InvalidAccess; + if (!m_bWriteable) + return store_E_AccessViolation; + + // Save Page. + return saveObjectAt_Impl (rPage, nAddr); +} + +/* + * saveObjectAt_Impl. + * Internal: Precond: initialized, writeable, exclusive access. + */ +storeError OStorePageBIOS::saveObjectAt_Impl (OStorePageObject & rPage, sal_uInt32 nAddr) +{ + // Guard page (incl. set location). + storeError eErrCode = rPage.guard (nAddr); + if (eErrCode != store_E_None) + return eErrCode; + + // Write page. + eErrCode = m_xLockBytes->writePageAt(rPage.get(), nAddr); + if (eErrCode != store_E_None) + return eErrCode; + + // Mark page as clean. + rPage.clean(); + + // Cache page. + return m_xCache->updatePageAt (rPage.get(), nAddr); +} + +/* + * close. + * Precond: none. + */ +storeError OStorePageBIOS::close (void) +{ + // Acquire exclusive access. + osl::MutexGuard aGuard (m_aMutex); + + // Check referer count. + if (m_ace_head.m_used > 0) + { + // Report remaining referer count. + OSL_TRACE("store::PageBIOS::close(): referer count: %d\n", m_ace_head.m_used); +#if 1 /* NEW */ + for (Ace * ace = m_ace_head.m_next; ace != &m_ace_head; ace = m_ace_head.m_next) + { + m_ace_head.m_used -= ace->m_used; + AceCache::get().destroy (ace); + } + OSL_ENSURE(m_ace_head.m_used == 0, "store::PageBIOS::close(): logic error"); +#endif /* NEW */ + } + + // Check SuperBlock page. + storeError eErrCode = store_E_None; + if (m_pSuper) + { + // Release SuperBlock page. + eErrCode = m_pSuper->close (*this); + delete m_pSuper, m_pSuper = 0; + } + + // Release PageCache. + m_xCache.clear(); + + // Check LockBytes. + if (m_xLockBytes.is()) + { +#ifdef STORE_FEATURE_COMMIT + // Commit. + storeError result = m_xLockBytes->flush(); + if (eErrCode == store_E_None) + { + // Previous result(s) okay. Propagate next result. + eErrCode = result; + } +#endif /* STORE_FEATURE_COMMIT */ + + // Release LockBytes. + m_xLockBytes.clear(); + } + + // Done. + return eErrCode; +} + +/* + * flush. + * Precond: initialized. + */ +storeError OStorePageBIOS::flush (void) +{ + // Acquire exclusive access. + osl::MutexGuard aGuard (m_aMutex); + + // Check precond. + if (!m_xLockBytes.is()) + return store_E_InvalidAccess; + + // Check mode and state. + storeError eErrCode = store_E_None; + if (!(m_bWriteable && m_bModified)) + return eErrCode; + + // Flush SuperBlock page. + eErrCode = m_pSuper->flush (*this); + + // Flush LockBytes. + storeError result = m_xLockBytes->flush(); + if (eErrCode == store_E_None) + { + // Previous result(s) okay. Propagate next result. + eErrCode = result; + } + + // Adjust modified state. + m_bModified = (eErrCode != store_E_None); + + // Done. + return eErrCode; +} + +/* + * size. + * Precond: initialized. + */ +storeError OStorePageBIOS::size (sal_uInt32 &rnSize) +{ + // Acquire exclusive access. + osl::MutexGuard aGuard (m_aMutex); + + // Initialize [out] param. + rnSize = 0; + + // Check precond. + if (!m_xLockBytes.is()) + return store_E_InvalidAccess; + + // Obtain LockBytes size. + return m_xLockBytes->getSize (rnSize); +} + +/* + * scanBegin. + * Precond: initialized. + */ +storeError OStorePageBIOS::scanBegin ( + ScanContext &rCtx, sal_uInt32 nMagic) +{ + // Acquire exclusive access. + osl::MutexGuard aGuard (m_aMutex); + + // Initialize [out] param. + rCtx.m_aDescr = OStorePageDescriptor(0, 0, 0); + rCtx.m_nSize = 0; + rCtx.m_nMagic = nMagic; + + // Check precond. + if (!m_xLockBytes.is()) + return store_E_InvalidAccess; + + // Check SuperBlock page. + storeError eErrCode = verify (m_pSuper); + if (eErrCode != store_E_None) + { + // Damaged. Determine page size (NYI). + OSL_TRACE ("OStorePageBIOS::scanBegin(): damaged.\n"); + return eErrCode; + } + + // Setup Context descriptor. + rCtx.m_aDescr = m_pSuper->m_aSuperOne.m_aDescr; + rCtx.m_aDescr.m_nAddr = rCtx.m_aDescr.m_nSize; // @@@ ntoh @@@ + + // Setup Context size. + eErrCode = size (rCtx.m_nSize); + if (eErrCode != store_E_None) + rCtx.m_nSize = ((sal_uInt32)(~0)); + + // Done. + return store_E_None; +} + +/* + * scanNext. + * Precond: initialized. + */ +storeError OStorePageBIOS::scanNext ( + ScanContext &rCtx, OStorePageObject &rPage) +{ + // Acquire exclusive access. + osl::MutexGuard aGuard (m_aMutex); + + // Check precond. + if (!m_xLockBytes.is()) + return store_E_InvalidAccess; + + // Setup PageHead. + OStorePageData aPageHead (OStorePageData::theSize); + + // Check context. + while (rCtx.isValid()) + { + // Assign next location. + aPageHead.location (rCtx.m_aDescr.m_nAddr); + rCtx.m_aDescr.m_nAddr += rCtx.m_aDescr.m_nSize; + + // Load PageHead. + storeError eErrCode = peek (aPageHead); + if (eErrCode != store_E_None) + continue; + + // Check PageHead Magic number. + if (aPageHead.m_aGuard.m_nMagic != rCtx.m_nMagic) + continue; + + // Check PageHead Unused link. + if (aPageHead.m_aUnused.m_nAddr != STORE_PAGE_NULL) + continue; + + // Load page. + eErrCode = loadObjectAt_Impl (rPage, aPageHead.location()); + if (eErrCode != store_E_None) + continue; + + // Deliver page. + return store_E_None; + } + + // Done. + return store_E_CantSeek; +} + +/* + * peek (PageHead). + * Internal: Precond: initialized, readable, exclusive access. + */ +storeError OStorePageBIOS::peek (OStorePageData &rData) +{ + // Read PageHead. + storeError eErrCode = read (rData.location(), &rData, OStorePageData::theSize); + if (eErrCode != store_E_None) + return eErrCode; + + // Verify PageHead. + return rData.verify(); +} + +/* + * poke (PageHead). + * Internal: Precond: initialized, writeable, exclusive access. + */ +storeError OStorePageBIOS::poke (OStorePageData &rData) +{ + // Guard PageHead. + rData.guard(); + + // Write PageHead. + return write (rData.location(), &rData, OStorePageData::theSize); +} diff --git a/store/source/storbios.hxx b/store/source/storbios.hxx new file mode 100644 index 000000000000..d9a0f982bd3c --- /dev/null +++ b/store/source/storbios.hxx @@ -0,0 +1,302 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: storbios.hxx,v $ + * + * $Revision: 1.1.2.3 $ + * + * last change: $Author: mhu $ $Date: 2008/10/31 18:28:18 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _STORE_STORBIOS_HXX_ +#define _STORE_STORBIOS_HXX_ "$Revision: 1.1.2.3 $" + +#include "sal/types.h" +#include "rtl/ref.hxx" +#include "osl/mutex.hxx" + +#include "store/types.h" +#include "object.hxx" +#include "lockbyte.hxx" +#include "storbase.hxx" +#include "storcach.hxx" + +/*======================================================================== + * + * OStorePageBIOS. + * + *======================================================================*/ +namespace store +{ + +struct OStoreSuperBlockPage; + +class OStorePageBIOS : public store::OStoreObject +{ +public: + /** Construction. + */ + OStorePageBIOS (void); + + /** Conversion into Mutex& + */ + inline operator osl::Mutex& (void) const; + + /** Initialization. + * @param pLockBytes [in] + * @param eAccessMode [in] + * @param rnPageSize [inout] + * @return store_E_None upon success + */ + virtual storeError initialize ( + ILockBytes * pLockBytes, + storeAccessMode eAccessMode, + sal_uInt16 & rnPageSize); + + rtl::Reference< PageData::Allocator > & allocator() + { + return m_xAllocator; + } + + /** acquireLock. + */ + storeError acquireLock ( + sal_uInt32 nAddr, sal_uInt32 nSize); + + /** releaseLock. + */ + storeError releaseLock ( + sal_uInt32 nAddr, sal_uInt32 nSize); + + /** read. + */ + storeError read ( + sal_uInt32 nAddr, void *pData, sal_uInt32 nSize); + + /** write. + */ + storeError write ( + sal_uInt32 nAddr, const void *pData, sal_uInt32 nSize); + + /** isModified. + */ + inline bool isModified (void) const; + + /** isWriteable. + */ + inline bool isWriteable (void) const; + + /** isValid. + */ + inline sal_Bool isValid (void) const; + + /** Page Access. + */ + storeError acquirePage ( + const OStorePageDescriptor& rDescr, storeAccessMode eMode); + + storeError releasePage ( + const OStorePageDescriptor& rDescr, storeAccessMode eMode); + + sal_uInt32 getRefererCount (void); + + /** Page Allocation. + */ + enum Allocation + { + ALLOCATE_FIRST = 0, + ALLOCATE_BEST = 1, + ALLOCATE_EOF = 2 + }; + + storeError allocate ( + OStorePageObject& rPage, Allocation eAllocation = ALLOCATE_FIRST); + + storeError free ( + OStorePageData & /* rData */, sal_uInt32 nAddr); + + /** Page I/O. + */ + storeError loadObjectAt ( + OStorePageObject& rPage, sal_uInt32 nAddr); + + storeError saveObjectAt ( + OStorePageObject& rPage, sal_uInt32 nAddr); + + /** close. + * @return store_E_None upon success. + */ + storeError close (void); + + /** flush. + * @return store_E_None upon success. + */ + storeError flush (void); + + /** size. + */ + storeError size (sal_uInt32 &rnSize); + + /** ScanContext. + */ + struct ScanContext + { + /** Representation. + */ + OStorePageDescriptor m_aDescr; + sal_uInt32 m_nSize; + sal_uInt32 m_nMagic; + + /** Construction. + */ + inline ScanContext (void); + + /** isValid. + */ + inline bool isValid (void) const; + }; + + /** scanBegin. + */ + storeError scanBegin ( + ScanContext &rCtx, + sal_uInt32 nMagic = 0); + + /** scanNext. + */ + storeError scanNext ( + ScanContext &rCtx, + OStorePageObject &rPage); + +protected: + /** Destruction (OReference). + */ + virtual ~OStorePageBIOS (void); + +private: + /** Representation. + */ + rtl::Reference m_xLockBytes; + osl::Mutex m_aMutex; + + typedef OStoreSuperBlockPage SuperPage; + SuperPage *m_pSuper; + + bool m_bModified; + bool m_bWriteable; + + rtl::Reference< PageData::Allocator > m_xAllocator; + rtl::Reference< PageCache > m_xCache; + + /** Page Access (control). + */ +public: + struct Ace + { + Ace * m_next; + Ace * m_prev; + + sal_uInt32 m_addr; + sal_uInt32 m_used; + + Ace(); + ~Ace(); + + static int SAL_CALL constructor (void * obj, void * arg); + + static Ace * find (Ace * head, sal_uInt32 addr); + static void insert (Ace * head, Ace * entry); + }; + +private: + Ace m_ace_head; + + class AceCache; + + /** create (SuperBlock). + */ + storeError create (sal_uInt16 nPageSize); + + /** SuperBlock verification and repair. + */ + storeError verify (SuperPage *&rpSuper); + storeError repair (SuperPage *&rpSuper); + + /** Page Maintenance. + */ + storeError peek ( + OStorePageData &rData); + storeError poke ( + OStorePageData &rData); + + storeError loadObjectAt_Impl ( + OStorePageObject & rPage, sal_uInt32 nAddr); + storeError saveObjectAt_Impl ( + OStorePageObject & rPage, sal_uInt32 nAddr); + + /** Not implemented. + */ + OStorePageBIOS (const OStorePageBIOS&); + OStorePageBIOS& operator= (const OStorePageBIOS&); +}; + +inline OStorePageBIOS::operator osl::Mutex& (void) const +{ + return (osl::Mutex&)m_aMutex; +} +inline bool OStorePageBIOS::isModified (void) const +{ + return m_bModified; +} +inline bool OStorePageBIOS::isWriteable (void) const +{ + return m_bWriteable; +} +inline sal_Bool OStorePageBIOS::isValid (void) const +{ + return m_xLockBytes.is(); +} + +inline OStorePageBIOS::ScanContext::ScanContext (void) + : m_aDescr (0, 0, 0), m_nSize (0), m_nMagic (0) +{ +} +inline bool OStorePageBIOS::ScanContext::isValid (void) const +{ + return (m_aDescr.m_nAddr < m_nSize); +} + +/*======================================================================== + * + * The End. + * + *======================================================================*/ + +} // namespace store + +#endif /* !_STORE_STORBIOS_HXX_ */ diff --git a/store/source/storcach.cxx b/store/source/storcach.cxx index e6851eba1cc7..6306784592e0 100644 --- a/store/source/storcach.cxx +++ b/store/source/storcach.cxx @@ -31,634 +31,534 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_store.hxx" -#define _STORE_STORCACH_CXX "$Revision: 1.8 $" -#include -#include -#include -#include -#include -#include -#ifndef _STORE_STORCACH_HXX_ -#include -#endif +#include "storcach.hxx" + +#include "sal/types.h" +#include "rtl/alloc.h" +#include "osl/diagnose.h" -#ifndef INCLUDED_CSTDDEF -#include -#define INCLUDED_CSTDDEF +#include "store/types.h" +#include "object.hxx" +#include "storbase.hxx" + +#ifndef INCLUDED_STDDEF_H +#include +#define INCLUDED_STDDEF_H #endif using namespace store; /*======================================================================== * - * OStorePageCacheEntry. + * PageCache (non-virtual interface) implementation. * *======================================================================*/ -namespace store -{ -struct OStorePageCacheEntry +storeError PageCache::lookupPageAt (PageHolder & rxPage, sal_uInt32 nOffset) { - typedef OStorePageCacheEntry self; - typedef OStorePageData data; - typedef OStorePageDescriptor D; + OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::PageCache::lookupPageAt(): invalid Offset"); + if (nOffset == STORE_PAGE_NULL) + return store_E_CantSeek; - /** Representation. - */ - D m_aDescr; - data *m_pData; - self *m_pNext; - self *m_pPrev; + return lookupPageAt_Impl (rxPage, nOffset); +} - /** Allocation. - */ - static void * operator new (std::size_t n) SAL_THROW(()) - { - return rtl_allocateMemory (sal_uInt32(n)); - } - static void operator delete (void * p, std::size_t) SAL_THROW(()) - { - rtl_freeMemory (p); - } +storeError PageCache::insertPageAt (PageHolder const & rxPage, sal_uInt32 nOffset) +{ + // [SECURITY:ValInput] + PageData const * pagedata = rxPage.get(); + OSL_PRECOND(!(pagedata == 0), "store::PageCache::insertPageAt(): invalid Page"); + if (pagedata == 0) + return store_E_InvalidParameter; + + sal_uInt32 const offset = pagedata->location(); + OSL_PRECOND(!(nOffset != offset), "store::PageCache::insertPageAt(): inconsistent Offset"); + if (nOffset != offset) + return store_E_InvalidParameter; + + OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::PageCache::insertPageAt(): invalid Offset"); + if (nOffset == STORE_PAGE_NULL) + return store_E_CantSeek; + + return insertPageAt_Impl (rxPage, nOffset); +} - /** Construction. - */ - OStorePageCacheEntry (const D& rDescr, const data& rData) - : m_aDescr (rDescr) - { - sal_uInt16 nSize = m_aDescr.m_nSize; - m_pData = new(nSize) data(nSize); - __store_memcpy (m_pData, &rData, nSize); - m_pNext = m_pPrev = this; - } +storeError PageCache::updatePageAt (PageHolder const & rxPage, sal_uInt32 nOffset) +{ + // [SECURITY:ValInput] + PageData const * pagedata = rxPage.get(); + OSL_PRECOND(!(pagedata == 0), "store::PageCache::updatePageAt(): invalid Page"); + if (pagedata == 0) + return store_E_InvalidParameter; + + sal_uInt32 const offset = pagedata->location(); + OSL_PRECOND(!(nOffset != offset), "store::PageCache::updatePageAt(): inconsistent Offset"); + if (nOffset != offset) + return store_E_InvalidParameter; + + OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::PageCache::updatePageAt(): invalid Offset"); + if (nOffset == STORE_PAGE_NULL) + return store_E_CantSeek; + + return updatePageAt_Impl (rxPage, nOffset); +} - /** Data assignment. - */ - void assign (const D& rDescr, const data& rData) - { - m_aDescr.m_nAddr = rDescr.m_nAddr; - if (!(m_aDescr.m_nSize == rDescr.m_nSize)) - { - delete m_pData; - m_pData = new(rDescr.m_nSize) data(rDescr.m_nSize); - m_aDescr.m_nSize = rDescr.m_nSize; - } - __store_memcpy (m_pData, &rData, m_aDescr.m_nSize); - } +storeError PageCache::removePageAt (sal_uInt32 nOffset) +{ + OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::PageCache::removePageAt(): invalid Offset"); + if (nOffset == STORE_PAGE_NULL) + return store_E_CantSeek; - /** Destruction. - */ - ~OStorePageCacheEntry (void) - { - delete m_pData; - } + return removePageAt_Impl (nOffset); +} - /** Comparison. - */ - enum CompareResult - { - COMPARE_LESS = -1, - COMPARE_EQUAL = 0, - COMPARE_GREATER = 1 - }; +/*======================================================================== + * + * Entry. + * + *======================================================================*/ +namespace +{ - CompareResult compare (const D& rDescr) const - { - if (m_aDescr.m_nAddr == rDescr.m_nAddr) - return COMPARE_EQUAL; - if (m_aDescr.m_nAddr < rDescr.m_nAddr) - return COMPARE_LESS; - else - return COMPARE_GREATER; - } +struct Entry +{ + /** Representation. + */ + PageHolder m_xPage; + sal_uInt32 m_nOffset; + Entry * m_pNext; - CompareResult compare (const self& rOther) const - { - return compare (rOther.m_aDescr); - } + /** Allocation. + */ + static void * operator new (size_t, void * p) { return p; } + static void operator delete (void *, void *) {} - /** Address operation. - */ - void invalidate (void) - { - m_aDescr.m_nAddr = STORE_PAGE_NULL; - } + /** Construction. + */ + explicit Entry (PageHolder const & rxPage = PageHolder(), sal_uInt32 nOffset = STORE_PAGE_NULL) + : m_xPage(rxPage), m_nOffset(nOffset), m_pNext(0) + {} - sal_Bool isValid (void) const - { - return (m_aDescr.m_nAddr != STORE_PAGE_NULL); - } + /** Destruction. + */ + ~Entry() {} +}; - /** Index operation. - */ - sal_uInt16 index (void) const - { - return (m_aDescr.m_nUsed & 0x7fff); - } +} // namespace - void index (sal_uInt16 nIndex) - { - m_aDescr.m_nUsed = ((m_aDescr.m_nUsed & 0x8000) | (nIndex & 0x7fff)); - } +/*======================================================================== + * + * EntryCache interface. + * + *======================================================================*/ +namespace +{ - /** DirtyBit operation. - */ - void clean (void) - { - m_aDescr.m_nUsed &= 0x7fff; - } +class EntryCache +{ + rtl_cache_type * m_entry_cache; - void dirty (void) - { - m_aDescr.m_nUsed |= 0x8000; - } +public: + static EntryCache & get(); - sal_Bool isDirty (void) const - { - return ((m_aDescr.m_nUsed & 0x8000) == 0x8000); - } + Entry * create (PageHolder const & rxPage, sal_uInt32 nOffset); - /** List operation. - */ - void backlink (self& rOther) - { - rOther.m_pNext = this; - rOther.m_pPrev = m_pPrev; - m_pPrev = &rOther; - rOther.m_pPrev->m_pNext = &rOther; - } + void destroy (Entry * entry); - void unlink (void) - { - m_pNext->m_pPrev = m_pPrev; - m_pPrev->m_pNext = m_pNext; - m_pNext = this; - m_pPrev = this; - } +protected: + EntryCache(); + ~EntryCache(); }; -} // namespace store +} // namespace /*======================================================================== * - * OStorePageCache debug internals. + * EntryCache implementation. * *======================================================================*/ -#ifdef __STORE_CACHE_DEBUG -/* - * __store_check_entry. - */ -static sal_Bool __store_check_entry ( - OStorePageCacheEntry **ppData, sal_uInt16 nUsed) +EntryCache & EntryCache::get() +{ + static EntryCache g_entry_cache; + return g_entry_cache; +} + +EntryCache::EntryCache() { - if (nUsed > 1) + m_entry_cache = rtl_cache_create ( + "store_cache_entry_cache", + sizeof(Entry), + 0, // objalign + 0, // constructor + 0, // destructor + 0, // reclaim + 0, // userarg + 0, // default source + 0 // flags + ); +} + +EntryCache::~EntryCache() +{ + rtl_cache_destroy (m_entry_cache), m_entry_cache = 0; +} + +Entry * EntryCache::create (PageHolder const & rxPage, sal_uInt32 nOffset) +{ + void * pAddr = rtl_cache_alloc (m_entry_cache); + if (pAddr != 0) { - for (sal_uInt16 i = 0; i < nUsed - 1; i++) - { - sal_uInt32 ai = ppData[i ]->m_aDescr.m_nAddr; - sal_uInt32 ak = ppData[i + 1]->m_aDescr.m_nAddr; - if (!(ai <= ak)) - return sal_False; - if (!(i == ppData[i]->index())) - return sal_False; - } + // construct. + return new(pAddr) Entry (rxPage, nOffset); } - return sal_True; + return 0; } -/* - * __store_find_entry. - */ -static sal_uInt16 __store_find_entry ( - const OStorePageDescriptor &rDescr, - const OStorePageCacheEntry *pHead) +void EntryCache::destroy (Entry * entry) { - if (pHead) + if (entry != 0) { - if (pHead->m_aDescr.m_nAddr == rDescr.m_nAddr) - return pHead->index(); + // destruct. + entry->~Entry(); - OStorePageCacheEntry *pEntry = pHead->m_pNext; - while (pEntry != pHead) - { - if (pEntry->m_aDescr.m_nAddr == rDescr.m_nAddr) - return pEntry->index(); - else - pEntry = pEntry->m_pNext; - } + // return to cache. + rtl_cache_free (m_entry_cache, entry); } - return ((sal_uInt16)(-1)); } -#endif /* __STORE_CACHE_DEBUG */ - /*======================================================================== * - * OStorePageCache implementation. - * - * (two-way association (sorted address array, LRU chain)). - * (external OStorePageData representation). + * highbit():= log2() + 1 (complexity O(1)) * *======================================================================*/ -/* - * Allocation. - */ -void * OStorePageCache::operator new (std::size_t n) SAL_THROW(()) +static int highbit(sal_Size n) { - return rtl_allocateMemory (sal_uInt32(n)); -} + register int k = 1; -void OStorePageCache::operator delete (void * p, std::size_t) SAL_THROW(()) -{ - rtl_freeMemory (p); + if (n == 0) + return (0); +#if SAL_TYPES_SIZEOFLONG == 8 + if (n & 0xffffffff00000000ul) + k |= 32, n >>= 32; +#endif + if (n & 0xffff0000) + k |= 16, n >>= 16; + if (n & 0xff00) + k |= 8, n >>= 8; + if (n & 0xf0) + k |= 4, n >>= 4; + if (n & 0x0c) + k |= 2, n >>= 2; + if (n & 0x02) + k++; + + return (k); } -/* - * OStorePageCache. - */ -OStorePageCache::OStorePageCache (sal_uInt16 nPages) - : m_nSize (STORE_LIMIT_CACHEPAGES), - m_nUsed (0), - m_pHead (0), - m_nHit (0), - m_nMissed (0), - m_nUpdHit (0), - m_nUpdLRU (0), - m_nWrtBack (0) +/*======================================================================== + * + * PageCache_Impl implementation. + * + *======================================================================*/ +namespace store { - for (sal_uInt16 i = 0; i < m_nSize; i++) - m_pData[i] = NULL; - if (nPages < m_nSize) - m_nSize = nPages; -} -/* - * ~OStorePageCache. - */ -OStorePageCache::~OStorePageCache (void) +class PageCache_Impl : + public store::OStoreObject, + public store::PageCache { -#if OSL_DEBUG_LEVEL > 1 - double x = hitRatio(); - x = 0; -#endif /* OSL_DEBUG_LEVEL > 1 */ + /** Representation. + */ + static size_t const theTableSize = 32; + STORE_STATIC_ASSERT(STORE_IMPL_ISP2(theTableSize)); - for (sal_uInt16 i = 0; i < m_nSize; i++) - delete m_pData[i]; -} + Entry ** m_hash_table; + Entry * m_hash_table_0[theTableSize]; + size_t m_hash_size; + size_t m_hash_shift; + size_t const m_page_shift; -/* - * find. - */ -sal_uInt16 OStorePageCache::find (const OStorePageDescriptor &rDescr) const -{ - register sal_Int32 l = 0; - register sal_Int32 r = m_nUsed - 1; + size_t m_hash_entries; // total number of entries in table. + size_t m_nHit; + size_t m_nMissed; - while (l < r) + inline int hash_Impl(sal_uInt32 a, size_t s, size_t q, size_t m) { - register sal_Int32 m = ((l + r) >> 1); - - if (m_pData[m]->m_aDescr.m_nAddr == rDescr.m_nAddr) - return ((sal_uInt16)(m)); - if (m_pData[m]->m_aDescr.m_nAddr < rDescr.m_nAddr) - l = m + 1; - else - r = m - 1; + return ((((a) + ((a) >> (s)) + ((a) >> ((s) << 1))) >> (q)) & (m)); } + inline int hash_index_Impl (sal_uInt32 nOffset) + { + return hash_Impl(nOffset, m_hash_shift, m_page_shift, m_hash_size - 1); + } + + Entry * lookup_Impl (Entry * entry, sal_uInt32 nOffset); + void rescale_Impl (sal_Size new_size); + + /** PageCache Implementation. + */ + virtual storeError lookupPageAt_Impl ( + PageHolder & rxPage, + sal_uInt32 nOffset); + + virtual storeError insertPageAt_Impl ( + PageHolder const & rxPage, + sal_uInt32 nOffset); + + virtual storeError updatePageAt_Impl ( + PageHolder const & rxPage, + sal_uInt32 nOffset); + + virtual storeError removePageAt_Impl ( + sal_uInt32 nOffset); + + /** Not implemented. + */ + PageCache_Impl (PageCache_Impl const &); + PageCache_Impl & operator= (PageCache_Impl const &); + +public: + /** Construction. + */ + explicit PageCache_Impl (sal_uInt16 nPageSize); + + /** Delegate multiple inherited IReference. + */ + virtual oslInterlockedCount SAL_CALL acquire(); + virtual oslInterlockedCount SAL_CALL release(); + +protected: + /** Destruction. + */ + virtual ~PageCache_Impl (void); +}; + +} // namespace store - // Match or insert position. Caller must do final compare. - return ((sal_uInt16)(r)); +PageCache_Impl::PageCache_Impl (sal_uInt16 nPageSize) + : m_hash_table (m_hash_table_0), + m_hash_size (theTableSize), + m_hash_shift (highbit(m_hash_size) - 1), + m_page_shift (highbit(nPageSize) - 1), + m_hash_entries (0), + m_nHit (0), + m_nMissed (0) +{ + static size_t const theSize = sizeof(m_hash_table_0) / sizeof(m_hash_table_0[0]); + STORE_STATIC_ASSERT(theSize == theTableSize); + memset(m_hash_table_0, 0, sizeof(m_hash_table_0)); } -/* - * move. - */ -void OStorePageCache::move (sal_uInt16 nSI, sal_uInt16 nDI) +PageCache_Impl::~PageCache_Impl() { - entry *p = m_pData[nSI]; - if (nSI < nDI) + double s_x = 0.0, s_xx = 0.0; + sal_Size i, n = m_hash_size; + for (i = 0; i < n; i++) { - // shift left. - __store_memmove ( - &m_pData[nSI ], - &m_pData[nSI + 1], - (nDI - nSI) * sizeof(entry*)); - - // re-index. - for (sal_uInt16 i = nSI; i < nDI; i++) - m_pData[i]->index(i); + int x = 0; + Entry * entry = m_hash_table[i]; + while (entry != 0) + { + m_hash_table[i] = entry->m_pNext, entry->m_pNext = 0; + EntryCache::get().destroy (entry); + entry = m_hash_table[i]; + x += 1; + } + s_x += double(x); + s_xx += double(x) * double(x); } - if (nSI > nDI) + double ave = s_x / double(n); + OSL_TRACE("ave hash chain length: %g", ave); + (void) ave; + + if (m_hash_table != m_hash_table_0) { - // shift right. - __store_memmove ( - &m_pData[nDI + 1], - &m_pData[nDI ], - (nSI - nDI) * sizeof(entry*)); - - // re-index. - for (sal_uInt16 i = nSI; i > nDI; i--) - m_pData[i]->index(i); + rtl_freeMemory (m_hash_table); + m_hash_table = m_hash_table_0; + m_hash_size = theTableSize; + m_hash_shift = highbit(m_hash_size) - 1; } - m_pData[nDI] = p; - m_pData[nDI]->index(nDI); - -#ifdef __STORE_CACHE_DEBUG - OSL_POSTCOND( - __store_check_entry(&m_pData[0], m_nUsed), - "OStorePageCache::move(): check_entry() failed"); -#endif /* __STORE_CACHE_DEBUG */ + OSL_TRACE("Hits: %u, Misses: %u", m_nHit, m_nMissed); } -/* - * insert. - */ -storeError OStorePageCache::insert ( - sal_uInt16 nDI, - const OStorePageDescriptor &rDescr, - const OStorePageData &rData, - OStorePageBIOS &rBIOS, - InsertMode eMode) +oslInterlockedCount PageCache_Impl::acquire() { -#ifdef __STORE_CACHE_DEBUG - OSL_PRECOND( - __store_check_entry(&m_pData[0], m_nUsed), - "OStorePageCache::insert(): check_entry() failed"); -#endif /* __STORE_CACHE_DEBUG */ - - entry::CompareResult result = entry::COMPARE_EQUAL; - if (nDI < m_nUsed) - { - result = m_pData[nDI]->compare (rDescr); - if (result == entry::COMPARE_LESS) - nDI += 1; - } + return OStoreObject::acquire(); +} - if (nDI == (sal_uInt16)(-1)) - nDI = 0; - if (nDI == m_nSize) - nDI -= 1; +oslInterlockedCount PageCache_Impl::release() +{ + return OStoreObject::release(); +} - if (m_nUsed < m_nSize) - { - // Allocate cache entry. - m_pData[m_nUsed] = new entry (rDescr, rData); - move (m_nUsed, nDI); - m_nUsed++; - - // Update LRU. - if (m_pHead) - m_pHead->backlink (*m_pData[nDI]); - m_pHead = m_pData[nDI]; - } - else +void PageCache_Impl::rescale_Impl (sal_Size new_size) +{ + sal_Size new_bytes = new_size * sizeof(Entry*); + Entry ** new_table = (Entry**)(rtl_allocateMemory(new_bytes)); + + if (new_table != 0) { - // Check for invalidated cache entry. - sal_uInt16 nSI = m_nUsed - 1; - if (m_pData[nSI]->isValid()) - { - // Replace least recently used cache entry. - m_nUpdLRU++; + Entry ** old_table = m_hash_table; + sal_Size old_size = m_hash_size; - m_pHead = m_pHead->m_pPrev; - nSI = m_pHead->index(); + OSL_TRACE("ave chain length: %u, total entries: %u [old_size: %u, new_size: %u]", + m_hash_entries >> m_hash_shift, m_hash_entries, old_size, new_size); - // Check DirtyBit. - if (m_pHead->isDirty()) - { - // Save PageDescriptor. - OStorePageDescriptor aDescr (m_pHead->m_aDescr); - - // Write page. - storeError eErrCode = rBIOS.write ( - aDescr.m_nAddr, m_pHead->m_pData, aDescr.m_nSize); - if (eErrCode != store_E_None) - return eErrCode; - - // Mark as clean. - m_pHead->clean(); - m_nWrtBack++; - } - } - else + memset (new_table, 0, new_bytes); + + m_hash_table = new_table; + m_hash_size = new_size; + m_hash_shift = highbit(m_hash_size) - 1; + + sal_Size i; + for (i = 0; i < old_size; i++) { - // Replace invalidated cache entry. Check LRU. - if (!(m_pData[nSI] == m_pHead)) + Entry * curr = old_table[i]; + while (curr != 0) { - // Update LRU. - m_pData[nSI]->unlink(); - m_pHead->backlink (*m_pData[nSI]); - m_pHead = m_pData[nSI]; + Entry * next = curr->m_pNext; + int index = hash_index_Impl(curr->m_nOffset); + curr->m_pNext = m_hash_table[index], m_hash_table[index] = curr; + curr = next; } + old_table[i] = 0; } - - // Check source and destination indices. - if (nSI < nDI) + if (old_table != m_hash_table_0) { - result = m_pData[nDI]->compare(rDescr); - if (result == entry::COMPARE_GREATER) - nDI -= 1; + // + rtl_freeMemory (old_table); } - - // Assign data. - m_pData[nSI]->assign (rDescr, rData); - move (nSI, nDI); } - - // Check InsertMode. - if (eMode == INSERT_CLEAN) - m_pHead->clean(); - else - m_pHead->dirty(); - - // Done. - return store_E_None; } -/* - * load. - */ -storeError OStorePageCache::load ( - const OStorePageDescriptor &rDescr, - OStorePageData &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) +Entry * PageCache_Impl::lookup_Impl (Entry * entry, sal_uInt32 nOffset) { - // Enter. - STORE_METHOD_ENTER(pMutex); - - // Find cache index. - sal_uInt16 i = find (rDescr); - if (i < m_nUsed) + register int lookups = 0; + while (entry != 0) { - if (m_pData[i]->compare(rDescr) == entry::COMPARE_EQUAL) - { - // Cache hit. - m_nHit++; - - if (!(m_pData[i] == m_pHead)) - { - // Update LRU. - m_pData[i]->unlink(); - m_pHead->backlink (*m_pData[i]); - m_pHead = m_pData[i]; - } + if (entry->m_nOffset == nOffset) + break; - // Load data and Leave. - __store_memcpy (&rData, m_pHead->m_pData, rDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, store_E_None); - } + lookups += 1; + entry = entry->m_pNext; } + if (lookups > 2) + { + sal_Size new_size = m_hash_size, ave = m_hash_entries >> m_hash_shift; + for (; ave > 4; new_size *= 2, ave /= 2) + continue; + if (new_size != m_hash_size) + rescale_Impl (new_size); + } + return entry; +} - // Cache miss. - m_nMissed++; - - // Load data. - storeError eErrCode = rBIOS.read ( - rDescr.m_nAddr, &rData, rDescr.m_nSize); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); +storeError PageCache_Impl::lookupPageAt_Impl ( + PageHolder & rxPage, + sal_uInt32 nOffset) +{ + int index = hash_index_Impl(nOffset); + Entry const * entry = lookup_Impl (m_hash_table[index], nOffset); + if (entry != 0) + { + // Existing entry. + rxPage = entry->m_xPage; - // Insert data. - eErrCode = insert (i, rDescr, rData, rBIOS, INSERT_CLEAN); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + // Update stats and leave. + m_nHit += 1; + return store_E_None; + } - // Leave with pending verification. - STORE_METHOD_LEAVE(pMutex, store_E_Pending); + // Cache miss. Update stats and leave. + m_nMissed += 1; + return store_E_NotExists; } -/* - * update. - */ -storeError OStorePageCache::update ( - const OStorePageDescriptor &rDescr, - const OStorePageData &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex, - UpdateMode eMode) +storeError PageCache_Impl::insertPageAt_Impl ( + PageHolder const & rxPage, + sal_uInt32 nOffset) { - // Enter. - STORE_METHOD_ENTER(pMutex); - - // Check UpdateMode. - if (eMode == UPDATE_WRITE_THROUGH) + Entry * entry = EntryCache::get().create (rxPage, nOffset); + if (entry != 0) { - // Save data. - storeError eErrCode = rBIOS.write ( - rDescr.m_nAddr, &rData, rDescr.m_nSize); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - m_nWrtBack++; + // Insert new entry. + int index = hash_index_Impl(nOffset); + entry->m_pNext = m_hash_table[index], m_hash_table[index] = entry; + + // Update stats and leave. + m_hash_entries += 1; + return store_E_None; } + return store_E_OutOfMemory; +} - // Find cache index. - sal_uInt16 i = find (rDescr); - if (i < m_nUsed) +storeError PageCache_Impl::updatePageAt_Impl ( + PageHolder const & rxPage, + sal_uInt32 nOffset) +{ + int index = hash_index_Impl(nOffset); + Entry * entry = lookup_Impl (m_hash_table[index], nOffset); + if (entry != 0) { - if (m_pData[i]->compare(rDescr) == entry::COMPARE_EQUAL) - { - // Cache hit. Check LRU. - m_nUpdHit++; - if (!(m_pData[i] == m_pHead)) - { - // Update LRU. - m_pData[i]->unlink(); - m_pHead->backlink (*m_pData[i]); - m_pHead = m_pData[i]; - } + // Update existing entry. + entry->m_xPage = rxPage; - // Check UpdateMode. - if (eMode == UPDATE_WRITE_THROUGH) - m_pHead->clean(); - else - m_pHead->dirty(); - - // Update data and leave. - __store_memcpy (m_pHead->m_pData, &rData, rDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, store_E_None); - } + // Update stats and leave. // m_nUpdHit += 1; + return store_E_None; } - - // Cache miss. Insert data and leave. - storeError eErrCode = insert ( - i, rDescr, rData, rBIOS, - ((eMode == UPDATE_WRITE_THROUGH) ? INSERT_CLEAN : INSERT_DIRTY)); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return insertPageAt_Impl (rxPage, nOffset); } -/* - * invalidate. - */ -storeError OStorePageCache::invalidate ( - const OStorePageDescriptor &rDescr, - osl::Mutex *pMutex) +storeError PageCache_Impl::removePageAt_Impl ( + sal_uInt32 nOffset) { - // Enter. - STORE_METHOD_ENTER(pMutex); - - // Find cache index. - sal_uInt16 i = find (rDescr); - if (i < m_nUsed) + Entry ** ppEntry = &(m_hash_table[hash_index_Impl(nOffset)]); + while (*ppEntry != 0) { - if (m_pData[i]->compare(rDescr) == entry::COMPARE_EQUAL) + if ((*ppEntry)->m_nOffset == nOffset) { - // Cache hit. Update LRU. - if (!(m_pData[i] == m_pHead)) - { - m_pData[i]->unlink(); - m_pHead->backlink (*m_pData[i]); - } - else - { - m_pHead = m_pHead->m_pNext; - } + // Existing entry. + Entry * entry = (*ppEntry); - // Invalidate. - m_pData[i]->clean(); - m_pData[i]->invalidate(); - move (i, m_nUsed - 1); + // Dequeue and destroy entry. + (*ppEntry) = entry->m_pNext, entry->m_pNext = 0; + EntryCache::get().destroy (entry); + + // Update stats and leave. + m_hash_entries -= 1; + return store_E_None; } + ppEntry = &((*ppEntry)->m_pNext); } - - // Leave. - STORE_METHOD_LEAVE(pMutex, store_E_None); + return store_E_NotExists; } -/* - * flush. - */ -storeError OStorePageCache::flush ( - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) -{ - // Enter. - STORE_METHOD_ENTER(pMutex); +/*======================================================================== + * + * Old OStorePageCache implementation. + * + * (two-way association (sorted address array, LRU chain)). + * (external OStorePageData representation). + * + *======================================================================*/ - // Check all entries. - for (sal_uInt16 i = 0; i < m_nUsed; i++) - { - // Check for dirty entry. - if (m_pData[i]->isDirty() && m_pData[i]->isValid()) - { - // Save PageDescriptor. - OStorePageDescriptor aDescr (m_pData[i]->m_aDescr); - - // Write page. - storeError eErrCode = rBIOS.write ( - aDescr.m_nAddr, m_pData[i]->m_pData, aDescr.m_nSize); - OSL_POSTCOND( - eErrCode == store_E_None, - "OStorePageCache::flush(): write() failed"); - - // Mark entry clean. - if (eErrCode == store_E_None) - m_pData[i]->clean(); - m_nWrtBack++; - } - } +/*======================================================================== + * + * PageCache factory implementation. + * + *======================================================================*/ +namespace store { + +storeError +PageCache_createInstance ( + rtl::Reference< store::PageCache > & rxCache, + sal_uInt16 nPageSize) +{ + rxCache = new PageCache_Impl (nPageSize); + if (!rxCache.is()) + return store_E_OutOfMemory; - // Leave. - STORE_METHOD_LEAVE(pMutex, store_E_None); + return store_E_None; } + +} // namespace store diff --git a/store/source/storcach.hxx b/store/source/storcach.hxx index 661343657be5..eb98bb786df5 100644 --- a/store/source/storcach.hxx +++ b/store/source/storcach.hxx @@ -29,158 +29,79 @@ ************************************************************************/ #ifndef _STORE_STORCACH_HXX -#define _STORE_STORCACH_HXX "$Revision: 1.6 $" +#define _STORE_STORCACH_HXX "$Revision: 1.6.8.2 $" -#include -#include -#include +#include "sal/types.h" +#include "rtl/ref.hxx" -#ifndef INCLUDED_CSTDDEF -#include -#define INCLUDED_CSTDDEF -#endif +#include "store/types.h" +#include "storbase.hxx" namespace store { -struct OStorePageDescriptor; -struct OStorePageData; -class OStorePageBIOS; - /*======================================================================== * - * OStorePageCache interface. - * (OStorePageData in external representation) + * PageCache interface. * *======================================================================*/ -#define STORE_LIMIT_CACHEPAGES 256 -#define STORE_DEFAULT_CACHEPAGES STORE_LIMIT_CACHEPAGES - -struct OStorePageCacheEntry; -class OStorePageCache +class PageCache : public rtl::IReference { - typedef OStorePageCacheEntry entry; - public: - /** Allocation. + /** load. */ - static void * operator new (std::size_t n) SAL_THROW(()); - static void operator delete (void * p, std::size_t) SAL_THROW(()); - - /** Construction. - */ - OStorePageCache ( - sal_uInt16 nPages = STORE_DEFAULT_CACHEPAGES); + storeError lookupPageAt ( + PageHolder & rxPage, + sal_uInt32 nOffset); - /** Destruction. - */ - ~OStorePageCache (void); + /** insert. + */ + storeError insertPageAt ( + PageHolder const & rxPage, + sal_uInt32 nOffset); - /** load. - */ - storeError load ( - const OStorePageDescriptor &rDescr, - OStorePageData &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); - - /** update. - */ - enum UpdateMode - { - UPDATE_WRITE_THROUGH = 0, - UPDATE_WRITE_DELAYED = 1 - }; - - storeError update ( - const OStorePageDescriptor &rDescr, - const OStorePageData &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL, - UpdateMode eMode = UPDATE_WRITE_THROUGH); - - /** invalidate. - */ - storeError invalidate ( - const OStorePageDescriptor &rDescr, - osl::Mutex *pMutex = NULL); - - /** flush. - */ - storeError flush ( - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); - - /** hitRatio [nHit / (nHit + nMissed)]. + /** update, or insert. */ - inline double hitRatio (void) const; + storeError updatePageAt ( + PageHolder const & rxPage, + sal_uInt32 nOffset); - /** usageRatio [nUsed / nSize]. - */ - inline double usageRatio (void) const; + /** remove (invalidate). + */ + storeError removePageAt ( + sal_uInt32 nOffset); private: - /** Representation. - */ - sal_uInt16 m_nSize; - sal_uInt16 m_nUsed; - entry *m_pData[STORE_LIMIT_CACHEPAGES]; - entry *m_pHead; - - sal_uInt32 m_nHit; - sal_uInt32 m_nMissed; - sal_uInt32 m_nUpdHit; - sal_uInt32 m_nUpdLRU; - sal_uInt32 m_nWrtBack; - - /** Implementation. - */ - sal_uInt16 find (const OStorePageDescriptor &rDescr) const; - void move (sal_uInt16 nSI, sal_uInt16 nDI); + /** Implementation (abstract). + */ + virtual storeError lookupPageAt_Impl ( + PageHolder & rxPage, + sal_uInt32 nOffset) = 0; - /** insert. - */ - enum InsertMode - { - INSERT_CLEAN = 0, - INSERT_DIRTY = 1 - }; - - storeError insert ( - sal_uInt16 nIndex, - const OStorePageDescriptor &rDescr, - const OStorePageData &rData, - OStorePageBIOS &rBIOS, - InsertMode eMode = INSERT_CLEAN); - - /** Not implemented. - */ - OStorePageCache (const OStorePageCache& rOther); - OStorePageCache& operator= (const OStorePageCache& rOther); + virtual storeError insertPageAt_Impl ( + PageHolder const & rxPage, + sal_uInt32 nOffset) = 0; + + virtual storeError updatePageAt_Impl ( + PageHolder const & rxPage, + sal_uInt32 nOffset) = 0; + + virtual storeError removePageAt_Impl ( + sal_uInt32 nOffset) = 0; }; -/* - * hitRatio [nHit / (nHit + nMissed)]. - */ -inline double OStorePageCache::hitRatio (void) const -{ - if (m_nHit || m_nMissed) - return ((double)m_nHit / (double)(m_nHit + m_nMissed)); - else - return 1.0; -} - -/* - * usageRatio [nUsed / nSize]. - */ -inline double OStorePageCache::usageRatio (void) const -{ - if (m_nUsed < m_nSize) - return ((double)m_nUsed / (double)m_nSize); - else - return 1.0; -} +/*======================================================================== + * + * PageCache factory. + * + *======================================================================*/ + +storeError +PageCache_createInstance ( + rtl::Reference< store::PageCache > & rxCache, + sal_uInt16 nPageSize +); /*======================================================================== * diff --git a/store/source/stordata.cxx b/store/source/stordata.cxx index d0e155e5c79d..29350f8ebfdd 100644 --- a/store/source/stordata.cxx +++ b/store/source/stordata.cxx @@ -31,456 +31,448 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_store.hxx" -#define _STORE_STORDATA_CXX_ "$Revision: 1.6 $" -#include -#include -#include -#include -#include -#include -#include +#include "stordata.hxx" + +#include "sal/types.h" +#include "osl/diagnose.h" + +#include "store/types.h" +#include "storbase.hxx" +#include "storbios.hxx" using namespace store; /*======================================================================== * - * OStoreIndirectionPageData implementation. + * OStoreDataPageObject implementation. * *======================================================================*/ /* - * OStoreIndirectionPageData. + * guard. */ -OStoreIndirectionPageData::OStoreIndirectionPageData (sal_uInt16 nPageSize) - : OStorePageData (nPageSize) +storeError OStoreDataPageObject::guard (sal_uInt32 nAddr) { - initialize(); + return PageHolderObject< page >::guard (m_xPage, nAddr); } /* - * initialize. + * verify. */ -void OStoreIndirectionPageData::initialize (void) +storeError OStoreDataPageObject::verify (sal_uInt32 nAddr) const { - base::m_aGuard.m_nMagic = STORE_MAGIC_INDIRECTPAGE; - base::m_aDescr.m_nUsed = sal::static_int_cast< sal_uInt16 >( - base::m_aDescr.m_nUsed + self::size()); - self::m_aGuard.m_nMagic = 0; - - sal_uInt16 i, n = capacityCount(); - for (i = 0; i < n; i++) - m_pData[i] = STORE_PAGE_NULL; + return PageHolderObject< page >::verify (m_xPage, nAddr); +} + +/*======================================================================== + * + * OStoreIndirectionPageObject implementation. + * + *======================================================================*/ +/* + * store_truncate_Impl (single indirect page). + */ +static storeError store_truncate_Impl ( + sal_uInt32 nAddr, + sal_uInt16 nSingle, + OStorePageBIOS &rBIOS) +{ + if (nAddr != STORE_PAGE_NULL) + { + // Load single indirect page. + OStoreIndirectionPageObject aSingle; + storeError eErrCode = rBIOS.loadObjectAt (aSingle, nAddr); + if (eErrCode == store_E_None) + { + // Truncate to 'nSingle' direct pages. + eErrCode = aSingle.truncate (nSingle, rBIOS); + if (eErrCode != store_E_None) + return eErrCode; + } + else + { + if (eErrCode != store_E_InvalidChecksum) + return eErrCode; + } + + // Check for complete truncation. + if (nSingle == 0) + { + // Free single indirect page. + OStorePageData aPageHead; + eErrCode = rBIOS.free (aPageHead, nAddr); + if (eErrCode != store_E_None) + return eErrCode; + } + } + return store_E_None; } /* - * swap. + * store_truncate_Impl (double indirect page). */ -void OStoreIndirectionPageData::swap ( - const D& -#ifdef OSL_BIGENDIAN - rDescr -#endif /* OSL_BIGENDIAN */ -) +static storeError store_truncate_Impl ( + sal_uInt32 nAddr, + sal_uInt16 nDouble, + sal_uInt16 nSingle, + OStorePageBIOS &rBIOS) { -#ifdef OSL_BIGENDIAN - m_aGuard.swap(); + if (nAddr != STORE_PAGE_NULL) + { + // Load double indirect page. + OStoreIndirectionPageObject aDouble; + storeError eErrCode = rBIOS.loadObjectAt (aDouble, nAddr); + if (eErrCode == store_E_None) + { + // Truncate to 'nDouble', 'nSingle' pages. + eErrCode = aDouble.truncate (nDouble, nSingle, rBIOS); + if (eErrCode != store_E_None) + return eErrCode; + } + else + { + if (eErrCode != store_E_InvalidChecksum) + return eErrCode; + } - sal_uInt16 i, n = capacityCount (rDescr); - for (i = 0; i < n; i++) - m_pData[i] = OSL_SWAPDWORD(m_pData[i]); -#endif /* OSL_BIGENDIAN */ + // Check for complete truncation. + if ((nDouble + nSingle) == 0) + { + // Free double indirect page. + OStorePageData aPageHead; + eErrCode = rBIOS.free (aPageHead, nAddr); + if (eErrCode != store_E_None) + return eErrCode; + } + } + return store_E_None; } -/*======================================================================== - * - * OStoreIndirectionPageObject implementation. - * - *======================================================================*/ /* - * swap. + * store_truncate_Impl (triple indirect page). */ -void OStoreIndirectionPageObject::swap ( - const D& -#ifdef OSL_BIGENDIAN - rDescr -#endif /* OSL_BIGENDIAN */ -) +static storeError store_truncate_Impl ( + sal_uInt32 nAddr, + sal_uInt16 nTriple, + sal_uInt16 nDouble, + sal_uInt16 nSingle, + OStorePageBIOS &rBIOS) { -#ifdef OSL_BIGENDIAN - base::swap (rDescr); - m_rPage.swap (rDescr); -#endif /* OSL_BIGENDIAN */ + if (nAddr != STORE_PAGE_NULL) + { + // Load triple indirect page. + OStoreIndirectionPageObject aTriple; + storeError eErrCode = rBIOS.loadObjectAt (aTriple, nAddr); + if (eErrCode != store_E_None) + return eErrCode; + + // Truncate to 'nTriple', 'nDouble', 'nSingle' pages. + eErrCode = aTriple.truncate (nTriple, nDouble, nSingle, rBIOS); + if (eErrCode != store_E_None) + return eErrCode; + + // Check for complete truncation. + if ((nTriple + nDouble + nSingle) == 0) + { + // Free triple indirect page. + OStorePageData aPageHead; + eErrCode = rBIOS.free (aPageHead, nAddr); + if (eErrCode != store_E_None) + return eErrCode; + } + } + return store_E_None; +} + +/* + * loadOrCreate. + */ +storeError OStoreIndirectionPageObject::loadOrCreate ( + sal_uInt32 nAddr, + OStorePageBIOS & rBIOS) +{ + if (nAddr == STORE_PAGE_NULL) + { + storeError eErrCode = construct(rBIOS.allocator()); + if (eErrCode != store_E_None) + return eErrCode; + + eErrCode = rBIOS.allocate (*this); + if (eErrCode != store_E_None) + return eErrCode; + + // Save location pending at caller. + return store_E_Pending; + } + return rBIOS.loadObjectAt (*this, nAddr); } /* * guard. */ -void OStoreIndirectionPageObject::guard (const D& rDescr) +storeError OStoreIndirectionPageObject::guard (sal_uInt32 nAddr) { - base::guard (rDescr); - m_rPage.guard (rDescr); + return PageHolderObject< page >::guard (m_xPage, nAddr); } /* * verify. */ -storeError OStoreIndirectionPageObject::verify (const D& rDescr) +storeError OStoreIndirectionPageObject::verify (sal_uInt32 nAddr) const { - storeError eErrCode = base::verify (rDescr); - if (eErrCode != store_E_None) - return eErrCode; - else - return m_rPage.verify (rDescr); + return PageHolderObject< page >::verify (m_xPage, nAddr); } /* - * get (single indirect). + * read (single indirect). */ -storeError OStoreIndirectionPageObject::get ( +storeError OStoreIndirectionPageObject::read ( sal_uInt16 nSingle, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + OStorePageBIOS &rBIOS) { - // Enter. - STORE_METHOD_ENTER(pMutex); + PageHolderObject< page > xImpl (m_xPage); + page const & rPage = (*xImpl); // Check arguments. - if (!(nSingle < m_rPage.capacityCount())) - STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess); + sal_uInt16 const nLimit = rPage.capacityCount(); + if (!(nSingle < nLimit)) + return store_E_InvalidAccess; // Obtain data page location. - sal_uInt32 nAddr = m_rPage.m_pData[nSingle]; + sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nSingle]); if (nAddr == STORE_PAGE_NULL) - STORE_METHOD_LEAVE(pMutex, store_E_NotExists); + return store_E_NotExists; - // Load data page. - rData.location (nAddr); - storeError eErrCode = rBIOS.load (rData); - - // Leave. - STORE_METHOD_LEAVE(pMutex, eErrCode); + // Load data page and leave. + return rBIOS.loadObjectAt (rData, nAddr); } /* - * get (double indirect). + * read (double indirect). */ -storeError OStoreIndirectionPageObject::get ( +storeError OStoreIndirectionPageObject::read ( sal_uInt16 nDouble, sal_uInt16 nSingle, - page *&rpSingle, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + OStorePageBIOS &rBIOS) { - // Enter. - STORE_METHOD_ENTER(pMutex); + PageHolderObject< page > xImpl (m_xPage); + page const & rPage = (*xImpl); // Check arguments. - if (!((nDouble < m_rPage.capacityCount()) && - (nSingle < m_rPage.capacityCount()) )) - STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess); + sal_uInt16 const nLimit = rPage.capacityCount(); + if (!((nDouble < nLimit) && (nSingle < nLimit))) + return store_E_InvalidAccess; // Check single indirect page location. - if (m_rPage.m_pData[nDouble] == STORE_PAGE_NULL) - STORE_METHOD_LEAVE(pMutex, store_E_NotExists); - - // Check single indirect page buffer. - if (rpSingle == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpSingle = new(nPageSize) page(nPageSize); - } + sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nDouble]); + if (nAddr == STORE_PAGE_NULL) + return store_E_NotExists; // Load single indirect page. - OStoreIndirectionPageObject aSingle (*rpSingle); - aSingle.location (m_rPage.m_pData[nDouble]); - - storeError eErrCode = rBIOS.load (aSingle); + OStoreIndirectionPageObject aSingle; + storeError eErrCode = rBIOS.loadObjectAt (aSingle, nAddr); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - - // Get single indirect. - eErrCode = aSingle.get (nSingle, rData, rBIOS, NULL); + return eErrCode; - // Leave. - STORE_METHOD_LEAVE(pMutex, eErrCode); + // Read single indirect and leave. + return aSingle.read (nSingle, rData, rBIOS); } /* - * get (triple indirect). + * read (triple indirect). */ -storeError OStoreIndirectionPageObject::get ( +storeError OStoreIndirectionPageObject::read ( sal_uInt16 nTriple, sal_uInt16 nDouble, sal_uInt16 nSingle, - page *&rpDouble, - page *&rpSingle, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + OStorePageBIOS &rBIOS) { - // Enter. - STORE_METHOD_ENTER(pMutex); + PageHolderObject< page > xImpl (m_xPage); + page const & rPage = (*xImpl); // Check arguments. - if (!((nTriple < m_rPage.capacityCount()) && - (nDouble < m_rPage.capacityCount()) && - (nSingle < m_rPage.capacityCount()) )) - STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess); + sal_uInt16 const nLimit = rPage.capacityCount(); + if (!((nTriple < nLimit) && (nDouble < nLimit) && (nSingle < nLimit))) + return store_E_InvalidAccess; // Check double indirect page location. - if (m_rPage.m_pData[nTriple] == STORE_PAGE_NULL) - STORE_METHOD_LEAVE(pMutex, store_E_NotExists); - - // Check double indirect page buffer. - if (rpDouble == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpDouble = new(nPageSize) page(nPageSize); - } + sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nTriple]); + if (nAddr == STORE_PAGE_NULL) + return store_E_NotExists; // Load double indirect page. - OStoreIndirectionPageObject aDouble (*rpDouble); - aDouble.location (m_rPage.m_pData[nTriple]); - - storeError eErrCode = rBIOS.load (aDouble); + OStoreIndirectionPageObject aDouble; + storeError eErrCode = rBIOS.loadObjectAt (aDouble, nAddr); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - - // Get double indirect. - eErrCode = aDouble.get (nDouble, nSingle, rpSingle, rData, rBIOS, NULL); + return eErrCode; - // Leave. - STORE_METHOD_LEAVE(pMutex, eErrCode); + // Read double indirect and leave. + return aDouble.read (nDouble, nSingle, rData, rBIOS); } /* - * put (single indirect). + * write (single indirect). */ -storeError OStoreIndirectionPageObject::put ( +storeError OStoreIndirectionPageObject::write ( sal_uInt16 nSingle, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + OStorePageBIOS &rBIOS) { - // Enter. - STORE_METHOD_ENTER(pMutex); + PageHolderObject< page > xImpl (m_xPage); + page & rPage = (*xImpl); // Check arguments. - storeError eErrCode = store_E_InvalidAccess; - if (!(nSingle < m_rPage.capacityCount())) - STORE_METHOD_LEAVE(pMutex, eErrCode); + sal_uInt16 const nLimit = rPage.capacityCount(); + if (!(nSingle < nLimit)) + return store_E_InvalidAccess; // Obtain data page location. - rData.location (m_rPage.m_pData[nSingle]); - if (rData.location() == STORE_PAGE_NULL) + sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[nSingle]); + if (nAddr == STORE_PAGE_NULL) { // Allocate data page. - eErrCode = rBIOS.allocate (rData); + storeError eErrCode = rBIOS.allocate (rData); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; - // Save data page location. - m_rPage.m_pData[nSingle] = rData.location(); - touch(); + // Store data page location. + rPage.m_pData[nSingle] = store::htonl(rData.location()); // Save this page. - eErrCode = rBIOS.save (*this); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return rBIOS.saveObjectAt (*this, location()); } else { // Save data page. - eErrCode = rBIOS.save (rData); + return rBIOS.saveObjectAt (rData, nAddr); } - - // Leave. - STORE_METHOD_LEAVE(pMutex, eErrCode); } /* - * put (double indirect). + * write (double indirect). */ -storeError OStoreIndirectionPageObject::put ( +storeError OStoreIndirectionPageObject::write ( sal_uInt16 nDouble, sal_uInt16 nSingle, - page *&rpSingle, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + OStorePageBIOS &rBIOS) { - // Enter. - STORE_METHOD_ENTER(pMutex); + PageHolderObject< page > xImpl (m_xPage); + page & rPage = (*xImpl); // Check arguments. - storeError eErrCode = store_E_InvalidAccess; - if (!((nDouble < m_rPage.capacityCount()) && - (nSingle < m_rPage.capacityCount()) )) - STORE_METHOD_LEAVE(pMutex, eErrCode); + sal_uInt16 const nLimit = rPage.capacityCount(); + if (!((nDouble < nLimit) && (nSingle < nLimit))) + return store_E_InvalidAccess; - // Check single indirect page buffer. - if (rpSingle == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpSingle = new(nPageSize) page(nPageSize); - } - - // Obtain single indirect page location. - OStoreIndirectionPageObject aSingle (*rpSingle); - aSingle.location (m_rPage.m_pData[nDouble]); - if (aSingle.location() == STORE_PAGE_NULL) + // Load or create single indirect page. + OStoreIndirectionPageObject aSingle; + storeError eErrCode = aSingle.loadOrCreate (store::ntohl(rPage.m_pData[nDouble]), rBIOS); + if (eErrCode != store_E_None) { - // Initialize single indirect page buffer. - rpSingle->initialize(); + if (eErrCode != store_E_Pending) + return eErrCode; + rPage.m_pData[nDouble] = store::htonl(aSingle.location()); - // Allocate single indirect page. - eErrCode = rBIOS.allocate (aSingle); + eErrCode = rBIOS.saveObjectAt (*this, location()); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - - // Save single indirect page location. - m_rPage.m_pData[nDouble] = aSingle.location(); - touch(); - - // Save this page. - eErrCode = rBIOS.save (*this); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - } - else - { - // Load single indirect page. - eErrCode = rBIOS.load (aSingle); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } - // Put single indirect. - eErrCode = aSingle.put (nSingle, rData, rBIOS, NULL); - - // Leave. - STORE_METHOD_LEAVE(pMutex, eErrCode); + // Write single indirect and leave. + return aSingle.write (nSingle, rData, rBIOS); } /* - * put (triple indirect). + * write (triple indirect). */ -storeError OStoreIndirectionPageObject::put ( +storeError OStoreIndirectionPageObject::write ( sal_uInt16 nTriple, sal_uInt16 nDouble, sal_uInt16 nSingle, - page *&rpDouble, - page *&rpSingle, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + OStorePageBIOS &rBIOS) { - // Enter. - STORE_METHOD_ENTER(pMutex); + PageHolderObject< page > xImpl (m_xPage); + page & rPage = (*xImpl); // Check arguments. - storeError eErrCode = store_E_InvalidAccess; - if (!((nTriple < m_rPage.capacityCount()) && - (nDouble < m_rPage.capacityCount()) && - (nSingle < m_rPage.capacityCount()) )) - STORE_METHOD_LEAVE(pMutex, eErrCode); - - // Check double indirect page buffer. - if (rpDouble == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpDouble = new(nPageSize) page(nPageSize); - } + sal_uInt16 const nLimit = rPage.capacityCount(); + if (!((nTriple < nLimit) && (nDouble < nLimit) && (nSingle < nLimit))) + return store_E_InvalidAccess; - // Obtain double indirect page location. - OStoreIndirectionPageObject aDouble (*rpDouble); - aDouble.location (m_rPage.m_pData[nTriple]); - if (aDouble.location() == STORE_PAGE_NULL) + // Load or create double indirect page. + OStoreIndirectionPageObject aDouble; + storeError eErrCode = aDouble.loadOrCreate (store::ntohl(rPage.m_pData[nTriple]), rBIOS); + if (eErrCode != store_E_None) { - // Initialize double indirect page buffer. - rpDouble->initialize(); - - // Allocate double indirect page. - eErrCode = rBIOS.allocate (aDouble); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + if (eErrCode != store_E_Pending) + return eErrCode; + rPage.m_pData[nTriple] = store::htonl(aDouble.location()); - // Save double indirect page location. - m_rPage.m_pData[nTriple] = aDouble.location(); - touch(); - - // Save this page. - eErrCode = rBIOS.save (*this); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - } - else - { - // Load double indirect page. - eErrCode = rBIOS.load (aDouble); + eErrCode = rBIOS.saveObjectAt (*this, location()); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } - // Put double indirect. - eErrCode = aDouble.put (nDouble, nSingle, rpSingle, rData, rBIOS, NULL); - - // Leave. - STORE_METHOD_LEAVE(pMutex, eErrCode); + // Write double indirect and leave. + return aDouble.write (nDouble, nSingle, rData, rBIOS); } /* * truncate (single indirect). */ storeError OStoreIndirectionPageObject::truncate ( - sal_uInt16 nSingle, - OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + sal_uInt16 nSingle, + OStorePageBIOS & rBIOS) { - // Enter. - STORE_METHOD_ENTER(pMutex); + PageHolderObject< page > xImpl (m_xPage); + page & rPage = (*xImpl); // Check arguments. - sal_uInt16 i, n = m_rPage.capacityCount(); - if (!(nSingle < n)) - STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess); + sal_uInt16 const nLimit = rPage.capacityCount(); + if (!(nSingle < nLimit)) + return store_E_InvalidAccess; // Save PageDescriptor. - D aDescr (m_rPage.m_aDescr); + OStorePageDescriptor aDescr (rPage.m_aDescr); + aDescr.m_nAddr = store::ntohl(aDescr.m_nAddr); + aDescr.m_nSize = store::ntohs(aDescr.m_nSize); // Acquire Lock. storeError eErrCode = rBIOS.acquireLock (aDescr.m_nAddr, aDescr.m_nSize); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; // Truncate. - for (i = n; i > nSingle; i--) + for (sal_uInt16 i = nLimit; i > nSingle; i--) { // Obtain data page location. - sal_uInt32 nAddr = m_rPage.m_pData[i - 1]; - if (nAddr == STORE_PAGE_NULL) continue; - - // Free data page. - rData.location (nAddr); - eErrCode = rBIOS.free (rData); - if (eErrCode != store_E_None) + sal_uInt32 const nAddr = store::ntohl(rPage.m_pData[i - 1]); + if (nAddr != STORE_PAGE_NULL) { - rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); - } + // Free data page. + OStorePageData aPageHead; + eErrCode = rBIOS.free (aPageHead, nAddr); + if (eErrCode != store_E_None) + { + rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); + return eErrCode; + } - // Clear pointer to data page. - m_rPage.m_pData[i - 1] = STORE_PAGE_NULL; - touch(); + // Clear pointer to data page. + rPage.m_pData[i - 1] = STORE_PAGE_NULL; + touch(); + } } // Check for modified page. if (dirty()) { // Save this page. - eErrCode = rBIOS.save (*this); + eErrCode = rBIOS.saveObjectAt (*this, location()); if (eErrCode != store_E_None) { // Must not happen. @@ -488,13 +480,12 @@ storeError OStoreIndirectionPageObject::truncate ( // Release Lock and Leave. rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } } // Release Lock and Leave. - eErrCode = rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); } /* @@ -503,136 +494,63 @@ storeError OStoreIndirectionPageObject::truncate ( storeError OStoreIndirectionPageObject::truncate ( sal_uInt16 nDouble, sal_uInt16 nSingle, - page *&rpSingle, - OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + OStorePageBIOS &rBIOS) { - // Acquire Mutex. - STORE_METHOD_ENTER(pMutex); + PageHolderObject< page > xImpl (m_xPage); + page & rPage = (*xImpl); // Check arguments. - if (!((nDouble < m_rPage.capacityCount()) && - (nSingle < m_rPage.capacityCount()) )) - STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess); + sal_uInt16 const nLimit = rPage.capacityCount(); + if (!((nDouble < nLimit) && (nSingle < nLimit))) + return store_E_InvalidAccess; // Save PageDescriptor. - D aDescr (m_rPage.m_aDescr); + OStorePageDescriptor aDescr (rPage.m_aDescr); + aDescr.m_nAddr = store::ntohl(aDescr.m_nAddr); + aDescr.m_nSize = store::ntohs(aDescr.m_nSize); // Acquire Lock. storeError eErrCode = rBIOS.acquireLock (aDescr.m_nAddr, aDescr.m_nSize); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; // Truncate. - sal_uInt16 i, n = m_rPage.capacityCount(); - for (i = n; i > nDouble + 1; i--) + for (sal_uInt16 i = nLimit; i > nDouble + 1; i--) { - // Obtain single indirect page location. - sal_uInt32 nAddr = m_rPage.m_pData[i - 1]; - if (nAddr == STORE_PAGE_NULL) continue; - - // Check single indirect page buffer. - if (rpSingle == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpSingle = new(nPageSize) page(nPageSize); - } - - // Load single indirect page. - OStoreIndirectionPageObject aSingle (*rpSingle); - aSingle.location (nAddr); - - eErrCode = rBIOS.load (aSingle); - if (eErrCode == store_E_None) - { - // Truncate to zero direct pages. - eErrCode = aSingle.truncate (0, rData, rBIOS, NULL); - if (eErrCode != store_E_None) - { - rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); - } - - // Free single indirect page. - eErrCode = rBIOS.free (aSingle); - if (eErrCode != store_E_None) - { - rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); - } - } - else + // Truncate single indirect page to zero direct pages. + eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[i - 1]), 0, rBIOS); + if (eErrCode != store_E_None) { - if (eErrCode != store_E_InvalidChecksum) - { - rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); - } + rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); + return eErrCode; } // Clear pointer to single indirect page. - m_rPage.m_pData[i - 1] = STORE_PAGE_NULL; + rPage.m_pData[i - 1] = STORE_PAGE_NULL; touch(); } - // Obtain last single indirect page location. - sal_uInt32 nAddr = m_rPage.m_pData[nDouble]; - if (nAddr != STORE_PAGE_NULL) + // Truncate last single indirect page to 'nSingle' direct pages. + eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[nDouble]), nSingle, rBIOS); + if (eErrCode != store_E_None) { - // Check single indirect page buffer. - if (rpSingle == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpSingle = new(nPageSize) page(nPageSize); - } - - // Load last single indirect page. - OStoreIndirectionPageObject aSingle (*rpSingle); - aSingle.location (nAddr); - - eErrCode = rBIOS.load (aSingle); - if (eErrCode == store_E_None) - { - // Truncate to 'nSingle' direct pages. - eErrCode = aSingle.truncate (nSingle, rData, rBIOS, NULL); - if (eErrCode != store_E_None) - { - rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); - } - } - else - { - if (eErrCode != store_E_InvalidChecksum) - { - rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); - } - } - - // Check for complete truncation. - if (nSingle == 0) - { - // Free last single indirect page. - eErrCode = rBIOS.free (aSingle); - if (eErrCode != store_E_None) - { - rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); - } + rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); + return eErrCode; + } - // Clear pointer to last single indirect page. - m_rPage.m_pData[nDouble] = STORE_PAGE_NULL; - touch(); - } + // Check for complete truncation. + if (nSingle == 0) + { + // Clear pointer to last single indirect page. + rPage.m_pData[nDouble] = STORE_PAGE_NULL; + touch(); } // Check for modified page. if (dirty()) { // Save this page. - eErrCode = rBIOS.save (*this); + eErrCode = rBIOS.saveObjectAt (*this, location()); if (eErrCode != store_E_None) { // Must not happen. @@ -640,13 +558,12 @@ storeError OStoreIndirectionPageObject::truncate ( // Release Lock and Leave. rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } } // Release Lock and Leave. - eErrCode = rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); } /* @@ -656,140 +573,63 @@ storeError OStoreIndirectionPageObject::truncate ( sal_uInt16 nTriple, sal_uInt16 nDouble, sal_uInt16 nSingle, - page *&rpDouble, - page *&rpSingle, - OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + OStorePageBIOS &rBIOS) { - // Enter. - STORE_METHOD_ENTER(pMutex); + PageHolderObject< page > xImpl (m_xPage); + page & rPage = (*xImpl); // Check arguments. - if (!((nTriple < m_rPage.capacityCount()) && - (nDouble < m_rPage.capacityCount()) && - (nSingle < m_rPage.capacityCount()) )) - STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess); + sal_uInt16 const nLimit = rPage.capacityCount(); + if (!((nTriple < nLimit) && (nDouble < nLimit) && (nSingle < nLimit))) + return store_E_InvalidAccess; // Save PageDescriptor. - D aDescr (m_rPage.m_aDescr); + OStorePageDescriptor aDescr (rPage.m_aDescr); + aDescr.m_nAddr = store::ntohl(aDescr.m_nAddr); + aDescr.m_nSize = store::ntohs(aDescr.m_nSize); // Acquire Lock. storeError eErrCode = rBIOS.acquireLock (aDescr.m_nAddr, aDescr.m_nSize); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; // Truncate. - sal_uInt16 i, n = m_rPage.capacityCount(); - for (i = n; i > nTriple + 1; i--) + for (sal_uInt16 i = nLimit; i > nTriple + 1; i--) { - // Obtain double indirect page location. - sal_uInt32 nAddr = m_rPage.m_pData[i - 1]; - if (nAddr == STORE_PAGE_NULL) continue; - - // Check double indirect page buffer. - if (rpDouble == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpDouble = new(nPageSize) page(nPageSize); - } - - // Load double indirect page. - OStoreIndirectionPageObject aDouble (*rpDouble); - aDouble.location (nAddr); - - eErrCode = rBIOS.load (aDouble); - if (eErrCode == store_E_None) - { - // Truncate to zero single indirect pages. - eErrCode = aDouble.truncate ( - 0, 0, rpSingle, rData, rBIOS, NULL); - if (eErrCode != store_E_None) - { - rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); - } - - // Free double indirect page. - eErrCode = rBIOS.free (aDouble); - if (eErrCode != store_E_None) - { - rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); - } - } - else + // Truncate double indirect page to zero single indirect pages. + eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[i - 1]), 0, 0, rBIOS); + if (eErrCode != store_E_None) { - if (eErrCode != store_E_InvalidChecksum) - { - rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); - } + rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); + return eErrCode; } // Clear pointer to double indirect page. - m_rPage.m_pData[i - 1] = STORE_PAGE_NULL; + rPage.m_pData[i - 1] = STORE_PAGE_NULL; touch(); } - // Obtain last double indirect page location. - sal_uInt32 nAddr = m_rPage.m_pData[nTriple]; - if (nAddr != STORE_PAGE_NULL) + // Truncate last double indirect page to 'nDouble', 'nSingle' pages. + eErrCode = store_truncate_Impl (store::ntohl(rPage.m_pData[nTriple]), nDouble, nSingle, rBIOS); + if (eErrCode != store_E_None) { - // Check double indirect page buffer. - if (rpDouble == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpDouble = new(nPageSize) page(nPageSize); - } - - // Load last double indirect page. - OStoreIndirectionPageObject aDouble (*rpDouble); - aDouble.location (nAddr); - - eErrCode = rBIOS.load (aDouble); - if (eErrCode == store_E_None) - { - // Truncate to 'nDouble', 'nSingle' pages. - eErrCode = aDouble.truncate ( - nDouble, nSingle, rpSingle, rData, rBIOS, NULL); - if (eErrCode != store_E_None) - { - rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); - } - } - else - { - if (eErrCode != store_E_InvalidChecksum) - { - rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); - } - } - - // Check for complete truncation. - if ((nDouble + nSingle) == 0) - { - // Free last double indirect page. - eErrCode = rBIOS.free (aDouble); - if (eErrCode != store_E_None) - { - rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); - } + rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); + return eErrCode; + } - // Clear pointer to last double indirect page. - m_rPage.m_pData[nTriple] = STORE_PAGE_NULL; - touch(); - } + // Check for complete truncation. + if ((nDouble + nSingle) == 0) + { + // Clear pointer to last double indirect page. + rPage.m_pData[nTriple] = STORE_PAGE_NULL; + touch(); } // Check for modified page. if (dirty()) { // Save this page. - eErrCode = rBIOS.save (*this); + eErrCode = rBIOS.saveObjectAt (*this, location()); if (eErrCode != store_E_None) { // Must not happen. @@ -797,60 +637,12 @@ storeError OStoreIndirectionPageObject::truncate ( // Release Lock and Leave. rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } } // Release Lock and Leave. - eErrCode = rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); -} - -/*======================================================================== - * - * OStoreDirectoryDataBlock::LinkTable implementation. - * - *======================================================================*/ -/* - * LinkTable::LinkTable. - */ -OStoreDirectoryDataBlock::LinkTable::LinkTable (void) -{ - initialize(); -} - -/* - * LinkTable::initialize. - */ -void OStoreDirectoryDataBlock::LinkTable::initialize (void) -{ - sal_Int32 i; - for (i = 0; i < STORE_LIMIT_DATAPAGE_DIRECT; i++) - m_pDirect[i] = STORE_PAGE_NULL; - for (i = 0; i < STORE_LIMIT_DATAPAGE_SINGLE; i++) - m_pSingle[i] = STORE_PAGE_NULL; - for (i = 0; i < STORE_LIMIT_DATAPAGE_DOUBLE; i++) - m_pDouble[i] = STORE_PAGE_NULL; - for (i = 0; i < STORE_LIMIT_DATAPAGE_TRIPLE; i++) - m_pTriple[i] = STORE_PAGE_NULL; -} - -/* - * LinkTable::swap. - */ -void OStoreDirectoryDataBlock::LinkTable::swap (void) -{ -#ifdef OSL_BIGENDIAN - sal_Int32 i; - for (i = 0; i < STORE_LIMIT_DATAPAGE_DIRECT; i++) - m_pDirect[i] = OSL_SWAPDWORD(m_pDirect[i]); - for (i = 0; i < STORE_LIMIT_DATAPAGE_SINGLE; i++) - m_pSingle[i] = OSL_SWAPDWORD(m_pSingle[i]); - for (i = 0; i < STORE_LIMIT_DATAPAGE_DOUBLE; i++) - m_pDouble[i] = OSL_SWAPDWORD(m_pDouble[i]); - for (i = 0; i < STORE_LIMIT_DATAPAGE_TRIPLE; i++) - m_pTriple[i] = OSL_SWAPDWORD(m_pTriple[i]); -#endif /* OSL_BIGENDIAN */ + return rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); } /*======================================================================== @@ -858,56 +650,38 @@ void OStoreDirectoryDataBlock::LinkTable::swap (void) * OStoreDirectoryPageObject implementation. * *======================================================================*/ -/* - * swap. - */ -void OStoreDirectoryPageObject::swap ( - const D& -#ifdef OSL_BIGENDIAN - rDescr -#endif /* OSL_BIGENDIAN */ -) -{ -#ifdef OSL_BIGENDIAN - base::swap (rDescr); - m_rPage.swap (); -#endif /* OSL_BIGENDIAN */ -} - /* * guard. */ -void OStoreDirectoryPageObject::guard (const D& rDescr) +storeError OStoreDirectoryPageObject::guard (sal_uInt32 nAddr) { - base::guard (rDescr); - m_rPage.guard (); + return PageHolderObject< page >::guard (m_xPage, nAddr); } /* * verify. */ -storeError OStoreDirectoryPageObject::verify (const D& rDescr) +storeError OStoreDirectoryPageObject::verify (sal_uInt32 nAddr) const { - storeError eErrCode = base::verify (rDescr); - if (eErrCode != store_E_None) - return eErrCode; - else - return m_rPage.verify (); + return PageHolderObject< page >::verify (m_xPage, nAddr); + // OLD: m_rPage.verifyVersion (STORE_MAGIC_DIRECTORYPAGE); } /* - * scope (external data page). + * scope (external data page; private). */ OStoreDirectoryPageData::ChunkScope OStoreDirectoryPageObject::scope ( sal_uInt32 nPage, page::DataBlock::LinkDescriptor &rDescr) const { - typedef OStoreIndirectionPageData indrct; + page const & rPage = PAGE(); + OStoreDirectoryDataBlock const & rDataBlock = rPage.m_aDataBlock; + sal_uInt32 index0, index1, index2, index3; // direct. - sal_uInt32 nCount = m_rPage.m_aDataBlock.directCount(); + sal_uInt32 nCount = rDataBlock.directCount(); sal_uInt32 nLimit = nCount; if (nPage < nLimit) { @@ -923,8 +697,8 @@ OStoreDirectoryPageObject::scope ( nPage -= nLimit; // single indirect. - sal_uInt32 nCapacity = indrct::capacityCount(m_rPage.m_aDescr); - nCount = m_rPage.m_aDataBlock.singleCount(); + sal_uInt32 const nCapacity = indirect::capacityCount(rPage.m_aDescr); + nCount = rDataBlock.singleCount(); nLimit = nCount * nCapacity; if (nPage < nLimit) { @@ -951,7 +725,7 @@ OStoreDirectoryPageObject::scope ( nPage -= nLimit; // double indirect. - nCount = m_rPage.m_aDataBlock.doubleCount(); + nCount = rDataBlock.doubleCount(); nLimit = nCount * nCapacity * nCapacity; if (nPage < nLimit) { @@ -984,7 +758,7 @@ OStoreDirectoryPageObject::scope ( nPage -= nLimit; // triple indirect. - nCount = m_rPage.m_aDataBlock.tripleCount(); + nCount = rDataBlock.tripleCount(); nLimit = nCount * nCapacity * nCapacity * nCapacity; if (nPage < nLimit) { @@ -1025,21 +799,39 @@ OStoreDirectoryPageObject::scope ( return page::SCOPE_UNREACHABLE; } +#if 0 /* NYI */ /* - * get (external data page). + * chunk (external data page). */ -storeError OStoreDirectoryPageObject::get ( +inode::ChunkDescriptor OStoreDirectoryPageObject::chunk (sal_uInt32 nOffset) +{ + // @@@ INSUFFICIENT: NEED SCOPE AS WELL @@@ + sal_uInt32 nCapacity = m_rPage.capacity(); + if (nOffset < nCapacity) + // Internal scope (inode page). + return inode::ChunkDescriptor (nOffset, nCapacity); + else + // External scope (data page). + return inode::ChunkDescriptor (nOffset - nCapacity, data::capacity(m_rPage.m_aDescr)); + + inode::ChunkScope eScope = m_rPage.scope(nOffset); + if (eScope == inode::SCOPE_INTERNAL) + // Inode page (internal scope). + return inode::ChunkDescriptor (nOffset, m_rPage.capacity()); + else + // Data page (external scope). + return inode::ChunkDescriptor (nOffset - m_rPage.capacity(), data::capacity(m_rPage.m_aDescr)); +} +#endif /* NYI */ + +/* + * read (external data page). + */ +storeError OStoreDirectoryPageObject::read ( sal_uInt32 nPage, - indirect *&rpSingle, - indirect *&rpDouble, - indirect *&rpTriple, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + OStorePageBIOS &rBIOS) { - // Enter. - STORE_METHOD_ENTER(pMutex); - // Determine scope and link indices. page::DataBlock::LinkDescriptor aLink; page::ChunkScope eScope = scope (nPage, aLink); @@ -1047,87 +839,50 @@ storeError OStoreDirectoryPageObject::get ( storeError eErrCode = store_E_None; if (eScope == page::SCOPE_DIRECT) { - sal_uInt32 nAddr = directLink (aLink.m_nIndex0); + sal_uInt32 const nAddr = directLink (aLink.m_nIndex0); if (nAddr == STORE_PAGE_NULL) - STORE_METHOD_LEAVE(pMutex, store_E_NotExists); + return store_E_NotExists; - rData.location (nAddr); - eErrCode = rBIOS.load (rData); + eErrCode = rBIOS.loadObjectAt (rData, nAddr); } else if (eScope == page::SCOPE_SINGLE) { - sal_uInt32 nAddr = singleLink (aLink.m_nIndex1); + sal_uInt32 const nAddr = singleLink (aLink.m_nIndex1); if (nAddr == STORE_PAGE_NULL) - STORE_METHOD_LEAVE(pMutex, store_E_NotExists); - - if (rpSingle == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpSingle = new(nPageSize) indirect(nPageSize); - } + return store_E_NotExists; - OStoreIndirectionPageObject aSingle (*rpSingle); - aSingle.location (nAddr); - - eErrCode = rBIOS.load (aSingle); + OStoreIndirectionPageObject aSingle; + eErrCode = rBIOS.loadObjectAt (aSingle, nAddr); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; - eErrCode = aSingle.get ( - aLink.m_nIndex0, - rData, rBIOS, NULL); + eErrCode = aSingle.read (aLink.m_nIndex0, rData, rBIOS); } else if (eScope == page::SCOPE_DOUBLE) { - sal_uInt32 nAddr = doubleLink (aLink.m_nIndex2); + sal_uInt32 const nAddr = doubleLink (aLink.m_nIndex2); if (nAddr == STORE_PAGE_NULL) - STORE_METHOD_LEAVE(pMutex, store_E_NotExists); + return store_E_NotExists; - if (rpDouble == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpDouble = new(nPageSize) indirect(nPageSize); - } - - OStoreIndirectionPageObject aDouble (*rpDouble); - aDouble.location (nAddr); - - eErrCode = rBIOS.load (aDouble); + OStoreIndirectionPageObject aDouble; + eErrCode = rBIOS.loadObjectAt (aDouble, nAddr); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; - eErrCode = aDouble.get ( - aLink.m_nIndex1, - aLink.m_nIndex0, - rpSingle, - rData, rBIOS, NULL); + eErrCode = aDouble.read (aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS); } else if (eScope == page::SCOPE_TRIPLE) { - sal_uInt32 nAddr = tripleLink (aLink.m_nIndex3); + sal_uInt32 const nAddr = tripleLink (aLink.m_nIndex3); if (nAddr == STORE_PAGE_NULL) - STORE_METHOD_LEAVE(pMutex, store_E_NotExists); - - if (rpTriple == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpTriple = new(nPageSize) indirect(nPageSize); - } - - OStoreIndirectionPageObject aTriple (*rpTriple); - aTriple.location (nAddr); + return store_E_NotExists; - eErrCode = rBIOS.load (aTriple); + OStoreIndirectionPageObject aTriple; + eErrCode = rBIOS.loadObjectAt (aTriple, nAddr); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - - eErrCode = aTriple.get ( - aLink.m_nIndex2, - aLink.m_nIndex1, - aLink.m_nIndex0, - rpDouble, - rpSingle, - rData, rBIOS, NULL); + return eErrCode; + + eErrCode = aTriple.read (aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS); } else if (eScope == page::SCOPE_UNREACHABLE) { @@ -1142,24 +897,17 @@ storeError OStoreDirectoryPageObject::get ( } // Leave. - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } /* - * put (external data page). + * write (external data page). */ -storeError OStoreDirectoryPageObject::put ( +storeError OStoreDirectoryPageObject::write ( sal_uInt32 nPage, - indirect *&rpSingle, - indirect *&rpDouble, - indirect *&rpTriple, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + OStorePageBIOS &rBIOS) { - // Enter. - STORE_METHOD_ENTER(pMutex); - // Determine scope and link indices. page::DataBlock::LinkDescriptor aLink; page::ChunkScope eScope = scope (nPage, aLink); @@ -1167,118 +915,61 @@ storeError OStoreDirectoryPageObject::put ( storeError eErrCode = store_E_None; if (eScope == page::SCOPE_DIRECT) { - rData.location (directLink (aLink.m_nIndex0)); - if (rData.location() == STORE_PAGE_NULL) + sal_uInt32 const nAddr = directLink (aLink.m_nIndex0); + if (nAddr == STORE_PAGE_NULL) { + // Allocate data page. eErrCode = rBIOS.allocate (rData); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; + // Store data page location. directLink (aLink.m_nIndex0, rData.location()); } else { - eErrCode = rBIOS.save (rData); + // Save data page. + eErrCode = rBIOS.saveObjectAt (rData, nAddr); } } else if (eScope == page::SCOPE_SINGLE) { - if (rpSingle == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpSingle = new(nPageSize) indirect(nPageSize); - } - - OStoreIndirectionPageObject aSingle (*rpSingle); - aSingle.location (singleLink (aLink.m_nIndex1)); - if (aSingle.location() == STORE_PAGE_NULL) + OStoreIndirectionPageObject aSingle; + eErrCode = aSingle.loadOrCreate (singleLink (aLink.m_nIndex1), rBIOS); + if (eErrCode != store_E_None) { - rpSingle->initialize(); - - eErrCode = rBIOS.allocate (aSingle); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - + if (eErrCode != store_E_Pending) + return eErrCode; singleLink (aLink.m_nIndex1, aSingle.location()); } - else - { - eErrCode = rBIOS.load (aSingle); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - } - eErrCode = aSingle.put ( - aLink.m_nIndex0, - rData, rBIOS, NULL); + eErrCode = aSingle.write (aLink.m_nIndex0, rData, rBIOS); } else if (eScope == page::SCOPE_DOUBLE) { - if (rpDouble == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpDouble = new(nPageSize) indirect(nPageSize); - } - - OStoreIndirectionPageObject aDouble (*rpDouble); - aDouble.location (doubleLink (aLink.m_nIndex2)); - if (aDouble.location() == STORE_PAGE_NULL) + OStoreIndirectionPageObject aDouble; + eErrCode = aDouble.loadOrCreate (doubleLink (aLink.m_nIndex2), rBIOS); + if (eErrCode != store_E_None) { - rpDouble->initialize(); - - eErrCode = rBIOS.allocate (aDouble); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - + if (eErrCode != store_E_Pending) + return eErrCode; doubleLink (aLink.m_nIndex2, aDouble.location()); } - else - { - eErrCode = rBIOS.load (aDouble); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - } - eErrCode = aDouble.put ( - aLink.m_nIndex1, - aLink.m_nIndex0, - rpSingle, - rData, rBIOS, NULL); + eErrCode = aDouble.write (aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS); } else if (eScope == page::SCOPE_TRIPLE) { - if (rpTriple == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpTriple = new(nPageSize) indirect(nPageSize); - } - - OStoreIndirectionPageObject aTriple (*rpTriple); - aTriple.location (tripleLink (aLink.m_nIndex3)); - if (aTriple.location() == STORE_PAGE_NULL) + OStoreIndirectionPageObject aTriple; + eErrCode = aTriple.loadOrCreate (tripleLink (aLink.m_nIndex3), rBIOS); + if (eErrCode != store_E_None) { - rpTriple->initialize(); - - eErrCode = rBIOS.allocate (aTriple); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - + if (eErrCode != store_E_Pending) + return eErrCode; tripleLink (aLink.m_nIndex3, aTriple.location()); } - else - { - eErrCode = rBIOS.load (aTriple); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - } - eErrCode = aTriple.put ( - aLink.m_nIndex2, - aLink.m_nIndex1, - aLink.m_nIndex0, - rpDouble, - rpSingle, - rData, rBIOS, NULL); + eErrCode = aTriple.write (aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rData, rBIOS); } else if (eScope == page::SCOPE_UNREACHABLE) { @@ -1293,7 +984,7 @@ storeError OStoreDirectoryPageObject::put ( } // Leave. - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } /* @@ -1301,16 +992,8 @@ storeError OStoreDirectoryPageObject::put ( */ storeError OStoreDirectoryPageObject::truncate ( sal_uInt32 nPage, - indirect *&rpSingle, - indirect *&rpDouble, - indirect *&rpTriple, - OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + OStorePageBIOS &rBIOS) { - // Enter. - STORE_METHOD_ENTER(pMutex); - // Determine scope and link indices. page::DataBlock::LinkDescriptor aLink; page::ChunkScope eScope = scope (nPage, aLink); @@ -1319,209 +1002,95 @@ storeError OStoreDirectoryPageObject::truncate ( if (eScope == page::SCOPE_DIRECT) { // Truncate all triple indirect pages. - eErrCode = truncate ( - page::SCOPE_TRIPLE, 0, - rpSingle, rpDouble, rpTriple, - rData, rBIOS, NULL); + eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; // Truncate all double indirect pages. - eErrCode = truncate ( - page::SCOPE_DOUBLE, 0, - rpSingle, rpDouble, rpTriple, - rData, rBIOS, NULL); + eErrCode = truncate (page::SCOPE_DOUBLE, 0, rBIOS); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; // Truncate all single indirect pages. - eErrCode = truncate ( - page::SCOPE_SINGLE, 0, - rpSingle, rpDouble, rpTriple, - rData, rBIOS, NULL); + eErrCode = truncate (page::SCOPE_SINGLE, 0, rBIOS); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; // Truncate direct pages, including 'aLink.m_nIndex0'. - eErrCode = truncate ( - eScope, aLink.m_nIndex0, - rpSingle, rpDouble, rpTriple, - rData, rBIOS, NULL); + eErrCode = truncate (eScope, aLink.m_nIndex0, rBIOS); } else if (eScope == page::SCOPE_SINGLE) { // Truncate all triple indirect pages. - eErrCode = truncate ( - page::SCOPE_TRIPLE, 0, - rpSingle, rpDouble, rpTriple, - rData, rBIOS, NULL); + eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; // Truncate all double indirect pages. - eErrCode = truncate ( - page::SCOPE_DOUBLE, 0, - rpSingle, rpDouble, rpTriple, - rData, rBIOS, NULL); + eErrCode = truncate (page::SCOPE_DOUBLE, 0, rBIOS); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; // Truncate single indirect pages, downto 'aLink.m_nIndex1'. - eErrCode = truncate ( - eScope, aLink.m_nIndex1 + 1, - rpSingle, rpDouble, rpTriple, - rData, rBIOS, NULL); + eErrCode = truncate (eScope, aLink.m_nIndex1 + 1, rBIOS); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; - // Obtain last single indirect page location. - sal_uInt32 nAddr = singleLink (aLink.m_nIndex1); - if (nAddr != STORE_PAGE_NULL) - { - // Check single indirect page buffer. - if (rpSingle == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpSingle = new(nPageSize) indirect(nPageSize); - } - - // Load last single indirect page. - OStoreIndirectionPageObject aSingle (*rpSingle); - aSingle.location (nAddr); - - eErrCode = rBIOS.load (aSingle); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - - // Truncate to ... pages. - eErrCode = aSingle.truncate ( - aLink.m_nIndex0, - rData, rBIOS, NULL); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - - // Check for complete truncation. - if (aLink.m_nIndex0 == 0) - { - // Free last single indirect page. - eErrCode = rBIOS.free (aSingle); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + // Truncate last single indirect page to ... pages. + eErrCode = store_truncate_Impl (singleLink (aLink.m_nIndex1), aLink.m_nIndex0, rBIOS); + if (eErrCode != store_E_None) + return eErrCode; - // Clear pointer to last single indirect page. - singleLink (aLink.m_nIndex1, STORE_PAGE_NULL); - } + // Check for complete truncation. + if (aLink.m_nIndex0 == 0) + { + // Clear pointer to last single indirect page. + singleLink (aLink.m_nIndex1, STORE_PAGE_NULL); } } else if (eScope == page::SCOPE_DOUBLE) { // Truncate all triple indirect pages. - eErrCode = truncate ( - page::SCOPE_TRIPLE, 0, - rpSingle, rpDouble, rpTriple, - rData, rBIOS, NULL); + eErrCode = truncate (page::SCOPE_TRIPLE, 0, rBIOS); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; // Truncate double indirect pages, downto 'aLink.m_nIndex2'. - eErrCode = truncate ( - eScope, aLink.m_nIndex2 + 1, - rpSingle, rpDouble, rpTriple, - rData, rBIOS, NULL); + eErrCode = truncate (eScope, aLink.m_nIndex2 + 1, rBIOS); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; - // Obtain last double indirect page location. - sal_uInt32 nAddr = doubleLink (aLink.m_nIndex2); - if (nAddr != STORE_PAGE_NULL) - { - // Check double indirect page buffer. - if (rpDouble == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpDouble = new(nPageSize) indirect(nPageSize); - } - - // Load last double indirect page. - OStoreIndirectionPageObject aDouble (*rpDouble); - aDouble.location (nAddr); - - eErrCode = rBIOS.load (aDouble); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - - // Truncate to ... pages. - eErrCode = aDouble.truncate ( - aLink.m_nIndex1, - aLink.m_nIndex0, - rpSingle, - rData, rBIOS, NULL); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - - // Check for complete truncation. - if ((aLink.m_nIndex1 + aLink.m_nIndex0) == 0) - { - // Free last double indirect page. - eErrCode = rBIOS.free (aDouble); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + // Truncate last double indirect page to ... pages. + eErrCode = store_truncate_Impl ( + doubleLink (aLink.m_nIndex2), aLink.m_nIndex1, aLink.m_nIndex0, rBIOS); + if (eErrCode != store_E_None) + return eErrCode; - // Clear pointer to last double indirect page. - doubleLink (aLink.m_nIndex2, STORE_PAGE_NULL); - } + // Check for complete truncation. + if ((aLink.m_nIndex1 + aLink.m_nIndex0) == 0) + { + // Clear pointer to last double indirect page. + doubleLink (aLink.m_nIndex2, STORE_PAGE_NULL); } } else if (eScope == page::SCOPE_TRIPLE) { // Truncate triple indirect pages, downto 'aLink.m_nIndex3'. - eErrCode = truncate ( - eScope, aLink.m_nIndex3 + 1, - rpSingle, rpDouble, rpTriple, - rData, rBIOS, NULL); + eErrCode = truncate (eScope, aLink.m_nIndex3 + 1, rBIOS); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - - // Obtain last triple indirect page location. - sal_uInt32 nAddr = tripleLink (aLink.m_nIndex3); - if (nAddr != STORE_PAGE_NULL) - { - // Check triple indirect page buffer. - if (rpTriple == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpTriple = new(nPageSize) indirect(nPageSize); - } - - // Load last triple indirect page. - OStoreIndirectionPageObject aTriple (*rpTriple); - aTriple.location (nAddr); + return eErrCode; - eErrCode = rBIOS.load (aTriple); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - - // Truncate to ... pages. - eErrCode = aTriple.truncate ( - aLink.m_nIndex2, - aLink.m_nIndex1, - aLink.m_nIndex0, - rpDouble, rpSingle, - rData, rBIOS, NULL); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); - - // Check for complete truncation. - if ((aLink.m_nIndex2 + aLink.m_nIndex1 + aLink.m_nIndex0) == 0) - { - // Free last triple indirect page. - eErrCode = rBIOS.free (aTriple); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + // Truncate last triple indirect page to ... pages. + eErrCode = store_truncate_Impl ( + tripleLink (aLink.m_nIndex3), aLink.m_nIndex2, aLink.m_nIndex1, aLink.m_nIndex0, rBIOS); + if (eErrCode != store_E_None) + return eErrCode; - // Clear pointer to last triple indirect page. - tripleLink (aLink.m_nIndex3, STORE_PAGE_NULL); - } + // Check for complete truncation. + if ((aLink.m_nIndex2 + aLink.m_nIndex1 + aLink.m_nIndex0) == 0) + { + // Clear pointer to last triple indirect page. + tripleLink (aLink.m_nIndex3, STORE_PAGE_NULL); } } else if (eScope == page::SCOPE_UNREACHABLE) @@ -1537,7 +1106,7 @@ storeError OStoreDirectoryPageObject::truncate ( } // Leave. - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } /* @@ -1546,21 +1115,16 @@ storeError OStoreDirectoryPageObject::truncate ( storeError OStoreDirectoryPageObject::truncate ( page::ChunkScope eScope, sal_uInt16 nRemain, - indirect *&rpSingle, - indirect *&rpDouble, - indirect *&rpTriple, - OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + OStorePageBIOS &rBIOS) { - // Enter. - STORE_METHOD_ENTER(pMutex); + OStoreDirectoryDataBlock const & rDataBlock = PAGE().m_aDataBlock; + // Enter. storeError eErrCode = store_E_None; if (eScope == page::SCOPE_DIRECT) { // Truncate direct data pages. - sal_uInt16 i, n = m_rPage.m_aDataBlock.directCount(); + sal_uInt16 i, n = rDataBlock.directCount(); for (i = n; i > nRemain; i--) { // Obtain data page location. @@ -1568,8 +1132,8 @@ storeError OStoreDirectoryPageObject::truncate ( if (nAddr == STORE_PAGE_NULL) continue; // Free data page. - rData.location (nAddr); - eErrCode = rBIOS.free (rData); + OStoreDataPageData aData; + eErrCode = rBIOS.free (aData, nAddr); if (eErrCode != store_E_None) break; @@ -1578,42 +1142,17 @@ storeError OStoreDirectoryPageObject::truncate ( } // Done. - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } if (eScope == page::SCOPE_SINGLE) { // Truncate single indirect pages. - sal_uInt16 i, n = m_rPage.m_aDataBlock.singleCount(); + sal_uInt16 i, n = rDataBlock.singleCount(); for (i = n; i > nRemain; i--) { - // Obtain single indirect page location. - sal_uInt32 nAddr = singleLink (i - 1); - if (nAddr == STORE_PAGE_NULL) continue; - - // Check single indirect page buffer. - if (rpSingle == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpSingle = new(nPageSize) indirect(nPageSize); - } - - OStoreIndirectionPageObject aSingle (*rpSingle); - aSingle.location (nAddr); - - // Load single indirect page. - eErrCode = rBIOS.load (aSingle); - if (eErrCode != store_E_None) - break; - - // Truncate to zero data pages. - eErrCode = aSingle.truncate ( - 0, rData, rBIOS, NULL); - if (eErrCode != store_E_None) - break; - - // Free single indirect page. - eErrCode = rBIOS.free (aSingle); + // Truncate single indirect page to zero data pages. + eErrCode = store_truncate_Impl (singleLink (i - 1), 0, rBIOS); if (eErrCode != store_E_None) break; @@ -1622,42 +1161,17 @@ storeError OStoreDirectoryPageObject::truncate ( } // Done. - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } if (eScope == page::SCOPE_DOUBLE) { // Truncate double indirect pages. - sal_uInt16 i, n = m_rPage.m_aDataBlock.doubleCount(); + sal_uInt16 i, n = rDataBlock.doubleCount(); for (i = n; i > nRemain; i--) { - // Obtain double indirect page location. - sal_uInt32 nAddr = doubleLink (i - 1); - if (nAddr == STORE_PAGE_NULL) continue; - - // Check double indirect page buffer. - if (rpDouble == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpDouble = new(nPageSize) indirect(nPageSize); - } - - OStoreIndirectionPageObject aDouble (*rpDouble); - aDouble.location (nAddr); - - // Load double indirect page. - eErrCode = rBIOS.load (aDouble); - if (eErrCode != store_E_None) - break; - - // Truncate to zero single indirect pages. - eErrCode = aDouble.truncate ( - 0, 0, rpSingle, rData, rBIOS, NULL); - if (eErrCode != store_E_None) - break; - - // Free double indirect page. - eErrCode = rBIOS.free (aDouble); + // Truncate double indirect page to zero single indirect pages. + eErrCode = store_truncate_Impl (doubleLink (i - 1), 0, 0, rBIOS); if (eErrCode != store_E_None) break; @@ -1666,42 +1180,17 @@ storeError OStoreDirectoryPageObject::truncate ( } // Done. - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } if (eScope == page::SCOPE_TRIPLE) { // Truncate triple indirect pages. - sal_uInt16 i, n = m_rPage.m_aDataBlock.tripleCount(); + sal_uInt16 i, n = rDataBlock.tripleCount(); for (i = n; i > nRemain; i--) { - // Obtain triple indirect page location. - sal_uInt32 nAddr = tripleLink (i - 1); - if (nAddr == STORE_PAGE_NULL) continue; - - // Check triple indirect page buffer. - if (rpTriple == NULL) - { - sal_uInt16 nPageSize = m_rPage.m_aDescr.m_nSize; - rpTriple = new(nPageSize) indirect(nPageSize); - } - - OStoreIndirectionPageObject aTriple (*rpTriple); - aTriple.location (nAddr); - - // Load triple indirect page. - eErrCode = rBIOS.load (aTriple); - if (eErrCode != store_E_None) - break; - // Truncate to zero double indirect pages. - eErrCode = aTriple.truncate ( - 0, 0, 0, rpDouble, rpSingle, rData, rBIOS, NULL); - if (eErrCode != store_E_None) - break; - - // Free triple indirect page. - eErrCode = rBIOS.free (aTriple); + eErrCode = store_truncate_Impl (tripleLink (i - 1), 0, 0, 0, rBIOS); if (eErrCode != store_E_None) break; @@ -1710,10 +1199,9 @@ storeError OStoreDirectoryPageObject::truncate ( } // Done. - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } // Invalid scope. - STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess); + return store_E_InvalidAccess; } - diff --git a/store/source/stordata.hxx b/store/source/stordata.hxx index ac267239ebdc..4610db5ac908 100644 --- a/store/source/stordata.hxx +++ b/store/source/stordata.hxx @@ -29,14 +29,13 @@ ************************************************************************/ #ifndef _STORE_STORDATA_HXX_ -#define _STORE_STORDATA_HXX_ "$Revision: 1.6 $" +#define _STORE_STORDATA_HXX_ "$Revision: 1.6.8.2 $" -#include -#include -#include -#include -#include -#include +#include "sal/types.h" +#include "sal/macros.h" + +#include "store/types.h" +#include "storbase.hxx" namespace store { @@ -59,54 +58,51 @@ struct OStoreDataPageData : public store::OStorePageData */ sal_uInt8 m_pData[1]; + /** type. + */ + static const sal_uInt32 theTypeId = STORE_MAGIC_DATAPAGE; + /** size. */ - static sal_uInt16 size (void) - { - return sal_uInt16(0); - } + static const size_t theSize = 0; + static const sal_uInt16 thePageSize = base::theSize + self::theSize; + STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= self::thePageSize); /** capacity. */ - static sal_uInt16 capacity (const D& rDescr) + static sal_uInt16 capacity (const D& rDescr) // @see inode::ChunkDescriptor { - return (rDescr.m_nSize - (base::size() + self::size())); + return (store::ntohs(rDescr.m_nSize) - self::thePageSize); } - - sal_uInt16 capacity (void) const + sal_uInt16 capacity() const { return self::capacity (base::m_aDescr); } /** usage. */ - static sal_uInt16 usage (const D& rDescr) + sal_uInt16 usage() const { - return (rDescr.m_nUsed - (base::size() + self::size())); + return (store::ntohs(base::m_aDescr.m_nUsed) - self::thePageSize); } - sal_uInt16 usage (void) const + /** Construction. + */ + explicit OStoreDataPageData (sal_uInt16 nPageSize = self::thePageSize) + : base (nPageSize) { - return self::usage (base::m_aDescr); + base::m_aGuard.m_nMagic = store::htonl(self::theTypeId); + base::m_aDescr.m_nUsed = store::htons(self::thePageSize); + memset (m_pData, 0, capacity()); } - /** initialize. + /** guard (external representation). */ - void initialize (void) - { - base::m_aGuard.m_nMagic = STORE_MAGIC_DATAPAGE; - base::m_aDescr.m_nUsed = sal::static_int_cast< sal_uInt16 >( - base::m_aDescr.m_nUsed + self::size()); - rtl_zeroMemory (m_pData, capacity()); - } + void guard() {} - /** Construction. + /** verify (external representation). */ - OStoreDataPageData (sal_uInt16 nPageSize) - : base (nPageSize) - { - initialize(); - } + storeError verify() const { return store_E_None; } }; /*======================================================================== @@ -116,25 +112,22 @@ struct OStoreDataPageData : public store::OStorePageData *======================================================================*/ class OStoreDataPageObject : public store::OStorePageObject { - typedef OStorePageObject base; - typedef OStoreDataPageData page; + typedef OStorePageObject base; + typedef OStoreDataPageData page; public: /** Construction. */ - inline OStoreDataPageObject (page& rPage); + explicit OStoreDataPageObject (PageHolder const & rxPage = PageHolder()) + : OStorePageObject (rxPage) + {} -private: - /** Representation. - */ - page& m_rPage; + /** External representation. + */ + virtual storeError guard (sal_uInt32 nAddr); + virtual storeError verify (sal_uInt32 nAddr) const; }; -inline OStoreDataPageObject::OStoreDataPageObject (page& rPage) - : OStorePageObject (rPage), m_rPage (rPage) -{ -} - /*======================================================================== * * OStoreIndirectionPageData. @@ -155,75 +148,67 @@ struct OStoreIndirectionPageData : public store::OStorePageData G m_aGuard; sal_uInt32 m_pData[1]; + /** type. + */ + static const sal_uInt32 theTypeId = STORE_MAGIC_INDIRECTPAGE; + /** size. - */ - static sal_uInt16 size (void) - { - return sal_uInt16(sizeof(G)); - } + */ + static const size_t theSize = sizeof(G); + static const sal_uInt16 thePageSize = base::theSize + self::theSize; + STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= self::thePageSize); /** capacity. */ static sal_uInt16 capacity (const D& rDescr) { - return (rDescr.m_nSize - (base::size() + self::size())); + return (store::ntohs(rDescr.m_nSize) - self::thePageSize); } - sal_uInt16 capacity (void) const + sal_uInt16 capacity() const { return self::capacity (base::m_aDescr); } /** capacityCount. */ - static sal_uInt16 capacityCount (const D& rDescr) + static sal_uInt16 capacityCount (const D& rDescr) // @see DirectoryPageObject::scope() { return sal_uInt16(capacity(rDescr) / sizeof(sal_uInt32)); } - sal_uInt16 capacityCount (void) const + sal_uInt16 capacityCount() const { return sal_uInt16(capacity() / sizeof(sal_uInt32)); } /** Construction. */ - OStoreIndirectionPageData (sal_uInt16 nPageSize); - void initialize (void); - - /** Comparison. - */ - sal_Bool operator== (const OStoreIndirectionPageData& rOther) const + explicit OStoreIndirectionPageData (sal_uInt16 nPageSize) + : base (nPageSize) { - return (base::operator==(rOther) && (m_aGuard == rOther.m_aGuard)); + base::m_aGuard.m_nMagic = store::htonl(self::theTypeId); + base::m_aDescr.m_nUsed = store::htons(self::thePageSize); + self::m_aGuard.m_nMagic = store::htonl(0); + memset (m_pData, STORE_PAGE_NULL, capacity()); } - /** swap (internal and external representation). - */ - void swap (const D& rDescr); - /** guard (external representation). */ - void guard (const D& rDescr) + void guard() { sal_uInt32 nCRC32 = 0; - nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); - nCRC32 = G::crc32 (nCRC32, m_pData, capacity(rDescr)); -#ifdef OSL_BIGENDIAN - nCRC32 = OSL_SWAPDWORD(nCRC32); -#endif /* OSL_BIGENDIAN */ - m_aGuard.m_nCRC32 = nCRC32; + nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); + nCRC32 = rtl_crc32 (nCRC32, m_pData, capacity()); + m_aGuard.m_nCRC32 = store::htonl(nCRC32); } /** verify (external representation). */ - storeError verify (const D& rDescr) + storeError verify() const { sal_uInt32 nCRC32 = 0; - nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); - nCRC32 = G::crc32 (nCRC32, m_pData, capacity(rDescr)); -#ifdef OSL_BIGENDIAN - nCRC32 = OSL_SWAPDWORD(nCRC32); -#endif /* OSL_BIGENDIAN */ - if (m_aGuard.m_nCRC32 != nCRC32) + nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); + nCRC32 = rtl_crc32 (nCRC32, m_pData, capacity()); + if (m_aGuard.m_nCRC32 != store::htonl(nCRC32)) return store_E_InvalidChecksum; else return store_E_None; @@ -240,107 +225,142 @@ class OStoreIndirectionPageObject : public store::OStorePageObject typedef OStorePageObject base; typedef OStoreIndirectionPageData page; - typedef OStorePageDescriptor D; - public: /** Construction. */ - inline OStoreIndirectionPageObject (page& rPage); + explicit OStoreIndirectionPageObject (PageHolder const & rxPage = PageHolder()) + : OStorePageObject (rxPage) + {} /** External representation. */ - virtual void swap (const D& rDescr); - virtual void guard (const D& rDescr); - virtual storeError verify (const D& rDescr); + storeError loadOrCreate ( + sal_uInt32 nAddr, + OStorePageBIOS & rBIOS); + + virtual storeError guard (sal_uInt32 nAddr); + virtual storeError verify (sal_uInt32 nAddr) const; - /** get (indirect data page). + /** read (indirect data page). */ - storeError get ( + storeError read ( sal_uInt16 nSingle, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + OStorePageBIOS &rBIOS); - storeError get ( + storeError read ( sal_uInt16 nDouble, sal_uInt16 nSingle, - page *&rpSingle, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + OStorePageBIOS &rBIOS); - storeError get ( + storeError read ( sal_uInt16 nTriple, sal_uInt16 nDouble, sal_uInt16 nSingle, - page *&rpDouble, - page *&rpSingle, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + OStorePageBIOS &rBIOS); - /** put (indirect data page). + /** write (indirect data page). */ - storeError put ( + storeError write ( sal_uInt16 nSingle, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + OStorePageBIOS &rBIOS); - storeError put ( + storeError write ( sal_uInt16 nDouble, sal_uInt16 nSingle, - page *&rpSingle, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + OStorePageBIOS &rBIOS); - storeError put ( + storeError write ( sal_uInt16 nTriple, sal_uInt16 nDouble, sal_uInt16 nSingle, - page *&rpDouble, - page *&rpSingle, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + OStorePageBIOS &rBIOS); /** truncate (indirect data page). */ storeError truncate ( sal_uInt16 nSingle, - OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + OStorePageBIOS &rBIOS); storeError truncate ( sal_uInt16 nDouble, sal_uInt16 nSingle, - page *&rpSingle, - OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + OStorePageBIOS &rBIOS); storeError truncate ( sal_uInt16 nTriple, sal_uInt16 nDouble, sal_uInt16 nSingle, - page *&rpDouble, - page *&rpSingle, - OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + OStorePageBIOS &rBIOS); +}; + +/*======================================================================== + * + * OStorePageNameBlock. + * + *======================================================================*/ +struct OStorePageNameBlock +{ + typedef OStorePageGuard G; + typedef OStorePageKey K; -private: /** Representation. */ - page& m_rPage; -}; + G m_aGuard; + K m_aKey; + sal_uInt32 m_nAttrib; + sal_Char m_pData[STORE_MAXIMUM_NAMESIZE]; -inline OStoreIndirectionPageObject::OStoreIndirectionPageObject (page& rPage) - : OStorePageObject (rPage), m_rPage (rPage) -{ -} + /** size. + */ + static const size_t theSize = sizeof(G) + sizeof(K) + sizeof(sal_uInt32) + sizeof(sal_Char[STORE_MAXIMUM_NAMESIZE]); + + /** initialize. + */ + void initialize (void) + { + m_aGuard = G(); + m_aKey = K(); + m_nAttrib = 0; + memset (m_pData, 0, sizeof(m_pData)); + } + + /** Construction. + */ + OStorePageNameBlock (void) + : m_aGuard(), m_aKey(), m_nAttrib (0) + { + memset (m_pData, 0, sizeof(m_pData)); + } + + /** guard (external representation). + */ + void guard() + { + sal_uInt32 nCRC32 = 0; + nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); + nCRC32 = rtl_crc32 (nCRC32, &m_aKey, theSize - sizeof(G)); + m_aGuard.m_nCRC32 = store::htonl(nCRC32); + } + + /** verify (external representation). + */ + storeError verify() const + { + sal_uInt32 nCRC32 = 0; + nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); + nCRC32 = rtl_crc32 (nCRC32, &m_aKey, theSize - sizeof(G)); + if (m_aGuard.m_nCRC32 != store::htonl(nCRC32)) + return store_E_InvalidChecksum; + else + return store_E_None; + } +}; /*======================================================================== * @@ -388,14 +408,22 @@ struct OStoreDirectoryDataBlock sal_uInt32 m_pDouble[STORE_LIMIT_DATAPAGE_DOUBLE]; sal_uInt32 m_pTriple[STORE_LIMIT_DATAPAGE_TRIPLE]; - /** Construction. + /** initialize. */ - LinkTable (void); - void initialize (void); + void initialize (void) + { + memset(m_pDirect, STORE_PAGE_NULL, sizeof(m_pDirect)); + memset(m_pSingle, STORE_PAGE_NULL, sizeof(m_pSingle)); + memset(m_pDouble, STORE_PAGE_NULL, sizeof(m_pDouble)); + memset(m_pTriple, STORE_PAGE_NULL, sizeof(m_pTriple)); + } - /** swap (internal and external representation). + /** Construction. */ - void swap (void); + LinkTable (void) + { + initialize(); + } }; /** Representation. @@ -405,11 +433,8 @@ struct OStoreDirectoryDataBlock sal_uInt32 m_nDataLen; /** size. - */ - static sal_uInt16 size (void) - { - return sal_uInt16(sizeof(G) + sizeof(LinkTable) + sizeof(sal_uInt32)); - } + */ + static const size_t theSize = sizeof(G) + sizeof(LinkTable) + sizeof(sal_uInt32); /** initialize. */ @@ -423,51 +448,27 @@ struct OStoreDirectoryDataBlock /** Construction. */ OStoreDirectoryDataBlock (void) - : m_nDataLen (0) + : m_aGuard(), m_aTable(), m_nDataLen (0) {} - /** Comparison. - */ - sal_Bool operator== (const OStoreDirectoryDataBlock& rOther) const - { - return (m_aGuard == rOther.m_aGuard); - } - - /** swap (internal and external representation). - */ - void swap (void) - { -#ifdef OSL_BIGENDIAN - m_aGuard.swap(); - m_aTable.swap(); - m_nDataLen = OSL_SWAPDWORD(m_nDataLen); -#endif /* OSL_BIGENDIAN */ - } - /** guard (external representation). */ - void guard (void) + void guard() { sal_uInt32 nCRC32 = 0; - nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); - nCRC32 = G::crc32 (nCRC32, &m_aTable, size() - sizeof(G)); -#ifdef OSL_BIGENDIAN - nCRC32 = OSL_SWAPDWORD(nCRC32); -#endif /* OSL_BIGENDIAN */ - m_aGuard.m_nCRC32 = nCRC32; + nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); + nCRC32 = rtl_crc32 (nCRC32, &m_aTable, theSize - sizeof(G)); + m_aGuard.m_nCRC32 = store::htonl(nCRC32); } /** verify (external representation). */ - storeError verify (void) + storeError verify() const { sal_uInt32 nCRC32 = 0; - nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); - nCRC32 = G::crc32 (nCRC32, &m_aTable, size() - sizeof(G)); -#ifdef OSL_BIGENDIAN - nCRC32 = OSL_SWAPDWORD(nCRC32); -#endif /* OSL_BIGENDIAN */ - if (m_aGuard.m_nCRC32 != nCRC32) + nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); + nCRC32 = rtl_crc32 (nCRC32, &m_aTable, theSize - sizeof(G)); + if (m_aGuard.m_nCRC32 != store::htonl(nCRC32)) return store_E_InvalidChecksum; else return store_E_None; @@ -482,14 +483,14 @@ struct OStoreDirectoryDataBlock sal_uInt32 directLink (sal_uInt16 nIndex) const { if (nIndex < directCount()) - return m_aTable.m_pDirect[nIndex]; + return store::ntohl(m_aTable.m_pDirect[nIndex]); else return STORE_PAGE_NULL; } void directLink (sal_uInt16 nIndex, sal_uInt32 nAddr) { if (nIndex < directCount()) - m_aTable.m_pDirect[nIndex] = nAddr; + m_aTable.m_pDirect[nIndex] = store::htonl(nAddr); } /** single. @@ -501,14 +502,14 @@ struct OStoreDirectoryDataBlock sal_uInt32 singleLink (sal_uInt16 nIndex) const { if (nIndex < singleCount()) - return m_aTable.m_pSingle[nIndex]; + return store::ntohl(m_aTable.m_pSingle[nIndex]); else return STORE_PAGE_NULL; } void singleLink (sal_uInt16 nIndex, sal_uInt32 nAddr) { if (nIndex < singleCount()) - m_aTable.m_pSingle[nIndex] = nAddr; + m_aTable.m_pSingle[nIndex] = store::htonl(nAddr); } /** double. @@ -520,14 +521,14 @@ struct OStoreDirectoryDataBlock sal_uInt32 doubleLink (sal_uInt16 nIndex) const { if (nIndex < doubleCount()) - return m_aTable.m_pDouble[nIndex]; + return store::ntohl(m_aTable.m_pDouble[nIndex]); else return STORE_PAGE_NULL; } void doubleLink (sal_uInt16 nIndex, sal_uInt32 nAddr) { if (nIndex < doubleCount()) - m_aTable.m_pDouble[nIndex] = nAddr; + m_aTable.m_pDouble[nIndex] = store::htonl(nAddr); } /** triple. @@ -539,14 +540,14 @@ struct OStoreDirectoryDataBlock sal_uInt32 tripleLink (sal_uInt16 nIndex) const { if (nIndex < tripleCount()) - return m_aTable.m_pTriple[nIndex]; + return store::ntohl(m_aTable.m_pTriple[nIndex]); else return STORE_PAGE_NULL; } void tripleLink (sal_uInt16 nIndex, sal_uInt32 nAddr) { if (nIndex < tripleCount()) - m_aTable.m_pTriple[nIndex] = nAddr; + m_aTable.m_pTriple[nIndex] = store::htonl(nAddr); } }; @@ -567,86 +568,61 @@ struct OStoreDirectoryPageData : public store::OStorePageData typedef OStoreDirectoryDataBlock DataBlock; /** Representation. - */ + */ NameBlock m_aNameBlock; DataBlock m_aDataBlock; sal_uInt8 m_pData[1]; + /** type. + */ + static const sal_uInt32 theTypeId = STORE_MAGIC_DIRECTORYPAGE; + /** size. - */ - static sal_uInt16 size (void) - { - return (NameBlock::size() + DataBlock::size()); - } + */ + static const size_t theSize = NameBlock::theSize + DataBlock::theSize; + static const sal_uInt16 thePageSize = base::theSize + self::theSize; + STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= self::thePageSize); /** capacity. */ - static sal_uInt16 capacity (const D& rDescr) + sal_uInt16 capacity() const { - return (rDescr.m_nSize - (base::size() + self::size())); - } - sal_uInt16 capacity (void) const - { - return self::capacity (base::m_aDescr); + return (store::ntohs(base::m_aDescr.m_nSize) - self::thePageSize); } /** usage. */ - static sal_uInt16 usage (const D& rDescr) - { - return (rDescr.m_nUsed - (base::size() + self::size())); - } - sal_uInt16 usage (void) const + sal_uInt16 usage() const { - return self::usage (base::m_aDescr); + return (store::ntohs(base::m_aDescr.m_nUsed) - self::thePageSize); } /** initialize. */ void initialize (void) { - base::m_aGuard.m_nMagic = STORE_MAGIC_DIRECTORYPAGE; - base::m_aDescr.m_nUsed = base::size() + self::size(); + base::m_aGuard.m_nMagic = store::htonl(self::theTypeId); + base::m_aDescr.m_nUsed = store::htons(self::thePageSize); m_aNameBlock.initialize(); m_aDataBlock.initialize(); - rtl_zeroMemory (m_pData, capacity()); + memset (m_pData, 0, capacity()); } /** Construction. */ - OStoreDirectoryPageData (sal_uInt16 nPageSize) - : base (nPageSize) - { - base::m_aGuard.m_nMagic = STORE_MAGIC_DIRECTORYPAGE; - base::m_aDescr.m_nUsed = sal::static_int_cast< sal_uInt16 >( - base::m_aDescr.m_nUsed + self::size()); - rtl_zeroMemory (m_pData, capacity()); - } - - /** Comparsion. - */ - sal_Bool operator== (const OStoreDirectoryPageData& rOther) const - { - return ((base::operator==(rOther) ) && - (m_aNameBlock == rOther.m_aNameBlock) && - (m_aDataBlock == rOther.m_aDataBlock) ); - } - - /** swap (internal and external representation). - */ - void swap () + explicit OStoreDirectoryPageData (sal_uInt16 nPageSize) + : base (nPageSize), m_aNameBlock(), m_aDataBlock() { -#ifdef OSL_BIGENDIAN - m_aNameBlock.swap(); - m_aDataBlock.swap(); -#endif /* OSL_BIGENDIAN */ + base::m_aGuard.m_nMagic = store::htonl(self::theTypeId); + base::m_aDescr.m_nUsed = store::htons(self::thePageSize); + memset (m_pData, 0, capacity()); } /** guard (external representation). */ - void guard () + void guard() { m_aNameBlock.guard(); m_aDataBlock.guard(); @@ -654,7 +630,7 @@ struct OStoreDirectoryPageData : public store::OStorePageData /** verify (external representation). */ - storeError verify () + storeError verify() const { storeError eErrCode = m_aNameBlock.verify(); if (eErrCode == store_E_None) @@ -724,35 +700,66 @@ class OStoreDirectoryPageObject : public store::OStorePageObject public: /** Construction. */ - inline OStoreDirectoryPageObject (page& rPage); + explicit OStoreDirectoryPageObject (PageHolder const & rxPage = PageHolder()) + : OStorePageObject (rxPage) + {} /** External representation. */ - virtual void swap (const D& rDescr); - virtual void guard (const D& rDescr); - virtual storeError verify (const D& rDescr); + virtual storeError guard (sal_uInt32 nAddr); + virtual storeError verify (sal_uInt32 nAddr) const; /** attrib. */ sal_uInt32 attrib (void) const { - return m_rPage.m_aNameBlock.m_nAttrib; + return store::ntohl(PAGE().m_aNameBlock.m_nAttrib); } void attrib (sal_uInt32 nAttrib) { - m_rPage.m_aNameBlock.m_nAttrib = nAttrib; + PAGE().m_aNameBlock.m_nAttrib = store::htonl(nAttrib); touch(); } + /** key. + */ + OStorePageKey key (void) const + { + return PAGE().m_aNameBlock.m_aKey; + } + void key (OStorePageKey const & rKey) + { + PAGE().m_aNameBlock.m_aKey = rKey; + touch(); + } + + /** path. + */ + sal_uInt32 path (void) const + { + page const & rPage = PAGE(); + const sal_Char * pszName = rPage.m_aNameBlock.m_pData; + sal_uInt32 nPath = store::ntohl(rPage.m_aNameBlock.m_aKey.m_nHigh); + return rtl_crc32 (nPath, pszName, rtl_str_getLength(pszName)); + } + + sal_Size getName (sal_Char * pBuffer, sal_Size nBufsiz) const + { + sal_Char const * pszName = PAGE().m_aNameBlock.m_pData; + sal_Size nLength = rtl_str_getLength(pszName); + memcpy (pBuffer, pszName, SAL_MIN(nLength, nBufsiz)); + return nLength; + } + /** dataLength. */ sal_uInt32 dataLength (void) const { - return m_rPage.m_aDataBlock.m_nDataLen; + return store::ntohl(PAGE().m_aDataBlock.m_nDataLen); } void dataLength (sal_uInt32 nLength) { - m_rPage.m_aDataBlock.m_nDataLen = nLength; + PAGE().m_aDataBlock.m_nDataLen = store::htonl(nLength); touch(); } @@ -760,11 +767,11 @@ public: */ sal_uInt32 directLink (sal_uInt16 nIndex) const { - return m_rPage.m_aDataBlock.directLink (nIndex); + return PAGE().m_aDataBlock.directLink (nIndex); } void directLink (sal_uInt16 nIndex, sal_uInt32 nAddr) { - m_rPage.m_aDataBlock.directLink (nIndex, nAddr); + PAGE().m_aDataBlock.directLink (nIndex, nAddr); touch(); } @@ -772,11 +779,11 @@ public: */ sal_uInt32 singleLink (sal_uInt16 nIndex) const { - return m_rPage.m_aDataBlock.singleLink (nIndex); + return PAGE().m_aDataBlock.singleLink (nIndex); } void singleLink (sal_uInt16 nIndex, sal_uInt32 nAddr) { - m_rPage.m_aDataBlock.singleLink (nIndex, nAddr); + PAGE().m_aDataBlock.singleLink (nIndex, nAddr); touch(); } @@ -784,11 +791,11 @@ public: */ sal_uInt32 doubleLink (sal_uInt16 nIndex) const { - return m_rPage.m_aDataBlock.doubleLink (nIndex); + return PAGE().m_aDataBlock.doubleLink (nIndex); } void doubleLink (sal_uInt16 nIndex, sal_uInt32 nAddr) { - m_rPage.m_aDataBlock.doubleLink (nIndex, nAddr); + PAGE().m_aDataBlock.doubleLink (nIndex, nAddr); touch(); } @@ -796,76 +803,64 @@ public: */ sal_uInt32 tripleLink (sal_uInt16 nIndex) const { - return m_rPage.m_aDataBlock.tripleLink (nIndex); + return PAGE().m_aDataBlock.tripleLink (nIndex); } void tripleLink (sal_uInt16 nIndex, sal_uInt32 nAddr) { - m_rPage.m_aDataBlock.tripleLink (nIndex, nAddr); + PAGE().m_aDataBlock.tripleLink (nIndex, nAddr); touch(); } - /** scope (external data page). - */ - page::ChunkScope scope ( - sal_uInt32 nPage, - page::DataBlock::LinkDescriptor &rDescr) const; - - /** get (external data page). + /** read (external data page). */ - storeError get ( + storeError read ( sal_uInt32 nPage, - indirect *&rpSingle, - indirect *&rpDouble, - indirect *&rpTriple, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + OStorePageBIOS &rBIOS); - /** put (external data page). + /** write (external data page). */ - storeError put ( + storeError write ( sal_uInt32 nPage, - indirect *&rpSingle, - indirect *&rpDouble, - indirect *&rpTriple, OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + OStorePageBIOS &rBIOS); /** truncate (external data page). */ storeError truncate ( sal_uInt32 nPage, - indirect *&rpSingle, - indirect *&rpDouble, - indirect *&rpTriple, - OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + OStorePageBIOS &rBIOS); private: /** Representation. */ - page& m_rPage; + page & PAGE() + { + page * pImpl = reinterpret_cast(m_xPage.get()); + OSL_PRECOND(pImpl != 0, "OStoreDirectoryPageObject::PAGE(): Null pointer"); + return (*pImpl); + } + page const & PAGE() const + { + page const * pImpl = reinterpret_cast(m_xPage.get()); + OSL_PRECOND(pImpl != 0, "OStoreDirectoryPageObject::PAGE(): Null pointer"); + return (*pImpl); + } + + /** scope (external data page; private). + */ + page::ChunkScope scope ( + sal_uInt32 nPage, + page::DataBlock::LinkDescriptor &rDescr) const; /** truncate (external data page scope; private). */ storeError truncate ( page::ChunkScope eScope, sal_uInt16 nRemain, - indirect *&rpSingle, - indirect *&rpDouble, - indirect *&rpTriple, - OStoreDataPageObject &rData, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + OStorePageBIOS &rBIOS); }; -inline OStoreDirectoryPageObject::OStoreDirectoryPageObject (page& rPage) - : OStorePageObject (rPage), m_rPage (rPage) -{ -} - /*======================================================================== * * The End. diff --git a/store/source/stordir.cxx b/store/source/stordir.cxx new file mode 100644 index 000000000000..0269e9cb51f1 --- /dev/null +++ b/store/source/stordir.cxx @@ -0,0 +1,249 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: stordir.cxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: mhu $ $Date: 2008/10/17 16:30:17 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_store.hxx" + +#include "stordir.hxx" + +#ifndef _SAL_TYPES_H_ +#include +#endif + +#ifndef _RTL_TEXTCVT_H_ +#include +#endif +#ifndef _RTL_REF_HXX_ +#include +#endif + +#ifndef _OSL_MUTEX_HXX_ +#include +#endif + +#ifndef _STORE_TYPES_H_ +#include "store/types.h" +#endif +#ifndef _STORE_OBJECT_HXX_ +#include "object.hxx" +#endif + +#ifndef _STORE_STORBASE_HXX_ +#include "storbase.hxx" +#endif +#ifndef _STORE_STORDATA_HXX_ +#include "stordata.hxx" +#endif +#ifndef _STORE_STORPAGE_HXX_ +#include "storpage.hxx" +#endif + +using namespace store; + +/*======================================================================== + * + * OStore... internals. + * + *======================================================================*/ +/* + * __store_convertTextToUnicode. + */ +inline sal_Size __store_convertTextToUnicode ( + rtl_TextToUnicodeConverter hConverter, + const sal_Char *pSrcBuffer, sal_Size nSrcLength, + sal_Unicode *pDstBuffer, sal_Size nDstLength) +{ + sal_uInt32 nCvtInfo = 0; + sal_Size nCvtBytes = 0; + return rtl_convertTextToUnicode ( + hConverter, 0, + pSrcBuffer, nSrcLength, + pDstBuffer, nDstLength, + OSTRING_TO_OUSTRING_CVTFLAGS, + &nCvtInfo, &nCvtBytes); +} + +/*======================================================================== + * + * OStoreDirectory_Impl implementation. + * + *======================================================================*/ +const sal_uInt32 OStoreDirectory_Impl::m_nTypeId = sal_uInt32(0x89191107); + +/* + * OStoreDirectory_Impl. + */ +OStoreDirectory_Impl::OStoreDirectory_Impl (void) + : m_xManager (), + m_aDescr (0, 0, 0), + m_nPath (0), + m_hTextCvt (NULL) +{} + +/* + * ~OStoreDirectory_Impl. + */ +OStoreDirectory_Impl::~OStoreDirectory_Impl (void) +{ + if (m_xManager.is()) + { + if (m_aDescr.m_nAddr != STORE_PAGE_NULL) + m_xManager->releasePage (m_aDescr, store_AccessReadOnly); + } + rtl_destroyTextToUnicodeConverter (m_hTextCvt); +} + +/* + * isKindOf. + */ +sal_Bool SAL_CALL OStoreDirectory_Impl::isKindOf (sal_uInt32 nTypeId) +{ + return (nTypeId == m_nTypeId); +} + +/* + * create. + */ +storeError OStoreDirectory_Impl::create ( + OStorePageManager *pManager, + rtl_String *pPath, + rtl_String *pName, + storeAccessMode eMode) +{ + rtl::Reference xManager (pManager); + if (!xManager.is()) + return store_E_InvalidAccess; + + if (!(pPath && pName)) + return store_E_InvalidParameter; + + OStoreDirectoryPageObject aPage; + storeError eErrCode = xManager->iget ( + aPage, STORE_ATTRIB_ISDIR, + pPath, pName, eMode); + if (eErrCode != store_E_None) + return eErrCode; + + if (!(aPage.attrib() & STORE_ATTRIB_ISDIR)) + return store_E_NotDirectory; + + inode_holder_type xNode (aPage.get()); + eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadOnly); + if (eErrCode != store_E_None) + return eErrCode; + + // Evaluate iteration path. + m_nPath = aPage.path(); + m_nPath = rtl_crc32 (m_nPath, "/", 1); + + // Save page manager, and descriptor. + m_xManager = xManager; + m_aDescr = xNode->m_aDescr; + + return store_E_None; +} + +/* + * iterate. + */ +storeError OStoreDirectory_Impl::iterate (storeFindData &rFindData) +{ + if (!m_xManager.is()) + return store_E_InvalidAccess; + + storeError eErrCode = store_E_NoMoreFiles; + if (!rFindData.m_nReserved) + return eErrCode; + + // Acquire exclusive access. + osl::MutexGuard aGuard (*m_xManager); + + // Check TextConverter. + if (m_hTextCvt == NULL) + m_hTextCvt = rtl_createTextToUnicodeConverter(RTL_TEXTENCODING_UTF8); + + // Setup iteration key. + OStorePageKey aKey (rFindData.m_nReserved, m_nPath); + + // Iterate. + for (;;) + { + OStorePageLink aLink; + eErrCode = m_xManager->iterate (aKey, aLink, rFindData.m_nAttrib); + if (!((eErrCode == store_E_None) && (aKey.m_nHigh == store::htonl(m_nPath)))) + break; + + if (!(rFindData.m_nAttrib & STORE_ATTRIB_ISLINK)) + { + // Load page. + OStoreDirectoryPageObject aPage; + eErrCode = m_xManager->loadObjectAt (aPage, aLink.location()); + if (eErrCode == store_E_None) + { + inode_holder_type xNode (aPage.get()); + + // Setup FindData. + sal_Char *p = xNode->m_aNameBlock.m_pData; + sal_Size n = rtl_str_getLength (p); + sal_Size k = rFindData.m_nLength; + + n = __store_convertTextToUnicode ( + m_hTextCvt, p, n, + rFindData.m_pszName, STORE_MAXIMUM_NAMESIZE - 1); + if (k > n) + { + k = (k - n) * sizeof(sal_Unicode); + memset (&rFindData.m_pszName[n], 0, k); + } + + rFindData.m_nLength = n; + rFindData.m_nAttrib |= aPage.attrib(); + rFindData.m_nSize = aPage.dataLength(); + + // Leave. + rFindData.m_nReserved = store::ntohl(aKey.m_nLow); + return store_E_None; + } + } + + if (aKey.m_nLow == 0) + break; + aKey.m_nLow = store::htonl(store::ntohl(aKey.m_nLow) - 1); + } + + // Finished. + memset (&rFindData, 0, sizeof (storeFindData)); + return store_E_NoMoreFiles; +} diff --git a/store/source/stordir.hxx b/store/source/stordir.hxx new file mode 100644 index 000000000000..acfbf36af8d6 --- /dev/null +++ b/store/source/stordir.hxx @@ -0,0 +1,157 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: stordir.hxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: mhu $ $Date: 2008/10/17 16:30:17 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _STORE_STORDIR_HXX_ +#define _STORE_STORDIR_HXX_ "$Revision: 1.1.2.2 $" + +#ifndef _SAL_TYPES_H_ +#include +#endif + +#ifndef _RTL_TEXTCVT_H_ +#include +#endif +#ifndef _RTL_STRING_H_ +#include +#endif +#ifndef _RTL_REF_HXX_ +#include +#endif + +#ifndef _STORE_OBJECT_HXX_ +#include "object.hxx" +#endif +#ifndef _STORE_STORBASE_HXX_ +#include "storbase.hxx" +#endif +#ifndef _STORE_STORPAGE_HXX_ +#include "storpage.hxx" +#endif + +namespace store +{ + +struct OStoreDirectoryPageData; + +/*======================================================================== + * + * OStoreDirectory_Impl interface. + * + *======================================================================*/ +class OStoreDirectory_Impl : public store::OStoreObject +{ +public: + /** Construction. + */ + OStoreDirectory_Impl (void); + + /** create (two-phase construction). + * @param pManager [in] + * @param pPath [in] + * @param pName [in] + * @param eAccessMode [in] + * @return store_E_None upon success. + */ + storeError create ( + OStorePageManager *pManager, + rtl_String *pPath, + rtl_String *pName, + storeAccessMode eAccessMode); + + /** iterate. + * @param rFindData [out] + * @return store_E_None upon success, + * store_E_NoMoreFiles upon end of iteration. + */ + storeError iterate ( + storeFindData &rFindData); + + /** IStoreHandle. + */ + virtual sal_Bool SAL_CALL isKindOf (sal_uInt32 nTypeId); + +protected: + /** Destruction. + */ + virtual ~OStoreDirectory_Impl (void); + +private: + /** IStoreHandle TypeId. + */ + static const sal_uInt32 m_nTypeId; + + /** IStoreHandle query() template function specialization. + */ + friend OStoreDirectory_Impl* + SAL_CALL query<> (IStoreHandle *pHandle, OStoreDirectory_Impl*); + + /** Representation. + */ + typedef OStoreDirectoryPageData inode; + typedef PageHolderObject< inode > inode_holder_type; + + rtl::Reference m_xManager; + + OStorePageDescriptor m_aDescr; + sal_uInt32 m_nPath; + rtl_TextToUnicodeConverter m_hTextCvt; + + /** Not implemented. + */ + OStoreDirectory_Impl (const OStoreDirectory_Impl&); + OStoreDirectory_Impl& operator= (const OStoreDirectory_Impl&); +}; + +template<> inline OStoreDirectory_Impl* +SAL_CALL query (IStoreHandle *pHandle, OStoreDirectory_Impl*) +{ + if (pHandle && pHandle->isKindOf (OStoreDirectory_Impl::m_nTypeId)) + { + // Handle is kind of OStoreDirectory_Impl. + return static_cast(pHandle); + } + return 0; +} + +/*======================================================================== + * + * The End. + * + *======================================================================*/ + +} // namespace store + +#endif /* !_STORE_STORDIR_HXX_ */ + diff --git a/store/source/store.cxx b/store/source/store.cxx index a037b6529792..db27f7cbb05b 100644 --- a/store/source/store.cxx +++ b/store/source/store.cxx @@ -31,18 +31,20 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_store.hxx" -#define _STORE_STORE_CXX_ "$Revision: 1.8 $" +#include "store/store.h" + #include #include #include #include -#include -#include -#include -#include -#include -#include -#include + +#include "object.hxx" +#include "lockbyte.hxx" + +#include "storbase.hxx" +#include "storpage.hxx" +#include "stordir.hxx" +#include "storlckb.hxx" using rtl::Reference; using rtl::OString; @@ -123,15 +125,18 @@ storeError SAL_CALL store_createMemoryFile ( return store_E_InvalidParameter; *phFile = NULL; - Reference xLockBytes (new OMemoryLockBytes()); - if (!xLockBytes.is()) - return store_E_OutOfMemory; + Reference xLockBytes; + + storeError eErrCode = MemoryLockBytes_createInstance(xLockBytes); + if (eErrCode != store_E_None) + return eErrCode; + OSL_ASSERT(xLockBytes.is()); Reference xManager (new OStorePageManager()); if (!xManager.is()) return store_E_OutOfMemory; - storeError eErrCode = xManager->initializeManager ( + eErrCode = xManager->initialize ( &*xLockBytes, store_AccessCreate, nPageSize); if (eErrCode != store_E_None) return eErrCode; @@ -158,19 +163,18 @@ storeError SAL_CALL store_openFile ( if (!(pFilename && phFile)) return store_E_InvalidParameter; - Reference xLockBytes (new OFileLockBytes()); - if (!xLockBytes.is()) - return store_E_OutOfMemory; + Reference xLockBytes; - storeError eErrCode = xLockBytes->create (pFilename, eAccessMode); + storeError eErrCode = FileLockBytes_createInstance (xLockBytes, pFilename, eAccessMode); if (eErrCode != store_E_None) return eErrCode; + OSL_ASSERT(xLockBytes.is()); Reference xManager (new OStorePageManager()); if (!xManager.is()) return store_E_OutOfMemory; - eErrCode = xManager->initializeManager ( + eErrCode = xManager->initialize ( &*xLockBytes, eAccessMode, nPageSize); if (eErrCode != store_E_None) return eErrCode; @@ -269,21 +273,17 @@ storeError SAL_CALL store_rebuildFile ( if (!xManager.is()) return store_E_OutOfMemory; - Reference xSrcLB (new OFileLockBytes()); - if (!xSrcLB.is()) - return store_E_OutOfMemory; - - eErrCode = xSrcLB->create (pSrcFilename, store_AccessReadOnly); + Reference xSrcLB; + eErrCode = FileLockBytes_createInstance (xSrcLB, pSrcFilename, store_AccessReadOnly); if (eErrCode != store_E_None) return eErrCode; + OSL_ASSERT(xSrcLB.is()); - Reference xDstLB (new OFileLockBytes()); - if (!xDstLB.is()) - return store_E_OutOfMemory; - - eErrCode = xDstLB->create (pDstFilename, store_AccessCreate); + Reference xDstLB; + eErrCode = FileLockBytes_createInstance (xDstLB, pDstFilename, store_AccessCreate); if (eErrCode != store_E_None) return eErrCode; + OSL_ASSERT(xDstLB.is()); return xManager->rebuild (&*xSrcLB, &*xDstLB); } @@ -316,11 +316,14 @@ storeError SAL_CALL store_openDirectory ( if (!(pPath && pName && phDirectory)) return store_E_InvalidParameter; - Reference xDirectory (new OStoreDirectory()); + Reference xDirectory (new OStoreDirectory_Impl()); if (!xDirectory.is()) return store_E_OutOfMemory; - eErrCode = xDirectory->create (&*xManager, pPath, pName, eAccessMode); + OString aPath (pPath->buffer, pPath->length, RTL_TEXTENCODING_UTF8); + OString aName (pName->buffer, pName->length, RTL_TEXTENCODING_UTF8); + + eErrCode = xDirectory->create (&*xManager, aPath.pData, aName.pData, eAccessMode); if (eErrCode != store_E_None) return eErrCode; @@ -337,8 +340,8 @@ storeError SAL_CALL store_closeDirectory ( storeDirectoryHandle Handle ) SAL_THROW_EXTERN_C() { - OStoreDirectory *pDirectory = - OStoreHandle::query (Handle); + OStoreDirectory_Impl *pDirectory = + OStoreHandle::query (Handle); if (!pDirectory) return store_E_InvalidHandle; @@ -354,8 +357,8 @@ storeError SAL_CALL store_findFirst ( storeFindData *pFindData ) SAL_THROW_EXTERN_C() { - OStoreHandle xDirectory ( - OStoreHandle::query (Handle)); + OStoreHandle xDirectory ( + OStoreHandle::query (Handle)); if (!xDirectory.is()) return store_E_InvalidHandle; @@ -378,8 +381,8 @@ storeError SAL_CALL store_findNext ( storeFindData *pFindData ) SAL_THROW_EXTERN_C() { - OStoreHandle xDirectory ( - OStoreHandle::query (Handle)); + OStoreHandle xDirectory ( + OStoreHandle::query (Handle)); if (!xDirectory.is()) return store_E_InvalidHandle; @@ -427,7 +430,10 @@ storeError SAL_CALL store_openStream ( if (!xLockBytes.is()) return store_E_OutOfMemory; - eErrCode = xLockBytes->create (&*xManager, pPath, pName, eAccessMode); + OString aPath (pPath->buffer, pPath->length, RTL_TEXTENCODING_UTF8); + OString aName (pName->buffer, pName->length, RTL_TEXTENCODING_UTF8); + + eErrCode = xLockBytes->create (&*xManager, aPath.pData, aName.pData, eAccessMode); if (eErrCode != store_E_None) return eErrCode; @@ -581,7 +587,7 @@ storeError SAL_CALL store_attrib ( OString aName (pName->buffer, pName->length, RTL_TEXTENCODING_UTF8); OStorePageKey aKey; - eErrCode = OStorePageNameBlock::namei (aPath.pData, aName.pData, aKey); + eErrCode = OStorePageManager::namei (aPath.pData, aName.pData, aKey); if (eErrCode != store_E_None) return eErrCode; @@ -622,7 +628,7 @@ storeError SAL_CALL store_link ( pSrcName->buffer, pSrcName->length, RTL_TEXTENCODING_UTF8); OStorePageKey aSrcKey; - eErrCode = OStorePageNameBlock::namei ( + eErrCode = OStorePageManager::namei ( aSrcPath.pData, aSrcName.pData, aSrcKey); if (eErrCode != store_E_None) return eErrCode; @@ -634,7 +640,7 @@ storeError SAL_CALL store_link ( pDstName->buffer, pDstName->length, RTL_TEXTENCODING_UTF8); OStorePageKey aDstKey; - eErrCode = OStorePageNameBlock::namei ( + eErrCode = OStorePageManager::namei ( aDstPath.pData, aDstName.pData, aDstKey); if (eErrCode != store_E_None) return eErrCode; @@ -672,7 +678,7 @@ storeError SAL_CALL store_symlink ( pDstName->buffer, pDstName->length, RTL_TEXTENCODING_UTF8); OStorePageKey aDstKey; - eErrCode = OStorePageNameBlock::namei ( + eErrCode = OStorePageManager::namei ( aDstPath.pData, aDstName.pData, aDstKey); if (eErrCode != store_E_None) return eErrCode; @@ -715,7 +721,7 @@ storeError SAL_CALL store_rename ( pSrcName->buffer, pSrcName->length, RTL_TEXTENCODING_UTF8); OStorePageKey aSrcKey; - eErrCode = OStorePageNameBlock::namei ( + eErrCode = OStorePageManager::namei ( aSrcPath.pData, aSrcName.pData, aSrcKey); if (eErrCode != store_E_None) return eErrCode; @@ -753,11 +759,10 @@ storeError SAL_CALL store_remove ( OString aName (pName->buffer, pName->length, RTL_TEXTENCODING_UTF8); OStorePageKey aKey; - eErrCode = OStorePageNameBlock::namei (aPath.pData, aName.pData, aKey); + eErrCode = OStorePageManager::namei (aPath.pData, aName.pData, aKey); if (eErrCode != store_E_None) return eErrCode; // Remove. return xManager->remove (aKey); } - diff --git a/store/source/storlckb.cxx b/store/source/storlckb.cxx index 3db1027c7ccb..837945d1646c 100644 --- a/store/source/storlckb.cxx +++ b/store/source/storlckb.cxx @@ -31,298 +31,22 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_store.hxx" -#define _STORE_STORLCKB_CXX_ "$Revision: 1.9 $" -#include -#include -#include -#ifndef _RTL_TEXTCVT_H_ -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "storlckb.hxx" -using namespace store; - -/*======================================================================== - * - * OStore... internals. - * - *======================================================================*/ -/* - * __store_convertTextToUnicode. - */ -inline sal_Size __store_convertTextToUnicode ( - rtl_TextToUnicodeConverter hConverter, - const sal_Char *pSrcBuffer, sal_Size nSrcLength, - sal_Unicode *pDstBuffer, sal_Size nDstLength) -{ - sal_uInt32 nCvtInfo = 0; - sal_Size nCvtBytes = 0; - return rtl_convertTextToUnicode ( - hConverter, 0, - pSrcBuffer, nSrcLength, - pDstBuffer, nDstLength, - OSTRING_TO_OUSTRING_CVTFLAGS, - &nCvtInfo, &nCvtBytes); -} - -/* - * __store_iget. - * Precond: exclusive access. - */ -static storeError __store_iget ( - OStorePageManager &rManager, - OStoreDirectoryPageData &rNode, - sal_uInt32 nAttrib, - const rtl_String *pPath, - const rtl_String *pName, - storeAccessMode eMode) -{ - // Setup inode page key. - OStorePageKey aKey; - storeError eErrCode = OStorePageNameBlock::namei (pPath, pName, aKey); - if (eErrCode != store_E_None) - return eErrCode; - - // Check for directory. - if (nAttrib & STORE_ATTRIB_ISDIR) - { - // Ugly, but necessary (backward compatibility). - aKey.m_nLow = OStorePageGuard::crc32 (aKey.m_nLow, "/", 1); - } - - // Load inode page. - OStoreDirectoryPageObject aPage (rNode); - eErrCode = rManager.load (aKey, aPage); - if (eErrCode != store_E_None) - { - // Check mode and reason. - if (eErrCode != store_E_NotExists) - return eErrCode; - - if (eMode == store_AccessReadWrite) - return store_E_NotExists; - if (eMode == store_AccessReadOnly) - return store_E_NotExists; - - if (!rManager.isWriteable()) - return store_E_AccessViolation; - - // Setup inode nameblock. - rNode.m_aNameBlock.m_aKey = aKey; - rNode.m_aNameBlock.m_nAttrib = nAttrib; - - rtl_copyMemory ( - &rNode.m_aNameBlock.m_pData[0], - pName->buffer, pName->length); - - // Save inode page. - eErrCode = rManager.save (aKey, aPage); - if (eErrCode != store_E_None) - return eErrCode; - } - - // Check for symbolic link. - if (aPage.attrib() & STORE_ATTRIB_ISLINK) - { - // Obtain 'Destination' page key. - OStorePageKey aDstKey; - rtl_copyMemory (&aDstKey, &rNode.m_pData[0], sizeof(aDstKey)); - -#ifdef OSL_BIGENDIAN - // Swap to internal representation. - aDstKey.swap(); -#endif /* OSL_BIGENDIAN */ - - // Load 'Destination' inode. - eErrCode = rManager.load (aDstKey, aPage); - if (eErrCode != store_E_None) - return eErrCode; - } - - // Done. - return store_E_None; -} - -/*======================================================================== - * - * OStoreDirectory implementation. - * - *======================================================================*/ -const sal_uInt32 OStoreDirectory::m_nTypeId = sal_uInt32(0x89191107); - -/* - * OStoreDirectory. - */ -OStoreDirectory::OStoreDirectory (void) - : m_xManager (NULL), - m_pNode (NULL), - m_aDescr (0, 0, 0), - m_nPath (0), - m_hTextCvt (NULL) -{ -} - -/* - * ~OStoreDirectory. - */ -OStoreDirectory::~OStoreDirectory (void) -{ - if (m_xManager.is()) - { - osl::MutexGuard aGuard (*m_xManager); - if (m_pNode) - { - m_xManager->releasePage (m_aDescr); - } - } - delete m_pNode; - rtl_destroyTextToUnicodeConverter (m_hTextCvt); -} - -/* - * isKindOf. - */ -sal_Bool SAL_CALL OStoreDirectory::isKindOf (sal_uInt32 nTypeId) -{ - return (nTypeId == m_nTypeId); -} - -/* - * create. - */ -storeError OStoreDirectory::create ( - OStorePageManager *pManager, - rtl_uString *pPath, - rtl_uString *pName, - storeAccessMode eMode) -{ - rtl::Reference xManager (pManager); - if (!xManager.is()) - return store_E_InvalidAccess; - - if (!(pPath && pName)) - return store_E_InvalidParameter; - - osl::MutexGuard aGuard (*xManager); - storeError eErrCode = xManager->getPageSize (m_aDescr.m_nSize); - if (eErrCode != store_E_None) - return eErrCode; - - delete m_pNode; - m_pNode = new(m_aDescr.m_nSize) inode(m_aDescr.m_nSize); - if (!m_pNode) - return store_E_OutOfMemory; - - rtl::OString aPath (pPath->buffer, pPath->length, RTL_TEXTENCODING_UTF8); - rtl::OString aName (pName->buffer, pName->length, RTL_TEXTENCODING_UTF8); - - eErrCode = __store_iget ( - *xManager, *m_pNode, STORE_ATTRIB_ISDIR, - aPath.pData, aName.pData, eMode); - if (eErrCode != store_E_None) - return eErrCode; - - sal_uInt32 nAttrib = m_pNode->m_aNameBlock.m_nAttrib; - if (!(nAttrib & STORE_ATTRIB_ISDIR)) - return store_E_NotDirectory; - - m_aDescr = m_pNode->m_aDescr; - eErrCode = xManager->acquirePage (m_aDescr, store_AccessReadOnly); - if (eErrCode == store_E_None) - { - // Evaluate iteration path from NameBlock. - typedef OStorePageGuard G; - sal_Char *pszName = m_pNode->m_aNameBlock.m_pData; - - m_nPath = m_pNode->m_aNameBlock.m_aKey.m_nHigh; - m_nPath = G::crc32 (m_nPath, pszName, rtl_str_getLength(pszName)); - m_nPath = G::crc32 (m_nPath, "/", 1); - - // Accept page manager. - m_xManager = xManager; - } - return eErrCode; -} - -/* - * iterate. - */ -storeError OStoreDirectory::iterate (storeFindData &rFindData) -{ - if (!m_xManager.is()) - return store_E_InvalidAccess; - - storeError eErrCode = store_E_NoMoreFiles; - if (!rFindData.m_nReserved) - return eErrCode; - - // Acquire exclusive access. - osl::MutexGuard aGuard (*m_xManager); - - // Check TextConverter. - if (m_hTextCvt == NULL) - m_hTextCvt = rtl_createTextToUnicodeConverter(RTL_TEXTENCODING_UTF8); - - // Setup iteration key and page buffer. - OStorePageKey aKey (rFindData.m_nReserved, m_nPath); - OStoreDirectoryPageObject aPage (*m_pNode); - - // Iterate. - for (;;) - { - eErrCode = m_xManager->iterate (aKey, aPage, rFindData.m_nAttrib); - if (!((eErrCode == store_E_None) && (aKey.m_nHigh == m_nPath))) - break; +#include "sal/types.h" +#include "sal/macros.h" +#include "rtl/string.h" +#include "rtl/ref.hxx" +#include "osl/mutex.hxx" - if (!(rFindData.m_nAttrib & STORE_ATTRIB_ISLINK)) - { - // Load page. - eErrCode = m_xManager->load (aPage); - if (eErrCode == store_E_None) - { - // Setup FindData. - sal_Char *p = m_pNode->m_aNameBlock.m_pData; - sal_Size n = rtl_str_getLength (p); - sal_Size k = rFindData.m_nLength; - - n = __store_convertTextToUnicode ( - m_hTextCvt, p, n, - rFindData.m_pszName, STORE_MAXIMUM_NAMESIZE - 1); - if (k > n) - { - k = (k - n) * sizeof(sal_Unicode); - rtl_zeroMemory (&rFindData.m_pszName[n], k); - } +#include "store/types.h" +#include "object.hxx" - rFindData.m_nLength = n; - rFindData.m_nAttrib |= aPage.attrib(); - rFindData.m_nSize = aPage.dataLength(); +#include "storbase.hxx" +#include "stordata.hxx" +#include "storpage.hxx" - // Leave. - rFindData.m_nReserved = aKey.m_nLow; - return store_E_None; - } - } - - if (aKey.m_nLow > 0) - aKey.m_nLow -= 1; - else - break; - } - - // Finished. - rtl_zeroMemory (&rFindData, sizeof (storeFindData)); - return store_E_NoMoreFiles; -} +using namespace store; /*======================================================================== * @@ -335,14 +59,9 @@ const sal_uInt32 OStoreLockBytes::m_nTypeId = sal_uInt32(0x94190310); * OStoreLockBytes. */ OStoreLockBytes::OStoreLockBytes (void) - : m_xManager (NULL), - m_pNode (NULL), - m_pData (NULL), - m_pSingle (NULL), - m_pDouble (NULL), - m_pTriple (NULL), - m_nPageSize (0), - m_bWriteable (sal_False) + : m_xManager (), + m_xNode (), + m_bWriteable (false) { } @@ -353,20 +72,15 @@ OStoreLockBytes::~OStoreLockBytes (void) { if (m_xManager.is()) { - osl::MutexGuard aGuard (*m_xManager); - if (m_pNode) + if (m_xNode.is()) { - OStorePageDescriptor aDescr (m_pNode->m_aDescr); - m_xManager->releasePage (aDescr); + OStorePageDescriptor aDescr (m_xNode->m_aDescr); + if (m_bWriteable) + m_xManager->releasePage (aDescr, store_AccessReadWrite); + else + m_xManager->releasePage (aDescr, store_AccessReadOnly); } } - - delete m_pNode; - delete m_pData; - - delete m_pSingle; - delete m_pDouble; - delete m_pTriple; } /* @@ -377,29 +91,13 @@ sal_Bool SAL_CALL OStoreLockBytes::isKindOf (sal_uInt32 nTypeId) return (nTypeId == m_nTypeId); } -/* - * acquire. - */ -oslInterlockedCount SAL_CALL OStoreLockBytes::acquire (void) -{ - return OStoreObject::acquire(); -} - -/* - * release. - */ -oslInterlockedCount SAL_CALL OStoreLockBytes::release (void) -{ - return OStoreObject::release(); -} - /* * create. */ storeError OStoreLockBytes::create ( OStorePageManager *pManager, - rtl_uString *pPath, - rtl_uString *pName, + rtl_String *pPath, + rtl_String *pName, storeAccessMode eMode) { rtl::Reference xManager (pManager); @@ -409,44 +107,32 @@ storeError OStoreLockBytes::create ( if (!(pPath && pName)) return store_E_InvalidParameter; - osl::MutexGuard aGuard (*xManager); - storeError eErrCode = xManager->getPageSize (m_nPageSize); + OStoreDirectoryPageObject aPage; + storeError eErrCode = xManager->iget ( + aPage, STORE_ATTRIB_ISFILE, + pPath, pName, eMode); if (eErrCode != store_E_None) return eErrCode; - delete m_pNode; - m_pNode = new(m_nPageSize) inode(m_nPageSize); - if (!m_pNode) - return store_E_OutOfMemory; - - rtl::OString aPath (pPath->buffer, pPath->length, RTL_TEXTENCODING_UTF8); - rtl::OString aName (pName->buffer, pName->length, RTL_TEXTENCODING_UTF8); - - eErrCode = __store_iget ( - *xManager, *m_pNode, STORE_ATTRIB_ISFILE, - aPath.pData, aName.pData, eMode); - if (eErrCode != store_E_None) - return eErrCode; - - sal_uInt32 nAttrib = m_pNode->m_aNameBlock.m_nAttrib; - if (!(nAttrib & STORE_ATTRIB_ISFILE)) + if (!(aPage.attrib() & STORE_ATTRIB_ISFILE)) { // No ISFILE in older versions (backward compatibility). - if (nAttrib & STORE_ATTRIB_ISLINK) + if (aPage.attrib() & STORE_ATTRIB_ISLINK) return store_E_NotFile; } // ... - OStorePageDescriptor aDescr (m_pNode->m_aDescr); + inode_holder_type xNode (aPage.get()); if (eMode != store_AccessReadOnly) - eErrCode = xManager->acquirePage (aDescr, store_AccessReadWrite); + eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadWrite); else - eErrCode = xManager->acquirePage (aDescr, store_AccessReadOnly); + eErrCode = xManager->acquirePage (xNode->m_aDescr, store_AccessReadOnly); if (eErrCode != store_E_None) return eErrCode; // ... m_xManager = xManager; + m_xNode = xNode; m_bWriteable = (eMode != store_AccessReadOnly); // Check for truncation. @@ -481,30 +167,31 @@ storeError OStoreLockBytes::readAt ( osl::MutexGuard aGuard (*m_xManager); // Determine data length. - OStoreDirectoryPageObject aPage (*m_pNode); + OStoreDirectoryPageObject aPage (m_xNode.get()); sal_uInt32 nDataLen = aPage.dataLength(); if ((nOffset + nBytes) > nDataLen) nBytes = nDataLen - nOffset; // Read data. + OStoreDataPageObject aData; sal_uInt8 *pData = (sal_uInt8*)pBuffer; while ((0 < nBytes) && (nOffset < nDataLen)) { // Determine 'Offset' scope. - inode::ChunkScope eScope = m_pNode->scope (nOffset); + inode::ChunkScope eScope = m_xNode->scope (nOffset); if (eScope == inode::SCOPE_INTERNAL) { // Read from inode page (internal scope). inode::ChunkDescriptor aDescr ( - nOffset, m_pNode->capacity()); + nOffset, m_xNode->capacity()); sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength); nLength = SAL_MIN(nLength, nBytes); - rtl_copyMemory ( + memcpy ( &pData[rnDone], - &m_pNode->m_pData[aDescr.m_nOffset], + &m_xNode->m_pData[aDescr.m_nOffset], nLength); // Adjust counters. @@ -515,35 +202,29 @@ storeError OStoreLockBytes::readAt ( else { // Read from data page (external scope). - if (!m_pData) - m_pData = new(m_nPageSize) data(m_nPageSize); - if (!m_pData) - return store_E_OutOfMemory; - OStoreDataPageObject aData (*m_pData); - inode::ChunkDescriptor aDescr ( - nOffset - m_pNode->capacity(), m_pData->capacity()); + nOffset - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); // @@@ sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength); nLength = SAL_MIN(nLength, nBytes); - storeError eErrCode = aPage.get ( - aDescr.m_nPage, m_pSingle, m_pDouble, m_pTriple, - aData, *m_xManager, NULL); + storeError eErrCode = aPage.read (aDescr.m_nPage, aData, *m_xManager); if (eErrCode != store_E_None) { if (eErrCode != store_E_NotExists) return eErrCode; - rtl_zeroMemory ( + memset ( &pData[rnDone], + 0, nLength); } else { - rtl_copyMemory ( + PageHolderObject< data > xData (aData.get()); + memcpy ( &pData[rnDone], - &m_pData->m_pData[aDescr.m_nOffset], + &xData->m_pData[aDescr.m_nOffset], nLength); } @@ -583,25 +264,25 @@ storeError OStoreLockBytes::writeAt ( osl::MutexGuard aGuard (*m_xManager); // Write data. - OStoreDirectoryPageObject aPage (*m_pNode); + OStoreDirectoryPageObject aPage (m_xNode.get()); const sal_uInt8 *pData = (const sal_uInt8*)pBuffer; storeError eErrCode = store_E_None; while (nBytes > 0) { // Determine 'Offset' scope. - inode::ChunkScope eScope = m_pNode->scope (nOffset); + inode::ChunkScope eScope = m_xNode->scope (nOffset); if (eScope == inode::SCOPE_INTERNAL) { // Write to inode page (internal scope). inode::ChunkDescriptor aDescr ( - nOffset, m_pNode->capacity()); + nOffset, m_xNode->capacity()); sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength); nLength = SAL_MIN(nLength, nBytes); - rtl_copyMemory ( - &m_pNode->m_pData[aDescr.m_nOffset], + memcpy ( + &m_xNode->m_pData[aDescr.m_nOffset], &pData[rnDone], nLength); // Mark inode dirty. @@ -619,44 +300,45 @@ storeError OStoreLockBytes::writeAt ( else { // Write to data page (external scope). - if (!m_pData) - m_pData = new(m_nPageSize) data(m_nPageSize); - if (!m_pData) - return store_E_OutOfMemory; - OStoreDataPageObject aData (*m_pData); + OStoreDataPageObject aData; inode::ChunkDescriptor aDescr ( - nOffset - m_pNode->capacity(), m_pData->capacity()); + nOffset - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); // @@@ sal_uInt32 nLength = sal_uInt32(aDescr.m_nLength); if ((aDescr.m_nOffset > 0) || (nBytes < nLength)) { // Unaligned. Need to load/create data page. - eErrCode = aPage.get ( - aDescr.m_nPage, m_pSingle, m_pDouble, m_pTriple, - aData, *m_xManager, NULL); +// @@@ loadOrCreate() + eErrCode = aPage.read (aDescr.m_nPage, aData, *m_xManager); if (eErrCode != store_E_None) { if (eErrCode != store_E_NotExists) return eErrCode; - rtl_zeroMemory ( - &m_pData->m_pData[0], - m_pData->capacity()); + eErrCode = aData.construct(m_xManager->allocator()); + if (eErrCode != store_E_None) + return eErrCode; } } + PageHolderObject< data > xData (aData.get()); + if (!xData.is()) + { + eErrCode = aData.construct(m_xManager->allocator()); + if (eErrCode != store_E_None) + return eErrCode; + xData = aData.get(); + } + // Modify data page. nLength = SAL_MIN(nLength, nBytes); - - rtl_copyMemory ( - &m_pData->m_pData[aDescr.m_nOffset], + memcpy ( + &xData->m_pData[aDescr.m_nOffset], &pData[rnDone], nLength); // Save data page. - eErrCode = aPage.put ( - aDescr.m_nPage, m_pSingle, m_pDouble, m_pTriple, - aData, *m_xManager, NULL); + eErrCode = aPage.write (aDescr.m_nPage, aData, *m_xManager); if (eErrCode != store_E_None) return eErrCode; @@ -673,7 +355,7 @@ storeError OStoreLockBytes::writeAt ( // Check for modified inode. if (aPage.dirty()) - return m_xManager->save (aPage); + return m_xManager->saveObjectAt (aPage, aPage.location()); else return store_E_None; } @@ -703,7 +385,7 @@ storeError OStoreLockBytes::setSize (sal_uInt32 nSize) osl::MutexGuard aGuard (*m_xManager); // Determine current length. - OStoreDirectoryPageObject aPage (*m_pNode); + OStoreDirectoryPageObject aPage (m_xNode.get()); sal_uInt32 nDataLen = aPage.dataLength(); if (nSize == nDataLen) @@ -715,53 +397,35 @@ storeError OStoreLockBytes::setSize (sal_uInt32 nSize) storeError eErrCode = store_E_None; // Determine 'Size' scope. - inode::ChunkScope eSizeScope = m_pNode->scope (nSize); + inode::ChunkScope eSizeScope = m_xNode->scope (nSize); if (eSizeScope == inode::SCOPE_INTERNAL) { // Internal 'Size' scope. Determine 'Data' scope. - inode::ChunkScope eDataScope = m_pNode->scope (nDataLen); + inode::ChunkScope eDataScope = m_xNode->scope (nDataLen); if (eDataScope == inode::SCOPE_EXTERNAL) { - // External 'Data' scope. - if (!m_pData) - m_pData = new(m_nPageSize) data(m_nPageSize); - if (!m_pData) - return store_E_OutOfMemory; - OStoreDataPageObject aData (*m_pData); - - // Truncate all external data pages. - eErrCode = aPage.truncate ( - 0, m_pSingle, m_pDouble, m_pTriple, - aData, *m_xManager, NULL); + // External 'Data' scope. Truncate all external data pages. + eErrCode = aPage.truncate (0, *m_xManager); if (eErrCode != store_E_None) return eErrCode; } // Truncate internal data page. - inode::ChunkDescriptor aDescr (nSize, m_pNode->capacity()); - rtl_zeroMemory ( - &m_pNode->m_pData[aDescr.m_nOffset], - aDescr.m_nLength); + inode::ChunkDescriptor aDescr (nSize, m_xNode->capacity()); + memset ( + &(m_xNode->m_pData[aDescr.m_nOffset]), + 0, aDescr.m_nLength); } else { - // External 'Size' scope. - if (!m_pData) - m_pData = new(m_nPageSize) data(m_nPageSize); - if (!m_pData) - return store_E_OutOfMemory; - OStoreDataPageObject aData (*m_pData); - - // Truncate external data pages. + // External 'Size' scope. Truncate external data pages. inode::ChunkDescriptor aDescr ( - nSize - m_pNode->capacity(), m_pData->capacity()); + nSize - m_xNode->capacity(), OStoreDataPageData::capacity(m_xNode->m_aDescr)); // @@@ sal_uInt32 nPage = aDescr.m_nPage; if (aDescr.m_nOffset) nPage += 1; - eErrCode = aPage.truncate ( - nPage, m_pSingle, m_pDouble, m_pTriple, - aData, *m_xManager, NULL); + eErrCode = aPage.truncate (nPage, *m_xManager); if (eErrCode != store_E_None) return eErrCode; } @@ -771,7 +435,7 @@ storeError OStoreLockBytes::setSize (sal_uInt32 nSize) aPage.dataLength (nSize); // Save modified inode. - return m_xManager->save (aPage); + return m_xManager->saveObjectAt (aPage, aPage.location()); } /* @@ -784,25 +448,7 @@ storeError OStoreLockBytes::stat (sal_uInt32 &rnSize) if (!m_xManager.is()) return store_E_InvalidAccess; - rnSize = m_pNode->m_aDataBlock.m_nDataLen; + OStoreDirectoryPageObject aPage (m_xNode.get()); + rnSize = aPage.dataLength(); return store_E_None; } - -/* - * lockRange. - */ -storeError OStoreLockBytes::lockRange (sal_uInt32, sal_uInt32) -{ - // (NYI). - return store_E_None; -} - -/* - * unlockRange. - */ -storeError OStoreLockBytes::unlockRange (sal_uInt32, sal_uInt32) -{ - // (NYI). - return store_E_None; -} - diff --git a/store/source/storlckb.hxx b/store/source/storlckb.hxx index 2420590ade48..4a0dbfde873a 100644 --- a/store/source/storlckb.hxx +++ b/store/source/storlckb.hxx @@ -29,115 +29,29 @@ ************************************************************************/ #ifndef _STORE_STORLCKB_HXX_ -#define _STORE_STORLCKB_HXX_ "$Revision: 1.6 $" +#define _STORE_STORLCKB_HXX_ "$Revision: 1.6.8.1 $" -#include +#include "sal/types.h" -#ifndef _RTL_TEXTCVT_H_ -#include -#endif -#include -#include -#include -#include -#include -#include +#include "rtl/ustring.h" +#include "rtl/ref.hxx" + +#include "object.hxx" +#include "storbase.hxx" +#include "storpage.hxx" namespace store { struct OStoreDataPageData; struct OStoreDirectoryPageData; -struct OStoreIndirectionPageData; - -/*======================================================================== - * - * OStoreDirectory interface. - * - *======================================================================*/ -class OStoreDirectory : public store::OStoreObject -{ -public: - /** Construction. - */ - OStoreDirectory (void); - - /** create (two-phase construction). - * @param pManager [in] - * @param pszPath [in] - * @param pszName [in] - * @param eAccessMode [in] - * @return store_E_None upon success. - */ - storeError create ( - OStorePageManager *pManager, - rtl_uString *pPath, - rtl_uString *pName, - storeAccessMode eAccessMode); - - /** iterate. - * @param rFindData [out] - * @return store_E_None upon success, - * store_E_NoMoreFiles upon end of iteration. - */ - storeError iterate ( - storeFindData &rFindData); - - /** IStoreHandle. - */ - virtual sal_Bool SAL_CALL isKindOf (sal_uInt32 nTypeId); - -protected: - /** Destruction. - */ - virtual ~OStoreDirectory (void); - -private: - /** IStoreHandle TypeId. - */ - static const sal_uInt32 m_nTypeId; - - /** IStoreHandle query() template function specialization. - */ - friend OStoreDirectory* - SAL_CALL query<> (IStoreHandle *pHandle, OStoreDirectory*); - - /** Representation. - */ - rtl::Reference m_xManager; - - typedef OStoreDirectoryPageData inode; - inode *m_pNode; - - OStorePageDescriptor m_aDescr; - sal_uInt32 m_nPath; - rtl_TextToUnicodeConverter m_hTextCvt; - - /** Not implemented. - */ - OStoreDirectory (const OStoreDirectory&); - OStoreDirectory& operator= (const OStoreDirectory&); -}; - -template<> inline OStoreDirectory* -SAL_CALL query (IStoreHandle *pHandle, OStoreDirectory*) -{ - if (pHandle && pHandle->isKindOf (OStoreDirectory::m_nTypeId)) - { - // Handle is kind of OStoreDirectory. - return static_cast(pHandle); - } - return 0; -} /*======================================================================== * * OStoreLockBytes interface. * *======================================================================*/ -class OStoreLockBytes : - public store::OStoreObject, - public store::ILockBytes +class OStoreLockBytes : public store::OStoreObject { public: /** Construction. @@ -146,14 +60,15 @@ public: /** create (two-phase construction). * @param pManager [in] - * @param rNode [in] + * @param pPath [in] + * @param pName [in] * @param eMode [in] * @return store_E_None upon success */ storeError create ( OStorePageManager *pManager, - rtl_uString *pPath, - rtl_uString *pName, + rtl_String *pPath, + rtl_String *pName, storeAccessMode eAccessMode); /** Read at Offset into Buffer. @@ -163,7 +78,7 @@ public: * @param rnDone [out] * @return store_E_None upon success */ - virtual storeError readAt ( + storeError readAt ( sal_uInt32 nOffset, void *pBuffer, sal_uInt32 nBytes, @@ -176,7 +91,7 @@ public: * @param rnDone [out] * @return store_E_None upon success */ - virtual storeError writeAt ( + storeError writeAt ( sal_uInt32 nOffset, const void *pBuffer, sal_uInt32 nBytes, @@ -185,49 +100,24 @@ public: /** flush. * @return store_E_None upon success */ - virtual storeError flush (void); + storeError flush (void); /** setSize. * @param nSize [in] * @return store_E_None upon success */ - virtual storeError setSize (sal_uInt32 nSize); + storeError setSize (sal_uInt32 nSize); /** stat. * @paran rnSize [out] * @return store_E_None upon success */ - virtual storeError stat (sal_uInt32 &rnSize); - - /** Lock range at Offset. - * @param nOffset [in] - * @param nBytes [in] - * @return store_E_None upon success - * store_E_LockingViolation - */ - virtual storeError lockRange ( - sal_uInt32 nOffset, - sal_uInt32 nBytes); - - /** Unlock range at Offset. - * @param nOffset [in] - * @param nBytes [in] - * @return store_E_None upon success - * store_E_LockingViolation - */ - virtual storeError unlockRange ( - sal_uInt32 nOffset, - sal_uInt32 nBytes); + storeError stat (sal_uInt32 &rnSize); /** IStoreHandle. */ virtual sal_Bool SAL_CALL isKindOf (sal_uInt32 nMagic); - /** Delegate multiple inherited IReference. - */ - virtual oslInterlockedCount SAL_CALL acquire (void); - virtual oslInterlockedCount SAL_CALL release (void); - protected: /** Destruction (OReference). */ @@ -249,17 +139,11 @@ private: typedef OStoreDataPageData data; typedef OStoreDirectoryPageData inode; - typedef OStoreIndirectionPageData indirect; - - inode *m_pNode; - data *m_pData; - indirect *m_pSingle; - indirect *m_pDouble; - indirect *m_pTriple; + typedef PageHolderObject< inode > inode_holder_type; + inode_holder_type m_xNode; - sal_uInt16 m_nPageSize; - sal_Bool m_bWriteable; + bool m_bWriteable; /** Not implemented. */ diff --git a/store/source/storpage.cxx b/store/source/storpage.cxx index ccf589489533..b112d5bb8fdd 100644 --- a/store/source/storpage.cxx +++ b/store/source/storpage.cxx @@ -31,24 +31,22 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_store.hxx" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef _STORE_STORCACH_HXX_ -#include -#endif -#include -#ifndef _STORE_STORTREE_HXX_ -#include -#endif +#include "storpage.hxx" + +#include "sal/types.h" +#include "rtl/string.h" +#include "rtl/ref.hxx" +#include "osl/diagnose.h" +#include "osl/mutex.hxx" + +#include "store/types.h" + +#include "object.hxx" +#include "lockbyte.hxx" + +#include "storbase.hxx" +#include "stordata.hxx" +#include "stortree.hxx" using namespace store; @@ -63,20 +61,7 @@ const sal_uInt32 OStorePageManager::m_nTypeId = sal_uInt32(0x62190120); * OStorePageManager. */ OStorePageManager::OStorePageManager (void) - : m_pCache (NULL), - m_pDirect (NULL), - m_pData (NULL), - m_nPageSize (0) { - // Node pages. - m_pNode[0] = NULL; - m_pNode[1] = NULL; - m_pNode[2] = NULL; - - // Indirect pages. - m_pLink[0] = NULL; - m_pLink[1] = NULL; - m_pLink[2] = NULL; } /* @@ -84,17 +69,6 @@ OStorePageManager::OStorePageManager (void) */ OStorePageManager::~OStorePageManager (void) { - delete m_pCache; - delete m_pDirect; - delete m_pData; - - delete m_pNode[0]; - delete m_pNode[1]; - delete m_pNode[2]; - - delete m_pLink[0]; - delete m_pLink[1]; - delete m_pLink[2]; } /* @@ -109,10 +83,10 @@ sal_Bool SAL_CALL OStorePageManager::isKindOf (sal_uInt32 nTypeId) * initialize (two-phase construction). * Precond: none. */ -storeError OStorePageManager::initializeManager ( - ILockBytes *pLockBytes, - storeAccessMode eAccessMode, - sal_uInt16 nPageSize) +storeError OStorePageManager::initialize ( + ILockBytes * pLockBytes, + storeAccessMode eAccessMode, + sal_uInt16 & rnPageSize) { // Acquire exclusive access. osl::MutexGuard aGuard(*this); @@ -122,312 +96,133 @@ storeError OStorePageManager::initializeManager ( return store_E_InvalidParameter; // Initialize base. - storeError eErrCode = base::initialize (pLockBytes, eAccessMode); - if (eErrCode != store_E_None) - { - // Check mode and reason. - if (eErrCode != store_E_NotExists) - return eErrCode; - - if (eAccessMode == store_AccessReadWrite) - return store_E_NotExists; - if (eAccessMode == store_AccessReadOnly) - return store_E_NotExists; - - // Create. - eErrCode = base::create (nPageSize); - if (eErrCode != store_E_None) - return eErrCode; - } - - // Obtain page size. - eErrCode = base::getPageSize (m_nPageSize); - OSL_POSTCOND( - eErrCode == store_E_None, - "OStorePageManager::initialize(): getPageSize() failed"); + storeError eErrCode = base::initialize (pLockBytes, eAccessMode, rnPageSize); if (eErrCode != store_E_None) return eErrCode; - // Cleanup. - __STORE_DELETEZ (m_pCache); - __STORE_DELETEZ (m_pDirect); - __STORE_DELETEZ (m_pData); - - __STORE_DELETEZ (m_pNode[0]); - __STORE_DELETEZ (m_pNode[1]); - __STORE_DELETEZ (m_pNode[2]); - - __STORE_DELETEZ (m_pLink[0]); - __STORE_DELETEZ (m_pLink[1]); - __STORE_DELETEZ (m_pLink[2]); - - // Initialize page buffers. - m_pNode[0] = new(m_nPageSize) page(m_nPageSize); - if (eAccessMode != store_AccessReadOnly) + // Check for (not) writeable. + if (!base::isWriteable()) { - m_pNode[1] = new(m_nPageSize) page(m_nPageSize); - m_pNode[2] = new(m_nPageSize) page(m_nPageSize); + // Readonly. Load RootNode. + return base::loadObjectAt (m_aRoot, rnPageSize); } - // Initialize page cache. - m_pCache = new OStorePageCache(); - - // Done. - return eErrCode; -} - -/* - * free (unmanaged). - * Precond: initialized, writeable. - */ -storeError OStorePageManager::free (OStorePageObject &rPage) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard(*this); - - // Check precond. - if (!self::isValid()) - return store_E_InvalidAccess; + // Writeable. Load or Create RootNode. + eErrCode = m_aRoot.loadOrCreate (rnPageSize, *this); + if (eErrCode == store_E_Pending) + { + // Creation notification. + PageHolderObject< page > xRoot (m_aRoot.get()); - if (!base::isWriteable()) - return store_E_AccessViolation; + // Pre-allocate left most entry (ugly, but we can't insert to left). + OStorePageKey aKey (rtl_crc32 (0, "/", 1), 0); + xRoot->insert (0, entry(aKey)); - // Check for cacheable page. - OStorePageData &rData = rPage.getData(); - if (rData.m_aGuard.m_nMagic == STORE_MAGIC_BTREENODE) - { - // Invalidate cache entry. - storeError eErrCode = m_pCache->invalidate (rData.m_aDescr); + // Save RootNode. + eErrCode = base::saveObjectAt (m_aRoot, rnPageSize); if (eErrCode != store_E_None) return eErrCode; + + // Flush for robustness. + (void) base::flush(); } - // Free page. - return base::free (rPage); + // Done. + return eErrCode; } /* - * load (unmanaged). - * Precond: initialized. + * find_lookup (w/o split()). + * Internal: Precond: initialized, readable, exclusive access. */ -storeError OStorePageManager::load (OStorePageObject &rPage) +storeError OStorePageManager::find_lookup ( + OStoreBTreeNodeObject & rNode, + sal_uInt16 & rIndex, + OStorePageKey const & rKey) { - // Acquire exclusive access. - osl::MutexGuard aGuard(*this); + // Find Node and Index. + storeError eErrCode = m_aRoot.find_lookup (rNode, rIndex, rKey, *this); + if (eErrCode != store_E_None) + return eErrCode; - // Check precond. - if (!self::isValid()) - return store_E_InvalidAccess; + // Greater or Equal. + PageHolderObject< page > xPage (rNode.get()); + OSL_POSTCOND(rIndex < xPage->usageCount(), "store::PageManager::find_lookup(): logic error"); + entry e (xPage->m_pData[rIndex]); - // Check for cacheable page. - OStorePageData &rData = rPage.getData(); - if (rData.m_aGuard.m_nMagic == STORE_MAGIC_BTREENODE) + // Check for exact match. + if (e.compare(entry(rKey)) != entry::COMPARE_EQUAL) { - // Save PageDescriptor. - OStorePageDescriptor aDescr (rData.m_aDescr); - - // Load (cached) page. - storeError eErrCode = m_pCache->load (aDescr, rData, *this); - if (eErrCode != store_E_None) - { - // Check for pending verification. - if (eErrCode != store_E_Pending) - return eErrCode; - - // Verify page. - eErrCode = rPage.verify (aDescr); - if (eErrCode != store_E_None) - return eErrCode; - } - -#ifdef OSL_BIGENDIAN - // Swap to internal representation. - rPage.swap (aDescr); -#endif /* OSL_BIGENDIAN */ - - // Done. - return store_E_None; + // Page not present. + return store_E_NotExists; } - // Load (uncached) page. - return base::load (rPage); -} - -/* - * save (unmanaged). - * Precond: initialized, writeable. - */ -storeError OStorePageManager::save (OStorePageObject &rPage) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard(*this); - - // Check precond. - if (!self::isValid()) - return store_E_InvalidAccess; - - if (!base::isWriteable()) - return store_E_AccessViolation; - - // Check for cacheable page. - OStorePageData &rData = rPage.getData(); - if (rData.m_aGuard.m_nMagic == STORE_MAGIC_BTREENODE) + // Check address. + if (e.m_aLink.location() == STORE_PAGE_NULL) { - // Save PageDescriptor. - OStorePageDescriptor aDescr (rData.m_aDescr); - -#ifdef OSL_BIGENDIAN - // Swap to external representation. - rPage.swap (aDescr); -#endif /* OSL_BIGENDIAN */ - - // Guard page. - rPage.guard (aDescr); - - // Save (cached) page. -#if 0 /* EXPERIMENTAL */ - storeError eErrCode = m_pCache->update ( - aDescr, rData, *this, NULL, - OStorePageCache::UPDATE_WRITE_DELAYED); -#else - storeError eErrCode = m_pCache->update ( - aDescr, rData, *this, NULL, - OStorePageCache::UPDATE_WRITE_THROUGH); -#endif /* EXPERIMENTAL */ - -#ifdef OSL_BIGENDIAN - // Swap back to internal representation. - rPage.swap (aDescr); -#endif /* OSL_BIGENDIAN */ - - // Mark page clean. - if (eErrCode == store_E_None) - rPage.clean(); - - // Done. - return eErrCode; + // Page not present. + return store_E_NotExists; } - // Save (uncached) page. - return base::save (rPage); + return store_E_None; } /* - * flush. - * Precond: initialized. + * remove_Impl (possibly down from root). + * Internal: Precond: initialized, writeable, exclusive access. */ -storeError OStorePageManager::flush (void) +#if 0 /* EXP */ +storeError OStorePageManager::remove_Impl (entry & rEntry) { - // Acquire exclusive access. - osl::MutexGuard aGuard(*this); + // Find Node and Index. + OStoreBTreeNodeObject aNode; + sal_uInt16 nIndex = 0; + eErrCode = m_aRoot.find_lookup (aNode, nIndex, entry::CompareGreater(rEntry), *this); - // Check precond. - if (!self::isValid()) - return store_E_InvalidAccess; + // @@@ - // Check access mode. - if (!base::isWriteable()) - return store_E_None; + PageHolderObject< page > xPage (aNode.get()); + page & rPage = (*xPage); - // Flush cache. - if (m_pCache->flush (*this, NULL) != store_E_None) { - OSL_POSTCOND( - false, "OStorePageManager::flush(): cache::flush() failed"); + // Check current page index. + sal_uInt16 i = rPage.find (rEntry), n = rPage.usageCount(); + if (!(i < n)) + { + // Path to entry not exists (Must not happen(?)). + return store_E_NotExists; } - // Flush base. - return base::flush(); -} - -/* - * find (w/o split()). - * Internal: Precond: initialized, readable, exclusive access. - */ -storeError OStorePageManager::find (const entry &rEntry, page &rPage) -{ - // Load RootNode. - OStoreBTreeRootObject aRoot (rPage); - aRoot.location (m_nPageSize); - - storeError eErrCode = load (aRoot); - if (eErrCode != store_E_None) - return eErrCode; + // Compare entry. + entry::CompareResult result = rEntry.compare (rPage.m_pData[i]); - // Check current Page. - while (rPage.depth()) + for (; result == entry::COMPARE_GREATER && xPage->depth() > 0; ) { - // Find next page. - sal_uInt16 i = rPage.find(rEntry), n = rPage.usageCount(); - if (!(i < n)) - { - // Path to entry not exists (Must not happen(?)). - return store_E_NotExists; - } - - // Check address. - sal_uInt32 nAddr = rPage.m_pData[i].m_aLink.m_nAddr; + // Check next node address. + sal_uInt32 const nAddr = rPage.m_pData[i].m_aLink.location(); if (nAddr == STORE_PAGE_NULL) { // Path to entry not exists (Must not happen(?)). return store_E_NotExists; } - // Load next page. - node aNode (rPage); - aNode.location (nAddr); + // Load next node page. + eErrCode = loadObjectAt (aNode, nAddr); - eErrCode = load (aNode); - if (eErrCode != store_E_None) - return eErrCode; + PageHolderObject< page > xNext (aNode.get()); + xNext.swap (xPage); } - // Done. - return store_E_None; -} + aNode.remove (nIndex, rEntry, *this); -/* - * find (possibly with split()). - * Internal: Precond: initialized, writeable, exclusive access. - */ -storeError OStorePageManager::find ( - const entry &rEntry, page &rPage, page &rPageL, page &rPageR) -{ - // Load RootNode. - OStoreBTreeRootObject aRoot (rPage); - aRoot.location (m_nPageSize); - storeError eErrCode = load (aRoot); - if (eErrCode != store_E_None) + do { - // Check existence. - if (eErrCode != store_E_NotExists) - return eErrCode; - - // Pre-allocate left most entry (ugly, but we can't insert to left). - rPage.insert (0, entry()); - rPage.m_pData[0].m_aKey.m_nLow = OStorePageGuard::crc32 (0, "/", 1); + // Load next node page. + eErrCode = loadObjectAt (aNode, nAddr); - // Allocate RootNode. - eErrCode = base::allocate (aRoot, ALLOCATE_EOF); - if (eErrCode != store_E_None) - return eErrCode; - } - else - { - // Check for RootNode split. - if (aRoot.querySplit()) - { - // Split root. - eErrCode = aRoot.split (0, rPageL, rPageR, *this); - if (eErrCode != store_E_None) - return eErrCode; - } - } + page const & rPage = (*xPage); - // Check current Page. - while (rPage.depth()) - { - // Find next page. + // Check current page index. sal_uInt16 i = rPage.find (rEntry), n = rPage.usageCount(); if (!(i < n)) { @@ -435,63 +230,20 @@ storeError OStorePageManager::find ( return store_E_NotExists; } - // Check address. - sal_uInt32 nAddr = rPage.m_pData[i].m_aLink.m_nAddr; - if (nAddr == STORE_PAGE_NULL) - { - // Path to entry not exists (Must not happen(?)). - return store_E_NotExists; - } - - // Load next page. - node aNode (rPageL); - aNode.location (nAddr); - - eErrCode = load (aNode); - if (eErrCode != store_E_None) - return eErrCode; - - // Check for node split. - if (rPageL.querySplit()) - { - // Split node. - node aParent (rPage); - eErrCode = aParent.split (i, rPageL, rPageR, *this); - if (eErrCode != store_E_None) - return eErrCode; - - // Restart. - continue; - } - else - { - // Let next page be current. - rPage = rPageL; - continue; - } - } + // Compare entry. + result = rEntry.compare (rPage.m_pData[i]); - // Done. - return store_E_None; + } while (result == entry::COMPATE_GREATER); } +#endif /* EXP */ -/* - * remove (possibly down from root). - * Internal: Precond: initialized, writeable, exclusive access. - */ -storeError OStorePageManager::remove ( - entry &rEntry, page &rPage, page &rPageL) +storeError OStorePageManager::remove_Impl (entry & rEntry) { - // Load RootNode. - OStoreBTreeRootObject aRoot (rPage); - aRoot.location (m_nPageSize); + OStoreBTreeNodeObject aNode (m_aRoot.get()); - storeError eErrCode = load (aRoot); - if (eErrCode != store_E_None) - return eErrCode; - - // Check index. - sal_uInt16 i = rPage.find (rEntry), n = rPage.usageCount(); + // Check current page index. + PageHolderObject< page > xPage (aNode.get()); + sal_uInt16 i = xPage->find (rEntry), n = xPage->usageCount(); if (!(i < n)) { // Path to entry not exists (Must not happen(?)). @@ -499,13 +251,13 @@ storeError OStorePageManager::remove ( } // Compare entry. - entry::CompareResult result = rEntry.compare (rPage.m_pData[i]); + entry::CompareResult result = rEntry.compare (xPage->m_pData[i]); // Iterate down until equal match. - while ((result == entry::COMPARE_GREATER) && (rPage.depth() > 0)) + while ((result == entry::COMPARE_GREATER) && (xPage->depth() > 0)) { // Check link address. - sal_uInt32 nAddr = rPage.m_pData[i].m_aLink.m_nAddr; + sal_uInt32 const nAddr = xPage->m_pData[i].m_aLink.location(); if (nAddr == STORE_PAGE_NULL) { // Path to entry not exists (Must not happen(?)). @@ -513,15 +265,15 @@ storeError OStorePageManager::remove ( } // Load link page. - node aNode (rPage); - aNode.location (nAddr); - - eErrCode = load (aNode); + storeError eErrCode = loadObjectAt (aNode, nAddr); if (eErrCode != store_E_None) return eErrCode; + PageHolderObject< page > xNext (aNode.get()); + xNext.swap (xPage); + // Check index. - i = rPage.find (rEntry), n = rPage.usageCount(); + i = xPage->find (rEntry), n = xPage->usageCount(); if (!(i < n)) { // Path to entry not exists (Must not happen(?)). @@ -529,7 +281,7 @@ storeError OStorePageManager::remove ( } // Compare entry. - result = rEntry.compare (rPage.m_pData[i]); + result = rEntry.compare (xPage->m_pData[i]); } OSL_POSTCOND( @@ -544,17 +296,42 @@ storeError OStorePageManager::remove ( } // Remove down from current page (recursive). - node aNode (rPage); - return aNode.remove (i, rEntry, rPageL, *this, NULL); + return aNode.remove (i, rEntry, *this); +} + +/* + * namei. + * Precond: none (static). + */ +storeError OStorePageManager::namei ( + const rtl_String *pPath, const rtl_String *pName, OStorePageKey &rKey) +{ + // Check parameter. + if (!(pPath && pName)) + return store_E_InvalidParameter; + + // Check name length. + if (!(pName->length < STORE_MAXIMUM_NAMESIZE)) + return store_E_NameTooLong; + + // Transform pathname into key. + rKey.m_nLow = store::htonl(rtl_crc32 (0, pName->buffer, pName->length)); + rKey.m_nHigh = store::htonl(rtl_crc32 (0, pPath->buffer, pPath->length)); + + // Done. + return store_E_None; } /* - * load. + * iget. * Precond: initialized. */ -storeError OStorePageManager::load ( - const OStorePageKey &rKey, - OStoreDirectoryPageObject &rPage) +storeError OStorePageManager::iget ( + OStoreDirectoryPageObject & rPage, + sal_uInt32 nAttrib, + const rtl_String * pPath, + const rtl_String * pName, + storeAccessMode eMode) { // Acquire exclusive access. osl::MutexGuard aGuard(*this); @@ -563,50 +340,83 @@ storeError OStorePageManager::load ( if (!self::isValid()) return store_E_InvalidAccess; - // Setup BTree entry. - entry e; - e.m_aKey = rKey; - - // Find NodePage. - storeError eErrCode = find (e, *m_pNode[0]); + // Setup inode page key. + OStorePageKey aKey; + storeError eErrCode = namei (pPath, pName, aKey); if (eErrCode != store_E_None) return eErrCode; - // Find Index. - sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount(); - if (!(i < n)) + // Check for directory. + if (nAttrib & STORE_ATTRIB_ISDIR) { - // Page not present. - return store_E_NotExists; + // Ugly, but necessary (backward compatibility). + aKey.m_nLow = store::htonl(rtl_crc32 (store::ntohl(aKey.m_nLow), "/", 1)); } - // Check for exact match. - if (!(e.compare (m_pNode[0]->m_pData[i]) == entry::COMPARE_EQUAL)) + // Load inode page. + eErrCode = load_dirpage_Impl (aKey, rPage); + if (eErrCode != store_E_None) { - // Page not present. - return store_E_NotExists; + // Check mode and reason. + if (eErrCode != store_E_NotExists) + return eErrCode; + + if (eMode == store_AccessReadWrite) + return store_E_NotExists; + if (eMode == store_AccessReadOnly) + return store_E_NotExists; + + if (!base::isWriteable()) + return store_E_AccessViolation; + + // Create inode page. + eErrCode = rPage.construct< inode >(base::allocator()); + if (eErrCode != store_E_None) + return eErrCode; + + // Setup inode nameblock. + PageHolderObject< inode > xPage (rPage.get()); + + rPage.key (aKey); + rPage.attrib (nAttrib); + + memcpy ( + &(xPage->m_aNameBlock.m_pData[0]), + pName->buffer, pName->length); + + // Save inode page. + eErrCode = save_dirpage_Impl (aKey, rPage); + if (eErrCode != store_E_None) + return eErrCode; } - // Existing entry. Check address. - sal_uInt32 nAddr = m_pNode[0]->m_pData[i].m_aLink.m_nAddr; - if (nAddr == STORE_PAGE_NULL) + // Check for symbolic link. + if (rPage.attrib() & STORE_ATTRIB_ISLINK) { - // Page not present. - return store_E_NotExists; + // Obtain 'Destination' page key. + PageHolderObject< inode > xPage (rPage.get()); + OStorePageKey aDstKey; + memcpy (&aDstKey, &(xPage->m_pData[0]), sizeof(aDstKey)); + + // Load 'Destination' inode. + eErrCode = load_dirpage_Impl (aDstKey, rPage); + if (eErrCode != store_E_None) + return eErrCode; } - // Load page. - rPage.location (nAddr); - return load (rPage); + // Done. + return store_E_None; } /* - * save. - * Precond: initialized, writeable. + * iterate. + * Precond: initialized. + * ToDo: skip hardlink entries. */ -storeError OStorePageManager::save ( - const OStorePageKey &rKey, - OStoreDirectoryPageObject &rPage) +storeError OStorePageManager::iterate ( + OStorePageKey & rKey, + OStorePageLink & rLink, + sal_uInt32 & rAttrib) { // Acquire exclusive access. osl::MutexGuard aGuard(*this); @@ -615,74 +425,97 @@ storeError OStorePageManager::save ( if (!self::isValid()) return store_E_InvalidAccess; - if (!base::isWriteable()) - return store_E_AccessViolation; + // Find NodePage and Index. + OStoreBTreeNodeObject aNode; + sal_uInt16 i = 0; + storeError eErrCode = m_aRoot.find_lookup (aNode, i, rKey, *this); + if (eErrCode != store_E_None) + return eErrCode; + + // GreaterEqual. Found next entry. + PageHolderObject< page > xNode (aNode.get()); + entry e (xNode->m_pData[i]); - // Setup BTree entry. - entry e; - e.m_aKey = rKey; + // Setup result. + rKey = e.m_aKey; + rLink = e.m_aLink; + rAttrib = store::ntohl(e.m_nAttrib); - // Find NodePage. - storeError eErrCode = find (e, *m_pNode[0], *m_pNode[1], *m_pNode[2]); + // Done. + return store_E_None; +} + +/* + * load => private: iget() @@@ + * Internal: Precond: initialized, exclusive access. + */ +storeError OStorePageManager::load_dirpage_Impl ( + const OStorePageKey &rKey, + OStoreDirectoryPageObject &rPage) +{ + // Find Node and Index. + OStoreBTreeNodeObject aNode; + sal_uInt16 i = 0; + storeError eErrCode = find_lookup (aNode, i, rKey); if (eErrCode != store_E_None) return eErrCode; - // Find Index. - sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount(); - if (i < n) + // Existing entry. Load page. + PageHolderObject< page > xNode (aNode.get()); + entry e (xNode->m_pData[i]); + return loadObjectAt (rPage, e.m_aLink.location()); +} + +/* + * save => private: iget(), rebuild() @@@ + * Internal: Precond: initialized, writeable, exclusive access. + */ +storeError OStorePageManager::save_dirpage_Impl ( + const OStorePageKey &rKey, + OStoreDirectoryPageObject &rPage) +{ + // Find NodePage and Index. + node aNode; + sal_uInt16 i = 0; + + storeError eErrCode = m_aRoot.find_insert (aNode, i, rKey, *this); + PageHolderObject< page > xNode (aNode.get()); + if (eErrCode != store_E_None) { - // Compare entry. - entry::CompareResult result = e.compare (m_pNode[0]->m_pData[i]); - OSL_POSTCOND( - result != entry::COMPARE_LESS, - "OStorePageManager::save(): find failed"); + if (eErrCode != store_E_AlreadyExists) + return eErrCode; - // Check result. - if (result == entry::COMPARE_LESS) + // Existing entry. + entry e (xNode->m_pData[i]); + if (e.m_aLink.location() != STORE_PAGE_NULL) { - // Must not happen. - return store_E_Unknown; + // Save page to existing location. + return saveObjectAt (rPage, e.m_aLink.location()); } - if (result == entry::COMPARE_EQUAL) - { - // Existing entry. Check address. - sal_uInt32 nAddr = m_pNode[0]->m_pData[i].m_aLink.m_nAddr; - if (nAddr == STORE_PAGE_NULL) - { - // Allocate page. - eErrCode = base::allocate (rPage); - if (eErrCode != store_E_None) - return eErrCode; + // Allocate page. + eErrCode = base::allocate (rPage); + if (eErrCode != store_E_None) + return eErrCode; - // Modify page address. - m_pNode[0]->m_pData[i].m_aLink.m_nAddr = rPage.location(); + // Update page location. + xNode->m_pData[i].m_aLink = rPage.location(); - // Save modified NodePage. - node aNode (*m_pNode[0]); - return save (aNode); - } - else - { - // Save page. - rPage.location (nAddr); - return save (rPage); - } - } + // Save modified NodePage. + return saveObjectAt (aNode, aNode.location()); } - // Allocate. + // Allocate page. eErrCode = base::allocate (rPage); if (eErrCode != store_E_None) return eErrCode; // Insert. - e.m_aLink.m_nAddr = rPage.location(); - m_pNode[0]->insert (i + 1, e); + OStorePageLink aLink (rPage.location()); + xNode->insert (i + 1, entry (rKey, aLink)); // Save modified NodePage. - node aNode (*m_pNode[0]); - return save (aNode); + return saveObjectAt (aNode, aNode.location()); } /* @@ -702,52 +535,35 @@ storeError OStorePageManager::attrib ( if (!self::isValid()) return store_E_InvalidAccess; - // Setup BTree entry. - entry e; - e.m_aKey = rKey; - - // Find NodePage. - storeError eErrCode = find (e, *m_pNode[0]); + // Find NodePage and index. + OStoreBTreeNodeObject aNode; + sal_uInt16 i = 0; + storeError eErrCode = find_lookup (aNode, i, rKey); if (eErrCode != store_E_None) return eErrCode; - // Find Index. - sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount(); - if (!(i < n)) - { - // Page not present. - return store_E_NotExists; - } - - // Check for exact match. - if (!(e.compare (m_pNode[0]->m_pData[i]) == entry::COMPARE_EQUAL)) - { - // Page not present. - return store_E_NotExists; - } - // Existing entry. - e = m_pNode[0]->m_pData[i]; + PageHolderObject< page > xNode (aNode.get()); + entry e (xNode->m_pData[i]); if (nMask1 != nMask2) { // Evaluate new attributes. - sal_uInt32 nAttrib = e.m_nAttrib; + sal_uInt32 nAttrib = store::ntohl(e.m_nAttrib); nAttrib &= ~nMask1; nAttrib |= nMask2; - if (nAttrib != e.m_nAttrib) + if (store::htonl(nAttrib) != e.m_nAttrib) { // Check access mode. if (base::isWriteable()) { // Set new attributes. - e.m_nAttrib = nAttrib; - m_pNode[0]->m_pData[i] = e; + e.m_nAttrib = store::htonl(nAttrib); + xNode->m_pData[i] = e; // Save modified NodePage. - node aNode (*m_pNode[0]); - eErrCode = save (aNode); + eErrCode = saveObjectAt (aNode, aNode.location()); } else { @@ -758,7 +574,7 @@ storeError OStorePageManager::attrib ( } // Obtain current attributes. - rAttrib = e.m_nAttrib; + rAttrib = store::ntohl(e.m_nAttrib); return eErrCode; } @@ -780,76 +596,28 @@ storeError OStorePageManager::link ( if (!base::isWriteable()) return store_E_AccessViolation; - // Setup 'Destination' BTree entry. - entry e; - e.m_aKey = rDstKey; - - // Find 'Destination' NodePage. - storeError eErrCode = find (e, *m_pNode[0]); + // Find 'Destination' NodePage and Index. + OStoreBTreeNodeObject aDstNode; + sal_uInt16 i = 0; + storeError eErrCode = find_lookup (aDstNode, i, rDstKey); if (eErrCode != store_E_None) return eErrCode; - // Find 'Destination' Index. - sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount(); - if (!(i < n)) - { - // Page not present. - return store_E_NotExists; - } - - // Check for exact match. - if (!(e.compare (m_pNode[0]->m_pData[i]) == entry::COMPARE_EQUAL)) - { - // Page not present. - return store_E_NotExists; - } - - // Existing entry. Check address. - e = m_pNode[0]->m_pData[i]; - if (e.m_aLink.m_nAddr == STORE_PAGE_NULL) - { - // Page not present. - return store_E_NotExists; - } - - // Setup 'Source' BTree entry. - e.m_aKey = rSrcKey; - e.m_nAttrib = STORE_ATTRIB_ISLINK; + // Existing 'Destination' entry. + PageHolderObject< page > xDstNode (aDstNode.get()); + entry e (xDstNode->m_pData[i]); + OStorePageLink aDstLink (e.m_aLink); - // Find 'Source' NodePage. - eErrCode = find (e, *m_pNode[0], *m_pNode[1], *m_pNode[2]); + // Find 'Source' NodePage and Index. + OStoreBTreeNodeObject aSrcNode; + eErrCode = m_aRoot.find_insert (aSrcNode, i, rSrcKey, *this); if (eErrCode != store_E_None) return eErrCode; - // Find 'Source' Index. - i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount(); - if (i < n) - { - // Compare entry. - entry::CompareResult result = e.compare (m_pNode[0]->m_pData[i]); - OSL_POSTCOND( - result != entry::COMPARE_LESS, - "OStorePageManager::link(): find failed"); - - // Check result. - if (result == entry::COMPARE_LESS) - { - // Must not happen. - return store_E_Unknown; - } - - if (result == entry::COMPARE_EQUAL) - { - // Existing 'Source' entry. - return store_E_AlreadyExists; - } - } - // Insert 'Source' entry. - m_pNode[0]->insert (i + 1, e); - - node aNode (*m_pNode[0]); - return save (aNode); + PageHolderObject< page > xSrcNode (aSrcNode.get()); + xSrcNode->insert (i + 1, entry (rSrcKey, aDstLink, STORE_ATTRIB_ISLINK)); + return saveObjectAt (aSrcNode, aSrcNode.location()); } /* @@ -878,66 +646,35 @@ storeError OStorePageManager::symlink ( // Setup 'Source' page key. OStorePageKey aSrcKey; - eErrCode = OStorePageNameBlock::namei (pSrcPath, pSrcName, aSrcKey); + eErrCode = namei (pSrcPath, pSrcName, aSrcKey); if (eErrCode != store_E_None) return eErrCode; - // Setup 'Source' BTree entry. - entry e; - e.m_aKey = aSrcKey; - - // Find 'Source' NodePage. - eErrCode = find (e, *m_pNode[0], *m_pNode[1], *m_pNode[2]); + // Find 'Source' NodePage and Index. + OStoreBTreeNodeObject aSrcNode; + sal_uInt16 i = 0; + eErrCode = m_aRoot.find_insert (aSrcNode, i, aSrcKey, *this); if (eErrCode != store_E_None) return eErrCode; - // Find 'Source' Index. - sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount(); - if (i < n) - { - // Compare entry. - entry::CompareResult result = e.compare (m_pNode[0]->m_pData[i]); - OSL_POSTCOND( - result != entry::COMPARE_LESS, - "OStorePageManager::symlink(): find failed"); - - // Check result. - if (result == entry::COMPARE_LESS) - { - // Must not happen. - return store_E_Unknown; - } - - if (result == entry::COMPARE_EQUAL) - { - // Existing 'Source' entry. - return store_E_AlreadyExists; - } - } - - // Initialize directory page buffer. - if (m_pDirect) - m_pDirect->initialize(); - if (!m_pDirect) - m_pDirect = new(m_nPageSize) inode(m_nPageSize); - if (!m_pDirect) - return store_E_OutOfMemory; + // Initialize directory page. + OStoreDirectoryPageObject aPage; + eErrCode = aPage.construct< inode >(base::allocator()); + if (eErrCode != store_E_None) + return eErrCode; // Setup as 'Source' directory page. - m_pDirect->m_aNameBlock.m_aKey = aSrcKey; - rtl_copyMemory ( - &m_pDirect->m_aNameBlock.m_pData[0], + inode_holder_type xNode (aPage.get()); + aPage.key (aSrcKey); + memcpy ( + &(xNode->m_aNameBlock.m_pData[0]), pSrcName->buffer, pSrcName->length); // Store 'Destination' page key. OStorePageKey aDstKey (rDstKey); -#ifdef OSL_BIGENDIAN - aDstKey.swap(); // Swap to external representation. -#endif /* OSL_BIGENDIAN */ - rtl_copyMemory (&m_pDirect->m_pData[0], &aDstKey, sizeof(aDstKey)); + memcpy (&(xNode->m_pData[0]), &aDstKey, sizeof(aDstKey)); // Mark 'Source' as symbolic link to 'Destination'. - OStoreDirectoryPageObject aPage (*m_pDirect); aPage.attrib (STORE_ATTRIB_ISLINK); aPage.dataLength (sal_uInt32(sizeof(aDstKey))); @@ -947,12 +684,12 @@ storeError OStorePageManager::symlink ( return eErrCode; // Insert 'Source' entry. - e.m_aLink.m_nAddr = aPage.location(); - m_pNode[0]->insert (i + 1, e); + PageHolderObject< page > xSrcNode (aSrcNode.get()); + OStorePageLink aSrcLink (aPage.location()); + xSrcNode->insert (i + 1, entry(aSrcKey, aSrcLink)); // Save modified NodePage. - node aNode (*m_pNode[0]); - return save (aNode); + return saveObjectAt (aSrcNode, aSrcNode.location()); } /* @@ -981,56 +718,27 @@ storeError OStorePageManager::rename ( // Setup 'Destination' page key. OStorePageKey aDstKey; - eErrCode = OStorePageNameBlock::namei (pDstPath, pDstName, aDstKey); + eErrCode = namei (pDstPath, pDstName, aDstKey); if (eErrCode != store_E_None) return eErrCode; - // Setup 'Source' BTree entry. - entry e; - e.m_aKey = rSrcKey; - - // Find 'Source' NodePage. - eErrCode = find (e, *m_pNode[0]); + // Find 'Source' NodePage and Index. + OStoreBTreeNodeObject aSrcNode; + sal_uInt16 i = 0; + eErrCode = find_lookup (aSrcNode, i, rSrcKey); if (eErrCode != store_E_None) return eErrCode; - // Find 'Source' Index. - sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount(); - if (!(i < n)) - { - // Page not present. - return store_E_NotExists; - } - - // Check for exact match. - if (!(e.compare (m_pNode[0]->m_pData[i]) == entry::COMPARE_EQUAL)) - { - // Page not present. - return store_E_NotExists; - } - - // Existing 'Source' entry. Check address. - e = m_pNode[0]->m_pData[i]; - if (e.m_aLink.m_nAddr == STORE_PAGE_NULL) - { - // Page not present. - return store_E_NotExists; - } + // Existing 'Source' entry. + PageHolderObject< page > xSrcNode (aSrcNode.get()); + entry e (xSrcNode->m_pData[i]); - // Check for hardlink. - if (!(e.m_nAttrib & STORE_ATTRIB_ISLINK)) + // Check for (not a) hardlink. + OStoreDirectoryPageObject aPage; + if (!(store::ntohl(e.m_nAttrib) & STORE_ATTRIB_ISLINK)) { - // Check directory page buffer. - if (!m_pDirect) - m_pDirect = new(m_nPageSize) inode(m_nPageSize); - if (!m_pDirect) - return store_E_OutOfMemory; - // Load directory page. - OStoreDirectoryPageObject aPage (*m_pDirect); - aPage.location (e.m_aLink.m_nAddr); - - eErrCode = base::load (aPage); + eErrCode = base::loadObjectAt (aPage, e.m_aLink.location()); if (eErrCode != store_E_None) return eErrCode; @@ -1038,75 +746,52 @@ storeError OStorePageManager::rename ( if (aPage.attrib() & STORE_ATTRIB_ISDIR) { // Ugly, but necessary (backward compatibility). - aDstKey.m_nLow = OStorePageGuard::crc32 (aDstKey.m_nLow, "/", 1); + aDstKey.m_nLow = store::htonl(rtl_crc32 (store::ntohl(aDstKey.m_nLow), "/", 1)); } } // Let 'Source' entry be 'Destination' entry. e.m_aKey = aDstKey; - // Find 'Destination' NodePage. - eErrCode = find (e, *m_pNode[0], *m_pNode[1], *m_pNode[2]); + // Find 'Destination' NodePage and Index. + OStoreBTreeNodeObject aDstNode; + eErrCode = m_aRoot.find_insert (aDstNode, i, e.m_aKey, *this); if (eErrCode != store_E_None) return eErrCode; - // Find 'Destination' Index. - i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount(); - if (i < n) - { - // Compare entry. - entry::CompareResult result = e.compare (m_pNode[0]->m_pData[i]); - OSL_POSTCOND( - result != entry::COMPARE_LESS, - "OStorePageManager::rename(): find failed"); - - // Check result. - if (result == entry::COMPARE_LESS) - { - // Must not happen. - return store_E_Unknown; - } - - if (result == entry::COMPARE_EQUAL) - { - // Existing 'Destination' entry. - return store_E_AlreadyExists; - } - } - // Insert 'Destination' entry. - node aNode (*m_pNode[0]); - m_pNode[0]->insert (i + 1, e); + PageHolderObject< page > xDstNode (aDstNode.get()); + xDstNode->insert (i + 1, e); - eErrCode = save (aNode); + eErrCode = saveObjectAt (aDstNode, aDstNode.location()); if (eErrCode != store_E_None) return eErrCode; - // Check for hardlink. - if (!(e.m_nAttrib & STORE_ATTRIB_ISLINK)) + // Check for (not a) hardlink. + if (!(store::ntohl(e.m_nAttrib) & STORE_ATTRIB_ISLINK)) { + // Modify 'Source' directory page. + inode_holder_type xNode (aPage.get()); + // Setup 'Destination' NameBlock. sal_Int32 nDstLen = pDstName->length; - rtl_copyMemory ( - &m_pDirect->m_aNameBlock.m_pData[0], - pDstName->buffer, nDstLen); - rtl_zeroMemory ( - &m_pDirect->m_aNameBlock.m_pData[nDstLen], - STORE_MAXIMUM_NAMESIZE - nDstLen); - m_pDirect->m_aNameBlock.m_aKey = e.m_aKey; + memcpy ( + &(xNode->m_aNameBlock.m_pData[0]), + pDstName->buffer, pDstName->length); + memset ( + &(xNode->m_aNameBlock.m_pData[nDstLen]), + 0, STORE_MAXIMUM_NAMESIZE - nDstLen); + aPage.key (e.m_aKey); // Save directory page. - OStoreDirectoryPageObject aPage (*m_pDirect); - aPage.location (e.m_aLink.m_nAddr); - - eErrCode = base::save (aPage); + eErrCode = base::saveObjectAt (aPage, e.m_aLink.location()); if (eErrCode != store_E_None) return eErrCode; } // Remove 'Source' entry. e.m_aKey = rSrcKey; - return remove (e, *m_pNode[0], *m_pNode[1]); + return remove_Impl (e); } /* @@ -1125,57 +810,30 @@ storeError OStorePageManager::remove (const OStorePageKey &rKey) if (!base::isWriteable()) return store_E_AccessViolation; - // Setup BTree entry. - entry e; - e.m_aKey = rKey; - - // Find NodePage. - storeError eErrCode = find (e, *m_pNode[0]); + // Find NodePage and index. + OStoreBTreeNodeObject aNodePage; + sal_uInt16 i = 0; + storeError eErrCode = find_lookup (aNodePage, i, rKey); if (eErrCode != store_E_None) return eErrCode; - // Find Index. - sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount(); - if (!(i < n)) - { - // Page not present. - return store_E_NotExists; - } - - // Check for exact match. - if (!(e.compare (m_pNode[0]->m_pData[i]) == entry::COMPARE_EQUAL)) - { - // Page not present. - return store_E_NotExists; - } - - // Existing entry. Check address. - e = m_pNode[0]->m_pData[i]; - if (e.m_aLink.m_nAddr == STORE_PAGE_NULL) - { - // Page not present. - return store_E_NotExists; - } + // Existing entry. + PageHolderObject< page > xNodePage (aNodePage.get()); + entry e (xNodePage->m_pData[i]); - // Check for hardlink. - if (!(e.m_nAttrib & STORE_ATTRIB_ISLINK)) + // Check for (not a) hardlink. + if (!(store::ntohl(e.m_nAttrib) & STORE_ATTRIB_ISLINK)) { - // Check directory page buffer. - if (!m_pDirect) - m_pDirect = new(m_nPageSize) inode(m_nPageSize); - if (!m_pDirect) - return store_E_OutOfMemory; - // Load directory page. - OStoreDirectoryPageObject aPage (*m_pDirect); - aPage.location (e.m_aLink.m_nAddr); - - eErrCode = base::load (aPage); + OStoreDirectoryPageObject aPage; + eErrCode = base::loadObjectAt (aPage, e.m_aLink.location()); if (eErrCode != store_E_None) return eErrCode; + inode_holder_type xNode (aPage.get()); + // Acquire page write access. - OStorePageDescriptor aDescr (m_pDirect->m_aDescr); + OStorePageDescriptor aDescr (xNode->m_aDescr); eErrCode = base::acquirePage (aDescr, store_AccessReadWrite); if (eErrCode != store_E_None) return eErrCode; @@ -1184,97 +842,30 @@ storeError OStorePageManager::remove (const OStorePageKey &rKey) if (!(aPage.attrib() & STORE_ATTRIB_ISLINK)) { // Ordinary inode. Determine 'Data' scope. - inode::ChunkScope eScope = m_pDirect->scope (aPage.dataLength()); + inode::ChunkScope eScope = xNode->scope (aPage.dataLength()); if (eScope == inode::SCOPE_EXTERNAL) { - // External 'Data' scope. Check data page buffer. - if (!m_pData) - m_pData = new(m_nPageSize) data(m_nPageSize); - if (!m_pData) - return store_E_OutOfMemory; - - // Truncate all external data pages. - OStoreDataPageObject aData (*m_pData); - eErrCode = aPage.truncate ( - 0, m_pLink[0], m_pLink[1], m_pLink[2], aData, *this); + // External 'Data' scope. Truncate all external data pages. + eErrCode = aPage.truncate (0, *this); if (eErrCode != store_E_None) return eErrCode; } // Truncate internal data page. - rtl_zeroMemory (&m_pDirect->m_pData[0], m_pDirect->capacity()); + memset (&(xNode->m_pData[0]), 0, xNode->capacity()); aPage.dataLength (0); } // Release page write access. - eErrCode = base::releasePage (aDescr); + eErrCode = base::releasePage (aDescr, store_AccessReadWrite); // Release and free directory page. - eErrCode = base::free (aPage); + OStorePageData aPageHead; + eErrCode = base::free (aPageHead, aPage.location()); } // Remove entry. - return remove (e, *m_pNode[0], *m_pNode[1]); -} - -/* - * iterate. - * Precond: initialized. - * ToDo: skip hardlink entries. - */ -storeError OStorePageManager::iterate ( - OStorePageKey &rKey, - OStorePageObject &rPage, - sal_uInt32 &rAttrib) -{ - // Acquire exclusive access. - osl::MutexGuard aGuard(*this); - - // Check precond. - if (!self::isValid()) - return store_E_InvalidAccess; - - // Setup BTree entry. - entry e; - e.m_aKey = rKey; - - // Find NodePage. - storeError eErrCode = find (e, *m_pNode[0]); - if (eErrCode != store_E_None) - return eErrCode; - - // Find Index. - sal_uInt16 i = m_pNode[0]->find(e), n = m_pNode[0]->usageCount(); - if (!(i < n)) - { - // Not found. - return store_E_NotExists; - } - - // Compare entry. - entry::CompareResult result = e.compare (m_pNode[0]->m_pData[i]); - OSL_POSTCOND( - result != entry::COMPARE_LESS, - "OStorePageManager::iterate(): find failed"); - - // Check result. - if (result == entry::COMPARE_LESS) - { - // Must not happen. - return store_E_Unknown; - } - - // GreaterEqual. Found next entry. - e = m_pNode[0]->m_pData[i]; - - // Setup result. - rKey = e.m_aKey; - rAttrib = e.m_nAttrib; - - rPage.location (e.m_aLink.m_nAddr); - - // Done. - return store_E_None; + return remove_Impl (e); } /* @@ -1286,11 +877,13 @@ struct RebuildContext */ rtl::Reference m_xBIOS; OStorePageBIOS::ScanContext m_aCtx; + sal_uInt16 m_nPageSize; /** Construction. */ RebuildContext (void) - : m_xBIOS (new OStorePageBIOS()) + : m_xBIOS (new OStorePageBIOS()), + m_nPageSize (0) {} /** initialize (PageBIOS and ScanContext). @@ -1300,7 +893,7 @@ struct RebuildContext storeError eErrCode = store_E_InvalidParameter; if (pLockBytes) { - m_xBIOS->initialize (pLockBytes, store_AccessReadOnly); + m_xBIOS->initialize (pLockBytes, store_AccessReadOnly, m_nPageSize); eErrCode = m_xBIOS->scanBegin (m_aCtx, nMagic); } return eErrCode; @@ -1322,13 +915,6 @@ struct RebuildContext else return store_E_CantSeek; } - - /** getPageSize. - */ - storeError getPageSize (sal_uInt16 &rnPageSize) - { - return m_xBIOS->getPageSize (rnPageSize); - } }; /* @@ -1351,147 +937,129 @@ storeError OStorePageManager::rebuild ( eErrCode = aCtx.initialize (pSrcLB, STORE_MAGIC_DIRECTORYPAGE); if (eErrCode != store_E_None) return eErrCode; - - // Obtain 'Source' page size. - sal_uInt16 nPageSize = 0; - eErrCode = aCtx.getPageSize (nPageSize); - if (eErrCode != store_E_None) - return eErrCode; + rtl::Reference xSrcBIOS (aCtx.m_xBIOS); // Initialize as 'Destination' with 'Source' page size. - eErrCode = self::initializeManager (pDstLB, store_AccessCreate, nPageSize); + eErrCode = self::initialize (pDstLB, store_AccessCreate, aCtx.m_nPageSize); if (eErrCode != store_E_None) return eErrCode; - // Initialize directory and data page buffers. - if (!m_pDirect) - m_pDirect = new(m_nPageSize) inode(m_nPageSize); - if (!m_pData) - m_pData = new(m_nPageSize) data(m_nPageSize); - if (!(m_pDirect && m_pData)) - return store_E_OutOfMemory; - - // Initialize 'Source' directory page. - inode *pDirect = new(m_nPageSize) inode(m_nPageSize); - if (!pDirect) - return store_E_OutOfMemory; - - // Scan 'Source' directory pages. - OStoreDirectoryPageObject aSrcPage (*pDirect); - while ((eErrCode = aCtx.load(aSrcPage)) == store_E_None) + // Pass One: Scan 'Source' directory pages. { - // Obtain page key and data length. - OStorePageKey aKey (pDirect->m_aNameBlock.m_aKey); - sal_uInt32 nDataLen = pDirect->m_aDataBlock.m_nDataLen; - - // Determine data page scope. - inode::ChunkScope eScope = pDirect->scope (nDataLen); - if (eScope == inode::SCOPE_INTERNAL) + // Scan 'Source' directory pages. + OStoreDirectoryPageObject aSrcPage; + while ((eErrCode = aCtx.load(aSrcPage)) == store_E_None) { - // Internal scope. Just insert directory node. - eErrCode = save (aKey, aSrcPage); + OStoreDirectoryPageObject aDstPage; + eErrCode = aDstPage.construct< inode >(base::allocator()); if (eErrCode != store_E_None) break; - } - else - { - // External scope. - OStoreDirectoryPageObject aDstPage (*m_pDirect); - rtl_copyMemory (m_pDirect, pDirect, m_nPageSize); - m_pDirect->m_aDataBlock.initialize(); - m_pDirect->m_aDataBlock.m_nDataLen = m_pDirect->capacity(); + inode_holder_type xSrcDir (aSrcPage.get()); + inode_holder_type xDstDir (aDstPage.get()); + + // Copy NameBlock @@@ OLD @@@ + memcpy (&(xDstDir->m_aNameBlock), &(xSrcDir->m_aNameBlock), sizeof(xSrcDir->m_aNameBlock)); + + // Obtain 'Source' data length. + sal_uInt32 nDataLen = aSrcPage.dataLength(); + if (nDataLen > 0) + { + // Copy internal data area @@@ OLD @@@ + memcpy (&(xDstDir->m_pData[0]), &(xSrcDir->m_pData[0]), xSrcDir->capacity()); + } // Insert 'Destination' directory page. - eErrCode = save (aKey, aDstPage); + eErrCode = save_dirpage_Impl (aDstPage.key(), aDstPage); if (eErrCode != store_E_None) break; - // Determine data page count. - inode::ChunkDescriptor aDescr ( - nDataLen - m_pDirect->capacity(), m_pData->capacity()); + // Check for external data page scope. + if (xSrcDir->scope(nDataLen) != inode::SCOPE_INTERNAL) + { + // Initialize 'Destination' data page. + typedef OStoreDataPageData data; + PageHolderObject< data > xData; + if (!xData.construct(base::allocator())) + return store_E_OutOfMemory; - sal_uInt32 i, n = aDescr.m_nPage; - if (aDescr.m_nOffset) n += 1; + // Determine data page count. + inode::ChunkDescriptor aDescr ( + nDataLen - xDstDir->capacity(), xData->capacity()); - // Copy data pages. - OStoreDataPageObject aData (*m_pData); - for (i = 0; i < n; i++) - { - // Re-initialize data page size. - m_pData->m_aDescr.m_nSize = m_nPageSize; + sal_uInt32 i, n = aDescr.m_nPage; + if (aDescr.m_nOffset) n += 1; - // Read 'Source' data page. - OStorePageBIOS &rBIOS = *(aCtx.m_xBIOS); - osl::Mutex &rMutex = rBIOS; + // Copy data pages. + OStoreDataPageObject aData; + for (i = 0; i < n; i++) + { + // Read 'Source' data page. + osl::MutexGuard aSrcGuard (*xSrcBIOS); - eErrCode = aSrcPage.get ( - i, m_pLink[0], m_pLink[1], m_pLink[2], - aData, rBIOS, &rMutex); - if (eErrCode != store_E_None) - continue; + eErrCode = aSrcPage.read (i, aData, *xSrcBIOS); + if (eErrCode != store_E_None) + continue; - // Write 'Destination' data page. - eErrCode = aDstPage.put ( - i, m_pLink[0], m_pLink[1], m_pLink[2], - aData, *this, NULL); + // Write 'Destination' data page. @@@ READONLY @@@ + eErrCode = aDstPage.write (i, aData, *this); + } } // Update 'Destination' directory page. - m_pDirect->m_aDataBlock.m_nDataLen = nDataLen; - eErrCode = base::save (aDstPage); + aDstPage.dataLength (nDataLen); + eErrCode = base::saveObjectAt (aDstPage, aDstPage.location()); } - } - // Save directory scan results. - flush(); - - // Scan 'Source' BTree nodes. - page *pNode = new(m_nPageSize) page(m_nPageSize); - node aNode (*pNode); - entry e; + // Save directory scan results. + flush(); + } - aCtx.initialize (STORE_MAGIC_BTREENODE); - while ((eErrCode = aCtx.load(aNode)) == store_E_None) + // Pass Two: Scan 'Source' BTree nodes. { - // Check for leaf node. - if (pNode->depth() == 0) + // Re-start 'Source' rebuild context. + aCtx.initialize (STORE_MAGIC_BTREENODE); + + // Scan 'Source' BTree nodes. + OStoreBTreeNodeObject aNode; + while ((eErrCode = aCtx.load(aNode)) == store_E_None) { - sal_uInt16 i, n = pNode->usageCount(); - for (i = 0; i < n; i++) + // Check for leaf node. + PageHolderObject< page > xNode (aNode.get()); + if (xNode->depth() == 0) { - e = pNode->m_pData[i]; - if (e.m_nAttrib & STORE_ATTRIB_ISLINK) + sal_uInt16 i, n = xNode->usageCount(); + for (i = 0; i < n; i++) { - // Hard link. - aSrcPage.location (e.m_aLink.m_nAddr); - pDirect->m_aDescr.m_nSize = m_nPageSize; + entry e (xNode->m_pData[i]); - eErrCode = aCtx.m_xBIOS->load (aSrcPage); - if (eErrCode == store_E_None) + // Check for Hard link. + if (e.m_nAttrib & STORE_ATTRIB_ISLINK) { - OStorePageKey aDstKey (pDirect->m_aNameBlock.m_aKey); - eErrCode = link (e.m_aKey, aDstKey); + // Load the hard link destination. + OStoreDirectoryPageObject aSrcPage; + eErrCode = xSrcBIOS->loadObjectAt (aSrcPage, e.m_aLink.location()); + if (eErrCode == store_E_None) + { + OStorePageKey aDstKey (aSrcPage.key()); + eErrCode = link (e.m_aKey, aDstKey); + } + e.m_nAttrib &= ~STORE_ATTRIB_ISLINK; } - e.m_nAttrib &= ~STORE_ATTRIB_ISLINK; - } - if (e.m_nAttrib) - { - // Ordinary attributes. - sal_uInt32 nAttrib = 0; - eErrCode = attrib (e.m_aKey, 0, e.m_nAttrib, nAttrib); + if (e.m_nAttrib) + { + // Ordinary attributes. + sal_uInt32 nAttrib = 0; + eErrCode = attrib (e.m_aKey, 0, e.m_nAttrib, nAttrib); + } } } } - } - - // Save BTree node scan results. - flush(); - // Cleanup. - delete pDirect; - delete pNode; + // Save BTree node scan results. + flush(); + } // Done. return store_E_None; diff --git a/store/source/storpage.hxx b/store/source/storpage.hxx index 3c441058c1ae..938e5dd63bc9 100644 --- a/store/source/storpage.hxx +++ b/store/source/storpage.hxx @@ -29,25 +29,22 @@ ************************************************************************/ #ifndef _STORE_STORPAGE_HXX_ -#define _STORE_STORPAGE_HXX_ "$Revision: 1.6 $" +#define _STORE_STORPAGE_HXX_ "$Revision: 1.6.8.2 $" -#include -#include -#include -#include +#include "sal/types.h" + +#include "object.hxx" +#include "lockbyte.hxx" + +#include "storbase.hxx" +#include "storbios.hxx" +#include "stortree.hxx" namespace store { -struct OStoreBTreeEntry; -struct OStoreBTreeNodeData; -class OStoreBTreeNodeObject; - -struct OStoreDataPageData; -struct OStoreIndirectionPageData; struct OStoreDirectoryPageData; class OStoreDirectoryPageObject; -class OStorePageCache; /*======================================================================== * @@ -63,10 +60,10 @@ public: /** Initialization (two-phase construction). */ - storeError initializeManager ( - ILockBytes *pLockBytes, - storeAccessMode eAccessMode, - sal_uInt16 nPageSize); + virtual storeError initialize ( + ILockBytes * pLockBytes, + storeAccessMode eAccessMode, + sal_uInt16 & rnPageSize); /** isValid. * @return sal_True upon successful initialization, @@ -74,30 +71,27 @@ public: */ inline sal_Bool isValid (void) const; - /** Page I/O (unmanaged). - */ - virtual storeError free ( - OStorePageObject &rPage); - - virtual storeError load ( - OStorePageObject &rPage); - - virtual storeError save ( - OStorePageObject &rPage); - - virtual storeError flush (void); - /** DirectoryPage I/O (managed). */ - storeError load ( - const OStorePageKey &rKey, - OStoreDirectoryPageObject &rPage); + static storeError namei ( + const rtl_String *pPath, + const rtl_String *pName, + OStorePageKey &rKey); + + storeError iget ( + OStoreDirectoryPageObject & rPage, // [out] + sal_uInt32 nAttrib, + const rtl_String * pPath, + const rtl_String * pName, + storeAccessMode eMode); - storeError save ( - const OStorePageKey &rKey, - OStoreDirectoryPageObject &rPage); + storeError iterate ( + OStorePageKey & rKey, + OStorePageLink & rLink, + sal_uInt32 & rAttrib); /** attrib [nAttrib = ((nAttrib & ~nMask1) | nMask2)]. + * @see store_attrib() */ storeError attrib ( const OStorePageKey &rKey, @@ -106,12 +100,14 @@ public: sal_uInt32 &rAttrib); /** link (insert Source Key as hardlink to Destination). + * @see store_link() */ storeError link ( const OStorePageKey &rSrcKey, const OStorePageKey &rDstKey); /** symlink (insert Source DirectoryPage as symlink to Destination). + * @see store_symlink() */ storeError symlink ( const rtl_String *pSrcPath, @@ -119,6 +115,7 @@ public: const OStorePageKey &rDstKey); /** rename. + * @see store_rename() */ storeError rename ( const OStorePageKey &rSrcKey, @@ -126,21 +123,17 @@ public: const rtl_String *pDstName); /** remove. + * @see store_remove() */ storeError remove ( const OStorePageKey &rKey); - /** iterate. - */ - storeError iterate ( - OStorePageKey &rKey, - OStorePageObject &rPage, - sal_uInt32 &rAttrib); - /** rebuild (combines recover and compact from 'Src' to 'Dst'). * @param pSrcLB [in] accessed readonly. * @param pDstLB [in] truncated and accessed readwrite (as initialize()). * @return store_E_None upon success. + * + * @see store_rebuildFile() */ storeError rebuild ( ILockBytes *pSrcLB, @@ -166,8 +159,7 @@ private: typedef OStoreBTreeNodeObject node; typedef OStoreDirectoryPageData inode; - typedef OStoreIndirectionPageData indirect; - typedef OStoreDataPageData data; + typedef PageHolderObject< inode > inode_holder_type; /** IStoreHandle TypeId. */ @@ -180,27 +172,28 @@ private: /** Representation. */ - OStorePageCache *m_pCache; - page *m_pNode[3]; - inode *m_pDirect; - indirect *m_pLink[3]; - data *m_pData; - sal_uInt16 m_nPageSize; - - /** find (node page, w/o split). - */ - storeError find ( - const entry& rEntry, page& rPage); + OStoreBTreeRootObject m_aRoot; - /** find (node page, possibly with split). + /** DirectoryPage I/O (managed). + */ + storeError load_dirpage_Impl ( // @@@ => private: iget() @@@ + const OStorePageKey &rKey, + OStoreDirectoryPageObject &rPage); + + storeError save_dirpage_Impl ( // @@@ => private: iget(), rebuild() @@@ + const OStorePageKey &rKey, + OStoreDirectoryPageObject &rPage); + + /** find_lookup (node page and index, w/o split). */ - storeError find ( - const entry &rEntry, page &rPage, page &rPageL, page &rPageR); + storeError find_lookup ( + OStoreBTreeNodeObject & rNode, + sal_uInt16 & rIndex, + OStorePageKey const & rKey); /** remove (possibly down from root). */ - storeError remove ( - entry &rEntry, page &rPage, page &rPageL); + storeError remove_Impl (entry & rEntry); /** Not implemented. */ @@ -210,7 +203,7 @@ private: inline sal_Bool OStorePageManager::isValid (void) const { - return (base::isValid() && (m_nPageSize > 0)); + return (base::isValid() /* @@@ NYI && (m_aRoot.is()) */); } template<> inline OStorePageManager* diff --git a/store/source/stortree.cxx b/store/source/stortree.cxx index 491896fd3f81..1967c744c66b 100644 --- a/store/source/stortree.cxx +++ b/store/source/stortree.cxx @@ -31,18 +31,15 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_store.hxx" -#define _STORE_STORTREE_CXX "$Revision: 1.8 $" -#include -#include -#include -#include -#include -#include - -#ifndef _STORE_STORBASE_HXX -#include -#endif -#include +#include "stortree.hxx" + +#include "sal/types.h" +#include "osl/diagnose.h" + +#include "store/types.h" + +#include "storbase.hxx" +#include "storbios.hxx" using namespace store; @@ -57,44 +54,17 @@ using namespace store; OStoreBTreeNodeData::OStoreBTreeNodeData (sal_uInt16 nPageSize) : OStorePageData (nPageSize) { - initialize(); -} - -/* - * initialize. - */ -void OStoreBTreeNodeData::initialize (void) -{ - base::m_aGuard.m_nMagic = STORE_MAGIC_BTREENODE; - base::m_aDescr.m_nUsed = base::size() + self::size(); - self::m_aGuard.m_nMagic = 0; + base::m_aGuard.m_nMagic = store::htonl(self::theTypeId); + base::m_aDescr.m_nUsed = store::htons(self::thePageSize); // usageCount(0) + self::m_aGuard.m_nMagic = store::htonl(0); // depth(0) - sal_uInt16 i, n = capacityCount(); - T t; + sal_uInt16 const n = capacityCount(); + T const t; - for (i = 1; i < n; i++) + for (sal_uInt16 i = 1; i < n; i++) m_pData[i] = t; } -/* - * swap. - */ -void OStoreBTreeNodeData::swap ( - const D& -#ifdef OSL_BIGENDIAN - rDescr -#endif /* OSL_BIGENDIAN */ -) -{ -#ifdef OSL_BIGENDIAN - m_aGuard.swap(); - - sal_uInt16 i, n = sal_uInt16(capacity(rDescr) / sizeof(T)); - for (i = 0; i < n; i++) - m_pData[i].swap(); -#endif /* OSL_BIGENDIAN */ -} - /* * find. */ @@ -105,7 +75,7 @@ sal_uInt16 OStoreBTreeNodeData::find (const T& t) const while (l < r) { - register sal_Int32 m = ((l + r) >> 1); + register sal_Int32 const m = ((l + r) >> 1); if (t.m_aKey == m_pData[m].m_aKey) return ((sal_uInt16)(m)); @@ -115,7 +85,7 @@ sal_uInt16 OStoreBTreeNodeData::find (const T& t) const l = m + 1; } - sal_uInt16 k = ((sal_uInt16)(r)); + sal_uInt16 const k = ((sal_uInt16)(r)); if ((k < capacityCount()) && (t.m_aKey < m_pData[k].m_aKey)) return(k - 1); else @@ -127,16 +97,16 @@ sal_uInt16 OStoreBTreeNodeData::find (const T& t) const */ void OStoreBTreeNodeData::insert (sal_uInt16 i, const T& t) { - sal_uInt16 n = usageCount(); - sal_uInt16 m = capacityCount(); + sal_uInt16 const n = usageCount(); + sal_uInt16 const m = capacityCount(); if ((n < m) && (i < m)) { // shift right. - rtl_moveMemory (&m_pData[i + 1], &m_pData[i], (n - i) * sizeof(T)); + memmove (&(m_pData[i + 1]), &(m_pData[i]), (n - i) * sizeof(T)); // insert. m_pData[i] = t; - base::m_aDescr.m_nUsed += sal_uInt16(sizeof(T)); + usageCount (n + 1); } } @@ -145,40 +115,39 @@ void OStoreBTreeNodeData::insert (sal_uInt16 i, const T& t) */ void OStoreBTreeNodeData::remove (sal_uInt16 i) { - sal_uInt16 n = usageCount(); + sal_uInt16 const n = usageCount(); if (i < n) { // shift left. - rtl_moveMemory ( - &m_pData[i], &m_pData[i + 1], (n - i - 1) * sizeof(T)); + memmove (&(m_pData[i]), &(m_pData[i + 1]), (n - i - 1) * sizeof(T)); // truncate. m_pData[n - 1] = T(); - base::m_aDescr.m_nUsed -= sal_uInt16(sizeof(T)); + usageCount (n - 1); } } /* - * merge. + * merge (with right page). */ void OStoreBTreeNodeData::merge (const self& rPageR) { - if (queryMerge (rPageR)) + sal_uInt16 const n = usageCount(); + sal_uInt16 const m = rPageR.usageCount(); + if ((n + m) <= capacityCount()) { - sal_uInt16 n = usageCount(); - sal_uInt16 m = rPageR.usageCount(); - rtl_copyMemory (&m_pData[n], &rPageR.m_pData[0], m * sizeof(T)); + memcpy (&(m_pData[n]), &(rPageR.m_pData[0]), m * sizeof(T)); usageCount (n + m); } } /* - * split. + * split (left half copied from right half of left page). */ void OStoreBTreeNodeData::split (const self& rPageL) { - sal_uInt16 h = capacityCount() / 2; - rtl_copyMemory (&m_pData[0], &rPageL.m_pData[h], h * sizeof(T)); + sal_uInt16 const h = capacityCount() / 2; + memcpy (&(m_pData[0]), &(rPageL.m_pData[h]), h * sizeof(T)); truncate (h); } @@ -187,8 +156,8 @@ void OStoreBTreeNodeData::split (const self& rPageL) */ void OStoreBTreeNodeData::truncate (sal_uInt16 n) { - sal_uInt16 m = capacityCount(); - T t; + sal_uInt16 const m = capacityCount(); + T const t; for (sal_uInt16 i = n; i < m; i++) m_pData[i] = t; @@ -200,89 +169,79 @@ void OStoreBTreeNodeData::truncate (sal_uInt16 n) * OStoreBTreeNodeObject implementation. * *======================================================================*/ -/* - * swap. - */ -void OStoreBTreeNodeObject::swap ( - const D& -#ifdef OSL_BIGENDIAN - rDescr -#endif /* OSL_BIGENDIAN */ -) -{ -#ifdef OSL_BIGENDIAN - base::swap (rDescr); - m_rPage.swap (rDescr); -#endif /* OSL_BIGENDIAN */ -} - /* * guard. */ -void OStoreBTreeNodeObject::guard (const D& rDescr) +storeError OStoreBTreeNodeObject::guard (sal_uInt32 nAddr) { - base::guard (rDescr); - m_rPage.guard (rDescr); + return PageHolderObject< page >::guard (m_xPage, nAddr); } /* * verify. */ -storeError OStoreBTreeNodeObject::verify (const D& rDescr) +storeError OStoreBTreeNodeObject::verify (sal_uInt32 nAddr) const { - storeError eErrCode = base::verify (rDescr); - if (eErrCode != store_E_None) - return eErrCode; - else - return m_rPage.verify (rDescr); + return PageHolderObject< page >::verify (m_xPage, nAddr); } /* * split. */ storeError OStoreBTreeNodeObject::split ( - sal_uInt16 nIndexL, - OStoreBTreeNodeData &rPageL, - OStoreBTreeNodeData &rPageR, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + sal_uInt16 nIndexL, + PageHolderObject< page > & rxPageL, + OStorePageBIOS & rBIOS) { - // Check usage. - if (!rPageL.querySplit()) + PageHolderObject< page > xPage (m_xPage); + if (!xPage.is()) + return store_E_InvalidAccess; + + // Check left page usage. + if (!rxPageL.is()) + return store_E_InvalidAccess; + if (!rxPageL->querySplit()) return store_E_None; - // Enter. - STORE_METHOD_ENTER(pMutex); - // Save PageDescriptor. - D aDescr (m_rPage.m_aDescr); + OStorePageDescriptor aDescr (xPage->m_aDescr); + aDescr.m_nAddr = store::ntohl(aDescr.m_nAddr); + aDescr.m_nSize = store::ntohs(aDescr.m_nSize); // Acquire Lock. storeError eErrCode = rBIOS.acquireLock (aDescr.m_nAddr, aDescr.m_nSize); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; - // Begin PageL Lock (NYI). + // [Begin PageL Lock (NYI)] + + // Construct right page. + PageHolderObject< page > xPageR; + if (!xPageR.construct (rBIOS.allocator())) + { + rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); + return store_E_OutOfMemory; + } // Split right page off left page. - rPageR.split (rPageL); - rPageR.depth (rPageL.depth()); + xPageR->split (*rxPageL); + xPageR->depth (rxPageL->depth()); // Allocate right page. - self aNodeR (rPageR); + self aNodeR (xPageR.get()); eErrCode = rBIOS.allocate (aNodeR); if (eErrCode != store_E_None) { rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } // Truncate left page. - rPageL.truncate (rPageL.capacityCount() / 2); + rxPageL->truncate (rxPageL->capacityCount() / 2); // Save left page. - self aNodeL (rPageL); - eErrCode = rBIOS.save (aNodeL); + self aNodeL (rxPageL.get()); + eErrCode = rBIOS.saveObjectAt (aNodeL, aNodeL.location()); if (eErrCode != store_E_None) { // Must not happen. @@ -290,20 +249,17 @@ storeError OStoreBTreeNodeObject::split ( // Release Lock and Leave. rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } - // End PageL Lock (NYI). + // [End PageL Lock (NYI)] // Insert right page. - T entry; - entry.m_aKey = rPageR.m_pData[0].m_aKey; - entry.m_aLink.m_nAddr = rPageR.location(); - - m_rPage.insert (nIndexL + 1, entry); + OStorePageLink aLink (xPageR->location()); + xPage->insert (nIndexL + 1, T(xPageR->m_pData[0].m_aKey, aLink)); // Save this page. - eErrCode = rBIOS.save (*this); + eErrCode = rBIOS.saveObjectAt (*this, location()); if (eErrCode != store_E_None) { // Must not happen. @@ -311,142 +267,120 @@ storeError OStoreBTreeNodeObject::split ( // Release Lock and Leave. rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } -#if 0 /* PERFORMANCE */ - eErrCode = rBIOS.flush(); -#endif /* PERFORMANCE */ - // Release Lock and Leave. - eErrCode = rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); } /* * remove (down to leaf node, recursive). */ storeError OStoreBTreeNodeObject::remove ( - sal_uInt16 nIndexL, - OStoreBTreeEntry &rEntryL, - OStoreBTreeNodeData &rPageL, -#if 0 /* NYI */ - OStoreBTreeNodeData &rPageR, -#endif /* NYI */ - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + sal_uInt16 nIndexL, + OStoreBTreeEntry & rEntryL, + OStorePageBIOS & rBIOS) { - // Enter. - STORE_METHOD_ENTER(pMutex); + PageHolderObject< page > xImpl (m_xPage); + page & rPage = (*xImpl); // Save PageDescriptor. - D aDescr (m_rPage.m_aDescr); + OStorePageDescriptor aDescr (rPage.m_aDescr); + aDescr.m_nAddr = store::ntohl(aDescr.m_nAddr); + aDescr.m_nSize = store::ntohs(aDescr.m_nSize); // Acquire Lock. storeError eErrCode = rBIOS.acquireLock (aDescr.m_nAddr, aDescr.m_nSize); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; // Check depth. - if (m_rPage.depth()) + if (rPage.depth()) { // Check link entry. - if (!(rEntryL.compare (m_rPage.m_pData[nIndexL]) == T::COMPARE_EQUAL)) + T const aEntryL (rPage.m_pData[nIndexL]); + if (!(rEntryL.compare (aEntryL) == T::COMPARE_EQUAL)) { rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, store_E_InvalidAccess); + return store_E_InvalidAccess; } // Load link node. - self aNodeL (rPageL); - aNodeL.location (m_rPage.m_pData[nIndexL].m_aLink.m_nAddr); - - eErrCode = rBIOS.load (aNodeL); - if (eErrCode != store_E_None) - { - rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); - } - - // Remove from link node (using current page as link buffer). - eErrCode = aNodeL.remove (0, rEntryL, m_rPage, rBIOS, NULL); + self aNodeL; + eErrCode = rBIOS.loadObjectAt (aNodeL, aEntryL.m_aLink.location()); if (eErrCode != store_E_None) { rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } - // Reload current page. - m_rPage.location (aDescr.m_nAddr); - eErrCode = rBIOS.load (*this); + // Recurse: remove from link node. + eErrCode = aNodeL.remove (0, rEntryL, rBIOS); if (eErrCode != store_E_None) { - // Must not happen. - OSL_TRACE("OStoreBTreeNodeObject::remove(): load() failed"); - - // Release Lock and Leave. rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } - // Check link node usage. - if (rPageL.usageCount() == 0) + // Check resulting link node usage. + PageHolderObject< page > xPageL (aNodeL.get()); + if (xPageL->usageCount() == 0) { // Free empty link node. - eErrCode = rBIOS.free (aNodeL); + OStorePageData aPageHead; + eErrCode = rBIOS.free (aPageHead, xPageL->location()); if (eErrCode != store_E_None) { rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } // Remove index. - m_rPage.remove (nIndexL); + rPage.remove (nIndexL); touch(); } else { #if 0 /* NYI */ // Check for right sibling. - sal_uInt16 nIndexR = nIndexL + 1; - if (nIndexR < m_rPage.usageCount()) + sal_uInt16 const nIndexR = nIndexL + 1; + if (nIndexR < rPage.usageCount()) { // Load right link node. - self aNodeR (rPageR); - aNodeR.location (m_rPage.m_pData[nIndexR].m_aLink.m_nAddr); - - eErrCode = rBIOS.load (aNodeR); + self aNodeR; + eErrCode = rBIOS.loadObjectAt (aNodeR, rPage.m_pData[nIndexR].m_aLink.location()); if (eErrCode == store_E_None) { if (rPageL.queryMerge (rPageR)) { rPageL.merge (rPageR); - eErrCode = rBIOS.free (rPageR); + eErrCode = rBIOS.free (aPageHead, rPageR.location()); } } } #endif /* NYI */ // Relink. - m_rPage.m_pData[nIndexL].m_aKey = rPageL.m_pData[0].m_aKey; + rPage.m_pData[nIndexL].m_aKey = xPageL->m_pData[0].m_aKey; touch(); } } else { // Check leaf entry. - if (!(rEntryL.compare (m_rPage.m_pData[nIndexL]) == T::COMPARE_EQUAL)) + if (!(rEntryL.compare (rPage.m_pData[nIndexL]) == T::COMPARE_EQUAL)) { rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, store_E_NotExists); + return store_E_NotExists; } // Save leaf entry. - rEntryL = m_rPage.m_pData[nIndexL]; + rEntryL = rPage.m_pData[nIndexL]; // Remove leaf index. - m_rPage.remove (nIndexL); + rPage.remove (nIndexL); touch(); } @@ -454,7 +388,7 @@ storeError OStoreBTreeNodeObject::remove ( if (dirty()) { // Save this page. - eErrCode = rBIOS.save (*this); + eErrCode = rBIOS.saveObjectAt (*this, location()); if (eErrCode != store_E_None) { // Must not happen. @@ -462,13 +396,12 @@ storeError OStoreBTreeNodeObject::remove ( // Release Lock and Leave. rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } } // Release Lock and Leave. - eErrCode = rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); } /*======================================================================== @@ -476,45 +409,95 @@ storeError OStoreBTreeNodeObject::remove ( * OStoreBTreeRootObject implementation. * *======================================================================*/ +/* + * testInvariant. + * Precond: root node page loaded. + */ +bool OStoreBTreeRootObject::testInvariant (char const * message) +{ + OSL_PRECOND(m_xPage.get() != 0, "OStoreBTreeRootObject::testInvariant(): Null pointer"); + bool result = ((m_xPage->location() - m_xPage->size()) == 0); + OSL_POSTCOND(result, message); (void) message; + return result; +} + +/* + * loadOrCreate. + */ +storeError OStoreBTreeRootObject::loadOrCreate ( + sal_uInt32 nAddr, + OStorePageBIOS & rBIOS) +{ + storeError eErrCode = rBIOS.loadObjectAt (*this, nAddr); + if (eErrCode != store_E_NotExists) + return eErrCode; + + eErrCode = construct(rBIOS.allocator()); + if (eErrCode != store_E_None) + return eErrCode; + + eErrCode = rBIOS.allocate (*this); + if (eErrCode != store_E_None) + return eErrCode; + + // Notify caller of the creation. + (void) testInvariant("OStoreBTreeRootObject::loadOrCreate(): leave"); + return store_E_Pending; +} + /* * change. */ storeError OStoreBTreeRootObject::change ( - OStoreBTreeNodeData &rPageL, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) + PageHolderObject< page > & rxPageL, + OStorePageBIOS & rBIOS) { - // Enter. - STORE_METHOD_ENTER(pMutex); + PageHolderObject< page > xPage (m_xPage); + (void) testInvariant("OStoreBTreeRootObject::change(): enter"); // Save PageDescriptor. - OStorePageDescriptor aDescr (m_rPage.m_aDescr); + OStorePageDescriptor aDescr (xPage->m_aDescr); + aDescr.m_nAddr = store::ntohl(aDescr.m_nAddr); + aDescr.m_nSize = store::ntohs(aDescr.m_nSize); + + // Save root location. + sal_uInt32 const nRootAddr = xPage->location(); // Acquire Lock. storeError eErrCode = rBIOS.acquireLock (aDescr.m_nAddr, aDescr.m_nSize); if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; - // Change root. - rPageL = m_rPage; + // Construct new root. + if (!rxPageL.construct (rBIOS.allocator())) + { + rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); + return store_E_OutOfMemory; + } - base aNodeL (rPageL); - eErrCode = rBIOS.allocate (aNodeL); + // Save this as prev root. + eErrCode = rBIOS.allocate (*this); if (eErrCode != store_E_None) { - // Release Lock and Leave. rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return store_E_OutOfMemory; } - m_rPage.m_pData[0].m_aKey = rPageL.m_pData[0].m_aKey; - m_rPage.m_pData[0].m_aLink.m_nAddr = rPageL.location(); + // Setup new root. + rxPageL->depth (xPage->depth() + 1); + rxPageL->m_pData[0] = xPage->m_pData[0]; + rxPageL->m_pData[0].m_aLink = xPage->location(); + rxPageL->usageCount(1); - m_rPage.truncate (1); - m_rPage.depth (m_rPage.depth() + 1); + // Change root. + rxPageL.swap (xPage); + { + PageHolder tmp (xPage.get()); + tmp.swap (m_xPage); + } - // Save root. - eErrCode = rBIOS.save (*this); + // Save this as new root. + eErrCode = rBIOS.saveObjectAt (*this, nRootAddr); if (eErrCode != store_E_None) { // Must not happen. @@ -522,44 +505,182 @@ storeError OStoreBTreeRootObject::change ( // Release Lock and Leave. rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + return eErrCode; } -#if 1 /* ROBUSTNESS */ - eErrCode = rBIOS.flush(); -#endif /* ROBUSTNESS */ + // Flush for robustness. + (void) rBIOS.flush(); // Done. Release Lock and Leave. - eErrCode = rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); - STORE_METHOD_LEAVE(pMutex, eErrCode); + (void) testInvariant("OStoreBTreeRootObject::change(): leave"); + return rBIOS.releaseLock (aDescr.m_nAddr, aDescr.m_nSize); } /* - * split. + * find_lookup (w/o split()). + * Precond: root node page loaded. */ -storeError OStoreBTreeRootObject::split ( - sal_uInt16, - OStoreBTreeNodeData &rPageL, - OStoreBTreeNodeData &rPageR, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex) +storeError OStoreBTreeRootObject::find_lookup ( + OStoreBTreeNodeObject & rNode, // [out] + sal_uInt16 & rIndex, // [out] + OStorePageKey const & rKey, + OStorePageBIOS & rBIOS) { - // Check usage. - if (!querySplit()) - return store_E_None; + // Init node w/ root page. + (void) testInvariant("OStoreBTreeRootObject::find_lookup(): enter"); + { + PageHolder tmp (m_xPage); + tmp.swap (rNode.get()); + } - // Enter. - STORE_METHOD_ENTER(pMutex); + // Setup BTree entry. + T const entry (rKey); - // Change root. - storeError eErrCode = change (rPageL, rBIOS, NULL); - if (eErrCode != store_E_None) - STORE_METHOD_LEAVE(pMutex, eErrCode); + // Check current page. + PageHolderObject< page > xPage (rNode.get()); + for (; xPage->depth() > 0; xPage = rNode.get< page >()) + { + // Find next page. + page const & rPage = (*xPage); + sal_uInt16 const i = rPage.find(entry); + sal_uInt16 const n = rPage.usageCount(); + if (!(i < n)) + { + // Path to entry not exists (Must not happen(?)). + return store_E_NotExists; + } - // Split Left Page. - eErrCode = base::split (0, rPageL, rPageR, rBIOS, NULL); + // Check address. + sal_uInt32 const nAddr = rPage.m_pData[i].m_aLink.location(); + if (nAddr == STORE_PAGE_NULL) + { + // Path to entry not exists (Must not happen(?)). + return store_E_NotExists; + } - // Leave. - STORE_METHOD_LEAVE(pMutex, eErrCode); + // Load next page. + storeError eErrCode = rBIOS.loadObjectAt (rNode, nAddr); + if (eErrCode != store_E_None) + return eErrCode; + } + + // Find index. + page const & rPage = (*xPage); + rIndex = rPage.find(entry); + if (!(rIndex < rPage.usageCount())) + return store_E_NotExists; + + // Compare entry. + T::CompareResult eResult = entry.compare(rPage.m_pData[rIndex]); + OSL_POSTCOND(eResult != T::COMPARE_LESS, "store::BTreeRoot::find_lookup(): sort error"); + if (eResult == T::COMPARE_LESS) + return store_E_Unknown; + + // Greater or Equal. + (void) testInvariant("OStoreBTreeRootObject::find_lookup(): leave"); + return store_E_None; } +/* + * find_insert (possibly with split()). + * Precond: root node page loaded. + */ +storeError OStoreBTreeRootObject::find_insert ( + OStoreBTreeNodeObject & rNode, // [out] + sal_uInt16 & rIndex, // [out] + OStorePageKey const & rKey, + OStorePageBIOS & rBIOS) +{ + (void) testInvariant("OStoreBTreeRootObject::find_insert(): enter"); + + // Check for RootNode split. + PageHolderObject< page > xRoot (m_xPage); + if (xRoot->querySplit()) + { + PageHolderObject< page > xPageL; + + // Change root. + storeError eErrCode = change (xPageL, rBIOS); + if (eErrCode != store_E_None) + return eErrCode; + + // Split left page (prev root). + eErrCode = split (0, xPageL, rBIOS); + if (eErrCode != store_E_None) + return eErrCode; + } + + // Init node w/ root page. + { + PageHolder tmp (m_xPage); + tmp.swap (rNode.get()); + } + + // Setup BTree entry. + T const entry (rKey); + + // Check current Page. + PageHolderObject< page > xPage (rNode.get()); + for (; xPage->depth() > 0; xPage = rNode.get< page >()) + { + // Find next page. + page const & rPage = (*xPage); + sal_uInt16 const i = rPage.find (entry); + sal_uInt16 const n = rPage.usageCount(); + if (!(i < n)) + { + // Path to entry not exists (Must not happen(?)). + return store_E_NotExists; + } + + // Check address. + sal_uInt32 const nAddr = rPage.m_pData[i].m_aLink.location(); + if (nAddr == STORE_PAGE_NULL) + { + // Path to entry not exists (Must not happen(?)). + return store_E_NotExists; + } + + // Load next page. + OStoreBTreeNodeObject aNext; + storeError eErrCode = rBIOS.loadObjectAt (aNext, nAddr); + if (eErrCode != store_E_None) + return eErrCode; + + // Check for next node split. + PageHolderObject< page > xNext (aNext.get()); + if (xNext->querySplit()) + { + // Split next node. + eErrCode = rNode.split (i, xNext, rBIOS); + if (eErrCode != store_E_None) + return eErrCode; + + // Restart. + continue; + } + + // Let next page be current. + PageHolder tmp (aNext.get()); + tmp.swap (rNode.get()); + } + + // Find index. + page const & rPage = (*xPage); + rIndex = rPage.find(entry); + if (rIndex < rPage.usageCount()) + { + // Compare entry. + T::CompareResult result = entry.compare (rPage.m_pData[rIndex]); + OSL_POSTCOND(result != T::COMPARE_LESS, "store::BTreeRoot::find_insert(): sort error"); + if (result == T::COMPARE_LESS) + return store_E_Unknown; + + if (result == T::COMPARE_EQUAL) + return store_E_AlreadyExists; + } + + // Greater or not (yet) existing. + (void) testInvariant("OStoreBTreeRootObject::find_insert(): leave"); + return store_E_None; +} diff --git a/store/source/stortree.hxx b/store/source/stortree.hxx index c33c1e6ca776..ddfe4fecc5bf 100644 --- a/store/source/stortree.hxx +++ b/store/source/stortree.hxx @@ -29,21 +29,19 @@ ************************************************************************/ #ifndef _STORE_STORTREE_HXX -#define _STORE_STORTREE_HXX "$Revision: 1.6 $" +#define _STORE_STORTREE_HXX "$Revision: 1.6.8.2 $" -#include -#include -#include -#include -#include +#include "sal/types.h" -#ifndef _STORE_STORBASE_HXX -#include -#endif +#include "store/types.h" + +#include "storbase.hxx" namespace store { +class OStorePageBIOS; + /*======================================================================== * * OStoreBTreeEntry. @@ -62,21 +60,26 @@ struct OStoreBTreeEntry /** Construction. */ - OStoreBTreeEntry (void) - : m_nAttrib (0) + explicit OStoreBTreeEntry ( + K const & rKey = K(), + L const & rLink = L(), + sal_uInt32 nAttrib = 0) + : m_aKey (rKey), + m_aLink (rLink), + m_nAttrib (store::htonl(nAttrib)) {} - OStoreBTreeEntry (const OStoreBTreeEntry& rOther) - : m_aKey (rOther.m_aKey), - m_aLink (rOther.m_aLink), - m_nAttrib (rOther.m_nAttrib) + OStoreBTreeEntry (const OStoreBTreeEntry & rhs) + : m_aKey (rhs.m_aKey), + m_aLink (rhs.m_aLink), + m_nAttrib (rhs.m_nAttrib) {} - OStoreBTreeEntry& operator= (const OStoreBTreeEntry& rOther) + OStoreBTreeEntry& operator= (const OStoreBTreeEntry & rhs) { - m_aKey = rOther.m_aKey; - m_aLink = rOther.m_aLink; - m_nAttrib = rOther.m_nAttrib; + m_aKey = rhs.m_aKey; + m_aLink = rhs.m_aLink; + m_nAttrib = rhs.m_nAttrib; return *this; } @@ -98,17 +101,6 @@ struct OStoreBTreeEntry else return COMPARE_GREATER; } - - /** swap (internal and external representation). - */ - void swap (void) - { -#ifdef OSL_BIGENDIAN - m_aKey.swap(); - m_aLink.swap(); - m_nAttrib = OSL_SWAPDWORD(m_nAttrib); -#endif /* OSL_BIGENDIAN */ - } }; /*======================================================================== @@ -127,26 +119,25 @@ struct OStoreBTreeNodeData : public store::OStorePageData typedef OStoreBTreeEntry T; /** Representation. - */ + */ G m_aGuard; T m_pData[1]; - /** size. - */ - static sal_uInt16 size (void) - { - return sal_uInt16(sizeof(G)); - } + /** type. + */ + static const sal_uInt32 theTypeId = STORE_MAGIC_BTREENODE; + + /** theSize. + */ + static const size_t theSize = sizeof(G); + static const sal_uInt16 thePageSize = base::theSize + self::theSize; + STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= self::thePageSize); /** capacity. */ - static sal_uInt16 capacity (const D& rDescr) - { - return (rDescr.m_nSize - (base::size() + self::size())); - } sal_uInt16 capacity (void) const { - return self::capacity (base::m_aDescr); + return (store::ntohs(base::m_aDescr.m_nSize) - self::thePageSize); } /** capacityCount (must be even). @@ -158,13 +149,9 @@ struct OStoreBTreeNodeData : public store::OStorePageData /** usage. */ - static sal_uInt16 usage (const D& rDescr) - { - return (rDescr.m_nUsed - (base::size() + self::size())); - } sal_uInt16 usage (void) const { - return self::usage (base::m_aDescr); + return (store::ntohs(base::m_aDescr.m_nUsed) - self::thePageSize); } /** usageCount. @@ -175,62 +162,32 @@ struct OStoreBTreeNodeData : public store::OStorePageData } void usageCount (sal_uInt16 nCount) { - base::m_aDescr.m_nUsed = base::size() + self::size() + - sal_uInt16(nCount * sizeof(T)); + size_t const nBytes = self::thePageSize + nCount * sizeof(T); + base::m_aDescr.m_nUsed = store::htons(sal::static_int_cast< sal_uInt16 >(nBytes)); } /** Construction. */ - OStoreBTreeNodeData (sal_uInt16 nPageSize); - void initialize (void); - - self& operator= (const self& rOther) - { - if (this != &rOther) - { - base::operator= (rOther); - - m_aGuard = rOther.m_aGuard; - rtl_copyMemory (m_pData, rOther.m_pData, capacity()); - } - return *this; - } - - /** Comparison. - */ - sal_Bool operator== (const self& rOther) const - { - return (base::operator==(rOther) && (m_aGuard == rOther.m_aGuard)); - } - - /** swap (external and internal representation). - */ - void swap (const D& rDescr); + explicit OStoreBTreeNodeData (sal_uInt16 nPageSize = self::thePageSize); /** guard (external representation). */ - void guard (const D& rDescr) + void guard() { sal_uInt32 nCRC32 = 0; - nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); - nCRC32 = G::crc32 (nCRC32, m_pData, capacity(rDescr)); -#ifdef OSL_BIGENDIAN - nCRC32 = OSL_SWAPDWORD(nCRC32); -#endif /* OSL_BIGENDIAN */ - m_aGuard.m_nCRC32 = nCRC32; + nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); + nCRC32 = rtl_crc32 (nCRC32, m_pData, capacity()); + m_aGuard.m_nCRC32 = store::htonl(nCRC32); } /** verify (external representation). */ - storeError verify (const D& rDescr) + storeError verify() const { sal_uInt32 nCRC32 = 0; - nCRC32 = G::crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); - nCRC32 = G::crc32 (nCRC32, m_pData, capacity(rDescr)); -#ifdef OSL_BIGENDIAN - nCRC32 = OSL_SWAPDWORD(nCRC32); -#endif /* OSL_BIGENDIAN */ - if (m_aGuard.m_nCRC32 != nCRC32) + nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32)); + nCRC32 = rtl_crc32 (nCRC32, m_pData, capacity()); + if (m_aGuard.m_nCRC32 != store::htonl(nCRC32)) return store_E_InvalidChecksum; else return store_E_None; @@ -240,11 +197,11 @@ struct OStoreBTreeNodeData : public store::OStorePageData */ sal_uInt32 depth (void) const { - return self::m_aGuard.m_nMagic; + return store::ntohl(self::m_aGuard.m_nMagic); } void depth (sal_uInt32 nDepth) { - self::m_aGuard.m_nMagic = nDepth; + self::m_aGuard.m_nMagic = store::htonl(nDepth); } /** queryMerge. @@ -291,61 +248,37 @@ class OStoreBTreeNodeObject : public store::OStorePageObject typedef OStoreBTreeNodeObject self; typedef OStoreBTreeNodeData page; - typedef OStorePageDescriptor D; typedef OStoreBTreeEntry T; public: /** Construction. */ - inline OStoreBTreeNodeObject (page& rPage); + explicit OStoreBTreeNodeObject (PageHolder const & rxPage = PageHolder()) + : OStorePageObject (rxPage) + {} /** External representation. */ - virtual void swap (const D& rDescr); - virtual void guard (const D& rDescr); - virtual storeError verify (const D& rDescr); - - /** Query split. - */ - inline sal_Bool querySplit (void) const; + virtual storeError guard (sal_uInt32 nAddr); + virtual storeError verify (sal_uInt32 nAddr) const; /** split. - */ - virtual storeError split ( - sal_uInt16 nIndexL, - OStoreBTreeNodeData &rPageL, - OStoreBTreeNodeData &rPageR, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + * + * @param rxPageL [inout] left child to be split + */ + storeError split ( + sal_uInt16 nIndexL, + PageHolderObject< page > & rxPageL, + OStorePageBIOS & rBIOS); /** remove (down to leaf node, recursive). */ storeError remove ( - sal_uInt16 nIndexL, - OStoreBTreeEntry &rEntryL, - OStoreBTreeNodeData &rPageL, -#if 0 /* NYI */ - OStoreBTreeNodeData &rPageR, -#endif /* NYI */ - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); - -private: - /** Representation. - */ - page& m_rPage; + sal_uInt16 nIndexL, + OStoreBTreeEntry & rEntryL, + OStorePageBIOS & rBIOS); }; -inline OStoreBTreeNodeObject::OStoreBTreeNodeObject (page& rPage) - : OStorePageObject (rPage), m_rPage (rPage) -{ -} - -inline sal_Bool OStoreBTreeNodeObject::querySplit (void) const -{ - return m_rPage.querySplit(); -} - /*======================================================================== * * OStoreBTreeRootObject. @@ -356,38 +289,52 @@ class OStoreBTreeRootObject : public store::OStoreBTreeNodeObject typedef OStoreBTreeNodeObject base; typedef OStoreBTreeNodeData page; + typedef OStoreBTreeEntry T; + public: /** Construction. - */ - inline OStoreBTreeRootObject (page& rPage); + */ + explicit OStoreBTreeRootObject (PageHolder const & rxPage = PageHolder()) + : OStoreBTreeNodeObject (rxPage) + {} - /** split. - */ - virtual storeError split ( - sal_uInt16 nIndexL, - OStoreBTreeNodeData &rPageL, - OStoreBTreeNodeData &rPageR, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + storeError loadOrCreate ( + sal_uInt32 nAddr, + OStorePageBIOS & rBIOS); + + /** find_lookup (w/o split()). + * Precond: root node page loaded. + */ + storeError find_lookup ( + OStoreBTreeNodeObject & rNode, // [out] + sal_uInt16 & rIndex, // [out] + OStorePageKey const & rKey, + OStorePageBIOS & rBIOS); + + /** find_insert (possibly with split()). + * Precond: root node page loaded. + */ + storeError find_insert ( + OStoreBTreeNodeObject & rNode, + sal_uInt16 & rIndex, + OStorePageKey const & rKey, + OStorePageBIOS & rBIOS); private: - /** Representation. - */ - page& m_rPage; + /** testInvariant. + * Precond: root node page loaded. + */ + bool testInvariant (char const * message); /** change (Root). - */ + * + * @param rxPageL [out] prev. root (needs split) + */ storeError change ( - OStoreBTreeNodeData &rPageL, - OStorePageBIOS &rBIOS, - osl::Mutex *pMutex = NULL); + PageHolderObject< page > & rxPageL, + OStorePageBIOS & rBIOS); }; -inline OStoreBTreeRootObject::OStoreBTreeRootObject (page& rPage) - : OStoreBTreeNodeObject (rPage), m_rPage (rPage) -{ -} - /*======================================================================== * * The End. @@ -397,4 +344,3 @@ inline OStoreBTreeRootObject::OStoreBTreeRootObject (page& rPage) } // namespace store #endif /* !_STORE_STORTREE_HXX */ - diff --git a/store/util/makefile.mk b/store/util/makefile.mk index 72d0ac7cd595..57733e5ca2a9 100644 --- a/store/util/makefile.mk +++ b/store/util/makefile.mk @@ -66,34 +66,10 @@ SHL1VERSIONMAP= $(TARGET).map SHL1STDLIBS= $(SALLIB) -# system STLport5 needs it -.IF "$(USE_STLP_DEBUG)" != "" || "$(STLPORT_VER)" >= "500" -SHL1STDLIBS+=$(LIBSTLPORT) -.ENDIF - -# On gcc3 __Unwind_SetIP is not in supc++ but in libgcc_s.so -.IF "$(COMID)"=="gcc3" && "$(GUI)"!="OS2" -.IF "$(GUI)"=="WNT" -SHL1STDLIBS+= -lsupc++ -.ELSE -.IF "$(OS)"=="NETBSD" -SHL1STDLIBS+= -lsupc++ -.ELIF "$(OS)"=="MACOSX" -.IF "$(CCNUMVER)"<="000399999999" -SHL1STDLIBS+= -lsupc++ -.ENDIF # CCNUMVER -.ELIF "$(CCNUMVER)"<="000400000999" -SHL1STDLIBS+= -lsupc++ -lgcc_s -.ENDIF -.ENDIF -.ENDIF - - SHL1DEF= $(MISC)$/$(SHL1TARGET).def SHL1LIBS= $(SLB)$/store.lib SHL1RPATH= URELIB - # --- Def-File --- DEF1NAME= $(SHL1TARGET) diff --git a/store/util/sto.dxp b/store/util/sto.dxp deleted file mode 100644 index b973c5e342fe..000000000000 --- a/store/util/sto.dxp +++ /dev/null @@ -1,25 +0,0 @@ -store_acquireHandle -store_attrib -store_closeDirectory -store_closeFile -store_closeStream -store_createMemoryFile -store_findFirst -store_findNext -store_flushFile -store_flushStream -store_getFileRefererCount -store_getFileSize -store_getStreamSize -store_link -store_openDirectory -store_openFile -store_openStream -store_readStream -store_rebuildFile -store_releaseHandle -store_remove -store_rename -store_setStreamSize -store_symlink -store_writeStream diff --git a/store/util/sto.map b/store/util/sto.map deleted file mode 100644 index 1f3bca011818..000000000000 --- a/store/util/sto.map +++ /dev/null @@ -1,30 +0,0 @@ -STO_1_0 { - global: - store_acquireHandle; - store_attrib; - store_closeDirectory; - store_closeFile; - store_closeStream; - store_createMemoryFile; - store_findFirst; - store_findNext; - store_flushFile; - store_flushStream; - store_getFileRefererCount; - store_getFileSize; - store_getStreamSize; - store_link; - store_openDirectory; - store_openFile; - store_openStream; - store_readStream; - store_rebuildFile; - store_releaseHandle; - store_remove; - store_rename; - store_setStreamSize; - store_symlink; - store_writeStream; - local: - *; -}; diff --git a/store/util/sto.mxp.map b/store/util/sto.mxp.map deleted file mode 100644 index 8de6847f1fb8..000000000000 --- a/store/util/sto.mxp.map +++ /dev/null @@ -1,204 +0,0 @@ -# C and C++ library symbols -__mh_dylib_header -___builtin_new -dyld_stub_binding_helper -___rtti_class -___builtin_delete -___pure_virtual -___rtti_si -___rtti_user -__._9bad_alloc -___check_eh_spec -___cp_pop_exception -___cp_push_exception -___eh_alloc -___get_eh_context -___sjthrow -___start_cp_handler -___terminate -___tf9bad_alloc -___vt_9bad_alloc -___vt_9exception -__keymgr_get_per_thread_data -_terminate__Fv -rest_world -save_world -___tf9exception -___ti9exception -_what__C9exception -__keymgr_set_per_thread_data -__._10bad_typeid -__._8bad_cast -___get_eh_info -___is_pointer__FPv -___throw_type_match_rtti -___vt_10bad_typeid -___vt_8bad_cast -__._9type_info -___eq__C9type_infoRCB0 -___tf16__user_type_info -___tf9type_info -___ti9type_info -___vt_9type_info -___tf13bad_exception -___uncatch_exception -___eh_free -___tfv -___dynamic_cast - -# Global symbols -_store_acquireHandle -_store_attrib -_store_closeDirectory -_store_closeFile -_store_closeStream -_store_createMemoryFile -_store_findFirst -_store_findNext -_store_flushFile -_store_flushStream -_store_getFileRefererCount -_store_getFileSize -_store_getStreamSize -_store_link -_store_openDirectory -_store_openFile -_store_openStream -_store_readStream -_store_rebuildFile -_store_releaseHandle -_store_remove -_store_rename -_store_setStreamSize -_store_symlink -_store_writeStream -_classInfo__Q25store16OMemoryLockBytes -_classInfo__Q25store14OFileLockBytes -_close__Q25store20OStoreSuperBlockPageRQ25store14OStorePageBIOS -_poke__Q25store14OStorePageBIOSRQ25store14OStorePageData -_poke__Q25store14OStorePageBIOSRQ25store16OStorePageObject -_peek__Q25store14OStorePageBIOSRQ25store14OStorePageData -_modified__Q25store20OStoreSuperBlockPageRQ25store14OStorePageBIOS -_flush__Q25store20OStoreSuperBlockPageRQ25store14OStorePageBIOS -_create__Q25store20OStoreSuperBlockPageRQ25store14OStorePageBIOSRCQ25store20OStorePageDescriptor -_repair__Q25store14OStorePageBIOSRPQ25store20OStoreSuperBlockPage -_verify__Q25store14OStorePageBIOSRPQ25store20OStoreSuperBlockPage -_verify__Q25store20OStoreSuperBlockPageRQ25store14OStorePageBIOS -_insert__Q25store15OStorePageCacheUsRCQ25store20OStorePageDescriptorRCQ25store14OStorePageDataRQ25store14OStorePageBIOSQ35store15OStorePageCache10InsertMode -_find__CQ25store15OStorePageCacheRCQ25store20OStorePageDescriptor -_move__Q25store15OStorePageCacheUsUs -_truncate__Q25store27OStoreIndirectionPageObjectUsn2RPQ25store25OStoreIndirectionPageDatan1RQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_truncate__Q25store25OStoreDirectoryPageObjectQ35store23OStoreDirectoryPageData10ChunkScopeUsRPQ25store25OStoreIndirectionPageDatan2RQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_put__Q25store27OStoreIndirectionPageObjectUsn2RPQ25store25OStoreIndirectionPageDatan1RQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_get__Q25store27OStoreIndirectionPageObjectUsn2RPQ25store25OStoreIndirectionPageDatan1RQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_scope__CQ25store25OStoreDirectoryPageObjectUlRQ35store24OStoreDirectoryDataBlock14LinkDescriptor -_truncate__Q25store27OStoreIndirectionPageObjectUsUsRPQ25store25OStoreIndirectionPageDataRQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_truncate__Q25store27OStoreIndirectionPageObjectUsRQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_put__Q25store27OStoreIndirectionPageObjectUsUsRPQ25store25OStoreIndirectionPageDataRQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_put__Q25store27OStoreIndirectionPageObjectUsRQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_get__Q25store27OStoreIndirectionPageObjectUsUsRPQ25store25OStoreIndirectionPageDataRQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_get__Q25store27OStoreIndirectionPageObjectUsRQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -___Q25store25OStoreIndirectionPageDataUs -_swap__Q25store25OStoreIndirectionPageDataRCQ25store20OStorePageDescriptor -_initialize__Q25store25OStoreIndirectionPageData -_swap__Q35store24OStoreDirectoryDataBlock9LinkTable -_classInfo__Q25store21OStorePageDaemon_Impl -_flush__Q25store21OStorePageDaemon_Impl -_empty__Q25store21OStorePageDaemon_Impl -_remove__Q25store21OStorePageDaemon_ImplPQ25store14OStorePageBIOS -_insert__Q25store21OStorePageDaemon_ImplPQ25store14OStorePageBIOS -___Q25store16OStorePageDaemoni -_getGlobalMutex__Q25store16OStorePageDaemon -___Q25store21OStorePageDaemon_Impl -_classInfo__Q25store16OStorePageDaemon -_change__Q25store21OStoreBTreeRootObjectRQ25store19OStoreBTreeNodeDataRQ25store14OStorePageBIOSPQ23vos6IMutex -_remove__Q25store19OStoreBTreeNodeDataUs -_split__Q25store19OStoreBTreeNodeDataRCB0 -_swap__Q25store19OStoreBTreeNodeDataRCQ25store20OStorePageDescriptor -_truncate__Q25store19OStoreBTreeNodeDataUs -_initialize__Q25store19OStoreBTreeNodeData -_initialize__Q25store17OStorePageManagerPQ25store10ILockBytes15storeAccessModeUs -_remove__Q25store17OStorePageManagerRQ25store16OStoreBTreeEntryRQ25store19OStoreBTreeNodeDatan1 -_find__Q25store17OStorePageManagerRCQ25store16OStoreBTreeEntryRQ25store19OStoreBTreeNodeDatan2 -_find__Q25store17OStorePageManagerRCQ25store16OStoreBTreeEntryRQ25store19OStoreBTreeNodeData -___Q25store14OFileLockBytes -___Q25store15OStoreDirectory -___Q25store15OStoreLockBytes -___Q25store16OMemoryLockBytes -___Q25store17OStorePageManager -_attrib__Q25store17OStorePageManagerRCQ25store13OStorePageKeyUlUlRUl -_classInfo__Q25store15OStoreDirectory -_classInfo__Q25store15OStoreLockBytes -_classInfo__Q25store17OStorePageManager -_create__Q25store14OFileLockBytesP12_rtl_uString15storeAccessMode -_create__Q25store15OStoreDirectoryPQ25store17OStorePageManagerP12_rtl_uStringn115storeAccessMode -_create__Q25store15OStoreLockBytesPQ25store17OStorePageManagerP12_rtl_uStringn115storeAccessMode -_getRefererCount__Q25store14OStorePageBIOS -_iterate__Q25store15OStoreDirectoryR13storeFindData -_link__Q25store17OStorePageManagerRCQ25store13OStorePageKeyn1 -_rebuild__Q25store17OStorePageManagerPQ25store10ILockBytesn1 -_remove__Q25store17OStorePageManagerRCQ25store13OStorePageKey -_rename__Q25store17OStorePageManagerRCQ25store13OStorePageKeyPC11_rtl_Stringn1 -_size__Q25store14OStorePageBIOSRUl -_symlink__Q25store17OStorePageManagerPC11_rtl_Stringn1RCQ25store13OStorePageKey -___Q35store24OStoreDirectoryDataBlock9LinkTable -___vt_Q25store25OStoreDirectoryPageObject -_acquirePage__Q25store14OStorePageBIOSRCQ25store20OStorePageDescriptor15storeAccessMode -_getPageSize__Q25store14OStorePageBIOSRUs -_get__Q25store25OStoreDirectoryPageObjectUlRPQ25store25OStoreIndirectionPageDatan2RQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_iterate__Q25store17OStorePageManagerRQ25store13OStorePageKeyRQ25store16OStorePageObjectRUl -_load__Q25store17OStorePageManagerRCQ25store13OStorePageKeyRQ25store25OStoreDirectoryPageObject -_put__Q25store25OStoreDirectoryPageObjectUlRPQ25store25OStoreIndirectionPageDatan2RQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_releasePage__Q25store14OStorePageBIOSRCQ25store20OStorePageDescriptor15storeAccessMode -_save__Q25store17OStorePageManagerRCQ25store13OStorePageKeyRQ25store25OStoreDirectoryPageObject -_truncate__Q25store25OStoreDirectoryPageObjectUlRPQ25store25OStoreIndirectionPageDatan2RQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -__._Q25store12OStoreObject -___Q25store12OStoreObject -___tfQ25store12OStoreObject -___tiQ25store12OStoreObject -_classInfo__Q25store12OStoreObject -__._Q25store14OStorePageBIOS -__._Q25store15OStorePageCache -___Q25store14OStorePageBIOS -___Q25store15OStorePageCacheUs -___Q25store19OStoreBTreeNodeDataUs -___tfQ25store14OStorePageBIOS -___tiQ25store14OStorePageBIOS -___vt_Q25store21OStoreBTreeNodeObject -___vt_Q25store21OStoreBTreeRootObject -_classInfo__Q25store14OStorePageBIOS -_close__Q25store14OStorePageBIOS -_create__Q25store14OStorePageBIOSUs -_find__CQ25store19OStoreBTreeNodeDataRCQ25store16OStoreBTreeEntry -_flush__Q25store14OStorePageBIOS -_flush__Q25store15OStorePageCacheRQ25store14OStorePageBIOSPQ23vos6IMutex -_free__Q25store14OStorePageBIOSRQ25store16OStorePageObject -_getOrCreate__Q25store16OStorePageDaemonRQ23vost4ORef1ZB0 -_initialize__Q25store14OStorePageBIOSPQ25store10ILockBytes15storeAccessMode -_initialize__Q35store24OStoreDirectoryDataBlock9LinkTable -_insert__Q25store16OStorePageDaemonPQ25store14OStorePageBIOS -_insert__Q25store19OStoreBTreeNodeDataUsRCQ25store16OStoreBTreeEntry -_invalidate__Q25store15OStorePageCacheRCQ25store20OStorePageDescriptorPQ23vos6IMutex -_load__Q25store14OStorePageBIOSRQ25store16OStorePageObject -_load__Q25store15OStorePageCacheRCQ25store20OStorePageDescriptorRQ25store14OStorePageDataRQ25store14OStorePageBIOSPQ23vos6IMutex -_remove__Q25store16OStorePageDaemonPQ25store14OStorePageBIOS -_remove__Q25store21OStoreBTreeNodeObjectUsRQ25store16OStoreBTreeEntryRQ25store19OStoreBTreeNodeDataRQ25store14OStorePageBIOSPQ23vos6IMutex -_save__Q25store14OStorePageBIOSRQ25store16OStorePageObject -_scanBegin__Q25store14OStorePageBIOSRQ35store14OStorePageBIOS11ScanContextUl -_scanNext__Q25store14OStorePageBIOSRQ35store14OStorePageBIOS11ScanContextRQ25store16OStorePageObject -_split__Q25store21OStoreBTreeNodeObjectUsRQ25store19OStoreBTreeNodeDatan1RQ25store14OStorePageBIOSPQ23vos6IMutex -_split__Q25store21OStoreBTreeRootObjectUsRQ25store19OStoreBTreeNodeDatan1RQ25store14OStorePageBIOSPQ23vos6IMutex -_update__Q25store15OStorePageCacheRCQ25store20OStorePageDescriptorRCQ25store14OStorePageDataRQ25store14OStorePageBIOSPQ23vos6IMutexQ35store15OStorePageCache10UpdateMode -__._Q25store16OStorePageObject -___tfQ25store16OStorePageObject -___tiQ25store16OStorePageObject -___vt_Q25store16OStorePageObject -_acquireLock__Q25store14OStorePageBIOSUlUl -_allocate__Q25store14OStorePageBIOSRQ25store16OStorePageObjectQ35store14OStorePageBIOS10Allocation -_crc32__Q25store15OStorePageGuardUlPCvUl -_guard__Q25store16OStorePageObjectRCQ25store20OStorePageDescriptor -_releaseLock__Q25store14OStorePageBIOSUlUl -_swap__Q25store16OStorePageObjectRCQ25store20OStorePageDescriptor -_verify__Q25store16OStorePageObjectRCQ25store20OStorePageDescriptor -_read__Q25store14OStorePageBIOSUlPvUl -_write__Q25store14OStorePageBIOSUlPCvUl diff --git a/store/util/store.mxp.map b/store/util/store.mxp.map deleted file mode 100644 index 8de6847f1fb8..000000000000 --- a/store/util/store.mxp.map +++ /dev/null @@ -1,204 +0,0 @@ -# C and C++ library symbols -__mh_dylib_header -___builtin_new -dyld_stub_binding_helper -___rtti_class -___builtin_delete -___pure_virtual -___rtti_si -___rtti_user -__._9bad_alloc -___check_eh_spec -___cp_pop_exception -___cp_push_exception -___eh_alloc -___get_eh_context -___sjthrow -___start_cp_handler -___terminate -___tf9bad_alloc -___vt_9bad_alloc -___vt_9exception -__keymgr_get_per_thread_data -_terminate__Fv -rest_world -save_world -___tf9exception -___ti9exception -_what__C9exception -__keymgr_set_per_thread_data -__._10bad_typeid -__._8bad_cast -___get_eh_info -___is_pointer__FPv -___throw_type_match_rtti -___vt_10bad_typeid -___vt_8bad_cast -__._9type_info -___eq__C9type_infoRCB0 -___tf16__user_type_info -___tf9type_info -___ti9type_info -___vt_9type_info -___tf13bad_exception -___uncatch_exception -___eh_free -___tfv -___dynamic_cast - -# Global symbols -_store_acquireHandle -_store_attrib -_store_closeDirectory -_store_closeFile -_store_closeStream -_store_createMemoryFile -_store_findFirst -_store_findNext -_store_flushFile -_store_flushStream -_store_getFileRefererCount -_store_getFileSize -_store_getStreamSize -_store_link -_store_openDirectory -_store_openFile -_store_openStream -_store_readStream -_store_rebuildFile -_store_releaseHandle -_store_remove -_store_rename -_store_setStreamSize -_store_symlink -_store_writeStream -_classInfo__Q25store16OMemoryLockBytes -_classInfo__Q25store14OFileLockBytes -_close__Q25store20OStoreSuperBlockPageRQ25store14OStorePageBIOS -_poke__Q25store14OStorePageBIOSRQ25store14OStorePageData -_poke__Q25store14OStorePageBIOSRQ25store16OStorePageObject -_peek__Q25store14OStorePageBIOSRQ25store14OStorePageData -_modified__Q25store20OStoreSuperBlockPageRQ25store14OStorePageBIOS -_flush__Q25store20OStoreSuperBlockPageRQ25store14OStorePageBIOS -_create__Q25store20OStoreSuperBlockPageRQ25store14OStorePageBIOSRCQ25store20OStorePageDescriptor -_repair__Q25store14OStorePageBIOSRPQ25store20OStoreSuperBlockPage -_verify__Q25store14OStorePageBIOSRPQ25store20OStoreSuperBlockPage -_verify__Q25store20OStoreSuperBlockPageRQ25store14OStorePageBIOS -_insert__Q25store15OStorePageCacheUsRCQ25store20OStorePageDescriptorRCQ25store14OStorePageDataRQ25store14OStorePageBIOSQ35store15OStorePageCache10InsertMode -_find__CQ25store15OStorePageCacheRCQ25store20OStorePageDescriptor -_move__Q25store15OStorePageCacheUsUs -_truncate__Q25store27OStoreIndirectionPageObjectUsn2RPQ25store25OStoreIndirectionPageDatan1RQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_truncate__Q25store25OStoreDirectoryPageObjectQ35store23OStoreDirectoryPageData10ChunkScopeUsRPQ25store25OStoreIndirectionPageDatan2RQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_put__Q25store27OStoreIndirectionPageObjectUsn2RPQ25store25OStoreIndirectionPageDatan1RQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_get__Q25store27OStoreIndirectionPageObjectUsn2RPQ25store25OStoreIndirectionPageDatan1RQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_scope__CQ25store25OStoreDirectoryPageObjectUlRQ35store24OStoreDirectoryDataBlock14LinkDescriptor -_truncate__Q25store27OStoreIndirectionPageObjectUsUsRPQ25store25OStoreIndirectionPageDataRQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_truncate__Q25store27OStoreIndirectionPageObjectUsRQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_put__Q25store27OStoreIndirectionPageObjectUsUsRPQ25store25OStoreIndirectionPageDataRQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_put__Q25store27OStoreIndirectionPageObjectUsRQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_get__Q25store27OStoreIndirectionPageObjectUsUsRPQ25store25OStoreIndirectionPageDataRQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_get__Q25store27OStoreIndirectionPageObjectUsRQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -___Q25store25OStoreIndirectionPageDataUs -_swap__Q25store25OStoreIndirectionPageDataRCQ25store20OStorePageDescriptor -_initialize__Q25store25OStoreIndirectionPageData -_swap__Q35store24OStoreDirectoryDataBlock9LinkTable -_classInfo__Q25store21OStorePageDaemon_Impl -_flush__Q25store21OStorePageDaemon_Impl -_empty__Q25store21OStorePageDaemon_Impl -_remove__Q25store21OStorePageDaemon_ImplPQ25store14OStorePageBIOS -_insert__Q25store21OStorePageDaemon_ImplPQ25store14OStorePageBIOS -___Q25store16OStorePageDaemoni -_getGlobalMutex__Q25store16OStorePageDaemon -___Q25store21OStorePageDaemon_Impl -_classInfo__Q25store16OStorePageDaemon -_change__Q25store21OStoreBTreeRootObjectRQ25store19OStoreBTreeNodeDataRQ25store14OStorePageBIOSPQ23vos6IMutex -_remove__Q25store19OStoreBTreeNodeDataUs -_split__Q25store19OStoreBTreeNodeDataRCB0 -_swap__Q25store19OStoreBTreeNodeDataRCQ25store20OStorePageDescriptor -_truncate__Q25store19OStoreBTreeNodeDataUs -_initialize__Q25store19OStoreBTreeNodeData -_initialize__Q25store17OStorePageManagerPQ25store10ILockBytes15storeAccessModeUs -_remove__Q25store17OStorePageManagerRQ25store16OStoreBTreeEntryRQ25store19OStoreBTreeNodeDatan1 -_find__Q25store17OStorePageManagerRCQ25store16OStoreBTreeEntryRQ25store19OStoreBTreeNodeDatan2 -_find__Q25store17OStorePageManagerRCQ25store16OStoreBTreeEntryRQ25store19OStoreBTreeNodeData -___Q25store14OFileLockBytes -___Q25store15OStoreDirectory -___Q25store15OStoreLockBytes -___Q25store16OMemoryLockBytes -___Q25store17OStorePageManager -_attrib__Q25store17OStorePageManagerRCQ25store13OStorePageKeyUlUlRUl -_classInfo__Q25store15OStoreDirectory -_classInfo__Q25store15OStoreLockBytes -_classInfo__Q25store17OStorePageManager -_create__Q25store14OFileLockBytesP12_rtl_uString15storeAccessMode -_create__Q25store15OStoreDirectoryPQ25store17OStorePageManagerP12_rtl_uStringn115storeAccessMode -_create__Q25store15OStoreLockBytesPQ25store17OStorePageManagerP12_rtl_uStringn115storeAccessMode -_getRefererCount__Q25store14OStorePageBIOS -_iterate__Q25store15OStoreDirectoryR13storeFindData -_link__Q25store17OStorePageManagerRCQ25store13OStorePageKeyn1 -_rebuild__Q25store17OStorePageManagerPQ25store10ILockBytesn1 -_remove__Q25store17OStorePageManagerRCQ25store13OStorePageKey -_rename__Q25store17OStorePageManagerRCQ25store13OStorePageKeyPC11_rtl_Stringn1 -_size__Q25store14OStorePageBIOSRUl -_symlink__Q25store17OStorePageManagerPC11_rtl_Stringn1RCQ25store13OStorePageKey -___Q35store24OStoreDirectoryDataBlock9LinkTable -___vt_Q25store25OStoreDirectoryPageObject -_acquirePage__Q25store14OStorePageBIOSRCQ25store20OStorePageDescriptor15storeAccessMode -_getPageSize__Q25store14OStorePageBIOSRUs -_get__Q25store25OStoreDirectoryPageObjectUlRPQ25store25OStoreIndirectionPageDatan2RQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_iterate__Q25store17OStorePageManagerRQ25store13OStorePageKeyRQ25store16OStorePageObjectRUl -_load__Q25store17OStorePageManagerRCQ25store13OStorePageKeyRQ25store25OStoreDirectoryPageObject -_put__Q25store25OStoreDirectoryPageObjectUlRPQ25store25OStoreIndirectionPageDatan2RQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -_releasePage__Q25store14OStorePageBIOSRCQ25store20OStorePageDescriptor15storeAccessMode -_save__Q25store17OStorePageManagerRCQ25store13OStorePageKeyRQ25store25OStoreDirectoryPageObject -_truncate__Q25store25OStoreDirectoryPageObjectUlRPQ25store25OStoreIndirectionPageDatan2RQ25store20OStoreDataPageObjectRQ25store14OStorePageBIOSPQ23vos6IMutex -__._Q25store12OStoreObject -___Q25store12OStoreObject -___tfQ25store12OStoreObject -___tiQ25store12OStoreObject -_classInfo__Q25store12OStoreObject -__._Q25store14OStorePageBIOS -__._Q25store15OStorePageCache -___Q25store14OStorePageBIOS -___Q25store15OStorePageCacheUs -___Q25store19OStoreBTreeNodeDataUs -___tfQ25store14OStorePageBIOS -___tiQ25store14OStorePageBIOS -___vt_Q25store21OStoreBTreeNodeObject -___vt_Q25store21OStoreBTreeRootObject -_classInfo__Q25store14OStorePageBIOS -_close__Q25store14OStorePageBIOS -_create__Q25store14OStorePageBIOSUs -_find__CQ25store19OStoreBTreeNodeDataRCQ25store16OStoreBTreeEntry -_flush__Q25store14OStorePageBIOS -_flush__Q25store15OStorePageCacheRQ25store14OStorePageBIOSPQ23vos6IMutex -_free__Q25store14OStorePageBIOSRQ25store16OStorePageObject -_getOrCreate__Q25store16OStorePageDaemonRQ23vost4ORef1ZB0 -_initialize__Q25store14OStorePageBIOSPQ25store10ILockBytes15storeAccessMode -_initialize__Q35store24OStoreDirectoryDataBlock9LinkTable -_insert__Q25store16OStorePageDaemonPQ25store14OStorePageBIOS -_insert__Q25store19OStoreBTreeNodeDataUsRCQ25store16OStoreBTreeEntry -_invalidate__Q25store15OStorePageCacheRCQ25store20OStorePageDescriptorPQ23vos6IMutex -_load__Q25store14OStorePageBIOSRQ25store16OStorePageObject -_load__Q25store15OStorePageCacheRCQ25store20OStorePageDescriptorRQ25store14OStorePageDataRQ25store14OStorePageBIOSPQ23vos6IMutex -_remove__Q25store16OStorePageDaemonPQ25store14OStorePageBIOS -_remove__Q25store21OStoreBTreeNodeObjectUsRQ25store16OStoreBTreeEntryRQ25store19OStoreBTreeNodeDataRQ25store14OStorePageBIOSPQ23vos6IMutex -_save__Q25store14OStorePageBIOSRQ25store16OStorePageObject -_scanBegin__Q25store14OStorePageBIOSRQ35store14OStorePageBIOS11ScanContextUl -_scanNext__Q25store14OStorePageBIOSRQ35store14OStorePageBIOS11ScanContextRQ25store16OStorePageObject -_split__Q25store21OStoreBTreeNodeObjectUsRQ25store19OStoreBTreeNodeDatan1RQ25store14OStorePageBIOSPQ23vos6IMutex -_split__Q25store21OStoreBTreeRootObjectUsRQ25store19OStoreBTreeNodeDatan1RQ25store14OStorePageBIOSPQ23vos6IMutex -_update__Q25store15OStorePageCacheRCQ25store20OStorePageDescriptorRCQ25store14OStorePageDataRQ25store14OStorePageBIOSPQ23vos6IMutexQ35store15OStorePageCache10UpdateMode -__._Q25store16OStorePageObject -___tfQ25store16OStorePageObject -___tiQ25store16OStorePageObject -___vt_Q25store16OStorePageObject -_acquireLock__Q25store14OStorePageBIOSUlUl -_allocate__Q25store14OStorePageBIOSRQ25store16OStorePageObjectQ35store14OStorePageBIOS10Allocation -_crc32__Q25store15OStorePageGuardUlPCvUl -_guard__Q25store16OStorePageObjectRCQ25store20OStorePageDescriptor -_releaseLock__Q25store14OStorePageBIOSUlUl -_swap__Q25store16OStorePageObjectRCQ25store20OStorePageDescriptor -_verify__Q25store16OStorePageObjectRCQ25store20OStorePageDescriptor -_read__Q25store14OStorePageBIOSUlPvUl -_write__Q25store14OStorePageBIOSUlPCvUl diff --git a/store/workben/makefile.mk b/store/workben/makefile.mk index b0bb9d2d6767..636006eaea7b 100644 --- a/store/workben/makefile.mk +++ b/store/workben/makefile.mk @@ -36,6 +36,7 @@ TARGET=workben LIBTARGET=NO TARGETTYPE=CUI +NO_DEFAULT_STL=TRUE # --- Settings --- @@ -59,13 +60,10 @@ CFLAGS+= -I..$/source # --- Files --- -CXXFILES= \ - t_file.cxx \ - t_base.cxx \ - t_store.cxx - OBJFILES= \ + $(OBJ)$/t_leak.obj \ $(OBJ)$/t_file.obj \ + $(OBJ)$/t_page.obj \ $(OBJ)$/t_base.obj \ $(OBJ)$/t_store.obj @@ -73,25 +71,29 @@ APP1TARGET= t_file APP1OBJS= $(OBJ)$/t_file.obj APP1STDLIBS= $(STOREDBGLIB) APP1STDLIBS+= $(SALLIB) -APP1DEPN= \ - $(STOREDBGLIB) \ - $(L)$/isal.lib +APP1DEPN= $(STOREDBGLIB) -APP2TARGET= t_base -APP2OBJS= $(OBJ)$/t_base.obj +APP2TARGET= t_page +APP2OBJS= $(OBJ)$/t_page.obj APP2STDLIBS= $(STOREDBGLIB) APP2STDLIBS+= $(SALLIB) -APP2DEPN= \ - $(STOREDBGLIB) \ - $(L)$/isal.lib +APP2DEPN= $(STOREDBGLIB) -APP3TARGET= t_store -APP3OBJS= $(OBJ)$/t_store.obj -APP3STDLIBS= $(STORELIB) +APP3TARGET= t_base +APP3OBJS= $(OBJ)$/t_base.obj +APP3STDLIBS= $(STOREDBGLIB) APP3STDLIBS+= $(SALLIB) -APP3DEPN= \ - $(SLB)$/store.lib \ - $(L)$/isal.lib +APP3DEPN= $(STOREDBGLIB) + + APP4TARGET= t_store + APP4OBJS= $(OBJ)$/t_store.obj + APP4STDLIBS= $(STORELIB) + APP4STDLIBS+= $(SALLIB) + APP4DEPN= $(SLB)$/store.lib + + APP5TARGET= t_leak + APP5OBJS= $(OBJ)$/t_leak.obj + APP5STDLIBS+= $(SALLIB) # --- Targets --- diff --git a/store/workben/t_base.cxx b/store/workben/t_base.cxx index 664fc9eaf773..593736e4d57b 100644 --- a/store/workben/t_base.cxx +++ b/store/workben/t_base.cxx @@ -31,97 +31,21 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_store.hxx" -#define _T_BASE_CXX "$Revision: 1.8 $" -#include -#include -#include -#include -#include -#include +#include "sal/types.h" +#include "osl/diagnose.h" +#include "osl/thread.h" +#include "rtl/memory.h" +#include "rtl/ustring.hxx" + +#include "object.hxx" #include "storbase.hxx" +#include "storbios.hxx" +#include "lockbyte.hxx" using namespace store; #define TEST_PAGESIZE 1024 -/*======================================================================== - * - * OTestDaemon. - * - *======================================================================*/ - -#if 1 /* EXP */ - -#include - -class OTestDaemon : public rtl::IReference -{ -public: - static sal_Bool getOrCreate ( - rtl::Reference &rxDaemon); - - virtual oslInterlockedCount SAL_CALL acquire (void); - virtual oslInterlockedCount SAL_CALL release (void); - -protected: - OTestDaemon (void); - virtual ~OTestDaemon (void); - -private: - static OTestDaemon *m_pThis; - - oslInterlockedCount m_nRefCount; -}; - -#include - -OTestDaemon* OTestDaemon::m_pThis = 0; - -OTestDaemon::OTestDaemon (void) -{ -} - -OTestDaemon::~OTestDaemon (void) -{ -} - -sal_Bool OTestDaemon::getOrCreate (rtl::Reference &rxDaemon) -{ - osl::MutexGuard aGuard (osl::Mutex::getGlobalMutex()); - - rxDaemon = m_pThis; - if (!rxDaemon.is()) - { - m_pThis = new OTestDaemon(); - rxDaemon = m_pThis; - } - return rxDaemon.is(); -} - -oslInterlockedCount SAL_CALL OTestDaemon::acquire (void) -{ - return osl_incrementInterlockedCount (&m_nRefCount); -} - -oslInterlockedCount SAL_CALL OTestDaemon::release (void) -{ - oslInterlockedCount result; - - result = osl_decrementInterlockedCount (&m_nRefCount); - if (result == 0) - { - osl::MutexGuard aGuard (osl::Mutex::getGlobalMutex()); - if (m_nRefCount == 0) - { - m_pThis = 0; - delete this; - } - } - return (result); -} - -#endif /* EXP */ - /*======================================================================== * * OTestObject. @@ -167,16 +91,22 @@ static OTestObject* SAL_CALL query (IStoreHandle *pHandle, OTestObject*) * OTestBIOS. * *======================================================================*/ +namespace store +{ + class OTestBIOS : public store::OStorePageBIOS { typedef store::OStorePageBIOS base; + friend OTestBIOS* SAL_CALL query<> (IStoreHandle * pHandle, OTestBIOS *); + public: OTestBIOS (void); virtual storeError initialize ( - ILockBytes *pLockBytes, - storeAccessMode eAccessMode); + ILockBytes * pLockBytes, + storeAccessMode eAccessMode, + sal_uInt16 & rnPageSize); virtual sal_Bool SAL_CALL isKindOf (sal_uInt32 nTypeId); @@ -184,6 +114,8 @@ protected: virtual ~OTestBIOS (void); }; +} // namespace store + OTestBIOS::OTestBIOS (void) { } @@ -198,26 +130,14 @@ sal_Bool SAL_CALL OTestBIOS::isKindOf (sal_uInt32 nTypeId) } storeError OTestBIOS::initialize ( - ILockBytes *pLockBytes, storeAccessMode eAccessMode) + ILockBytes *pLockBytes, storeAccessMode eAccessMode, sal_uInt16 & rnPageSize) { - storeError eErrCode = base::initialize (pLockBytes, eAccessMode); - if (eErrCode != store_E_None) - { - if (eAccessMode == store_AccessReadWrite) - return eErrCode; - if (eAccessMode == store_AccessReadOnly) - return eErrCode; - if (eErrCode != store_E_NotExists) - return eErrCode; - - eErrCode = base::create (TEST_PAGESIZE); - } - return eErrCode; + return base::initialize (pLockBytes, eAccessMode, rnPageSize); } namespace store { -static OTestBIOS* SAL_CALL query (IStoreHandle *pHandle, OTestBIOS*) +template<> OTestBIOS* SAL_CALL query (IStoreHandle *pHandle, OTestBIOS*) { if (pHandle && pHandle->isKindOf (4242)) return static_cast(pHandle); @@ -248,15 +168,6 @@ static void __store_test_handle (void* Handle) pObj->isKindOf (42); pObj->release(); } - - store::OStoreHandle xObj ( - store::OStoreHandle::query (Handle)); - if (xObj.is()) - { - xObj->acquire(); - xObj->isKindOf (42); - xObj->release(); - } } /*======================================================================== @@ -274,12 +185,14 @@ static void __store_string_newFromUnicode_WithLength ( OUSTRING_TO_OSTRING_CVTFLAGS); } +#if 0 /* UNSUSED */ static void __store_string_newFromUnicode ( rtl_String **newString, const rtl_uString *value) { __store_string_newFromUnicode_WithLength ( newString, value->buffer, value->length); } +#endif /* UNUSED */ static void __store_string_newFromUnicode ( rtl_String **newString, const sal_Unicode *value) @@ -288,14 +201,6 @@ static void __store_string_newFromUnicode ( newString, value, rtl_ustr_getLength (value)); } -static storeError __store_namei ( - const rtl::OString &rPath, - const rtl::OString &rName, - OStorePageKey &rKey) -{ - return store_E_Unknown; -} - static storeError __store_namei ( const sal_Unicode *pszPath, const sal_Unicode *pszName, @@ -308,14 +213,13 @@ static storeError __store_namei ( __store_string_newFromUnicode (&pszNameA, pszName); storeError eErrCode = store_E_NameTooLong; - if (pszNameA->length < sizeof(sal_Char[STORE_MAXIMUM_NAMESIZE])) + if (pszNameA->length < sal_Int32(sizeof(sal_Char[STORE_MAXIMUM_NAMESIZE]))) { rtl_String *pszPathA = 0; __store_string_newFromUnicode (&pszPathA, pszPath); - typedef OStorePageGuard G; - rKey.m_nLow = G::crc32 (0, pszNameA->buffer, pszNameA->length); - rKey.m_nHigh = G::crc32 (0, pszPathA->buffer, pszPathA->length); + rKey.m_nLow = rtl_crc32 (0, pszNameA->buffer, pszNameA->length); + rKey.m_nHigh = rtl_crc32 (0, pszPathA->buffer, pszPathA->length); rtl_string_release (pszPathA); eErrCode = store_E_None; @@ -418,20 +322,16 @@ int SAL_CALL main (int argc, char **argv) if (argc < 2) return 0; -#if 0 /* EXP */ __store_testUnicode (argv[1]); -#endif /* EXP */ - rtl::Reference xLockBytes (new OFileLockBytes()); - if (!xLockBytes.is()) - return 0; + rtl::Reference xLockBytes; rtl::OUString aFilename ( argv[1], rtl_str_getLength(argv[1]), osl_getThreadTextEncoding()); - storeError eErrCode = xLockBytes->create ( - aFilename.pData, store_AccessReadCreate); + storeError eErrCode = FileLockBytes_createInstance ( + xLockBytes, aFilename.pData, store_AccessReadCreate); if (eErrCode != store_E_None) return eErrCode; @@ -446,7 +346,8 @@ int SAL_CALL main (int argc, char **argv) if (!xBIOS.is()) return 0; - eErrCode = xBIOS->initialize (&*xLockBytes, store_AccessReadWrite); + sal_uInt16 nPageSize = TEST_PAGESIZE; + eErrCode = xBIOS->initialize (&*xLockBytes, store_AccessReadWrite, nPageSize); if (eErrCode != store_E_None) { // Check reason. @@ -454,7 +355,7 @@ int SAL_CALL main (int argc, char **argv) return eErrCode; // Create. - eErrCode = xBIOS->initialize (&*xLockBytes, store_AccessReadCreate); + eErrCode = xBIOS->initialize (&*xLockBytes, store_AccessReadCreate, nPageSize); if (eErrCode != store_E_None) return eErrCode; } @@ -482,4 +383,3 @@ int SAL_CALL main (int argc, char **argv) xBIOS.clear(); return 0; } - diff --git a/store/workben/t_file.cxx b/store/workben/t_file.cxx index e84372352d4d..ea7b6bcd37d2 100644 --- a/store/workben/t_file.cxx +++ b/store/workben/t_file.cxx @@ -31,13 +31,11 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_store.hxx" -#define _T_FILE_CXX "$Revision: 1.8 $" -#include -#include -#include -#include -#include -#include +#include "sal/types.h" +#include "osl/thread.h" +#include "rtl/ustring.hxx" + +#include "lockbyte.hxx" #ifndef INCLUDED_STDIO_H #include @@ -55,39 +53,54 @@ using namespace store; *======================================================================*/ int SAL_CALL main (int argc, char **argv) { - if (argc < 2) - { - fprintf (stderr, "usage: t_file \n"); - return 0; - } - - rtl::Reference xLockBytes (new OFileLockBytes()); - if (!xLockBytes.is()) - return 0; - - rtl::OUString aFilename ( - argv[1], rtl_str_getLength(argv[1]), - osl_getThreadTextEncoding()); + storeError eErrCode = store_E_None; + rtl::Reference xLockBytes; - storeError eErrCode = xLockBytes->create ( - aFilename.pData, store_AccessReadWrite); - if (eErrCode != store_E_None) + if (argc > 1) { - // Check reason. - if (eErrCode != store_E_NotExists) + rtl::OUString aFilename ( + argv[1], rtl_str_getLength(argv[1]), + osl_getThreadTextEncoding()); + + eErrCode = FileLockBytes_createInstance ( + xLockBytes, aFilename.pData, store_AccessReadWrite); + if (eErrCode != store_E_None) { - fprintf (stderr, "t_file: create() error: %d\n", eErrCode); - return eErrCode; - } + // Check reason. + if (eErrCode != store_E_NotExists) + { + fprintf (stderr, "t_file: create() error: %d\n", eErrCode); + return eErrCode; + } - // Create. - eErrCode = xLockBytes->create ( - aFilename.pData, store_AccessReadCreate); + // Create. + eErrCode = FileLockBytes_createInstance ( + xLockBytes, aFilename.pData, store_AccessReadCreate); + if (eErrCode != store_E_None) + { + fprintf (stderr, "t_file: create() error: %d\n", eErrCode); + return eErrCode; + } + } + fprintf (stdout, "t_file: using FileLockBytes(\"%s\") implementation.\n", argv[1]); + } + else + { + eErrCode = MemoryLockBytes_createInstance (xLockBytes); if (eErrCode != store_E_None) { fprintf (stderr, "t_file: create() error: %d\n", eErrCode); return eErrCode; } + fprintf (stdout, "t_file: using MemoryLockBytes implementation.\n"); + } + + rtl::Reference< PageData::Allocator > xAllocator; + eErrCode = xLockBytes->initialize (xAllocator, TEST_PAGESIZE); + if (eErrCode != store_E_None) + { + fprintf (stderr, "t_file: initialize() error: %d\n", eErrCode); + return eErrCode; } sal_Char buffer[TEST_PAGESIZE]; @@ -112,12 +125,12 @@ int SAL_CALL main (int argc, char **argv) for (k = 0; k < 4; k++) { - sal_uInt32 magic = i * 4 + k, done = 0; + sal_uInt32 magic = i * 4 + k; if (magic) { sal_uInt32 verify = 0; eErrCode = xLockBytes->readAt ( - 0, &verify, sizeof(verify), done); + 0, &verify, sizeof(verify)); if (eErrCode != store_E_None) { fprintf (stderr, "t_file: readAt() error: %d\n", eErrCode); @@ -126,13 +139,13 @@ int SAL_CALL main (int argc, char **argv) if (verify != magic) { // Failure. - fprintf (stderr, "Expected %d read %d\n", magic, verify); + fprintf (stderr, "Expected %ld read %ld\n", (unsigned long)(magic), (unsigned long)(verify)); } } sal_uInt32 index = k * TEST_PAGESIZE / 4; eErrCode = xLockBytes->writeAt ( - offset + index, &(buffer[index]), TEST_PAGESIZE / 4, done); + offset + index, &(buffer[index]), TEST_PAGESIZE / 4); if (eErrCode != store_E_None) { fprintf (stderr, "t_file: writeAt() error: %d\n", eErrCode); @@ -141,7 +154,7 @@ int SAL_CALL main (int argc, char **argv) magic += 1; eErrCode = xLockBytes->writeAt ( - 0, &magic, sizeof(magic), done); + 0, &magic, sizeof(magic)); if (eErrCode != store_E_None) { fprintf (stderr, "t_file: writeAt() error: %d\n", eErrCode); @@ -160,9 +173,9 @@ int SAL_CALL main (int argc, char **argv) sal_Char verify[TEST_PAGESIZE]; for (i = 0; i < 256; i++) { - sal_uInt32 offset = i * TEST_PAGESIZE, done = 0; + sal_uInt32 offset = i * TEST_PAGESIZE; - eErrCode = xLockBytes->readAt (offset, verify, TEST_PAGESIZE, done); + eErrCode = xLockBytes->readAt (offset, verify, TEST_PAGESIZE); if (eErrCode != store_E_None) { fprintf (stderr, "t_file: readAt() error: %d\n", eErrCode); @@ -184,11 +197,26 @@ int SAL_CALL main (int argc, char **argv) &verify[index], &buffer[index], TEST_PAGESIZE - index)) { // Failure. - fprintf (stderr, "t_file: Unexpected block at 0x%08x\n", offset); + fprintf (stderr, "t_file: Unexpected block at 0x%08x\n", (unsigned)(offset)); } } + for (i = 0; i < 256; i++) + { + PageHolder xPage; + sal_uInt32 offset = i * TEST_PAGESIZE; + + eErrCode = xLockBytes->readPageAt (xPage, offset); + if (eErrCode != store_E_None) + { + fprintf (stderr, "t_file: readPageAt() error: %d\n", eErrCode); + return eErrCode; + } + + PageData * page = xPage.get(); + (void)page; // UNUSED + } + xLockBytes.clear(); return 0; } - diff --git a/store/workben/t_leak.cxx b/store/workben/t_leak.cxx new file mode 100644 index 000000000000..d4d7b8a840e1 --- /dev/null +++ b/store/workben/t_leak.cxx @@ -0,0 +1,19 @@ +/* + * t_leak.cxx + */ + +#include "sal/main.h" +#include "osl/process.h" +#include "osl/thread.h" + + int main (int /*argc*/, char ** /*argv*/) +//SAL_IMPLEMENT_MAIN() +{ + rtl_Locale * pLocale = 0; + osl_getProcessLocale (&pLocale); +#if 0 + rtl_TextEncoding te = osl_getThreadTextEncoding(); + (void) te; +#endif + return 0; +} diff --git a/store/workben/t_page.cxx b/store/workben/t_page.cxx new file mode 100644 index 000000000000..b488e1ac997b --- /dev/null +++ b/store/workben/t_page.cxx @@ -0,0 +1,1574 @@ +/* + * t_page.cxx + */ + +#include "osl/diagnose.h" +#include "rtl/alloc.h" +#include "rtl/ref.hxx" + +#include "storbase.hxx" + +#include "osl/file.h" +#include "rtl/ustring.hxx" + +/*======================================================================== + * + * OTest... + * + *======================================================================*/ + +template< class T > inline void swap (T & lhs, T & rhs) +{ + T tmp = rhs; rhs = lhs; lhs = tmp; +} + +/*======================================================================*/ + +class SharedCount +{ + long * m_pCount; + + class Allocator + { + rtl_cache_type * m_cache; + + public: + static Allocator & get(); + + long * alloc() + { + return static_cast(rtl_cache_alloc (m_cache)); + } + void free (long * pCount) + { + rtl_cache_free (m_cache, pCount); + } + + protected: + Allocator(); + ~Allocator(); + }; + +public: + SharedCount() + : m_pCount(Allocator::get().alloc()) + { + if (m_pCount != 0) (*m_pCount) = 1; + } + + ~SharedCount() + { + if (m_pCount != 0) + { + long new_count = --(*m_pCount); + if (new_count == 0) + Allocator::get().free(m_pCount); + } + } + + bool operator== (long count) const + { + return (m_pCount != 0) ? *m_pCount == count : false; + } + + friend void swap<> (SharedCount & lhs, SharedCount & rhs); // nothrow + + SharedCount (SharedCount const & rhs); // nothrow + SharedCount & operator= (SharedCount const & rhs); // nothrow +}; + +template<> +inline void swap (SharedCount & lhs, SharedCount & rhs) // nothrow +{ + swap(lhs.m_pCount, rhs.m_pCount); +} + +SharedCount::SharedCount (SharedCount const & rhs) // nothrow + : m_pCount (rhs.m_pCount) +{ + if (m_pCount != 0) ++(*m_pCount); +} + +SharedCount & +SharedCount::operator= (SharedCount const & rhs) // nothrow +{ + SharedCount tmp(rhs); + swap(tmp, *this); + return *this; +} + +SharedCount::Allocator & +SharedCount::Allocator::get() +{ + static Allocator g_aSharedCountAllocator; + return g_aSharedCountAllocator; +} + +SharedCount::Allocator::Allocator() +{ + m_cache = rtl_cache_create ( + "store_shared_count_cache", + sizeof(long), + 0, // objalign + 0, // constructor + 0, // destructor + 0, // reclaim + 0, // userarg + 0, // default source + 0 // flags + ); +} + +SharedCount::Allocator::~Allocator() +{ + rtl_cache_destroy (m_cache), m_cache = 0; +} + +/*======================================================================*/ + +#if 0 /* OLD */ + +typedef store::OStorePageData PageData; + +#else /* NEW */ + +#if defined(OSL_BIGENDIAN) +#define STORE_DWORD(dword) OSL_SWAPDWORD((dword)) +#else +#define STORE_DWORD(dword) (dword) +#endif + +struct PageData +{ + typedef store::OStorePageGuard G; + typedef store::OStorePageDescriptor D; + typedef store::OStorePageLink L; + + /** Representation. + */ + G m_aGuard; + D m_aDescr; + L m_aMarked; + L m_aUnused; + + /** theSize. + */ + static const size_t theSize = sizeof(G) + sizeof(D) + 2 * sizeof(L); + static const sal_uInt16 thePageSize = theSize; + STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= thePageSize); + + /** type. + */ + sal_uInt32 type() const { return m_aGuard.m_nMagic; /* @@@ */ } + + /** offset. + */ + sal_uInt32 offset() const { return m_aDescr.m_nAddr; /* @@@ */ } + void offset (sal_uInt32 nOffset) { m_aDescr.m_nAddr = nOffset; } + + /** size. + */ + sal_uInt16 size() const { return m_aDescr.m_nSize; /* @@@ */ } + + /** Allocation. + */ + class Allocator : public rtl::IReference + { + public: + template< class T > T * construct() + { + void * page = 0; sal_uInt16 size = 0; + if (allocate (&page, &size)) + { + return new(page) T(size); + } + return 0; + } + + virtual bool allocate (void ** ppPage, sal_uInt16 * pnSize) = 0; + virtual void deallocate (void * pPage) = 0; + }; + + static void * operator new (size_t, void * p) { return p; } + static void operator delete (void *, void *) {} + + /** Construction. + */ + explicit PageData (sal_uInt16 nPageSize = thePageSize) + : m_aDescr (STORE_PAGE_NULL, nPageSize, thePageSize) + {} + + /** ... + */ + void guard() + {} + + storeError verify() const + { + return store_E_None; + } +}; + +#endif /* NEW */ + +class IPageAllocator +{ +public: + virtual void deallocate (void * p) = 0; +}; + +class PageAllocator +{ + rtl_cache_type * m_cache; + SharedCount m_refcount; + +public: + PageAllocator() + : m_cache(0), m_refcount() + {} + + ~PageAllocator() + { + // NYI + if (m_refcount == 1) + { + } + } + + friend void swap<>(PageAllocator & lhs, PageAllocator & rhs); + + PageAllocator (PageAllocator const & rhs); + PageAllocator & operator= (PageAllocator const & rhs); +}; + +template<> +inline void swap (PageAllocator & lhs, PageAllocator & rhs) +{ + swap(lhs.m_cache, rhs.m_cache); + swap(lhs.m_refcount, rhs.m_refcount); +} + +PageAllocator::PageAllocator (PageAllocator const & rhs) + : m_cache (rhs.m_cache), + m_refcount (rhs.m_refcount) +{ +} + +PageAllocator & +PageAllocator::operator= (PageAllocator const & rhs) +{ + PageAllocator tmp (rhs); + swap(tmp, *this); + return *this; +} + +/*======================================================================*/ + +class PageHolder +{ + SharedCount m_refcount; + PageData * m_pagedata; + + typedef rtl::Reference< PageData::Allocator > allocator_type; + allocator_type m_allocator; + +public: + explicit PageHolder (PageData * pagedata = 0, allocator_type const & allocator = allocator_type()) + : m_refcount (), + m_pagedata (pagedata), + m_allocator(allocator) + {} + + ~PageHolder() + { + if ((m_refcount == 1) && (m_pagedata != 0) && m_allocator.is()) + { + // free pagedata. + m_allocator->deallocate (m_pagedata); + } + } + + PageData * get() { return m_pagedata; } + PageData const * get() const { return m_pagedata; } + + PageData * operator->() { return m_pagedata; } + PageData const * operator->() const { return m_pagedata; } + + friend void swap<> (PageHolder & lhs, PageHolder & rhs); // nothrow + + PageHolder (PageHolder const & rhs); // nothrow + PageHolder & operator= (PageHolder const & rhs); // nothrow +}; + +template<> +inline void swap (PageHolder & lhs, PageHolder & rhs) // nothrow +{ + swap(lhs.m_refcount, rhs.m_refcount); + swap(lhs.m_pagedata, rhs.m_pagedata); + swap(lhs.m_allocator, rhs.m_allocator); +} + +PageHolder::PageHolder (PageHolder const & rhs) // nothrow + : m_refcount (rhs.m_refcount), + m_pagedata (rhs.m_pagedata), + m_allocator(rhs.m_allocator) +{} + +PageHolder & +PageHolder::operator= (PageHolder const & rhs) // nothrow +{ + PageHolder tmp (rhs); + swap(tmp, *this); + return *this; +} + +/*======================================================================*/ + +template< class T > +class PageHolderObject +{ +protected: + /** Representation. + */ + PageHolder m_xPage; + + /** Checked cast. + */ + template< class U > + static bool isA (PageData const * p) + { + return ((p != 0) && (p->type() == U::theTypeId)); + } + + template< class U > + static U * dynamic_page_cast (PageData * p) + { + return isA(p) ? static_cast(p) : 0; + } + + template< class U > + static U const * dynamic_page_cast (PageData const * p) + { + return isA(p) ? static_cast(p) : 0; + } + +public: + static PageHolderObject construct (rtl::Reference< PageData::Allocator > const & rxAllocator) + { + PageHolderObject tmp; + if (rxAllocator.is()) + { + PageHolder xPage (rxAllocator->construct(), rxAllocator); + store::swap(tmp.m_xPage, xPage); + } + return tmp; + } + + explicit PageHolderObject (PageHolder const & rxPage = PageHolder()) + : m_xPage (rxPage) + {} + + void swap (PageHolderObject & rhs) + { + store::swap(m_xPage, rhs.m_xPage); + } + + PageHolderObject (PageHolderObject const & rhs) + : m_xPage (rhs.m_xPage) + { + } + + PageHolderObject & operator= (PageHolderObject const & rhs) + { + PageHolderObject tmp (rhs); + this->swap(tmp); + return *this; + } + + T * operator->() + { + T * pImpl = dynamic_page_cast(m_xPage.get()); + OSL_PRECOND(pImpl != 0, "store::PageHolder::operator->(): Null pointer"); + return pImpl; + } + T const * operator->() const + { + T const * pImpl = dynamic_page_cast(m_xPage.get()); + OSL_PRECOND(pImpl != 0, "store::PageHolder::operator->(): Null pointer"); + return pImpl; + } + + T & operator*() + { + T * pImpl = dynamic_page_cast(m_xPage.get()); + OSL_PRECOND(pImpl != 0, "store::PageHolder::operator*(): Null pointer"); + return *pImpl; + } + T const & operator*() const + { + T const * pImpl = dynamic_page_cast(m_xPage.get()); + OSL_PRECOND(pImpl != 0, "store::PageHolder::operator*(): Null pointer"); + return *pImpl; + } + + static storeError guard (PageHolder & rxPage) + { + T * pImpl = dynamic_page_cast(rxPage.get()); + if (pImpl != 0) + { pImpl->guard(); return store_E_None; } + else if (rxPage.get() != 0) + return store_E_WrongVersion; + else + return store_E_InvalidAccess; + } + static storeError verify (PageHolder const & rxPage) + { + T const * pImpl = dynamic_page_cast(rxPage.get()); + if (pImpl != 0) + return pImpl->verify(); + else if (rxPage.get() != 0) + return store_E_WrongVersion; + else + return store_E_InvalidAccess; + } +}; + +/*======================================================================*/ + +class PageObject +{ +public: + explicit PageObject (PageHolder const & rxPage = PageHolder()) + : m_xPage (rxPage) + {} + + virtual ~PageObject(); + + PageHolder & get() { return m_xPage; } + PageHolder const & get() const { return m_xPage; } + + PageData * operator->() + { + PageData * pImpl = m_xPage.get(); + OSL_PRECOND(pImpl != 0, "store::PageObject::operator->(): Null pointer"); + return pImpl; + } + PageData & operator*() + { + PageData * pImpl = m_xPage.get(); + OSL_PRECOND(pImpl != 0, "store::PageObject::operator*(): Null pointer"); + return *pImpl; + } + + virtual void guard(); + virtual storeError verify() const; + +protected: + PageHolder m_xPage; +}; + +PageObject::~PageObject() +{} +void PageObject::guard() +{ + PageData * p = m_xPage.get(); + p->guard(); +} +storeError PageObject::verify() const +{ + PageData const * p = m_xPage.get(); + return p->verify(); +} + +/*======================================================================*/ + +template< class T > +T * dynamic_page_cast (PageData * pagedata) +{ + if ((pagedata != 0) && (pagedata->type() == T::theTypeId)) + return static_cast(pagedata); + return 0; +} + +template< class T > +T * dynamic_page_cast (PageData const * pagedata) +{ + if ((pagedata != 0) && (pagedata->type() == T::theTypeId)) + return static_cast(pagedata); + return 0; +} + +/*======================================================================*/ + +class TestBIOS +{ +public: + storeError loadPageAt (PageHolder & rPage, storeError (*pfnVerify)(PageHolder const &)) + { + return (pfnVerify)(rPage); + } + + storeError allocate (PageHolder & rxPage, ...) + { + // NYI: PageObject.save(nAddr, *this); + (void)rxPage; // NYI + return store_E_Unknown; // NYI + } + + storeError loadAt (PageHolder & rPage, sal_uInt32 nOffset) + { + (void)rPage; // NYI + (void)nOffset; // NYI + return store_E_Unknown; // NYI + } + storeError saveAt (PageHolder const & rPage, sal_uInt32 nOffset) + { + (void)rPage; // NYI + (void)nOffset; // NYI + return store_E_Unknown; // NYI + } + + template< class T > + storeError save (PageHolder & rxPage, sal_uInt32 nOffset) + { + storeError result = PageHolderObject::guard (rxPage); + if (result != store_E_None) + return result; + return saveAt (rxPage, nOffset); + } + + storeError lookupAt (PageHolder & rPage, sal_uInt32 nOffset) + { + (void)rPage; // NYI + (void)nOffset; // NYI + return store_E_NotExists; + } + storeError replaceAt (PageHolder const & rPage, sal_uInt32 nOffset) + { + (void)rPage; // NYI + (void)nOffset; // NYI + return store_E_None; + } +}; + +struct TestDataV1 : public PageData +{ + static const sal_uInt32 theTypeId = 6 * 9; +}; +struct TestData : public PageData +{ + typedef PageData base; + typedef TestData self; + + static const sal_uInt32 theTypeId = 42; + + void guard() + { + base::guard(); + // self::m_aGuard = ...; + } + storeError verify() const + { + storeError result = base::verify(); + if (result != store_E_None) + return result; + if (!(base::type() == self::theTypeId)) + return store_E_WrongVersion; + return store_E_None; + } + + storeError dwim() const + { + return store_E_None; + } +}; +class TestObject : public PageObject +{ + typedef PageObject base; + +public: + + void dwim() + { + PageHolderObject< TestData > xPage (m_xPage); + xPage->guard(); + } + + virtual void guard() + { + TestData * pagedata = dynamic_page_cast< TestData >(m_xPage.get()); + if (pagedata != 0) + {} + } + virtual storeError verify() const + { + storeError result = base::verify(); + if (result != store_E_None) + return result; + + TestData const * pagedata = dynamic_page_cast< TestData const >(m_xPage.get()); + if (!pagedata) + return store_E_WrongVersion; + + return pagedata->verify(); + } + + static storeError verify (PageHolder const & rPage) + { + return PageHolderObject< TestData >::verify (rPage); + } + + storeError loadAt (sal_uInt32 nOffset, TestBIOS & rBIOS) + { + storeError result = rBIOS.lookupAt (m_xPage, nOffset); // cache lookup + if (result == store_E_NotExists) + { + result = rBIOS.loadAt (m_xPage, nOffset); + if (result != store_E_None) + return result; + + result = PageHolderObject< TestData >::verify (m_xPage); + if (result != store_E_None) + return result; + + result = rBIOS.replaceAt (m_xPage, nOffset); // cache insert + } + return result; + } + storeError saveAt (sal_uInt32 nOffset, TestBIOS & rBIOS) + { + if (!m_xPage.get()) + return store_E_InvalidAccess; + m_xPage->m_aDescr.m_nAddr = store::htonl(nOffset); // m_xPage->location (nOffset); + + storeError result = PageHolderObject< TestData >::guard (m_xPage); + if (result != store_E_None) + return result; + + result = rBIOS.saveAt (m_xPage, nOffset); + if (result != store_E_None) + return result; + + return rBIOS.replaceAt (m_xPage, nOffset); // cache update + } +}; + +class TestObjectV2 : public PageHolderObject< TestData > +{ + typedef PageHolderObject< TestData > base; + +public: + storeError saveAt (sal_uInt32 nOffset, TestBIOS & rBIOS) + { + m_xPage->offset(nOffset); + + storeError result = PageHolderObject< TestData >::guard (m_xPage); + if (result != store_E_None) + return result; + + result = rBIOS.saveAt (m_xPage, nOffset); + if (result != store_E_None) + return result; + + return rBIOS.replaceAt (m_xPage, nOffset); + } +#if 1 + storeError dwim() const + { + TestData const * pImpl1 = operator->(); + + PageHolderObject< TestData > xImpl (m_xPage); + + TestData const * pImpl2 = &*xImpl; + OSL_ASSERT(pImpl1 == pImpl2); + + return xImpl->dwim(); + } +#endif +}; + +class TestClient +{ +public: + void dwim(TestBIOS & rBIOS) + { + TestObject aObj; + + rBIOS.loadPageAt(aObj.get(), &aObj.verify); + rBIOS.loadPageAt(aObj.get(), TestObject::verify); + rBIOS.loadPageAt(aObj.get(), PageHolderObject::verify); + + aObj.loadAt (1024, rBIOS); + + TestObjectV2 aObj2; + aObj2.dwim(); + aObj2->dwim(); + } +}; + +/*======================================================================*/ +#if 0 /* NYI */ +BIOS::load (PageObject & rPage, sal_uInt32 nOffset) +{ + result = m_xCache->readPageAt (rPage.get(), nOffset); + if (result == NotExists) + { + result = m_xLockBytes->readPageAt (rPage.get(), nOffset); + if (result != None) + return result; + + result = rPage.verify(); + if (result != None) + return result; + + result = m_xCache->writePageAt (rPage.get(), nOffset); + } + return result; +} +BIOS::save (PageObject & rPage, sal_uInt32 nOffset) +{ + rPage.guard(); + result = m_xLockBytes->writePageAt (rPage.get(), nOffset); + if (result != None) + return result; + + return m_xCache->writePageAt (rPage.get(), nOffset); +} +BIOS::init (rxLockBytes, eAccessMode, nPageSize) +{ + SuperPage super; + if (eAccessMode == store_AccessCreate) + { + sal_uInt16 pagesize = nPageSize; + if ((STORE_MINIMUM_PAGESIZE > pagesize) || (pagesize > STORE_MAXIMUM_PAGESIZE)) + return store_E_InvalidParameter; + + pagesize = ((pagesize + STORE_MINIMUM_PAGESIZE - 1) & ~(STORE_MINIMUM_PAGESIZE - 1)); + rxLockBytes->init (pagesize); + + super = allocator->construct(); + super->guard(); + + rxLockBytes->writeAt (0, super, super->size()); + + } + if (eAccessMode != store_AccessCreate) + { + rxLockBytes->readAt (0, &super, super::theSize); + + super.verify(); + } + if (eErrCode != store_E_NotExists) + + +} +#endif /* NYI */ +/*======================================================================*/ + +#if 0 /* NYI */ +class PageCache +{ + std::set m_pages; +public: + storeError readPageAt (PageObject & rPage, sal_uInt32 nOffset); + storeError writePageAt (PageObject const & rPage, sal_uInt32 nOffset); +}; +#endif /* NYI */ + +/*======================================================================*/ + +class IPageAllocator; +class IPageAccess +{ +public: + virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize) = 0; + virtual IPageAllocator & getAllocator () = 0; + +public: + storeError readPageAt (PageHolder & rPage, sal_uInt32 nOffset) + { + return readPageAt_Impl (rPage, nOffset); + } + storeError writePageAt (PageHolder const & rPage, sal_uInt32 nOffset) + { + // [SECURITY:ValInput] + PageData const * pagedata = rPage.get(); + OSL_PRECOND(!(pagedata == 0), "invalid Page"); + if (pagedata == 0) + return store_E_InvalidParameter; + + sal_uInt32 const offset = pagedata->offset(); + OSL_PRECOND(!(nOffset != offset), "inconsistent Offset"); + if (nOffset != offset) + return store_E_InvalidParameter; + + OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::IPageAccess::writePageAt(): invalid Offset"); + if (nOffset == STORE_PAGE_NULL) + return store_E_CantSeek; + + return writePageAt_Impl (rPage, nOffset); + } + + storeError peekAt (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes) + { + // [SECURITY:ValInput] + sal_uInt8 * dst_lo = static_cast(pBuffer); + if (!(dst_lo != 0)) + return store_E_InvalidParameter; + + sal_uInt8 * dst_hi = dst_lo + nBytes; + if (!(dst_lo < dst_hi)) + return (dst_lo > dst_hi) ? store_E_InvalidParameter : store_E_None; + + sal_uInt64 const dst_size = nOffset + nBytes; + if (dst_size > SAL_MAX_UINT32) + return store_E_CantSeek; + + return peekAt_Impl (nOffset, dst_lo, (dst_hi - dst_lo)); + } + + storeError pokeAt (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes) + { + // [SECURITY:ValInput] + sal_uInt8 const * src_lo = static_cast(pBuffer); + if (!(src_lo != 0)) + return store_E_InvalidParameter; + + sal_uInt8 const * src_hi = src_lo + nBytes; + if (!(src_lo < src_hi)) + return (src_lo > src_hi) ? store_E_InvalidParameter : store_E_None; + + sal_uInt64 const dst_size = nOffset + nBytes; + if (dst_size > SAL_MAX_UINT32) + return store_E_CantSeek; + + return pokeAt_Impl (nOffset, src_lo, (src_hi - src_lo)); + } + + storeError getSize (sal_uInt32 & rnSize) + { + rnSize = 0; + return getSize_Impl (rnSize); + } + + storeError setSize (sal_uInt32 nSize) + { + return setSize_Impl (nSize); + } + +private: + virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset) = 0; + virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset) = 0; + + virtual storeError peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes) = 0; + virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes) = 0; + + virtual storeError getSize_Impl (sal_uInt32 & rnSize) = 0; + virtual storeError setSize_Impl (sal_uInt32 nSize) = 0; +}; + +/*======================================================================*/ + +template< class T > struct ResourceHolder +{ + typedef typename T::destructor_type destructor_type; + + T m_value; + + explicit ResourceHolder (T const & value = T()) : m_value (value) {} + ~ResourceHolder() { reset(); } + + T & get() { return m_value; } + T const & get() const { return m_value; } + + void set (T const & value) { m_value = value; } + void reset (T const & value = T()) + { + T tmp (m_value); + if (tmp != value) + destructor_type()(tmp); + set (value); + } + T release() + { + T tmp (m_value); + set (T()); + return tmp; + } + + ResourceHolder (ResourceHolder & rhs) + { + set (rhs.release()); + } + ResourceHolder & operator= (ResourceHolder & rhs) + { + reset (rhs.release()); + return *this; + } +}; + +struct FileHandle +{ + oslFileHandle m_handle; + + FileHandle() : m_handle(0) {} + + operator oslFileHandle() { return m_handle; } + + bool operator != (FileHandle const & rhs) + { + return (m_handle != rhs.m_handle); + } + + oslFileError initialize (rtl_uString * pFilename, sal_uInt32 nFlags) + { + // Verify arguments. + if (!pFilename || !nFlags) + return osl_File_E_INVAL; + + // Convert into FileUrl. + rtl::OUString aFileUrl; + if (osl_getFileURLFromSystemPath (pFilename, &(aFileUrl.pData)) != osl_File_E_None) + { + // Not system path. Maybe a file url, already. + rtl_uString_assign (&(aFileUrl.pData), pFilename); + } + + // Acquire handle. + return osl_openFile (aFileUrl.pData, &m_handle, nFlags); + } + + struct CloseFile + { + void operator()(FileHandle & rFile) const + { + if (rFile.m_handle != 0) + { + // Release handle. + (void) osl_closeFile (rFile.m_handle); + rFile.m_handle = 0; + } + } + }; + typedef CloseFile destructor_type; +}; + +struct FileMapping +{ + void * m_pAddr; + sal_uInt64 m_uSize; + + FileMapping() : m_pAddr(0), m_uSize(0) {} + + bool operator != (FileMapping const & rhs) const + { + return ((m_pAddr != rhs.m_pAddr) || (m_uSize != rhs.m_uSize)); + } + + oslFileError initialize (oslFileHandle hFile) + { + // Determine mapping size. + oslFileError result = osl_getFileSize (hFile, &m_uSize); + if (result != osl_File_E_None) + return result; + if (m_uSize > SAL_MAX_UINT32) + return osl_File_E_OVERFLOW; + + // Acquire mapping. + return osl_mapFile (hFile, &m_pAddr, m_uSize, 0, 0); + } + + struct UnmapFile + { + void operator ()(FileMapping & rMapping) const + { + if ((rMapping.m_pAddr != 0) && (rMapping.m_uSize != 0)) + { + // Release mapping. + (void) osl_unmapFile (rMapping.m_pAddr, rMapping.m_uSize); + rMapping.m_pAddr = 0, rMapping.m_uSize = 0; + } + } + }; + typedef UnmapFile destructor_type; +}; + +/*======================================================================*/ + +class FilePageAccess : public IPageAccess +{ + oslFileHandle m_hFile; + +public: + static storeError ERROR_FROM_NATIVE (oslFileError eErrno); + static sal_uInt32 MODE_TO_NATIVE (storeAccessMode eMode); + +public: + explicit FilePageAccess (oslFileHandle hFile = 0) : m_hFile (hFile) {} + virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize); + +private: + virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset); + virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset); + + /* see @ OFileLockBytes */ + virtual storeError peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes); + virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes); + + virtual storeError getSize_Impl (sal_uInt32 & rnSize); + virtual storeError setSize_Impl (sal_uInt32 nSize); + +protected: + virtual ~FilePageAccess(); + +private: + /** Not implemented. + */ + FilePageAccess (FilePageAccess const &); + FilePageAccess & operator= (FilePageAccess const &); +}; + +storeError FilePageAccess::initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize) +{ + (void) eAccessMode; // UNUSED + (void) nPageSize; // UNUSED + return store_E_Unknown; // NYI +} +FilePageAccess::~FilePageAccess() +{ + if (m_hFile != 0) + (void) osl_closeFile (m_hFile); +} +storeError FilePageAccess::readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset) +{ + PageHolder page (0/*allocate()*/); /* @@@ construct w/ deallocator argument @@@ */ + if (!page.get()) + return store_E_OutOfMemory; + + swap(page, rPage); + return peekAt (nOffset, rPage.get(), 0/*size*/); +} +storeError FilePageAccess::writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset) +{ + return pokeAt (nOffset, rPage.get(), 0/*size*/); +} +storeError FilePageAccess::peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes) +{ + sal_uInt64 nDone = 0; + oslFileError result = osl_readFileAt (m_hFile, nOffset, pBuffer, nBytes, &nDone); + if (result != osl_File_E_None) + return ERROR_FROM_NATIVE(result); + if (nDone != nBytes) + return (nDone != 0) ? store_E_CantRead : store_E_NotExists; + return store_E_None; +} +storeError FilePageAccess::pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes) +{ + sal_uInt64 nDone = 0; + oslFileError result = osl_writeFileAt (m_hFile, nOffset, pBuffer, nBytes, &nDone); + if (result != osl_File_E_None) + return ERROR_FROM_NATIVE(result); + if (nDone != nBytes) + return store_E_CantWrite; + return store_E_None; +} +storeError FilePageAccess::getSize_Impl (sal_uInt32 & rnSize) +{ + sal_uInt64 uSize = 0; + oslFileError result = osl_getFileSize (m_hFile, &uSize); + if (result != osl_File_E_None) + return ERROR_FROM_NATIVE(result); + if (uSize > SAL_MAX_UINT32) + return store_E_CantSeek; + + rnSize = sal::static_int_cast(uSize); + return store_E_None; +} +storeError FilePageAccess::setSize_Impl (sal_uInt32 nSize) +{ + oslFileError result = osl_setFileSize (m_hFile, nSize); + if (result != osl_File_E_None) + return ERROR_FROM_NATIVE(result); + return store_E_None; +} +storeError FilePageAccess::ERROR_FROM_NATIVE (oslFileError eErrno) +{ + switch (eErrno) + { + case osl_File_E_None: + return store_E_None; + + case osl_File_E_NOENT: + return store_E_NotExists; + + case osl_File_E_ACCES: + case osl_File_E_PERM: + return store_E_AccessViolation; + + case osl_File_E_AGAIN: + case osl_File_E_DEADLK: + return store_E_LockingViolation; + + case osl_File_E_BADF: + return store_E_InvalidHandle; + + case osl_File_E_INVAL: + return store_E_InvalidParameter; + + case osl_File_E_NOSPC: + return store_E_OutOfSpace; + + case osl_File_E_OVERFLOW: + return store_E_CantSeek; + + default: + return store_E_Unknown; + } +} +sal_uInt32 FilePageAccess::MODE_TO_NATIVE(storeAccessMode eAccessMode) +{ + sal_uInt32 nMode = 0; + switch (eAccessMode) + { + case store_AccessCreate: + case store_AccessReadCreate: + nMode |= osl_File_OpenFlag_Create; + // fall through + case store_AccessReadWrite: + nMode |= osl_File_OpenFlag_Write; + // fall through + case store_AccessReadOnly: + nMode |= osl_File_OpenFlag_Read; + break; + default: + OSL_PRECOND(0, "store::FilePageAccess: unknown storeAccessMode"); + } + return nMode; +} + +/*===*/ + +class MemoryPageAccess : public IPageAccess +{ + /** Representation. + */ + sal_uInt8 * m_pData; + sal_uInt32 m_nSize; + + /** Callback function to release Representation. + */ + typedef void (*destructor_type)(sal_uInt8 * pData, sal_uInt32 nSize); + destructor_type m_destructor; + + /** Default destructor callback. + */ + static void freeMemory (sal_uInt8 * pData, sal_uInt32 nSize); + +public: + MemoryPageAccess() + : m_pData (0), m_nSize (0), m_destructor (MemoryPageAccess::freeMemory) + {} + MemoryPageAccess (sal_uInt8 * pData, sal_uInt32 nSize, destructor_type destructor = MemoryPageAccess::freeMemory) + : m_pData (pData), m_nSize (nSize), m_destructor (destructor) + {} + + virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize); + +private: + /** Page (size aligned) access. + */ + virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset); + virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset); + + /** Low level access. + */ + virtual storeError peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes); + virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes); + + virtual storeError getSize_Impl (sal_uInt32 & rnSize); + virtual storeError setSize_Impl (sal_uInt32 nSize); + +protected: + virtual ~MemoryPageAccess(); + +private: + /** Not implemented. + */ + MemoryPageAccess (MemoryPageAccess const &); + MemoryPageAccess & operator= (MemoryPageAccess const &); +}; + +storeError MemoryPageAccess::initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize) +{ + (void) eAccessMode; // UNUSED + (void) nPageSize; // UNUSED + return store_E_Unknown; // NYI +} +MemoryPageAccess::~MemoryPageAccess() +{ + if (m_destructor != 0) + { + // release resource. + (*m_destructor)(m_pData, m_nSize); + } +} +storeError MemoryPageAccess::readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset) +{ + /* OSL_PRECOND(nOffset % size == 0, "Unaligned page read."); */ + PageHolder page (reinterpret_cast< PageData* >(m_pData + nOffset)); + swap(page, rPage); + return store_E_None; +} +storeError MemoryPageAccess::writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset) +{ + PageData const * pagedata = rPage.get(); + if (!(pagedata != 0)) + return store_E_InvalidParameter; + +#if 0 /* NYI */ + sal_uInt16 const bytes = pagedata->size(); // Descr.m_nSize; + OSL_ASSERT(bytes >= PageData::thePageSize); + + offset = rPage.location(); // Descr.m_nAddr; + OSL_ASSERT(nOffset == offset); + + OSL_PRECOND(offset % bytes == 0, "Unaligned page write."); +#endif /* NYI */ + return pokeAt (nOffset, pagedata, pagedata->size()); +} +storeError MemoryPageAccess::peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes) +{ + // [SECURITY:ValInput] + sal_uInt8 * dst_lo = static_cast(pBuffer); + if (!(dst_lo != 0)) + return store_E_InvalidParameter; + + sal_uInt8 * dst_hi = dst_lo + nBytes; + if (!(dst_lo <= dst_hi)) + return store_E_InvalidParameter; + + // ... + sal_uInt8 const * src_lo = m_pData + nOffset; + if (!(src_lo <= m_pData + m_nSize)) + return store_E_CantSeek; + + sal_uInt8 const * src_hi = src_lo + nBytes; + if (!(src_hi <= m_pData + m_nSize)) + return store_E_CantRead; + + // copy. + memcpy (pBuffer, src_lo, (src_hi - src_lo)); + return store_E_None; +} +storeError MemoryPageAccess::pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes) +{ + // [SECURITY:ValInput] + sal_uInt8 const * src_lo = static_cast(pBuffer); + if (!(src_lo != 0)) + return store_E_InvalidParameter; + + sal_uInt8 const * src_hi = src_lo + nBytes; + if (!(src_lo <= src_hi)) + return store_E_InvalidParameter; + + sal_uInt64 const uSize = nOffset + nBytes; + if (uSize > SAL_MAX_UINT32) + return store_E_CantSeek; + + // ... + if (uSize > m_nSize) + { + // increase size. + storeError eErrCode = setSize (sal::static_int_cast(uSize)); + if (eErrCode != store_E_None) + return eErrCode; + } + + sal_uInt8 * dst_lo = m_pData + nOffset; + if (!(dst_lo <= m_pData + m_nSize)) + return store_E_CantSeek; + + sal_uInt8 * dst_hi = dst_lo + nBytes; + if (!(dst_hi <= m_pData + m_nSize)) + return store_E_CantWrite; + + // copy. + memcpy (dst_lo, src_lo, (src_hi - src_lo)); + return store_E_None; +} +storeError MemoryPageAccess::getSize_Impl (sal_uInt32 & rnSize) +{ + rnSize = m_nSize; + return store_E_None; +} +storeError MemoryPageAccess::setSize_Impl (sal_uInt32 nSize) +{ + if (nSize != m_nSize) + { + sal_uInt8 * pData = static_cast(rtl_reallocateMemory (m_pData, nSize)); + if (pData != 0) + { + if (nSize > m_nSize) + memset (pData + m_nSize, 0, sal::static_int_cast< size_t >(nSize - m_nSize)); + } + else + { + if (nSize != 0) + return store_E_OutOfMemory; + } + m_pData = pData, m_nSize = nSize; + } + return store_E_None; +} +void MemoryPageAccess::freeMemory (sal_uInt8 * pData, sal_uInt32 /*nSize*/) +{ + rtl_freeMemory (pData); +} + +/*===*/ + +class MappedPageAccess : public MemoryPageAccess +{ + /** @see MemoryPageAccess::destructor_type callback function. + */ + static void unmapFile (sal_uInt8 * pData, sal_uInt32 nSize); + +public: + MappedPageAccess (sal_uInt8 * pData, sal_uInt32 nSize); + + virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize); + + virtual storeError writePageAt (PageHolder const & rPage, sal_uInt32 nOffset); + +private: + virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes); + virtual storeError setSize_Impl (sal_uInt32 nSize); + +protected: + virtual ~MappedPageAccess() {} +}; + +MappedPageAccess::MappedPageAccess (sal_uInt8 * pData, sal_uInt32 nSize) + : MemoryPageAccess (pData, nSize, MappedPageAccess::unmapFile) +{ +} +storeError MappedPageAccess::initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize) +{ + OSL_PRECOND(eAccessMode == store_AccessReadOnly, "store::MappedPageAccess: invalid AccessMode"); + return MemoryPageAccess::initialize (eAccessMode, nPageSize); +} +storeError MappedPageAccess::writePageAt (PageHolder const & /*rPage*/, sal_uInt32 /*nOffset*/) +{ + return store_E_AccessViolation; +} +storeError MappedPageAccess::pokeAt_Impl (sal_uInt32 /*nOffset*/, void const * /*pBuffer*/, sal_uInt32 /*nBytes*/) +{ + return store_E_AccessViolation; +} +storeError MappedPageAccess::setSize_Impl (sal_uInt32 /*nSize*/) +{ + return store_E_AccessViolation; +} +void MappedPageAccess::unmapFile (sal_uInt8 * pData, sal_uInt32 nSize) +{ + (void) osl_unmapFile (pData, nSize); +} + +#if 0 /* NYI */ +storeError MemoryPageAccess_createInstance ( + rtl::Reference< IPageAccess > & rxPageAccess, + storeAccessMode eAccessMode, + sal_uInt16 nPageSize +) +{ + rxPageAccess = new MemoryPageAccess(); + if (!rxPageAccess.is()) + return store_E_OutOfMemory; + + return rxPageAccess->initialize (eAccessMode, nPageSize); +} + +storeError FilePageAccess_createInstance ( + rtl::Reference< IPageAccess > & rxPageAccess, + rtl_uString * pFilename, + storeAccessMode eAccessMode, + sal_uInt16 nPageSize +) +{ + // Acquire file handle. + ResourceHolder xFile; + result = xFile.get().initialize (pFilename, MODE_TO_NATIVE(eAccessMode)); + if (result != osl_File_E_None) + return ERROR_FROM_NATIVE(result); + + if (eAccessMode == store_AccessReadOnly) + { + ResourceHolder xMapping; + result = xMapping.get().initialize (xFile.get()); + if (result == osl_File_E_None) + { + const sal_uInt32 nSize = sal::static_int_cast(xMapping.get().m_uSize); + rxPageAccess = new MappedPageAccess (xMapping.get().m_pAddr, nSize); + if (!rxPageAccess.is()) + return store_E_OutOfMemory; + (void) xMapping.release(); + } + } + if (!rxPageAccess.is()) + { + rxPageAccess = new FilePageAccess (xFile.get()); + if (!rxPageAccess.is()) + return store_E_OutOfMemory; + (void) xFile.release(); + } + return rxPageAccess->initialize (eAccessMode, nPageSize); +} +#endif /* NYI */ + +/*======================================================================== + * + * test... + * + *======================================================================*/ +#if 0 /* NYI */ + +struct IDataBlock +{ + virtual sal_uInt16 singleCount() const = 0; + virtual sal_uInt32 singleLink (sal_uInt16 nIndex) const = 0; + virtual void singleLink (sal_uInt16 nIndex, sal_uInt32 nAddr) = 0; + + virtual storeError get() = 0; + virtual storeError put() = 0; + virtual storeError truncate() = 0; +}; + +struct InodePageData : public PageData +{ + virtual INameBlock & getNameBlock() = 0; + virtual IDataBlock & getDataBlock() = 0; +}; + +template< class page_data_type > +page_data_type * query (PageData *, page_data_type *); + +template<> InodePageDataV2* +query (PageData & rData, InodePageDataV2 *) +{ + if (rData.isKindOf(InodePageDataV2::m_nTypeId)) + return static_cast(&rData); + return 0; +} + +class InodePageObject : public PageObject +{ +public: + static InodePageObject createInstance (PageData & rData) + { + if (query(&rData, static_cast(0))) + return InodePageObjectV2 (static_cast(rData)); + else if (query(&rData, static_cast(0))) + return InodePageObjectV1 (static_cast(rData)); + } +}; + +#endif /* NYI */ + +/*======================================================================== + * + * main. + * + *======================================================================*/ + +#include + +#if 0 /* EXP */ +class Interface +{ +public: + virtual void deallocate(void *) /* = 0 */; +}; + +class Implementation : public Interface +{ + SharedCount m_count; + +public: + Implementation() : Interface() { printf("Ctor(%p)\n", this); } + ~Implementation() { printf("Dtor(%p)\n", this); } + + Implementation (Implementation const & rhs) : Interface(), m_count (rhs.m_count) { printf("CopyCtor(%p)\n", this); } + + virtual void deallocate(void *) {} +}; + +Interface Interface_createInstance() +{ + Implementation aInst; + return aInst; +} +#endif /* EXP */ + +int SAL_CALL main (int argc, char ** argv) +{ + OSL_PRECOND(argc >= 1, "t_page: error: insufficient number of arguments."); + if (argc < 1) + return 0; + + { + void *a = (void*)1, *b = (void*)2; + swap(a, b); + } + { + PageObject a; + PageObject b (a); + PageObject c; + + c = b; + a = a; + + } + { + TestBIOS aBIOS; + TestClient aClient; + aClient.dwim (aBIOS); + } +#if 0 /* EXP */ + { + Interface aIfc1 (Interface_createInstance()); + Interface aIfc2 (aIfc1); + } +#endif /* EXP */ + + if (argc > 1) + { + rtl_uString * pFilename = 0; + rtl_uString_newFromAscii (&pFilename, argv[1]); + storeAccessMode eAccessMode = store_AccessReadOnly; + + // Acquire file handle. + ResourceHolder h1; + oslFileError result = h1.get().initialize (pFilename, FilePageAccess::MODE_TO_NATIVE(eAccessMode)); + if (result == osl_File_E_None) + { + ResourceHolder h2 (h1); + h1 = h2; + + if (eAccessMode == store_AccessReadOnly) + { + ResourceHolder m1; + result = m1.get().initialize (h1.get()); + + const sal_uInt32 nSize = sal::static_int_cast(m1.get().m_uSize); + (void) nSize; // UNUSED + + ResourceHolder m2 (m1); + m1 = m2; + + result = osl_File_E_None; + } + } + } + + return 0; +} diff --git a/store/workben/t_store.cxx b/store/workben/t_store.cxx index d8d0d73e02b1..cabd301cd5d2 100644 --- a/store/workben/t_store.cxx +++ b/store/workben/t_store.cxx @@ -31,7 +31,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_store.hxx" -#define _T_STORE_CXX "$Revision: 1.7 $" +#define _T_STORE_CXX "$Revision: 1.7.8.2 $" #include #include #include @@ -50,7 +50,7 @@ extern "C" } #endif /* PROFILE */ -using namespace rtl; +using rtl::OUString; /*======================================================================== * @@ -144,8 +144,8 @@ class DirectoryTraveller : public Directory::traveller OUString m_aPath; sal_uInt32 m_nOptions; - sal_uInt32 m_nLevel; - sal_uInt32 m_nCount; + unsigned int m_nLevel; + unsigned int m_nCount; public: DirectoryTraveller ( @@ -153,7 +153,7 @@ public: const OUString &rPath, const OUString &rName, sal_uInt32 nOptions, - sal_uInt32 nLevel = 0); + unsigned int nLevel = 0); virtual ~DirectoryTraveller (void); @@ -168,7 +168,7 @@ DirectoryTraveller::DirectoryTraveller ( const OUString &rPath, const OUString &rName, sal_uInt32 nOptions, - sal_uInt32 nLevel) + unsigned int nLevel) : m_aFile (rFile), m_aPath (rPath), m_nOptions (nOptions), @@ -194,10 +194,10 @@ sal_Bool DirectoryTraveller::visit (const iter& it) m_nCount++; if (m_nOptions & OPTION_DUMP) { - OString aName (it.m_pszName, it.m_nLength, RTL_TEXTENCODING_UTF8); + rtl::OString aName (it.m_pszName, it.m_nLength, RTL_TEXTENCODING_UTF8); printf ("Visit(%d,%d): %s [0x%08x] %d [Bytes]\n", m_nLevel, m_nCount, - aName.pData->buffer, it.m_nAttrib, it.m_nSize); + aName.pData->buffer, (unsigned int)(it.m_nAttrib), (unsigned int)(it.m_nSize)); } if (it.m_nAttrib & STORE_ATTRIB_ISDIR) { @@ -233,7 +233,7 @@ int SAL_CALL main (int argc, char **argv) #if (defined(WNT) && defined(PROFILE)) StartCAP(); #else - OTime aStartTime (OTime::getSystemTime()); + OTime aMainStartTime (OTime::getSystemTime()); #endif /* PROFILE */ store::OStoreFile aFile; @@ -368,7 +368,7 @@ int SAL_CALL main (int argc, char **argv) OTime aStartTime (OTime::getSystemTime()); #endif /* PROFILE */ - for (sal_Int32 i = 0; i < _DEMOSTOR_LOOPS; i++) + for (int i = 0; i < _DEMOSTOR_LOOPS; i++) { OUString aName (RTL_CONSTASCII_USTRINGPARAM("demostor-")); aName += OUString::valueOf ((sal_Int32)(i + 1), 10); @@ -384,13 +384,19 @@ int SAL_CALL main (int argc, char **argv) store::OStoreStream aStream; eErrCode = aStream.create (aFile, aPath, aName, eMode); if (eErrCode != store_E_None) + { + OSL_TRACE("OStoreStream(%d)::create(): error: %d", i, eErrCode); break; + } if (nOptions & OPTION_TRUNC) { eErrCode = aStream.setSize(0); if (eErrCode != store_E_None) + { + OSL_TRACE("OStoreStream(%d)::setSize(0): error: %d", i, eErrCode); break; + } } sal_uInt32 nDone = 0; @@ -399,7 +405,10 @@ int SAL_CALL main (int argc, char **argv) eErrCode = aStream.writeAt ( 0, pBuffer, sizeof(pBuffer), nDone); if (eErrCode != store_E_None) + { + OSL_TRACE("OStoreStream(%d)::writeAt(): error: %d", i, eErrCode); break; + } } if (nOptions & OPTION_READ) @@ -410,7 +419,10 @@ int SAL_CALL main (int argc, char **argv) eErrCode = aStream.readAt ( nOffset, pBuffer, sizeof(pBuffer), nDone); if (eErrCode != store_E_None) + { + OSL_TRACE("OStoreStream(%d)::readAt(): error: %d", i, eErrCode); break; + } if (nDone == 0) break; nOffset += nDone; @@ -439,7 +451,7 @@ int SAL_CALL main (int argc, char **argv) sal_uInt32 nDelta = aDelta.Seconds * 1000000; nDelta += (aDelta.Nanosec / 1000); - printf ("Total(rd,wr): %d[usec]\n", nDelta); + printf ("Total(rd,wr): %d[usec]\n", (unsigned int)(nDelta)); #endif /* PROFILE */ } @@ -560,7 +572,7 @@ int SAL_CALL main (int argc, char **argv) sal_uInt32 nDelta = aDelta.Seconds * 1000000; nDelta += (aDelta.Nanosec / 1000); - printf ("Total(iter): %d[usec]\n", nDelta); + printf ("Total(iter): %d[usec]\n", (unsigned int)(nDelta)); #endif /* PROFILE */ } @@ -584,12 +596,12 @@ int SAL_CALL main (int argc, char **argv) DumpCAP(); #endif /* PROFILE */ #ifndef PROFILE - OTime aDelta (OTime::getSystemTime() - aStartTime); + OTime aDelta (OTime::getSystemTime() - aMainStartTime); sal_uInt32 nDelta = aDelta.Seconds * 1000000; nDelta += (aDelta.Nanosec / 1000); - printf ("Total: %d[usec]\n", nDelta); + printf ("Total: %d[usec]\n", (unsigned int)(nDelta)); #endif /* PROFILE */ return 0; -- cgit v1.2.3