/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the 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_ */
