1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
6 #include "osl/diagnose.h"
10 #include "storbase.hxx"
13 #include "rtl/ustring.hxx"
15 /*========================================================================
19 *======================================================================*/
21 template< class T
> void swap (T
& lhs
, T
& rhs
)
23 T tmp
= rhs
; rhs
= lhs
; lhs
= tmp
;
26 /*======================================================================*/
34 rtl_cache_type
* m_cache
;
37 static Allocator
& get();
41 return static_cast<long*>(rtl_cache_alloc (m_cache
));
43 void free (long * pCount
)
45 rtl_cache_free (m_cache
, pCount
);
55 : m_pCount(Allocator::get().alloc())
57 if (m_pCount
!= 0) (*m_pCount
) = 1;
64 long new_count
= --(*m_pCount
);
66 Allocator::get().free(m_pCount
);
70 bool operator== (long count
) const
72 return (m_pCount
!= 0) ? *m_pCount
== count
: false;
75 friend void swap
<> (SharedCount
& lhs
, SharedCount
& rhs
); // nothrow
77 SharedCount (SharedCount
const & rhs
); // nothrow
78 SharedCount
& operator= (SharedCount
const & rhs
); // nothrow
82 inline void swap (SharedCount
& lhs
, SharedCount
& rhs
) // nothrow
84 swap
<long*>(lhs
.m_pCount
, rhs
.m_pCount
);
87 SharedCount::SharedCount (SharedCount
const & rhs
) // nothrow
88 : m_pCount (rhs
.m_pCount
)
90 if (m_pCount
!= 0) ++(*m_pCount
);
94 SharedCount::operator= (SharedCount
const & rhs
) // nothrow
97 swap
<SharedCount
>(tmp
, *this);
101 SharedCount::Allocator
&
102 SharedCount::Allocator::get()
104 static Allocator g_aSharedCountAllocator
;
105 return g_aSharedCountAllocator
;
108 SharedCount::Allocator::Allocator()
110 m_cache
= rtl_cache_create (
111 "store_shared_count_cache",
123 SharedCount::Allocator::~Allocator()
125 rtl_cache_destroy (m_cache
), m_cache
= 0;
128 /*======================================================================*/
130 #if defined(OSL_BIGENDIAN)
131 #define STORE_DWORD(dword) OSL_SWAPDWORD((dword))
133 #define STORE_DWORD(dword) (dword)
138 typedef store::OStorePageGuard G
;
139 typedef store::OStorePageDescriptor D
;
140 typedef store::OStorePageLink L
;
151 static const size_t theSize
= sizeof(G
) + sizeof(D
) + 2 * sizeof(L
);
152 static const sal_uInt16 thePageSize
= theSize
;
153 STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE
>= thePageSize
);
157 sal_uInt32
type() const { return m_aGuard
.m_nMagic
; /* @@@ */ }
161 sal_uInt32
offset() const { return m_aDescr
.m_nAddr
; /* @@@ */ }
162 void offset (sal_uInt32 nOffset
) { m_aDescr
.m_nAddr
= nOffset
; }
166 sal_uInt16
size() const { return m_aDescr
.m_nSize
; /* @@@ */ }
170 class Allocator
: public rtl::IReference
173 template< class T
> T
* construct()
175 void * page
= 0; sal_uInt16 size
= 0;
176 if (allocate (&page
, &size
))
178 return new(page
) T(size
);
183 virtual bool allocate (void ** ppPage
, sal_uInt16
* pnSize
) = 0;
184 virtual void deallocate (void * pPage
) = 0;
187 static void * operator new (size_t, void * p
) { return p
; }
188 static void operator delete (void *, void *) {}
192 explicit PageData (sal_uInt16 nPageSize
= thePageSize
)
193 : m_aDescr (STORE_PAGE_NULL
, nPageSize
, thePageSize
)
201 storeError
verify() const
210 virtual void deallocate (void * p
) = 0;
215 rtl_cache_type
* m_cache
;
216 SharedCount m_refcount
;
220 : m_cache(0), m_refcount()
231 friend void swap
<>(PageAllocator
& lhs
, PageAllocator
& rhs
);
233 PageAllocator (PageAllocator
const & rhs
);
234 PageAllocator
& operator= (PageAllocator
const & rhs
);
238 inline void swap (PageAllocator
& lhs
, PageAllocator
& rhs
)
240 swap
<rtl_cache_type
*>(lhs
.m_cache
, rhs
.m_cache
);
241 swap
<SharedCount
>(lhs
.m_refcount
, rhs
.m_refcount
);
244 PageAllocator::PageAllocator (PageAllocator
const & rhs
)
245 : m_cache (rhs
.m_cache
),
246 m_refcount (rhs
.m_refcount
)
251 PageAllocator::operator= (PageAllocator
const & rhs
)
253 PageAllocator
tmp (rhs
);
254 swap
<PageAllocator
>(tmp
, *this);
258 /*======================================================================*/
262 SharedCount m_refcount
;
263 PageData
* m_pagedata
;
265 typedef rtl::Reference
< PageData::Allocator
> allocator_type
;
266 allocator_type m_allocator
;
269 explicit PageHolder (PageData
* pagedata
= 0, allocator_type
const & allocator
= allocator_type())
271 m_pagedata (pagedata
),
272 m_allocator(allocator
)
277 if ((m_refcount
== 1) && (m_pagedata
!= 0) && m_allocator
.is())
280 m_allocator
->deallocate (m_pagedata
);
284 PageData
* get() { return m_pagedata
; }
285 PageData
const * get() const { return m_pagedata
; }
287 PageData
* operator->() { return m_pagedata
; }
288 PageData
const * operator->() const { return m_pagedata
; }
290 friend void swap
<> (PageHolder
& lhs
, PageHolder
& rhs
); // nothrow
292 PageHolder (PageHolder
const & rhs
); // nothrow
293 PageHolder
& operator= (PageHolder
const & rhs
); // nothrow
297 inline void swap (PageHolder
& lhs
, PageHolder
& rhs
) // nothrow
299 swap
<SharedCount
>(lhs
.m_refcount
, rhs
.m_refcount
);
300 swap
<PageData
*>(lhs
.m_pagedata
, rhs
.m_pagedata
);
301 swap
<PageHolder::allocator_type
>(lhs
.m_allocator
, rhs
.m_allocator
);
304 PageHolder::PageHolder (PageHolder
const & rhs
) // nothrow
305 : m_refcount (rhs
.m_refcount
),
306 m_pagedata (rhs
.m_pagedata
),
307 m_allocator(rhs
.m_allocator
)
311 PageHolder::operator= (PageHolder
const & rhs
) // nothrow
313 PageHolder
tmp (rhs
);
314 swap
<PageHolder
>(tmp
, *this);
318 /*======================================================================*/
321 class PageHolderObject
331 static bool isA (PageData
const * p
)
333 return ((p
!= 0) && (p
->type() == U::theTypeId
));
337 static U
* dynamic_page_cast (PageData
* p
)
339 return isA
<U
>(p
) ? static_cast<U
*>(p
) : 0;
343 static U
const * dynamic_page_cast (PageData
const * p
)
345 return isA
<U
>(p
) ? static_cast<U
const *>(p
) : 0;
349 static PageHolderObject
<T
> construct (rtl::Reference
< PageData::Allocator
> const & rxAllocator
)
351 PageHolderObject
<T
> tmp
;
352 if (rxAllocator
.is())
354 PageHolder
xPage (rxAllocator
->construct
<T
>(), rxAllocator
);
355 store::swap
<PageHolder
>(tmp
.m_xPage
, xPage
);
360 explicit PageHolderObject (PageHolder
const & rxPage
= PageHolder())
364 void swap (PageHolderObject
<T
> & rhs
)
366 store::swap
<PageHolder
>(m_xPage
, rhs
.m_xPage
);
369 PageHolderObject (PageHolderObject
<T
> const & rhs
)
370 : m_xPage (rhs
.m_xPage
)
374 PageHolderObject
<T
> & operator= (PageHolderObject
<T
> const & rhs
)
376 PageHolderObject
<T
> tmp (rhs
);
383 T
* pImpl
= dynamic_page_cast
<T
>(m_xPage
.get());
384 OSL_PRECOND(pImpl
!= 0, "store::PageHolder<T>::operator->(): Null pointer");
387 T
const * operator->() const
389 T
const * pImpl
= dynamic_page_cast
<T
>(m_xPage
.get());
390 OSL_PRECOND(pImpl
!= 0, "store::PageHolder<T>::operator->(): Null pointer");
396 T
* pImpl
= dynamic_page_cast
<T
>(m_xPage
.get());
397 OSL_PRECOND(pImpl
!= 0, "store::PageHolder<T>::operator*(): Null pointer");
400 T
const & operator*() const
402 T
const * pImpl
= dynamic_page_cast
<T
>(m_xPage
.get());
403 OSL_PRECOND(pImpl
!= 0, "store::PageHolder<T>::operator*(): Null pointer");
407 static storeError
guard (PageHolder
& rxPage
)
409 T
* pImpl
= dynamic_page_cast
<T
>(rxPage
.get());
411 { pImpl
->guard(); return store_E_None
; }
412 else if (rxPage
.get() != 0)
413 return store_E_WrongVersion
;
415 return store_E_InvalidAccess
;
417 static storeError
verify (PageHolder
const & rxPage
)
419 T
const * pImpl
= dynamic_page_cast
<T
>(rxPage
.get());
421 return pImpl
->verify();
422 else if (rxPage
.get() != 0)
423 return store_E_WrongVersion
;
425 return store_E_InvalidAccess
;
429 /*======================================================================*/
434 explicit PageObject (PageHolder
const & rxPage
= PageHolder())
438 virtual ~PageObject();
440 PageHolder
& get() { return m_xPage
; }
441 PageHolder
const & get() const { return m_xPage
; }
443 PageData
* operator->()
445 PageData
* pImpl
= m_xPage
.get();
446 OSL_PRECOND(pImpl
!= 0, "store::PageObject::operator->(): Null pointer");
449 PageData
& operator*()
451 PageData
* pImpl
= m_xPage
.get();
452 OSL_PRECOND(pImpl
!= 0, "store::PageObject::operator*(): Null pointer");
456 virtual void guard();
457 virtual storeError
verify() const;
463 PageObject::~PageObject()
465 void PageObject::guard()
467 PageData
* p
= m_xPage
.get();
470 storeError
PageObject::verify() const
472 PageData
const * p
= m_xPage
.get();
476 /*======================================================================*/
479 T
* dynamic_page_cast (PageData
* pagedata
)
481 if ((pagedata
!= 0) && (pagedata
->type() == T::theTypeId
))
482 return static_cast<T
*>(pagedata
);
487 T
* dynamic_page_cast (PageData
const * pagedata
)
489 if ((pagedata
!= 0) && (pagedata
->type() == T::theTypeId
))
490 return static_cast<T
*>(pagedata
);
494 /*======================================================================*/
499 storeError
loadPageAt (PageHolder
& rPage
, storeError (*pfnVerify
)(PageHolder
const &))
501 return (pfnVerify
)(rPage
);
504 storeError
allocate (PageHolder
& rxPage
, ...)
506 // NYI: PageObject.save(nAddr, *this);
508 return store_E_Unknown
; // NYI
511 storeError
loadAt (PageHolder
& rPage
, sal_uInt32 nOffset
)
514 (void)nOffset
; // NYI
515 return store_E_Unknown
; // NYI
517 storeError
saveAt (PageHolder
const & rPage
, sal_uInt32 nOffset
)
520 (void)nOffset
; // NYI
521 return store_E_Unknown
; // NYI
525 storeError
save (PageHolder
& rxPage
, sal_uInt32 nOffset
)
527 storeError result
= PageHolderObject
<T
>::guard (rxPage
);
528 if (result
!= store_E_None
)
530 return saveAt (rxPage
, nOffset
);
533 storeError
lookupAt (PageHolder
& rPage
, sal_uInt32 nOffset
)
536 (void)nOffset
; // NYI
537 return store_E_NotExists
;
539 storeError
replaceAt (PageHolder
const & rPage
, sal_uInt32 nOffset
)
542 (void)nOffset
; // NYI
547 struct TestDataV1
: public PageData
549 static const sal_uInt32 theTypeId
= 6 * 9;
551 struct TestData
: public PageData
553 typedef PageData base
;
554 typedef TestData self
;
556 static const sal_uInt32 theTypeId
= 42;
561 // self::m_aGuard = ...;
563 storeError
verify() const
565 storeError result
= base::verify();
566 if (result
!= store_E_None
)
568 if (!(base::type() == self::theTypeId
))
569 return store_E_WrongVersion
;
573 storeError
dwim() const
578 class TestObject
: public PageObject
580 typedef PageObject base
;
586 PageHolderObject
< TestData
> xPage (m_xPage
);
592 TestData
* pagedata
= dynamic_page_cast
< TestData
>(m_xPage
.get());
596 virtual storeError
verify() const
598 storeError result
= base::verify();
599 if (result
!= store_E_None
)
602 TestData
const * pagedata
= dynamic_page_cast
< TestData
const >(m_xPage
.get());
604 return store_E_WrongVersion
;
606 return pagedata
->verify();
609 static storeError
verify (PageHolder
const & rPage
)
611 return PageHolderObject
< TestData
>::verify (rPage
);
614 storeError
loadAt (sal_uInt32 nOffset
, TestBIOS
& rBIOS
)
616 storeError result
= rBIOS
.lookupAt (m_xPage
, nOffset
); // cache lookup
617 if (result
== store_E_NotExists
)
619 result
= rBIOS
.loadAt (m_xPage
, nOffset
);
620 if (result
!= store_E_None
)
623 result
= PageHolderObject
< TestData
>::verify (m_xPage
);
624 if (result
!= store_E_None
)
627 result
= rBIOS
.replaceAt (m_xPage
, nOffset
); // cache insert
631 storeError
saveAt (sal_uInt32 nOffset
, TestBIOS
& rBIOS
)
634 return store_E_InvalidAccess
;
635 m_xPage
->m_aDescr
.m_nAddr
= store::htonl(nOffset
); // m_xPage->location (nOffset);
637 storeError result
= PageHolderObject
< TestData
>::guard (m_xPage
);
638 if (result
!= store_E_None
)
641 result
= rBIOS
.saveAt (m_xPage
, nOffset
);
642 if (result
!= store_E_None
)
645 return rBIOS
.replaceAt (m_xPage
, nOffset
); // cache update
649 class TestObjectV2
: public PageHolderObject
< TestData
>
651 typedef PageHolderObject
< TestData
> base
;
654 storeError
saveAt (sal_uInt32 nOffset
, TestBIOS
& rBIOS
)
656 m_xPage
->offset(nOffset
);
658 storeError result
= PageHolderObject
< TestData
>::guard (m_xPage
);
659 if (result
!= store_E_None
)
662 result
= rBIOS
.saveAt (m_xPage
, nOffset
);
663 if (result
!= store_E_None
)
666 return rBIOS
.replaceAt (m_xPage
, nOffset
);
669 storeError
dwim() const
671 TestData
const * pImpl1
= operator->();
673 PageHolderObject
< TestData
> xImpl (m_xPage
);
675 TestData
const * pImpl2
= &*xImpl
;
676 OSL_ASSERT(pImpl1
== pImpl2
);
678 return xImpl
->dwim();
686 void dwim(TestBIOS
& rBIOS
)
690 rBIOS
.loadPageAt(aObj
.get(), aObj
.verify
);
691 rBIOS
.loadPageAt(aObj
.get(), TestObject::verify
);
692 rBIOS
.loadPageAt(aObj
.get(), PageHolderObject
<TestData
>::verify
);
694 aObj
.loadAt (1024, rBIOS
);
702 /*======================================================================*/
704 class IPageAllocator
;
708 virtual storeError
initialize (storeAccessMode eAccessMode
, sal_uInt16 nPageSize
) = 0;
709 virtual IPageAllocator
& getAllocator () = 0;
712 storeError
readPageAt (PageHolder
& rPage
, sal_uInt32 nOffset
)
714 return readPageAt_Impl (rPage
, nOffset
);
716 storeError
writePageAt (PageHolder
const & rPage
, sal_uInt32 nOffset
)
718 // [SECURITY:ValInput]
719 PageData
const * pagedata
= rPage
.get();
720 OSL_PRECOND(!(pagedata
== 0), "invalid Page");
722 return store_E_InvalidParameter
;
724 sal_uInt32
const offset
= pagedata
->offset();
725 OSL_PRECOND(!(nOffset
!= offset
), "inconsistent Offset");
726 if (nOffset
!= offset
)
727 return store_E_InvalidParameter
;
729 OSL_PRECOND(!(nOffset
== STORE_PAGE_NULL
), "store::IPageAccess::writePageAt(): invalid Offset");
730 if (nOffset
== STORE_PAGE_NULL
)
731 return store_E_CantSeek
;
733 return writePageAt_Impl (rPage
, nOffset
);
736 storeError
peekAt (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
738 // [SECURITY:ValInput]
739 sal_uInt8
* dst_lo
= static_cast<sal_uInt8
*>(pBuffer
);
741 return store_E_InvalidParameter
;
743 sal_uInt8
* dst_hi
= dst_lo
+ nBytes
;
744 if (!(dst_lo
< dst_hi
))
745 return (dst_lo
> dst_hi
) ? store_E_InvalidParameter
: store_E_None
;
747 sal_uInt64
const dst_size
= nOffset
+ nBytes
;
748 if (dst_size
> SAL_MAX_UINT32
)
749 return store_E_CantSeek
;
751 return peekAt_Impl (nOffset
, dst_lo
, (dst_hi
- dst_lo
));
754 storeError
pokeAt (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
)
756 // [SECURITY:ValInput]
757 sal_uInt8
const * src_lo
= static_cast<sal_uInt8
const*>(pBuffer
);
759 return store_E_InvalidParameter
;
761 sal_uInt8
const * src_hi
= src_lo
+ nBytes
;
762 if (!(src_lo
< src_hi
))
763 return (src_lo
> src_hi
) ? store_E_InvalidParameter
: store_E_None
;
765 sal_uInt64
const dst_size
= nOffset
+ nBytes
;
766 if (dst_size
> SAL_MAX_UINT32
)
767 return store_E_CantSeek
;
769 return pokeAt_Impl (nOffset
, src_lo
, (src_hi
- src_lo
));
772 storeError
getSize (sal_uInt32
& rnSize
)
775 return getSize_Impl (rnSize
);
778 storeError
setSize (sal_uInt32 nSize
)
780 return setSize_Impl (nSize
);
784 virtual storeError
readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
) = 0;
785 virtual storeError
writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
) = 0;
787 virtual storeError
peekAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
) = 0;
788 virtual storeError
pokeAt_Impl (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
) = 0;
790 virtual storeError
getSize_Impl (sal_uInt32
& rnSize
) = 0;
791 virtual storeError
setSize_Impl (sal_uInt32 nSize
) = 0;
794 /*======================================================================*/
796 template< class T
> struct ResourceHolder
798 typedef typename
T::destructor_type destructor_type
;
802 explicit ResourceHolder (T
const & value
= T()) : m_value (value
) {}
803 ~ResourceHolder() { reset(); }
805 T
& get() { return m_value
; }
806 T
const & get() const { return m_value
; }
808 void set (T
const & value
) { m_value
= value
; }
809 void reset (T
const & value
= T())
813 destructor_type()(tmp
);
823 ResourceHolder (ResourceHolder
& rhs
)
827 ResourceHolder
& operator= (ResourceHolder
& rhs
)
829 reset (rhs
.release());
836 oslFileHandle m_handle
;
838 FileHandle() : m_handle(0) {}
840 operator oslFileHandle() { return m_handle
; }
842 bool operator != (FileHandle
const & rhs
)
844 return (m_handle
!= rhs
.m_handle
);
847 oslFileError
initialize (rtl_uString
* pFilename
, sal_uInt32 nFlags
)
850 if (!pFilename
|| !nFlags
)
851 return osl_File_E_INVAL
;
853 // Convert into FileUrl.
854 rtl::OUString aFileUrl
;
855 if (osl_getFileURLFromSystemPath (pFilename
, &(aFileUrl
.pData
)) != osl_File_E_None
)
857 // Not system path. Maybe a file url, already.
858 rtl_uString_assign (&(aFileUrl
.pData
), pFilename
);
862 return osl_openFile (aFileUrl
.pData
, &m_handle
, nFlags
);
867 void operator()(FileHandle
& rFile
) const
869 if (rFile
.m_handle
!= 0)
872 (void) osl_closeFile (rFile
.m_handle
);
877 typedef CloseFile destructor_type
;
885 FileMapping() : m_pAddr(0), m_uSize(0) {}
887 bool operator != (FileMapping
const & rhs
) const
889 return ((m_pAddr
!= rhs
.m_pAddr
) || (m_uSize
!= rhs
.m_uSize
));
892 oslFileError
initialize (oslFileHandle hFile
)
894 // Determine mapping size.
895 oslFileError result
= osl_getFileSize (hFile
, &m_uSize
);
896 if (result
!= osl_File_E_None
)
898 if (m_uSize
> SAL_MAX_UINT32
)
899 return osl_File_E_OVERFLOW
;
902 return osl_mapFile (hFile
, &m_pAddr
, m_uSize
, 0, 0);
907 void operator ()(FileMapping
& rMapping
) const
909 if ((rMapping
.m_pAddr
!= 0) && (rMapping
.m_uSize
!= 0))
912 (void) osl_unmapFile (rMapping
.m_pAddr
, rMapping
.m_uSize
);
913 rMapping
.m_pAddr
= 0, rMapping
.m_uSize
= 0;
917 typedef UnmapFile destructor_type
;
920 /*======================================================================*/
922 class FilePageAccess
: public IPageAccess
924 oslFileHandle m_hFile
;
927 static storeError
ERROR_FROM_NATIVE (oslFileError eErrno
);
928 static sal_uInt32
MODE_TO_NATIVE (storeAccessMode eMode
);
931 explicit FilePageAccess (oslFileHandle hFile
= 0) : m_hFile (hFile
) {}
932 virtual storeError
initialize (storeAccessMode eAccessMode
, sal_uInt16 nPageSize
);
935 virtual storeError
readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
);
936 virtual storeError
writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
);
938 /* see @ OFileLockBytes */
939 virtual storeError
peekAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
);
940 virtual storeError
pokeAt_Impl (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
);
942 virtual storeError
getSize_Impl (sal_uInt32
& rnSize
);
943 virtual storeError
setSize_Impl (sal_uInt32 nSize
);
946 virtual ~FilePageAccess();
951 FilePageAccess (FilePageAccess
const &);
952 FilePageAccess
& operator= (FilePageAccess
const &);
955 storeError
FilePageAccess::initialize (storeAccessMode eAccessMode
, sal_uInt16 nPageSize
)
957 (void) eAccessMode
; // UNUSED
958 (void) nPageSize
; // UNUSED
959 return store_E_Unknown
; // NYI
961 FilePageAccess::~FilePageAccess()
964 (void) osl_closeFile (m_hFile
);
966 storeError
FilePageAccess::readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
)
968 PageHolder
page (0/*allocate()*/); /* @@@ construct w/ deallocator argument @@@ */
970 return store_E_OutOfMemory
;
972 swap
<PageHolder
>(page
, rPage
);
973 return peekAt (nOffset
, rPage
.get(), 0/*size*/);
975 storeError
FilePageAccess::writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
)
977 return pokeAt (nOffset
, rPage
.get(), 0/*size*/);
979 storeError
FilePageAccess::peekAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
981 sal_uInt64 nDone
= 0;
982 oslFileError result
= osl_readFileAt (m_hFile
, nOffset
, pBuffer
, nBytes
, &nDone
);
983 if (result
!= osl_File_E_None
)
984 return ERROR_FROM_NATIVE(result
);
986 return (nDone
!= 0) ? store_E_CantRead
: store_E_NotExists
;
989 storeError
FilePageAccess::pokeAt_Impl (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
)
991 sal_uInt64 nDone
= 0;
992 oslFileError result
= osl_writeFileAt (m_hFile
, nOffset
, pBuffer
, nBytes
, &nDone
);
993 if (result
!= osl_File_E_None
)
994 return ERROR_FROM_NATIVE(result
);
996 return store_E_CantWrite
;
999 storeError
FilePageAccess::getSize_Impl (sal_uInt32
& rnSize
)
1001 sal_uInt64 uSize
= 0;
1002 oslFileError result
= osl_getFileSize (m_hFile
, &uSize
);
1003 if (result
!= osl_File_E_None
)
1004 return ERROR_FROM_NATIVE(result
);
1005 if (uSize
> SAL_MAX_UINT32
)
1006 return store_E_CantSeek
;
1008 rnSize
= sal::static_int_cast
<sal_uInt32
>(uSize
);
1009 return store_E_None
;
1011 storeError
FilePageAccess::setSize_Impl (sal_uInt32 nSize
)
1013 oslFileError result
= osl_setFileSize (m_hFile
, nSize
);
1014 if (result
!= osl_File_E_None
)
1015 return ERROR_FROM_NATIVE(result
);
1016 return store_E_None
;
1018 storeError
FilePageAccess::ERROR_FROM_NATIVE (oslFileError eErrno
)
1022 case osl_File_E_None
:
1023 return store_E_None
;
1025 case osl_File_E_NOENT
:
1026 return store_E_NotExists
;
1028 case osl_File_E_ACCES
:
1029 case osl_File_E_PERM
:
1030 return store_E_AccessViolation
;
1032 case osl_File_E_AGAIN
:
1033 case osl_File_E_DEADLK
:
1034 return store_E_LockingViolation
;
1036 case osl_File_E_BADF
:
1037 return store_E_InvalidHandle
;
1039 case osl_File_E_INVAL
:
1040 return store_E_InvalidParameter
;
1042 case osl_File_E_NOSPC
:
1043 return store_E_OutOfSpace
;
1045 case osl_File_E_OVERFLOW
:
1046 return store_E_CantSeek
;
1049 return store_E_Unknown
;
1052 sal_uInt32
FilePageAccess::MODE_TO_NATIVE(storeAccessMode eAccessMode
)
1054 sal_uInt32 nMode
= 0;
1055 switch (eAccessMode
)
1057 case store_AccessCreate
:
1058 case store_AccessReadCreate
:
1059 nMode
|= osl_File_OpenFlag_Create
;
1061 case store_AccessReadWrite
:
1062 nMode
|= osl_File_OpenFlag_Write
;
1064 case store_AccessReadOnly
:
1065 nMode
|= osl_File_OpenFlag_Read
;
1068 OSL_PRECOND(0, "store::FilePageAccess: unknown storeAccessMode");
1075 class MemoryPageAccess
: public IPageAccess
1079 sal_uInt8
* m_pData
;
1082 /** Callback function to release Representation.
1084 typedef void (*destructor_type
)(sal_uInt8
* pData
, sal_uInt32 nSize
);
1085 destructor_type m_destructor
;
1087 /** Default destructor callback.
1089 static void freeMemory (sal_uInt8
* pData
, sal_uInt32 nSize
);
1093 : m_pData (0), m_nSize (0), m_destructor (MemoryPageAccess::freeMemory
)
1095 MemoryPageAccess (sal_uInt8
* pData
, sal_uInt32 nSize
, destructor_type destructor
= MemoryPageAccess::freeMemory
)
1096 : m_pData (pData
), m_nSize (nSize
), m_destructor (destructor
)
1099 virtual storeError
initialize (storeAccessMode eAccessMode
, sal_uInt16 nPageSize
);
1102 /** Page (size aligned) access.
1104 virtual storeError
readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
);
1105 virtual storeError
writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
);
1107 /** Low level access.
1109 virtual storeError
peekAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
);
1110 virtual storeError
pokeAt_Impl (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
);
1112 virtual storeError
getSize_Impl (sal_uInt32
& rnSize
);
1113 virtual storeError
setSize_Impl (sal_uInt32 nSize
);
1116 virtual ~MemoryPageAccess();
1119 /** Not implemented.
1121 MemoryPageAccess (MemoryPageAccess
const &);
1122 MemoryPageAccess
& operator= (MemoryPageAccess
const &);
1125 storeError
MemoryPageAccess::initialize (storeAccessMode eAccessMode
, sal_uInt16 nPageSize
)
1127 (void) eAccessMode
; // UNUSED
1128 (void) nPageSize
; // UNUSED
1129 return store_E_Unknown
; // NYI
1131 MemoryPageAccess::~MemoryPageAccess()
1133 if (m_destructor
!= 0)
1135 // release resource.
1136 (*m_destructor
)(m_pData
, m_nSize
);
1139 storeError
MemoryPageAccess::readPageAt_Impl (PageHolder
& rPage
, sal_uInt32 nOffset
)
1141 /* OSL_PRECOND(nOffset % size == 0, "Unaligned page read."); */
1142 PageHolder
page (reinterpret_cast< PageData
* >(m_pData
+ nOffset
));
1143 swap
<PageHolder
>(page
, rPage
);
1144 return store_E_None
;
1146 storeError
MemoryPageAccess::writePageAt_Impl (PageHolder
const & rPage
, sal_uInt32 nOffset
)
1148 PageData
const * pagedata
= rPage
.get();
1149 if (!(pagedata
!= 0))
1150 return store_E_InvalidParameter
;
1152 return pokeAt (nOffset
, pagedata
, pagedata
->size());
1154 storeError
MemoryPageAccess::peekAt_Impl (sal_uInt32 nOffset
, void * pBuffer
, sal_uInt32 nBytes
)
1156 // [SECURITY:ValInput]
1157 sal_uInt8
* dst_lo
= static_cast<sal_uInt8
*>(pBuffer
);
1159 return store_E_InvalidParameter
;
1161 sal_uInt8
* dst_hi
= dst_lo
+ nBytes
;
1162 if (!(dst_lo
<= dst_hi
))
1163 return store_E_InvalidParameter
;
1166 sal_uInt8
const * src_lo
= m_pData
+ nOffset
;
1167 if (!(src_lo
<= m_pData
+ m_nSize
))
1168 return store_E_CantSeek
;
1170 sal_uInt8
const * src_hi
= src_lo
+ nBytes
;
1171 if (!(src_hi
<= m_pData
+ m_nSize
))
1172 return store_E_CantRead
;
1175 memcpy (pBuffer
, src_lo
, (src_hi
- src_lo
));
1176 return store_E_None
;
1178 storeError
MemoryPageAccess::pokeAt_Impl (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
)
1180 // [SECURITY:ValInput]
1181 sal_uInt8
const * src_lo
= static_cast<sal_uInt8
const*>(pBuffer
);
1183 return store_E_InvalidParameter
;
1185 sal_uInt8
const * src_hi
= src_lo
+ nBytes
;
1186 if (!(src_lo
<= src_hi
))
1187 return store_E_InvalidParameter
;
1189 sal_uInt64
const uSize
= nOffset
+ nBytes
;
1190 if (uSize
> SAL_MAX_UINT32
)
1191 return store_E_CantSeek
;
1194 if (uSize
> m_nSize
)
1197 storeError eErrCode
= setSize (sal::static_int_cast
<sal_uInt32
>(uSize
));
1198 if (eErrCode
!= store_E_None
)
1202 sal_uInt8
* dst_lo
= m_pData
+ nOffset
;
1203 if (!(dst_lo
<= m_pData
+ m_nSize
))
1204 return store_E_CantSeek
;
1206 sal_uInt8
* dst_hi
= dst_lo
+ nBytes
;
1207 if (!(dst_hi
<= m_pData
+ m_nSize
))
1208 return store_E_CantWrite
;
1211 memcpy (dst_lo
, src_lo
, (src_hi
- src_lo
));
1212 return store_E_None
;
1214 storeError
MemoryPageAccess::getSize_Impl (sal_uInt32
& rnSize
)
1217 return store_E_None
;
1219 storeError
MemoryPageAccess::setSize_Impl (sal_uInt32 nSize
)
1221 if (nSize
!= m_nSize
)
1223 sal_uInt8
* pData
= static_cast<sal_uInt8
*>(rtl_reallocateMemory (m_pData
, nSize
));
1226 if (nSize
> m_nSize
)
1227 memset (pData
+ m_nSize
, 0, sal::static_int_cast
< size_t >(nSize
- m_nSize
));
1232 return store_E_OutOfMemory
;
1234 m_pData
= pData
, m_nSize
= nSize
;
1236 return store_E_None
;
1238 void MemoryPageAccess::freeMemory (sal_uInt8
* pData
, sal_uInt32
/*nSize*/)
1240 rtl_freeMemory (pData
);
1245 class MappedPageAccess
: public MemoryPageAccess
1247 /** @see MemoryPageAccess::destructor_type callback function.
1249 static void unmapFile (sal_uInt8
* pData
, sal_uInt32 nSize
);
1252 MappedPageAccess (sal_uInt8
* pData
, sal_uInt32 nSize
);
1254 virtual storeError
initialize (storeAccessMode eAccessMode
, sal_uInt16 nPageSize
);
1256 virtual storeError
writePageAt (PageHolder
const & rPage
, sal_uInt32 nOffset
);
1259 virtual storeError
pokeAt_Impl (sal_uInt32 nOffset
, void const * pBuffer
, sal_uInt32 nBytes
);
1260 virtual storeError
setSize_Impl (sal_uInt32 nSize
);
1263 virtual ~MappedPageAccess() {}
1266 MappedPageAccess::MappedPageAccess (sal_uInt8
* pData
, sal_uInt32 nSize
)
1267 : MemoryPageAccess (pData
, nSize
, MappedPageAccess::unmapFile
)
1270 storeError
MappedPageAccess::initialize (storeAccessMode eAccessMode
, sal_uInt16 nPageSize
)
1272 OSL_PRECOND(eAccessMode
== store_AccessReadOnly
, "store::MappedPageAccess: invalid AccessMode");
1273 return MemoryPageAccess::initialize (eAccessMode
, nPageSize
);
1275 storeError
MappedPageAccess::writePageAt (PageHolder
const & /*rPage*/, sal_uInt32
/*nOffset*/)
1277 return store_E_AccessViolation
;
1279 storeError
MappedPageAccess::pokeAt_Impl (sal_uInt32
/*nOffset*/, void const * /*pBuffer*/, sal_uInt32
/*nBytes*/)
1281 return store_E_AccessViolation
;
1283 storeError
MappedPageAccess::setSize_Impl (sal_uInt32
/*nSize*/)
1285 return store_E_AccessViolation
;
1287 void MappedPageAccess::unmapFile (sal_uInt8
* pData
, sal_uInt32 nSize
)
1289 (void) osl_unmapFile (pData
, nSize
);
1292 /*========================================================================
1296 *======================================================================*/
1300 int SAL_CALL
main (int argc
, char ** argv
)
1302 OSL_PRECOND(argc
>= 1, "t_page: error: insufficient number of arguments.");
1307 void *a
= (void*)1, *b
= (void*)2;
1322 aClient
.dwim (aBIOS
);
1327 rtl_uString
* pFilename
= 0;
1328 rtl_uString_newFromAscii (&pFilename
, argv
[1]);
1329 storeAccessMode eAccessMode
= store_AccessReadOnly
;
1331 // Acquire file handle.
1332 ResourceHolder
<FileHandle
> h1
;
1333 oslFileError result
= h1
.get().initialize (pFilename
, FilePageAccess::MODE_TO_NATIVE(eAccessMode
));
1334 if (result
== osl_File_E_None
)
1336 ResourceHolder
<FileHandle
> h2 (h1
);
1339 if (eAccessMode
== store_AccessReadOnly
)
1341 ResourceHolder
<FileMapping
> m1
;
1342 result
= m1
.get().initialize (h1
.get());
1344 const sal_uInt32 nSize
= sal::static_int_cast
<sal_uInt32
>(m1
.get().m_uSize
);
1345 (void) nSize
; // UNUSED
1347 ResourceHolder
<FileMapping
> m2 (m1
);
1350 result
= osl_File_E_None
;
1358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */