summaryrefslogtreecommitdiff
path: root/store/source/storbase.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'store/source/storbase.hxx')
-rw-r--r--store/source/storbase.hxx954
1 files changed, 954 insertions, 0 deletions
diff --git a/store/source/storbase.hxx b/store/source/storbase.hxx
new file mode 100644
index 000000000000..9c1e4ea985bf
--- /dev/null
+++ b/store/source/storbase.hxx
@@ -0,0 +1,954 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STORE_STORBASE_HXX_
+#define _STORE_STORBASE_HXX_ "$Revision: 1.10.8.4 $"
+
+#include "sal/types.h"
+
+#include "rtl/alloc.h"
+#include "rtl/crc.h"
+#include "rtl/ref.hxx"
+
+#include "osl/diagnose.h"
+#include "osl/endian.h"
+
+#include "store/types.h"
+
+#ifndef INCLUDED_STDDEF_H
+#include <stddef.h>
+#define INCLUDED_STDDEF_H
+#endif
+
+#ifndef INCLUDED_STRING_H
+#include <string.h>
+#define INCLUDED_STRING_H
+#endif
+
+/*========================================================================
+ *
+ * store common internals.
+ *
+ *======================================================================*/
+
+#ifndef STORE_IMPL_ISP2
+#define STORE_IMPL_ISP2(value) (((value) & ((value) - 1)) == 0)
+#endif
+
+#ifndef STORE_IMPL_CONCAT
+#define STORE_IMPL_CONCAT(x, y) STORE_IMPL_CONCAT2(x,y)
+#define STORE_IMPL_CONCAT2(x, y) x##y
+#endif
+
+#ifndef STORE_STATIC_ASSERT /* Compile time assertion */
+namespace store
+{
+ template< bool x > struct STATIC_ASSERTION_FAILURE;
+ template<> struct STATIC_ASSERTION_FAILURE< true > { enum { value = 1 }; };
+
+ template< int x > struct static_assert_test{};
+} // namespace store
+
+#define STORE_STATIC_ASSERT(pred) \
+typedef \
+store::static_assert_test< sizeof( store::STATIC_ASSERTION_FAILURE< (bool)(pred) > ) > \
+STORE_IMPL_CONCAT(static_assert_typedef_, __LINE__)
+
+#endif /* !STORE_STATIC_ASSERT */
+
+namespace store
+{
+
+#ifdef htons
+#undef htons
+#endif
+#ifdef ntohs
+#undef ntohs
+#endif
+
+#ifdef htonl
+#undef htonl
+#endif
+#ifdef ntohl
+#undef ntohl
+#endif
+
+#ifdef OSL_BIGENDIAN
+inline sal_uInt16 htons (sal_uInt16 h) { return OSL_SWAPWORD(h); }
+inline sal_uInt16 ntohs (sal_uInt16 n) { return OSL_SWAPWORD(n); }
+
+inline sal_uInt32 htonl (sal_uInt32 h) { return OSL_SWAPDWORD(h); }
+inline sal_uInt32 ntohl (sal_uInt32 n) { return OSL_SWAPDWORD(n); }
+#else
+inline sal_uInt16 htons (sal_uInt16 h) { return (h); }
+inline sal_uInt16 ntohs (sal_uInt16 n) { return (n); }
+
+inline sal_uInt32 htonl (sal_uInt32 h) { return (h); }
+inline sal_uInt32 ntohl (sal_uInt32 n) { return (n); }
+#endif /* OSL_BIGENDIAN */
+
+/** swap.
+ */
+template< typename T > void swap (T & lhs, T & rhs)
+{
+ T tmp = lhs; lhs = rhs; rhs = tmp;
+}
+
+/*========================================================================
+ *
+ * SharedCount.
+ *
+ *======================================================================*/
+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);
+ }
+ }
+
+ void swap (SharedCount & rhs) // nothrow
+ {
+ store::swap(m_pCount, rhs.m_pCount);
+ }
+
+ SharedCount (SharedCount const & rhs) // nothrow
+ : m_pCount (rhs.m_pCount)
+ {
+ if (m_pCount != 0) ++(*m_pCount);
+ }
+ SharedCount & operator= (SharedCount const & rhs) // nothrow
+ {
+ SharedCount tmp(rhs);
+ swap(tmp);
+ return *this;
+ }
+
+ bool operator== (long count) const
+ {
+ return (m_pCount != 0) ? *m_pCount == count : false;
+ }
+};
+
+/*========================================================================
+ *
+ * OStorePageGuard.
+ *
+ *======================================================================*/
+struct OStorePageGuard
+{
+ /** Representation.
+ */
+ sal_uInt32 m_nMagic;
+ sal_uInt32 m_nCRC32;
+
+ /** Construction.
+ */
+ explicit OStorePageGuard (sal_uInt32 nMagic = 0, sal_uInt32 nCRC32 = 0)
+ : m_nMagic (store::htonl(nMagic)),
+ m_nCRC32 (store::htonl(nCRC32))
+ {}
+
+ void swap (OStorePageGuard & rhs)
+ {
+ store::swap(m_nMagic, rhs.m_nMagic);
+ store::swap(m_nCRC32, rhs.m_nCRC32);
+ }
+
+ OStorePageGuard (OStorePageGuard const & rhs)
+ : m_nMagic (rhs.m_nMagic),
+ m_nCRC32 (rhs.m_nCRC32)
+ {}
+
+ OStorePageGuard& operator= (const OStorePageGuard& rhs)
+ {
+ m_nMagic = rhs.m_nMagic;
+ m_nCRC32 = rhs.m_nCRC32;
+ return *this;
+ }
+
+ /** Comparison.
+ */
+ bool operator== (const OStorePageGuard& rhs) const
+ {
+ return ((m_nMagic == rhs.m_nMagic) &&
+ (m_nCRC32 == rhs.m_nCRC32) );
+ }
+};
+
+/*========================================================================
+ *
+ * OStorePageDescriptor.
+ *
+ *======================================================================*/
+#define STORE_PAGE_NULL ((sal_uInt32)(~0))
+
+struct OStorePageDescriptor
+{
+ /** Representation.
+ */
+ sal_uInt32 m_nAddr;
+ sal_uInt16 m_nSize;
+ sal_uInt16 m_nUsed;
+
+ /** Construction.
+ */
+ explicit OStorePageDescriptor (
+ sal_uInt32 nAddr = STORE_PAGE_NULL,
+ sal_uInt16 nSize = 0,
+ sal_uInt16 nUsed = 0)
+ : m_nAddr (store::htonl(nAddr)),
+ m_nSize (store::htons(nSize)),
+ m_nUsed (store::htons(nUsed))
+ {}
+
+ void swap (OStorePageDescriptor & rhs)
+ {
+ store::swap(m_nAddr, rhs.m_nAddr);
+ store::swap(m_nSize, rhs.m_nSize);
+ store::swap(m_nUsed, rhs.m_nUsed);
+ }
+
+ OStorePageDescriptor (const OStorePageDescriptor & rhs)
+ : m_nAddr (rhs.m_nAddr),
+ m_nSize (rhs.m_nSize),
+ m_nUsed (rhs.m_nUsed)
+ {}
+
+ OStorePageDescriptor & operator= (const OStorePageDescriptor & rhs)
+ {
+ m_nAddr = rhs.m_nAddr;
+ m_nSize = rhs.m_nSize;
+ m_nUsed = rhs.m_nUsed;
+ return *this;
+ }
+
+ /** Comparison.
+ */
+ bool operator== (const OStorePageDescriptor & rhs) const
+ {
+ return ((m_nAddr == rhs.m_nAddr) &&
+ (m_nSize == rhs.m_nSize) );
+ }
+
+ bool operator<= (const OStorePageDescriptor & rhs) const
+ {
+ return ((m_nAddr == rhs.m_nAddr ) &&
+ (store::ntohs(m_nSize) <= store::ntohs(rhs.m_nSize)) );
+ }
+
+ bool operator< (const OStorePageDescriptor & rhs) const
+ {
+ if (m_nAddr == rhs.m_nAddr)
+ return (store::ntohs(m_nSize) < store::ntohs(rhs.m_nSize));
+ else
+ return (store::ntohl(m_nAddr) < store::ntohl(rhs.m_nAddr));
+ }
+};
+
+/*========================================================================
+ *
+ * OStorePageKey.
+ *
+ *======================================================================*/
+struct OStorePageKey
+{
+ /** Representation.
+ */
+ sal_uInt32 m_nLow;
+ sal_uInt32 m_nHigh;
+
+ /** Construction.
+ */
+ explicit OStorePageKey (sal_uInt32 nLow = 0, sal_uInt32 nHigh = 0)
+ : m_nLow (store::htonl(nLow)),
+ m_nHigh (store::htonl(nHigh))
+ {}
+
+ void swap (OStorePageKey & rhs)
+ {
+ store::swap(m_nLow, rhs.m_nLow);
+ store::swap(m_nHigh, rhs.m_nHigh);
+ }
+
+ OStorePageKey (const OStorePageKey & rhs)
+ : m_nLow (rhs.m_nLow), m_nHigh (rhs.m_nHigh)
+ {}
+
+ OStorePageKey & operator= (const OStorePageKey & rhs)
+ {
+ m_nLow = rhs.m_nLow;
+ m_nHigh = rhs.m_nHigh;
+ return *this;
+ }
+
+ /** Comparison.
+ */
+ bool operator== (const OStorePageKey & rhs) const
+ {
+ return ((m_nLow == rhs.m_nLow ) &&
+ (m_nHigh == rhs.m_nHigh) );
+ }
+
+ bool operator< (const OStorePageKey & rhs) const
+ {
+ if (m_nHigh == rhs.m_nHigh)
+ return (store::ntohl(m_nLow) < store::ntohl(rhs.m_nLow));
+ else
+ return (store::ntohl(m_nHigh) < store::ntohl(rhs.m_nHigh));
+ }
+};
+
+/*========================================================================
+ *
+ * OStorePageLink.
+ *
+ *======================================================================*/
+struct OStorePageLink
+{
+ /** Representation.
+ */
+ sal_uInt32 m_nAddr;
+
+ /** Construction.
+ */
+ explicit OStorePageLink (sal_uInt32 nAddr = STORE_PAGE_NULL)
+ : m_nAddr (store::htonl(nAddr))
+ {}
+
+ void swap (OStorePageLink & rhs)
+ {
+ store::swap(m_nAddr, rhs.m_nAddr);
+ }
+
+ OStorePageLink (const OStorePageLink & rhs)
+ : m_nAddr (rhs.m_nAddr)
+ {}
+
+ OStorePageLink & operator= (const OStorePageLink & rhs)
+ {
+ m_nAddr = rhs.m_nAddr;
+ return *this;
+ }
+
+ OStorePageLink & operator= (sal_uInt32 nAddr)
+ {
+ m_nAddr = store::htonl(nAddr);
+ return *this;
+ }
+
+ /** Comparison.
+ */
+ bool operator== (const OStorePageLink & rhs) const
+ {
+ return (m_nAddr == rhs.m_nAddr);
+ }
+
+ bool operator< (const OStorePageLink& rhs) const
+ {
+ return (store::ntohl(m_nAddr) < store::ntohl(rhs.m_nAddr));
+ }
+
+ /** Operation.
+ */
+ sal_uInt32 location() const
+ {
+ return store::ntohl(m_nAddr);
+ }
+
+ void link (OStorePageLink & rPred)
+ {
+ // @@@ swap (rPred); @@@
+ OStorePageLink tmp (rPred);
+ rPred = *this;
+ *this = tmp;
+ }
+
+ void unlink (OStorePageLink& rPred)
+ {
+ rPred = *this;
+ *this = OStorePageLink();
+ }
+};
+
+/*========================================================================
+ *
+ * PageData.
+ *
+ *======================================================================*/
+typedef struct PageData OStorePageData; // backward compat.
+struct PageData
+{
+ typedef OStorePageGuard G;
+ typedef OStorePageDescriptor D;
+ typedef 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);
+
+ /** location.
+ */
+ sal_uInt32 location() const
+ {
+ return store::ntohl(m_aDescr.m_nAddr);
+ }
+ void location (sal_uInt32 nAddr)
+ {
+ m_aDescr.m_nAddr = store::htonl(nAddr);
+ }
+
+ /** size.
+ */
+ sal_uInt16 size() const
+ {
+ return store::ntohs(m_aDescr.m_nSize);
+ }
+
+ /** type.
+ */
+ sal_uInt32 type() const
+ {
+ return store::ntohl(m_aGuard.m_nMagic);
+ }
+
+ /** Allocation.
+ */
+ class Allocator_Impl;
+ class Allocator : public rtl::IReference
+ {
+ public:
+ template< class T > T * construct()
+ {
+ void * page = 0; sal_uInt16 size = 0;
+ if (allocate (&page, &size))
+ {
+ return new(page) T(size);
+ }
+ return 0;
+ }
+
+ bool allocate (void ** ppPage, sal_uInt16 * pnSize)
+ {
+ allocate_Impl (ppPage, pnSize);
+ return ((*ppPage != 0) && (*pnSize != 0));
+ }
+
+ void deallocate (void * pPage)
+ {
+ if (pPage != 0)
+ deallocate_Impl (pPage);
+ }
+
+ static storeError createInstance (
+ rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize);
+
+ private:
+ /** Implementation (abstract).
+ */
+ virtual void allocate_Impl (void ** ppPage, sal_uInt16 * pnSize) = 0;
+ virtual void deallocate_Impl (void * pPage) = 0;
+ };
+
+ static void* operator new (size_t, void * p) { return p; }
+ static void operator delete (void * , void *) {}
+
+ /** Construction.
+ */
+ explicit PageData (sal_uInt16 nPageSize = thePageSize)
+ : m_aGuard(),
+ m_aDescr(STORE_PAGE_NULL, nPageSize, thePageSize),
+ m_aMarked(),
+ m_aUnused()
+ {}
+
+ void swap (PageData & rhs) // nothrow
+ {
+ m_aGuard.swap(rhs.m_aGuard);
+ m_aDescr.swap(rhs.m_aDescr);
+ m_aMarked.swap(rhs.m_aMarked);
+ m_aUnused.swap(rhs.m_aUnused);
+ }
+
+ PageData (PageData const & rhs) // nothrow
+ : m_aGuard (rhs.m_aGuard),
+ m_aDescr (rhs.m_aDescr),
+ m_aMarked(rhs.m_aMarked),
+ m_aUnused(rhs.m_aUnused)
+ {}
+
+ PageData & operator= (PageData const & rhs) // nothrow
+ {
+ PageData tmp (rhs);
+ swap (tmp);
+ return *this;
+ }
+
+ /** guard (external representation).
+ */
+ void guard (sal_uInt32 nAddr)
+ {
+ sal_uInt32 nCRC32 = 0;
+ nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
+ m_aDescr.m_nAddr = store::htonl(nAddr);
+ nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G));
+ m_aGuard.m_nCRC32 = store::htonl(nCRC32);
+ }
+
+ /** verify (external representation).
+ */
+ storeError verify (sal_uInt32 nAddr) const
+ {
+ sal_uInt32 nCRC32 = 0;
+ nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
+ nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G));
+ if (m_aGuard.m_nCRC32 != store::htonl(nCRC32))
+ return store_E_InvalidChecksum;
+ if (m_aDescr.m_nAddr != store::htonl(nAddr))
+ return store_E_InvalidAccess;
+ return store_E_None;
+ }
+
+ storeError verifyVersion (sal_uInt32 nMagic) const
+ {
+ if (m_aGuard.m_nMagic != store::htonl(nMagic))
+ return store_E_WrongVersion;
+ else
+ return store_E_None;
+ }
+};
+
+/*========================================================================
+ *
+ * PageHolder.
+ *
+ *======================================================================*/
+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)
+ {
+ OSL_ENSURE((m_pagedata == 0) || m_allocator.is(), "store::PageHolder::ctor(): pagedata w/o allocator.");
+ }
+
+ ~PageHolder()
+ {
+ if ((m_refcount == 1) && (m_pagedata != 0))
+ {
+ // free pagedata.
+ OSL_ENSURE(m_allocator.is(), "store::PageHolder::dtor(): pagedata w/o allocator.");
+ m_allocator->deallocate (m_pagedata);
+ }
+ }
+
+ void swap (PageHolder & rhs) // nothrow
+ {
+ m_refcount.swap(rhs.m_refcount);
+ store::swap(m_pagedata, rhs.m_pagedata);
+ store::swap(m_allocator, rhs.m_allocator);
+ }
+
+ PageHolder (PageHolder const & rhs) // nothrow
+ : m_refcount (rhs.m_refcount),
+ m_pagedata (rhs.m_pagedata),
+ m_allocator(rhs.m_allocator)
+ {}
+
+ PageHolder & operator= (PageHolder const & rhs) // nothrow
+ {
+ PageHolder tmp (rhs);
+ swap(tmp);
+ return *this;
+ }
+
+ PageData * get() { return m_pagedata; }
+ PageData const * get() const { return m_pagedata; }
+
+ PageData * operator->()
+ {
+ OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator->(): Null pointer");
+ return m_pagedata;
+ }
+ PageData const * operator->() const
+ {
+ OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator->(): Null pointer");
+ return m_pagedata;
+ }
+
+ PageData & operator*()
+ {
+ OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator*(): Null pointer");
+ return *m_pagedata;
+ }
+ PageData const & operator*() const
+ {
+ OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator*(): Null pointer");
+ return *m_pagedata;
+ }
+};
+
+/*========================================================================
+ *
+ * PageHolderObject.
+ *
+ *======================================================================*/
+template< class T >
+class PageHolderObject
+{
+ /** 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:
+ bool construct (rtl::Reference< PageData::Allocator > const & rxAllocator)
+ {
+ if ((m_xPage.get() == 0) && rxAllocator.is())
+ {
+ PageHolder tmp (rxAllocator->construct<T>(), rxAllocator);
+ m_xPage.swap (tmp);
+ }
+ return (m_xPage.get() != 0);
+ }
+
+ static PageHolderObject<T> createInstance (rtl::Reference< PageData::Allocator > const & rxAllocator)
+ {
+ PageHolderObject<T> tmp;
+ (void) tmp.construct (rxAllocator);
+ return tmp;
+ }
+
+ explicit PageHolderObject (PageHolder const & rxPage = PageHolder())
+ : m_xPage (rxPage)
+ {}
+
+ void swap (PageHolderObject<T> & rhs)
+ {
+ m_xPage.swap (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;
+ }
+
+ bool is() const
+ {
+ return (m_xPage.get() != 0);
+ }
+
+#if 1 /* EXP */
+ PageHolder & get() { return m_xPage; }
+ PageHolder const & get() const { return m_xPage; }
+#endif /* EXP */
+
+ 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, sal_uInt32 nAddr)
+ {
+ PageData * pHead = rxPage.get();
+ if (!pHead)
+ return store_E_InvalidAccess;
+ pHead->guard(nAddr);
+
+ T * pImpl = dynamic_page_cast<T>(pHead);
+ OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::guard(): Null pointer");
+ pImpl->guard();
+
+ return store_E_None;
+ }
+ static storeError verify (PageHolder const & rxPage, sal_uInt32 nAddr)
+ {
+ PageData const * pHead = rxPage.get();
+ if (!pHead)
+ return store_E_InvalidAccess;
+
+ storeError eErrCode = pHead->verify(nAddr);
+ if (eErrCode != store_E_None)
+ return eErrCode;
+
+ T const * pImpl = dynamic_page_cast<T>(pHead);
+ if (!pImpl)
+ return store_E_WrongVersion;
+
+ return pImpl->verify();
+ }
+};
+
+/*========================================================================
+ *
+ * PageObject.
+ *
+ *======================================================================*/
+#if 1 /* EXP */
+class PageObject
+{
+public:
+ explicit PageObject (PageHolder const & rxPage = PageHolder())
+ : m_xPage (rxPage), m_bDirty (false)
+ {}
+
+ virtual ~PageObject()
+ {}
+
+ PageHolder & get() { return m_xPage; }
+ PageHolder const & get() const { return m_xPage; }
+
+ void clean() { m_bDirty = false; }
+ void touch() { m_bDirty = true; }
+
+ sal_uInt32 location() const
+ {
+ PageData const * pagedata = m_xPage.get();
+ return (pagedata != 0) ? pagedata->location() : STORE_PAGE_NULL;
+ }
+ void location (sal_uInt32 nAddr)
+ {
+ PageData * pagedata = m_xPage.get();
+ if (pagedata != 0)
+ pagedata->location (nAddr);
+ }
+
+protected:
+ PageHolder m_xPage;
+ bool m_bDirty;
+
+ virtual storeError guard (sal_uInt32 nAddr) = 0;
+ virtual storeError verify (sal_uInt32 nAddr) const = 0;
+};
+#endif /* EXP */
+
+class OStorePageBIOS;
+
+class OStorePageObject
+{
+ typedef OStorePageData page;
+
+public:
+ /** Allocation.
+ */
+ static void * operator new (size_t n) SAL_THROW(())
+ {
+ return rtl_allocateMemory (sal_uInt32(n));
+ }
+ static void operator delete (void * p, size_t) SAL_THROW(())
+ {
+ rtl_freeMemory (p);
+ }
+
+ /** State.
+ */
+ inline bool dirty (void) const;
+ inline void clean (void);
+ inline void touch (void);
+
+ /** Location.
+ */
+ inline sal_uInt32 location (void) const;
+ inline void location (sal_uInt32 nAddr);
+
+protected:
+ /** Representation.
+ */
+ PageHolder m_xPage;
+ bool m_bDirty;
+
+ /** Construction.
+ */
+ explicit OStorePageObject (PageHolder const & rxPage = PageHolder())
+ : m_xPage (rxPage), m_bDirty (false)
+ {}
+
+ /** Destruction.
+ */
+ virtual ~OStorePageObject (void);
+
+public:
+ template< class U >
+ PageHolderObject<U> makeHolder() const
+ {
+ return PageHolderObject<U>(m_xPage);
+ }
+
+ template< class U >
+ storeError construct (rtl::Reference< PageData::Allocator > const & rxAllocator)
+ {
+ if (!rxAllocator.is())
+ return store_E_InvalidAccess;
+
+ PageHolder tmp (rxAllocator->construct<U>(), rxAllocator);
+ if (!tmp.get())
+ return store_E_OutOfMemory;
+
+ m_xPage.swap (tmp);
+ return store_E_None;
+ }
+
+
+ PageHolder & get() { return m_xPage; }
+ PageHolder const & get() const { return m_xPage; }
+
+ virtual storeError guard (sal_uInt32 nAddr) = 0;
+ virtual storeError verify (sal_uInt32 nAddr) const = 0;
+};
+
+inline bool OStorePageObject::dirty (void) const
+{
+ return m_bDirty;
+}
+
+inline void OStorePageObject::clean (void)
+{
+ m_bDirty = false;
+}
+
+inline void OStorePageObject::touch (void)
+{
+ m_bDirty = true;
+}
+
+inline sal_uInt32 OStorePageObject::location (void) const
+{
+ return m_xPage->location();
+}
+
+inline void OStorePageObject::location (sal_uInt32 nAddr)
+{
+ m_xPage->location(nAddr);
+ touch();
+}
+
+/*========================================================================
+ *
+ * The End.
+ *
+ *======================================================================*/
+
+} // namespace store
+
+#endif /* !_STORE_STORBASE_HXX_ */