/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/

/*
 * 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 > 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;
}
