1358 lines
34 KiB
C++
1358 lines
34 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* 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 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;
|
|
}
|
|
};
|
|
|
|
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();
|
|
}
|
|
};
|
|
|
|
/*======================================================================*/
|
|
|
|
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;
|
|
|
|
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);
|
|
}
|
|
|
|
/*========================================================================
|
|
*
|
|
* main.
|
|
*
|
|
*======================================================================*/
|
|
|
|
#include <stdio.h>
|
|
|
|
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 (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;
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|