diff options
author | Vladimir Glazounov <vg@openoffice.org> | 2009-03-13 15:52:34 +0000 |
---|---|---|
committer | Vladimir Glazounov <vg@openoffice.org> | 2009-03-13 15:52:34 +0000 |
commit | cbedb240486a21c5d5676e7a7f4e2ba17a55dbab (patch) | |
tree | ec2690bb5e5d18df0a9493c54cfac64f9e5ab494 /store/workben | |
parent | 32a3f76b3695cbf54fecc77730395bbace21c8bc (diff) |
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.
Diffstat (limited to 'store/workben')
-rw-r--r-- | store/workben/makefile.mk | 40 | ||||
-rw-r--r-- | store/workben/t_base.cxx | 166 | ||||
-rw-r--r-- | store/workben/t_file.cxx | 108 | ||||
-rw-r--r-- | store/workben/t_leak.cxx | 19 | ||||
-rw-r--r-- | store/workben/t_page.cxx | 1574 | ||||
-rw-r--r-- | store/workben/t_store.cxx | 40 |
6 files changed, 1741 insertions, 206 deletions
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,14 +31,16 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_store.hxx" -#define _T_BASE_CXX "$Revision: 1.8 $" -#include <sal/types.h> -#include <osl/thread.h> -#include <rtl/memory.h> -#include <rtl/ustring.hxx> -#include <rtl/ref.hxx> -#include <store/filelckb.hxx> +#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; @@ -46,84 +48,6 @@ using namespace store; /*======================================================================== * - * OTestDaemon. - * - *======================================================================*/ - -#if 1 /* EXP */ - -#include <osl/interlck.h> - -class OTestDaemon : public rtl::IReference -{ -public: - static sal_Bool getOrCreate ( - rtl::Reference<OTestDaemon> &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 <osl/mutex.hxx> - -OTestDaemon* OTestDaemon::m_pThis = 0; - -OTestDaemon::OTestDaemon (void) -{ -} - -OTestDaemon::~OTestDaemon (void) -{ -} - -sal_Bool OTestDaemon::getOrCreate (rtl::Reference<OTestDaemon> &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<OTestBIOS*>(pHandle); @@ -248,15 +168,6 @@ static void __store_test_handle (void* Handle) pObj->isKindOf (42); pObj->release(); } - - store::OStoreHandle<OTestObject> xObj ( - store::OStoreHandle<OTestObject>::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) @@ -289,14 +202,6 @@ static void __store_string_newFromUnicode ( } 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, OStorePageKey &rKey) @@ -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<OFileLockBytes> xLockBytes (new OFileLockBytes()); - if (!xLockBytes.is()) - return 0; + rtl::Reference<ILockBytes> 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 <sal/types.h> -#include <osl/file.h> -#include <osl/thread.h> -#include <rtl/ustring.hxx> -#include <rtl/ref.hxx> -#include <store/filelckb.hxx> +#include "sal/types.h" +#include "osl/thread.h" +#include "rtl/ustring.hxx" + +#include "lockbyte.hxx" #ifndef INCLUDED_STDIO_H #include <stdio.h> @@ -55,39 +53,54 @@ using namespace store; *======================================================================*/ int SAL_CALL main (int argc, char **argv) { - if (argc < 2) - { - fprintf (stderr, "usage: t_file <output-filename>\n"); - return 0; - } - - rtl::Reference<OFileLockBytes> 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<ILockBytes> 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<long*>(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<long*>(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<SharedCount>(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<rtl_cache_type*>(lhs.m_cache, rhs.m_cache); + swap<SharedCount>(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<PageAllocator>(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<SharedCount>(lhs.m_refcount, rhs.m_refcount); + swap<PageData*>(lhs.m_pagedata, rhs.m_pagedata); + swap<PageHolder::allocator_type>(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<PageHolder>(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<U>(p) ? static_cast<U*>(p) : 0; + } + + template< class U > + static U const * dynamic_page_cast (PageData const * p) + { + return isA<U>(p) ? static_cast<U const *>(p) : 0; + } + +public: + static PageHolderObject<T> construct (rtl::Reference< PageData::Allocator > const & rxAllocator) + { + PageHolderObject<T> tmp; + if (rxAllocator.is()) + { + PageHolder xPage (rxAllocator->construct<T>(), rxAllocator); + store::swap<PageHolder>(tmp.m_xPage, xPage); + } + return tmp; + } + + explicit PageHolderObject (PageHolder const & rxPage = PageHolder()) + : m_xPage (rxPage) + {} + + void swap (PageHolderObject<T> & rhs) + { + store::swap<PageHolder>(m_xPage, rhs.m_xPage); + } + + PageHolderObject (PageHolderObject<T> const & rhs) + : m_xPage (rhs.m_xPage) + { + } + + PageHolderObject<T> & operator= (PageHolderObject<T> const & rhs) + { + PageHolderObject<T> tmp (rhs); + this->swap(tmp); + return *this; + } + + T * operator->() + { + T * pImpl = dynamic_page_cast<T>(m_xPage.get()); + OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator->(): Null pointer"); + return pImpl; + } + T const * operator->() const + { + T const * pImpl = dynamic_page_cast<T>(m_xPage.get()); + OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator->(): Null pointer"); + return pImpl; + } + + T & operator*() + { + T * pImpl = dynamic_page_cast<T>(m_xPage.get()); + OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer"); + return *pImpl; + } + T const & operator*() const + { + T const * pImpl = dynamic_page_cast<T>(m_xPage.get()); + OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer"); + return *pImpl; + } + + static storeError guard (PageHolder & rxPage) + { + T * pImpl = dynamic_page_cast<T>(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<T>(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<T*>(pagedata); + return 0; +} + +template< class T > +T * dynamic_page_cast (PageData const * pagedata) +{ + if ((pagedata != 0) && (pagedata->type() == T::theTypeId)) + return static_cast<T*>(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<T>::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<TestData>::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<SuperPage>(); + 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<const sal_uInt32, PageObject> 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<sal_uInt8*>(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<sal_uInt8 const*>(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<PageHolder>(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<sal_uInt32>(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<PageHolder>(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<sal_uInt8*>(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<sal_uInt8 const*>(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<sal_uInt32>(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<sal_uInt8*>(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<FileHandle> 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<FileMapping> xMapping; + result = xMapping.get().initialize (xFile.get()); + if (result == osl_File_E_None) + { + const sal_uInt32 nSize = sal::static_int_cast<sal_uInt32>(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<InodePageDataV2*>(&rData); + return 0; +} + +class InodePageObject : public PageObject +{ +public: + static InodePageObject createInstance (PageData & rData) + { + if (query(&rData, static_cast<InodePageDataV2*>(0))) + return InodePageObjectV2 (static_cast<InodePageDataV2&>(rData)); + else if (query(&rData, static_cast<InodePageDataV1*>(0))) + return InodePageObjectV1 (static_cast<InodePageDataV1&>(rData)); + } +}; + +#endif /* NYI */ + +/*======================================================================== + * + * main. + * + *======================================================================*/ + +#include <stdio.h> + +#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<void*>(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<FileHandle> h1; + oslFileError result = h1.get().initialize (pFilename, FilePageAccess::MODE_TO_NATIVE(eAccessMode)); + if (result == osl_File_E_None) + { + ResourceHolder<FileHandle> h2 (h1); + h1 = h2; + + if (eAccessMode == store_AccessReadOnly) + { + ResourceHolder<FileMapping> m1; + result = m1.get().initialize (h1.get()); + + const sal_uInt32 nSize = sal::static_int_cast<sal_uInt32>(m1.get().m_uSize); + (void) nSize; // UNUSED + + ResourceHolder<FileMapping> 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 <sal/types.h> #include <osl/diagnose.h> #include <osl/thread.h> @@ -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; |