summaryrefslogtreecommitdiff
path: root/store/workben/t_page.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'store/workben/t_page.cxx')
-rw-r--r--store/workben/t_page.cxx1574
1 files changed, 1574 insertions, 0 deletions
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;
+}