xref: /aoo41x/main/store/workben/t_page.cxx (revision cdf0e10c)
1 /*
2  * t_page.cxx
3  */
4 
5 #include "osl/diagnose.h"
6 #include "rtl/alloc.h"
7 #include "rtl/ref.hxx"
8 
9 #include "storbase.hxx"
10 
11 #include "osl/file.h"
12 #include "rtl/ustring.hxx"
13 
14 /*========================================================================
15  *
16  * OTest...
17  *
18  *======================================================================*/
19 
20 template< class T > void swap (T & lhs, T & rhs)
21 {
22   T tmp = rhs; rhs = lhs; lhs = tmp;
23 }
24 
25 /*======================================================================*/
26 
27 class SharedCount
28 {
29   long * m_pCount;
30 
31   class Allocator
32   {
33     rtl_cache_type * m_cache;
34 
35   public:
36     static Allocator & get();
37 
38     long * alloc()
39     {
40       return static_cast<long*>(rtl_cache_alloc (m_cache));
41     }
42     void free (long * pCount)
43     {
44       rtl_cache_free (m_cache, pCount);
45     }
46 
47   protected:
48     Allocator();
49     ~Allocator();
50   };
51 
52 public:
53   SharedCount()
54     : m_pCount(Allocator::get().alloc())
55   {
56     if (m_pCount != 0) (*m_pCount) = 1;
57   }
58 
59   ~SharedCount()
60   {
61     if (m_pCount != 0)
62     {
63       long new_count = --(*m_pCount);
64       if (new_count == 0)
65 	Allocator::get().free(m_pCount);
66     }
67   }
68 
69   bool operator== (long count) const
70   {
71     return (m_pCount != 0) ? *m_pCount == count : false;
72   }
73 
74   friend void swap<> (SharedCount & lhs, SharedCount & rhs); // nothrow
75 
76   SharedCount (SharedCount const & rhs); // nothrow
77   SharedCount & operator= (SharedCount const & rhs); // nothrow
78 };
79 
80 template<>
81 inline void swap (SharedCount & lhs, SharedCount & rhs) // nothrow
82 {
83     swap<long*>(lhs.m_pCount, rhs.m_pCount);
84 }
85 
86 SharedCount::SharedCount (SharedCount const & rhs) // nothrow
87     : m_pCount (rhs.m_pCount)
88 {
89     if (m_pCount != 0) ++(*m_pCount);
90 }
91 
92 SharedCount &
93 SharedCount::operator= (SharedCount const & rhs) // nothrow
94 {
95     SharedCount tmp(rhs);
96     swap<SharedCount>(tmp, *this);
97     return *this;
98 }
99 
100 SharedCount::Allocator &
101 SharedCount::Allocator::get()
102 {
103     static Allocator g_aSharedCountAllocator;
104     return g_aSharedCountAllocator;
105 }
106 
107 SharedCount::Allocator::Allocator()
108 {
109     m_cache = rtl_cache_create (
110         "store_shared_count_cache",
111         sizeof(long),
112         0, // objalign
113         0, // constructor
114         0, // destructor
115         0, // reclaim
116         0, // userarg
117         0, // default source
118         0  // flags
119         );
120 }
121 
122 SharedCount::Allocator::~Allocator()
123 {
124     rtl_cache_destroy (m_cache), m_cache = 0;
125 }
126 
127 /*======================================================================*/
128 
129 #if 0  /* OLD */
130 
131 typedef store::OStorePageData PageData;
132 
133 #else  /* NEW */
134 
135 #if defined(OSL_BIGENDIAN)
136 #define STORE_DWORD(dword) OSL_SWAPDWORD((dword))
137 #else
138 #define STORE_DWORD(dword) (dword)
139 #endif
140 
141 struct PageData
142 {
143     typedef store::OStorePageGuard      G;
144     typedef store::OStorePageDescriptor D;
145     typedef store::OStorePageLink       L;
146 
147     /** Representation.
148      */
149     G m_aGuard;
150     D m_aDescr;
151     L m_aMarked;
152     L m_aUnused;
153 
154     /** theSize.
155      */
156     static const size_t     theSize     = sizeof(G) + sizeof(D) + 2 * sizeof(L);
157     static const sal_uInt16 thePageSize = theSize;
158     STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= thePageSize);
159 
160     /** type.
161      */
162     sal_uInt32 type() const { return m_aGuard.m_nMagic; /* @@@ */ }
163 
164     /** offset.
165      */
166     sal_uInt32 offset() const { return m_aDescr.m_nAddr; /* @@@ */ }
167     void offset (sal_uInt32 nOffset) { m_aDescr.m_nAddr = nOffset; }
168 
169     /** size.
170      */
171     sal_uInt16 size() const { return m_aDescr.m_nSize; /* @@@ */ }
172 
173     /** Allocation.
174      */
175     class Allocator : public rtl::IReference
176     {
177     public:
178         template< class T > T * construct()
179         {
180             void * page = 0; sal_uInt16 size = 0;
181             if (allocate (&page, &size))
182             {
183                 return new(page) T(size);
184             }
185             return 0;
186         }
187 
188         virtual bool allocate (void ** ppPage, sal_uInt16 * pnSize) = 0;
189         virtual void deallocate (void * pPage) = 0;
190     };
191 
192     static void * operator new (size_t, void * p) { return p; }
193     static void   operator delete (void *, void *) {}
194 
195     /** Construction.
196      */
197     explicit PageData (sal_uInt16 nPageSize = thePageSize)
198         : m_aDescr (STORE_PAGE_NULL, nPageSize, thePageSize)
199     {}
200 
201     /** ...
202      */
203     void guard()
204     {}
205 
206     storeError verify() const
207     {
208         return store_E_None;
209     }
210 };
211 
212 #endif /* NEW */
213 
214 class IPageAllocator
215 {
216 public:
217   virtual void deallocate (void * p) = 0;
218 };
219 
220 class PageAllocator
221 {
222     rtl_cache_type * m_cache;
223     SharedCount      m_refcount;
224 
225 public:
226     PageAllocator()
227         : m_cache(0), m_refcount()
228     {}
229 
230     ~PageAllocator()
231     {
232         // NYI
233         if (m_refcount == 1)
234         {
235         }
236     }
237 
238     friend void swap<>(PageAllocator & lhs, PageAllocator & rhs);
239 
240     PageAllocator (PageAllocator const & rhs);
241     PageAllocator & operator= (PageAllocator const & rhs);
242 };
243 
244 template<>
245 inline void swap (PageAllocator & lhs, PageAllocator & rhs)
246 {
247     swap<rtl_cache_type*>(lhs.m_cache, rhs.m_cache);
248     swap<SharedCount>(lhs.m_refcount, rhs.m_refcount);
249 }
250 
251 PageAllocator::PageAllocator (PageAllocator const & rhs)
252     : m_cache (rhs.m_cache),
253       m_refcount (rhs.m_refcount)
254 {
255 }
256 
257 PageAllocator &
258 PageAllocator::operator= (PageAllocator const & rhs)
259 {
260     PageAllocator tmp (rhs);
261     swap<PageAllocator>(tmp, *this);
262     return *this;
263 }
264 
265 /*======================================================================*/
266 
267 class PageHolder
268 {
269     SharedCount m_refcount;
270     PageData  * m_pagedata;
271 
272     typedef rtl::Reference< PageData::Allocator > allocator_type;
273     allocator_type m_allocator;
274 
275 public:
276     explicit PageHolder (PageData * pagedata = 0, allocator_type const & allocator = allocator_type())
277         : m_refcount (),
278           m_pagedata (pagedata),
279           m_allocator(allocator)
280     {}
281 
282     ~PageHolder()
283     {
284         if ((m_refcount == 1) && (m_pagedata != 0) && m_allocator.is())
285         {
286             // free pagedata.
287             m_allocator->deallocate (m_pagedata);
288         }
289     }
290 
291     PageData * get() { return m_pagedata; }
292     PageData const * get() const { return m_pagedata; }
293 
294     PageData * operator->() { return m_pagedata; }
295     PageData const * operator->() const { return m_pagedata; }
296 
297     friend void swap<> (PageHolder & lhs, PageHolder & rhs); // nothrow
298 
299     PageHolder (PageHolder const & rhs); // nothrow
300     PageHolder & operator= (PageHolder const & rhs); // nothrow
301 };
302 
303 template<>
304 inline void swap (PageHolder & lhs, PageHolder & rhs) // nothrow
305 {
306     swap<SharedCount>(lhs.m_refcount, rhs.m_refcount);
307     swap<PageData*>(lhs.m_pagedata, rhs.m_pagedata);
308     swap<PageHolder::allocator_type>(lhs.m_allocator, rhs.m_allocator);
309 }
310 
311 PageHolder::PageHolder (PageHolder const & rhs) // nothrow
312     : m_refcount (rhs.m_refcount),
313       m_pagedata (rhs.m_pagedata),
314       m_allocator(rhs.m_allocator)
315 {}
316 
317 PageHolder &
318 PageHolder::operator= (PageHolder const & rhs) // nothrow
319 {
320     PageHolder tmp (rhs);
321     swap<PageHolder>(tmp, *this);
322     return *this;
323 }
324 
325 /*======================================================================*/
326 
327 template< class T >
328 class PageHolderObject
329 {
330 protected:
331     /** Representation.
332      */
333     PageHolder m_xPage;
334 
335     /** Checked cast.
336      */
337     template< class U >
338     static bool isA (PageData const * p)
339     {
340         return ((p != 0) && (p->type() == U::theTypeId));
341     }
342 
343     template< class U >
344     static U * dynamic_page_cast (PageData * p)
345     {
346         return isA<U>(p) ? static_cast<U*>(p) : 0;
347     }
348 
349     template< class U >
350     static U const * dynamic_page_cast (PageData const * p)
351     {
352         return isA<U>(p) ? static_cast<U const *>(p) : 0;
353     }
354 
355 public:
356     static PageHolderObject<T> construct (rtl::Reference< PageData::Allocator > const & rxAllocator)
357     {
358         PageHolderObject<T> tmp;
359         if (rxAllocator.is())
360         {
361             PageHolder xPage (rxAllocator->construct<T>(), rxAllocator);
362             store::swap<PageHolder>(tmp.m_xPage, xPage);
363         }
364         return tmp;
365     }
366 
367     explicit PageHolderObject (PageHolder const & rxPage = PageHolder())
368         : m_xPage (rxPage)
369     {}
370 
371     void swap (PageHolderObject<T> & rhs)
372     {
373         store::swap<PageHolder>(m_xPage, rhs.m_xPage);
374     }
375 
376     PageHolderObject (PageHolderObject<T> const & rhs)
377         : m_xPage (rhs.m_xPage)
378     {
379     }
380 
381     PageHolderObject<T> & operator= (PageHolderObject<T> const & rhs)
382     {
383         PageHolderObject<T> tmp (rhs);
384         this->swap(tmp);
385         return *this;
386     }
387 
388     T * operator->()
389     {
390         T * pImpl = dynamic_page_cast<T>(m_xPage.get());
391         OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator->(): Null pointer");
392         return pImpl;
393     }
394     T const * operator->() const
395     {
396         T const * pImpl = dynamic_page_cast<T>(m_xPage.get());
397         OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator->(): Null pointer");
398         return pImpl;
399     }
400 
401     T & operator*()
402     {
403         T * pImpl = dynamic_page_cast<T>(m_xPage.get());
404         OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
405         return *pImpl;
406     }
407     T const & operator*() const
408     {
409         T const * pImpl = dynamic_page_cast<T>(m_xPage.get());
410         OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
411         return *pImpl;
412     }
413 
414     static storeError guard (PageHolder & rxPage)
415     {
416         T * pImpl = dynamic_page_cast<T>(rxPage.get());
417         if (pImpl != 0)
418         { pImpl->guard(); return store_E_None; }
419         else if (rxPage.get() != 0)
420             return store_E_WrongVersion;
421         else
422             return store_E_InvalidAccess;
423     }
424     static storeError verify (PageHolder const & rxPage)
425     {
426         T const * pImpl = dynamic_page_cast<T>(rxPage.get());
427         if (pImpl != 0)
428             return pImpl->verify();
429         else if (rxPage.get() != 0)
430             return store_E_WrongVersion;
431         else
432             return store_E_InvalidAccess;
433     }
434 };
435 
436 /*======================================================================*/
437 
438 class PageObject
439 {
440 public:
441     explicit PageObject (PageHolder const & rxPage = PageHolder())
442         : m_xPage (rxPage)
443     {}
444 
445     virtual ~PageObject();
446 
447     PageHolder & get() { return m_xPage; }
448     PageHolder const & get() const { return m_xPage; }
449 
450     PageData * operator->()
451     {
452         PageData * pImpl = m_xPage.get();
453         OSL_PRECOND(pImpl != 0, "store::PageObject::operator->(): Null pointer");
454         return pImpl;
455     }
456     PageData & operator*()
457     {
458         PageData * pImpl = m_xPage.get();
459         OSL_PRECOND(pImpl != 0, "store::PageObject::operator*(): Null pointer");
460         return *pImpl;
461     }
462 
463     virtual void guard();
464     virtual storeError verify() const;
465 
466 protected:
467     PageHolder m_xPage;
468 };
469 
470 PageObject::~PageObject()
471 {}
472 void PageObject::guard()
473 {
474     PageData * p = m_xPage.get();
475     p->guard();
476 }
477 storeError PageObject::verify() const
478 {
479     PageData const * p = m_xPage.get();
480     return p->verify();
481 }
482 
483 /*======================================================================*/
484 
485 template< class T >
486 T * dynamic_page_cast (PageData * pagedata)
487 {
488     if ((pagedata != 0) && (pagedata->type() == T::theTypeId))
489         return static_cast<T*>(pagedata);
490     return 0;
491 }
492 
493 template< class T >
494 T * dynamic_page_cast (PageData const * pagedata)
495 {
496     if ((pagedata != 0) && (pagedata->type() == T::theTypeId))
497         return static_cast<T*>(pagedata);
498     return 0;
499 }
500 
501 /*======================================================================*/
502 
503 class TestBIOS
504 {
505 public:
506     storeError loadPageAt (PageHolder & rPage, storeError (*pfnVerify)(PageHolder const &))
507     {
508         return (pfnVerify)(rPage);
509     }
510 
511     storeError allocate (PageHolder & rxPage, ...)
512     {
513         // NYI: PageObject.save(nAddr, *this);
514         (void)rxPage; // NYI
515         return store_E_Unknown; // NYI
516     }
517 
518     storeError loadAt (PageHolder & rPage, sal_uInt32 nOffset)
519     {
520         (void)rPage; // NYI
521         (void)nOffset; // NYI
522         return store_E_Unknown; // NYI
523     }
524     storeError saveAt (PageHolder const & rPage, sal_uInt32 nOffset)
525     {
526         (void)rPage; // NYI
527         (void)nOffset; // NYI
528         return store_E_Unknown; // NYI
529     }
530 
531     template< class T >
532     storeError save (PageHolder & rxPage, sal_uInt32 nOffset)
533     {
534         storeError result = PageHolderObject<T>::guard (rxPage);
535         if (result != store_E_None)
536             return result;
537         return saveAt (rxPage, nOffset);
538     }
539 
540     storeError lookupAt (PageHolder & rPage, sal_uInt32 nOffset)
541     {
542         (void)rPage; // NYI
543         (void)nOffset; // NYI
544         return store_E_NotExists;
545     }
546     storeError replaceAt (PageHolder const & rPage, sal_uInt32 nOffset)
547     {
548         (void)rPage; // NYI
549         (void)nOffset; // NYI
550         return store_E_None;
551     }
552 };
553 
554 struct TestDataV1 : public PageData
555 {
556     static const sal_uInt32 theTypeId = 6 * 9;
557 };
558 struct TestData : public PageData
559 {
560     typedef PageData base;
561     typedef TestData self;
562 
563     static const sal_uInt32 theTypeId = 42;
564 
565     void guard()
566     {
567         base::guard();
568         // self::m_aGuard = ...;
569     }
570     storeError verify() const
571     {
572         storeError result = base::verify();
573         if (result != store_E_None)
574             return result;
575         if (!(base::type() == self::theTypeId))
576             return store_E_WrongVersion;
577         return store_E_None;
578     }
579 
580     storeError dwim() const
581     {
582         return store_E_None;
583     }
584 };
585 class TestObject : public PageObject
586 {
587     typedef PageObject base;
588 
589 public:
590 
591     void dwim()
592     {
593         PageHolderObject< TestData > xPage (m_xPage);
594         xPage->guard();
595     }
596 
597     virtual void guard()
598     {
599         TestData * pagedata = dynamic_page_cast< TestData >(m_xPage.get());
600         if (pagedata != 0)
601         {}
602     }
603     virtual storeError verify() const
604     {
605         storeError result = base::verify();
606         if (result != store_E_None)
607             return result;
608 
609         TestData const * pagedata = dynamic_page_cast< TestData const >(m_xPage.get());
610         if (!pagedata)
611             return store_E_WrongVersion;
612 
613         return pagedata->verify();
614     }
615 
616     static storeError verify (PageHolder const & rPage)
617     {
618         return PageHolderObject< TestData >::verify (rPage);
619     }
620 
621     storeError loadAt (sal_uInt32 nOffset, TestBIOS & rBIOS)
622     {
623         storeError result = rBIOS.lookupAt (m_xPage, nOffset); // cache lookup
624         if (result == store_E_NotExists)
625         {
626             result = rBIOS.loadAt (m_xPage, nOffset);
627             if (result != store_E_None)
628                 return result;
629 
630             result = PageHolderObject< TestData >::verify (m_xPage);
631             if (result != store_E_None)
632                 return result;
633 
634             result = rBIOS.replaceAt (m_xPage, nOffset); // cache insert
635         }
636         return result;
637     }
638     storeError saveAt (sal_uInt32 nOffset, TestBIOS & rBIOS)
639     {
640         if (!m_xPage.get())
641             return store_E_InvalidAccess;
642         m_xPage->m_aDescr.m_nAddr = store::htonl(nOffset); // m_xPage->location (nOffset);
643 
644         storeError result = PageHolderObject< TestData >::guard (m_xPage);
645         if (result != store_E_None)
646             return result;
647 
648         result = rBIOS.saveAt (m_xPage, nOffset);
649         if (result != store_E_None)
650             return result;
651 
652         return rBIOS.replaceAt (m_xPage, nOffset); // cache update
653     }
654 };
655 
656 class TestObjectV2 : public PageHolderObject< TestData >
657 {
658     typedef PageHolderObject< TestData > base;
659 
660 public:
661     storeError saveAt (sal_uInt32 nOffset, TestBIOS & rBIOS)
662     {
663         m_xPage->offset(nOffset);
664 
665         storeError result = PageHolderObject< TestData >::guard (m_xPage);
666         if (result != store_E_None)
667             return result;
668 
669         result = rBIOS.saveAt (m_xPage, nOffset);
670         if (result != store_E_None)
671             return result;
672 
673         return rBIOS.replaceAt (m_xPage, nOffset);
674     }
675 #if 1
676     storeError dwim() const
677     {
678         TestData const * pImpl1 = operator->();
679 
680         PageHolderObject< TestData > xImpl (m_xPage);
681 
682         TestData const * pImpl2 = &*xImpl;
683         OSL_ASSERT(pImpl1 == pImpl2);
684 
685         return xImpl->dwim();
686     }
687 #endif
688 };
689 
690 class TestClient
691 {
692 public:
693     void dwim(TestBIOS & rBIOS)
694     {
695         TestObject aObj;
696 
697         rBIOS.loadPageAt(aObj.get(), aObj.verify);
698         rBIOS.loadPageAt(aObj.get(), TestObject::verify);
699         rBIOS.loadPageAt(aObj.get(), PageHolderObject<TestData>::verify);
700 
701         aObj.loadAt (1024, rBIOS);
702 
703         TestObjectV2 aObj2;
704         aObj2.dwim();
705         aObj2->dwim();
706     }
707 };
708 
709 /*======================================================================*/
710 #if 0  /* NYI */
711 BIOS::load (PageObject & rPage, sal_uInt32 nOffset)
712 {
713     result = m_xCache->readPageAt (rPage.get(), nOffset);
714     if (result == NotExists)
715     {
716         result = m_xLockBytes->readPageAt (rPage.get(), nOffset);
717         if (result != None)
718             return result;
719 
720         result = rPage.verify();
721         if (result != None)
722             return result;
723 
724         result = m_xCache->writePageAt (rPage.get(), nOffset);
725     }
726     return result;
727 }
728 BIOS::save (PageObject & rPage, sal_uInt32 nOffset)
729 {
730     rPage.guard();
731     result = m_xLockBytes->writePageAt (rPage.get(), nOffset);
732     if (result != None)
733         return result;
734 
735     return m_xCache->writePageAt (rPage.get(), nOffset);
736 }
737 BIOS::init (rxLockBytes, eAccessMode, nPageSize)
738 {
739     SuperPage super;
740     if (eAccessMode == store_AccessCreate)
741     {
742         sal_uInt16 pagesize = nPageSize;
743         if ((STORE_MINIMUM_PAGESIZE > pagesize) || (pagesize > STORE_MAXIMUM_PAGESIZE))
744             return store_E_InvalidParameter;
745 
746         pagesize = ((pagesize + STORE_MINIMUM_PAGESIZE - 1) & ~(STORE_MINIMUM_PAGESIZE - 1));
747         rxLockBytes->init (pagesize);
748 
749         super = allocator->construct<SuperPage>();
750         super->guard();
751 
752         rxLockBytes->writeAt (0, super, super->size());
753 
754     }
755     if (eAccessMode != store_AccessCreate)
756     {
757         rxLockBytes->readAt (0, &super, super::theSize);
758 
759         super.verify();
760     }
761     if (eErrCode != store_E_NotExists)
762 
763 
764 }
765 #endif /* NYI */
766 /*======================================================================*/
767 
768 #if 0  /* NYI */
769 class PageCache
770 {
771   std::set<const sal_uInt32, PageObject> m_pages;
772 public:
773   storeError readPageAt (PageObject & rPage, sal_uInt32 nOffset);
774   storeError writePageAt (PageObject const & rPage, sal_uInt32 nOffset);
775 };
776 #endif /* NYI */
777 
778 /*======================================================================*/
779 
780 class IPageAllocator;
781 class IPageAccess
782 {
783 public:
784     virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize) = 0;
785     virtual IPageAllocator & getAllocator () = 0;
786 
787 public:
788     storeError readPageAt (PageHolder & rPage, sal_uInt32 nOffset)
789     {
790         return readPageAt_Impl (rPage, nOffset);
791     }
792     storeError writePageAt (PageHolder const & rPage, sal_uInt32 nOffset)
793     {
794         // [SECURITY:ValInput]
795         PageData const * pagedata = rPage.get();
796         OSL_PRECOND(!(pagedata == 0), "invalid Page");
797         if (pagedata == 0)
798             return store_E_InvalidParameter;
799 
800         sal_uInt32 const offset = pagedata->offset();
801         OSL_PRECOND(!(nOffset != offset), "inconsistent Offset");
802         if (nOffset != offset)
803             return store_E_InvalidParameter;
804 
805         OSL_PRECOND(!(nOffset == STORE_PAGE_NULL), "store::IPageAccess::writePageAt(): invalid Offset");
806         if (nOffset == STORE_PAGE_NULL)
807             return store_E_CantSeek;
808 
809         return writePageAt_Impl (rPage, nOffset);
810     }
811 
812     storeError peekAt (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes)
813     {
814         // [SECURITY:ValInput]
815         sal_uInt8 * dst_lo = static_cast<sal_uInt8*>(pBuffer);
816         if (!(dst_lo != 0))
817             return store_E_InvalidParameter;
818 
819         sal_uInt8 * dst_hi = dst_lo + nBytes;
820         if (!(dst_lo < dst_hi))
821             return (dst_lo > dst_hi) ? store_E_InvalidParameter : store_E_None;
822 
823         sal_uInt64 const dst_size = nOffset + nBytes;
824         if (dst_size > SAL_MAX_UINT32)
825             return store_E_CantSeek;
826 
827         return peekAt_Impl (nOffset, dst_lo, (dst_hi - dst_lo));
828     }
829 
830     storeError pokeAt (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes)
831     {
832         // [SECURITY:ValInput]
833         sal_uInt8 const * src_lo = static_cast<sal_uInt8 const*>(pBuffer);
834         if (!(src_lo != 0))
835             return store_E_InvalidParameter;
836 
837         sal_uInt8 const * src_hi = src_lo + nBytes;
838         if (!(src_lo < src_hi))
839             return (src_lo > src_hi) ? store_E_InvalidParameter : store_E_None;
840 
841         sal_uInt64 const dst_size = nOffset + nBytes;
842         if (dst_size > SAL_MAX_UINT32)
843             return store_E_CantSeek;
844 
845         return pokeAt_Impl (nOffset, src_lo, (src_hi - src_lo));
846     }
847 
848     storeError getSize (sal_uInt32 & rnSize)
849     {
850         rnSize = 0;
851         return getSize_Impl (rnSize);
852     }
853 
854     storeError setSize (sal_uInt32 nSize)
855     {
856         return setSize_Impl (nSize);
857     }
858 
859 private:
860     virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset) = 0;
861     virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset) = 0;
862 
863     virtual storeError peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes) = 0;
864     virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes) = 0;
865 
866     virtual storeError getSize_Impl (sal_uInt32 & rnSize) = 0;
867     virtual storeError setSize_Impl (sal_uInt32 nSize) = 0;
868 };
869 
870 /*======================================================================*/
871 
872 template< class T > struct ResourceHolder
873 {
874     typedef typename T::destructor_type destructor_type;
875 
876   T m_value;
877 
878   explicit ResourceHolder (T const & value = T()) : m_value (value) {}
879   ~ResourceHolder() { reset(); }
880 
881   T & get() { return m_value; }
882   T const & get() const { return m_value; }
883 
884   void set (T const & value) { m_value = value; }
885   void reset (T const & value = T())
886   {
887     T tmp (m_value);
888     if (tmp != value)
889       destructor_type()(tmp);
890     set (value);
891   }
892   T release()
893   {
894     T tmp (m_value);
895     set (T());
896     return tmp;
897   }
898 
899   ResourceHolder (ResourceHolder & rhs)
900   {
901     set (rhs.release());
902   }
903   ResourceHolder & operator= (ResourceHolder & rhs)
904   {
905     reset (rhs.release());
906     return *this;
907   }
908 };
909 
910 struct FileHandle
911 {
912   oslFileHandle m_handle;
913 
914   FileHandle() : m_handle(0) {}
915 
916   operator oslFileHandle() { return m_handle; }
917 
918   bool operator != (FileHandle const & rhs)
919   {
920     return (m_handle != rhs.m_handle);
921   }
922 
923   oslFileError initialize (rtl_uString * pFilename, sal_uInt32 nFlags)
924   {
925     // Verify arguments.
926     if (!pFilename || !nFlags)
927       return osl_File_E_INVAL;
928 
929     // Convert into FileUrl.
930     rtl::OUString aFileUrl;
931     if (osl_getFileURLFromSystemPath (pFilename, &(aFileUrl.pData)) != osl_File_E_None)
932     {
933       // Not system path. Maybe a file url, already.
934       rtl_uString_assign (&(aFileUrl.pData), pFilename);
935     }
936 
937     // Acquire handle.
938     return osl_openFile (aFileUrl.pData, &m_handle, nFlags);
939   }
940 
941   struct CloseFile
942   {
943     void operator()(FileHandle & rFile) const
944     {
945       if (rFile.m_handle != 0)
946       {
947 	// Release handle.
948 	(void) osl_closeFile (rFile.m_handle);
949 	rFile.m_handle = 0;
950       }
951     }
952   };
953   typedef CloseFile destructor_type;
954 };
955 
956 struct FileMapping
957 {
958   void *     m_pAddr;
959   sal_uInt64 m_uSize;
960 
961   FileMapping() : m_pAddr(0), m_uSize(0) {}
962 
963   bool operator != (FileMapping const & rhs) const
964   {
965     return ((m_pAddr != rhs.m_pAddr) || (m_uSize != rhs.m_uSize));
966   }
967 
968   oslFileError initialize (oslFileHandle hFile)
969   {
970     // Determine mapping size.
971     oslFileError result = osl_getFileSize (hFile, &m_uSize);
972     if (result != osl_File_E_None)
973       return result;
974     if (m_uSize > SAL_MAX_UINT32)
975       return osl_File_E_OVERFLOW;
976 
977     // Acquire mapping.
978     return osl_mapFile (hFile, &m_pAddr, m_uSize, 0, 0);
979   }
980 
981   struct UnmapFile
982   {
983     void operator ()(FileMapping & rMapping) const
984     {
985       if ((rMapping.m_pAddr != 0) && (rMapping.m_uSize != 0))
986       {
987 	// Release mapping.
988 	(void) osl_unmapFile (rMapping.m_pAddr, rMapping.m_uSize);
989 	rMapping.m_pAddr = 0, rMapping.m_uSize = 0;
990       }
991     }
992   };
993   typedef UnmapFile destructor_type;
994 };
995 
996 /*======================================================================*/
997 
998 class FilePageAccess : public IPageAccess
999 {
1000   oslFileHandle m_hFile;
1001 
1002 public:
1003   static storeError ERROR_FROM_NATIVE (oslFileError eErrno);
1004   static sal_uInt32 MODE_TO_NATIVE (storeAccessMode eMode);
1005 
1006 public:
1007   explicit FilePageAccess (oslFileHandle hFile = 0) : m_hFile (hFile) {}
1008   virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize);
1009 
1010 private:
1011   virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset);
1012   virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset);
1013 
1014   /* see @ OFileLockBytes */
1015   virtual storeError peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes);
1016   virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes);
1017 
1018   virtual storeError getSize_Impl (sal_uInt32 & rnSize);
1019   virtual storeError setSize_Impl (sal_uInt32 nSize);
1020 
1021 protected:
1022   virtual ~FilePageAccess();
1023 
1024 private:
1025   /** Not implemented.
1026    */
1027   FilePageAccess (FilePageAccess const &);
1028   FilePageAccess & operator= (FilePageAccess const &);
1029 };
1030 
1031 storeError FilePageAccess::initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize)
1032 {
1033   (void) eAccessMode;     // UNUSED
1034   (void) nPageSize;       // UNUSED
1035   return store_E_Unknown; // NYI
1036 }
1037 FilePageAccess::~FilePageAccess()
1038 {
1039   if (m_hFile != 0)
1040     (void) osl_closeFile (m_hFile);
1041 }
1042 storeError FilePageAccess::readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset)
1043 {
1044   PageHolder page (0/*allocate()*/); /* @@@ construct w/ deallocator argument @@@ */
1045   if (!page.get())
1046     return store_E_OutOfMemory;
1047 
1048   swap<PageHolder>(page, rPage);
1049   return peekAt (nOffset, rPage.get(), 0/*size*/);
1050 }
1051 storeError FilePageAccess::writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset)
1052 {
1053   return pokeAt (nOffset, rPage.get(), 0/*size*/);
1054 }
1055 storeError FilePageAccess::peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes)
1056 {
1057   sal_uInt64 nDone = 0;
1058   oslFileError result = osl_readFileAt (m_hFile, nOffset, pBuffer, nBytes, &nDone);
1059   if (result != osl_File_E_None)
1060     return ERROR_FROM_NATIVE(result);
1061   if (nDone != nBytes)
1062     return (nDone != 0) ? store_E_CantRead : store_E_NotExists;
1063   return store_E_None;
1064 }
1065 storeError FilePageAccess::pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes)
1066 {
1067   sal_uInt64 nDone = 0;
1068   oslFileError result = osl_writeFileAt (m_hFile, nOffset, pBuffer, nBytes, &nDone);
1069   if (result != osl_File_E_None)
1070     return ERROR_FROM_NATIVE(result);
1071   if (nDone != nBytes)
1072     return store_E_CantWrite;
1073   return store_E_None;
1074 }
1075 storeError FilePageAccess::getSize_Impl (sal_uInt32 & rnSize)
1076 {
1077   sal_uInt64 uSize = 0;
1078   oslFileError result = osl_getFileSize (m_hFile, &uSize);
1079   if (result != osl_File_E_None)
1080     return ERROR_FROM_NATIVE(result);
1081   if (uSize > SAL_MAX_UINT32)
1082     return store_E_CantSeek;
1083 
1084   rnSize = sal::static_int_cast<sal_uInt32>(uSize);
1085   return store_E_None;
1086 }
1087 storeError FilePageAccess::setSize_Impl (sal_uInt32 nSize)
1088 {
1089   oslFileError result = osl_setFileSize (m_hFile, nSize);
1090   if (result != osl_File_E_None)
1091     return ERROR_FROM_NATIVE(result);
1092   return store_E_None;
1093 }
1094 storeError FilePageAccess::ERROR_FROM_NATIVE (oslFileError eErrno)
1095 {
1096   switch (eErrno)
1097   {
1098   case osl_File_E_None:
1099     return store_E_None;
1100 
1101   case osl_File_E_NOENT:
1102     return store_E_NotExists;
1103 
1104   case osl_File_E_ACCES:
1105   case osl_File_E_PERM:
1106     return store_E_AccessViolation;
1107 
1108   case osl_File_E_AGAIN:
1109   case osl_File_E_DEADLK:
1110     return store_E_LockingViolation;
1111 
1112   case osl_File_E_BADF:
1113     return store_E_InvalidHandle;
1114 
1115   case osl_File_E_INVAL:
1116     return store_E_InvalidParameter;
1117 
1118   case osl_File_E_NOSPC:
1119     return store_E_OutOfSpace;
1120 
1121   case osl_File_E_OVERFLOW:
1122     return store_E_CantSeek;
1123 
1124   default:
1125     return store_E_Unknown;
1126   }
1127 }
1128 sal_uInt32 FilePageAccess::MODE_TO_NATIVE(storeAccessMode eAccessMode)
1129 {
1130   sal_uInt32 nMode = 0;
1131   switch (eAccessMode)
1132   {
1133   case store_AccessCreate:
1134   case store_AccessReadCreate:
1135     nMode |= osl_File_OpenFlag_Create;
1136     // fall through
1137   case store_AccessReadWrite:
1138     nMode |= osl_File_OpenFlag_Write;
1139     // fall through
1140   case store_AccessReadOnly:
1141     nMode |= osl_File_OpenFlag_Read;
1142     break;
1143   default:
1144     OSL_PRECOND(0, "store::FilePageAccess: unknown storeAccessMode");
1145   }
1146   return nMode;
1147 }
1148 
1149 /*===*/
1150 
1151 class MemoryPageAccess : public IPageAccess
1152 {
1153   /** Representation.
1154    */
1155   sal_uInt8 * m_pData;
1156   sal_uInt32  m_nSize;
1157 
1158   /** Callback function to release Representation.
1159    */
1160   typedef void (*destructor_type)(sal_uInt8 * pData, sal_uInt32 nSize);
1161   destructor_type m_destructor;
1162 
1163   /** Default destructor callback.
1164    */
1165   static void freeMemory (sal_uInt8 * pData, sal_uInt32 nSize);
1166 
1167 public:
1168   MemoryPageAccess()
1169     : m_pData (0), m_nSize (0), m_destructor (MemoryPageAccess::freeMemory)
1170   {}
1171   MemoryPageAccess (sal_uInt8 * pData, sal_uInt32 nSize, destructor_type destructor = MemoryPageAccess::freeMemory)
1172     : m_pData (pData), m_nSize (nSize), m_destructor (destructor)
1173   {}
1174 
1175   virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize);
1176 
1177 private:
1178   /** Page (size aligned) access.
1179    */
1180   virtual storeError readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset);
1181   virtual storeError writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset);
1182 
1183   /** Low level access.
1184    */
1185   virtual storeError peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes);
1186   virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes);
1187 
1188   virtual storeError getSize_Impl (sal_uInt32 & rnSize);
1189   virtual storeError setSize_Impl (sal_uInt32 nSize);
1190 
1191 protected:
1192   virtual ~MemoryPageAccess();
1193 
1194 private:
1195   /** Not implemented.
1196    */
1197   MemoryPageAccess (MemoryPageAccess const &);
1198   MemoryPageAccess & operator= (MemoryPageAccess const &);
1199 };
1200 
1201 storeError MemoryPageAccess::initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize)
1202 {
1203   (void) eAccessMode;     // UNUSED
1204   (void) nPageSize;       // UNUSED
1205   return store_E_Unknown; // NYI
1206 }
1207 MemoryPageAccess::~MemoryPageAccess()
1208 {
1209   if (m_destructor != 0)
1210   {
1211     // release resource.
1212     (*m_destructor)(m_pData, m_nSize);
1213   }
1214 }
1215 storeError MemoryPageAccess::readPageAt_Impl (PageHolder & rPage, sal_uInt32 nOffset)
1216 {
1217     /* OSL_PRECOND(nOffset % size == 0, "Unaligned page read."); */
1218     PageHolder page (reinterpret_cast< PageData* >(m_pData + nOffset));
1219     swap<PageHolder>(page, rPage);
1220     return store_E_None;
1221 }
1222 storeError MemoryPageAccess::writePageAt_Impl (PageHolder const & rPage, sal_uInt32 nOffset)
1223 {
1224     PageData const * pagedata = rPage.get();
1225     if (!(pagedata != 0))
1226         return store_E_InvalidParameter;
1227 
1228 #if 0  /* NYI */
1229     sal_uInt16 const bytes = pagedata->size(); // Descr.m_nSize;
1230     OSL_ASSERT(bytes >= PageData::thePageSize);
1231 
1232     offset = rPage.location(); // Descr.m_nAddr;
1233     OSL_ASSERT(nOffset == offset);
1234 
1235     OSL_PRECOND(offset % bytes == 0, "Unaligned page write.");
1236 #endif /* NYI */
1237     return pokeAt (nOffset, pagedata, pagedata->size());
1238 }
1239 storeError MemoryPageAccess::peekAt_Impl (sal_uInt32 nOffset, void * pBuffer, sal_uInt32 nBytes)
1240 {
1241   // [SECURITY:ValInput]
1242   sal_uInt8 * dst_lo = static_cast<sal_uInt8*>(pBuffer);
1243   if (!(dst_lo != 0))
1244     return store_E_InvalidParameter;
1245 
1246   sal_uInt8 * dst_hi = dst_lo + nBytes;
1247   if (!(dst_lo <= dst_hi))
1248     return store_E_InvalidParameter;
1249 
1250   // ...
1251   sal_uInt8 const * src_lo = m_pData + nOffset;
1252   if (!(src_lo <= m_pData + m_nSize))
1253     return store_E_CantSeek;
1254 
1255   sal_uInt8 const * src_hi = src_lo + nBytes;
1256   if (!(src_hi <= m_pData + m_nSize))
1257     return store_E_CantRead;
1258 
1259   // copy.
1260   memcpy (pBuffer, src_lo, (src_hi - src_lo));
1261   return store_E_None;
1262 }
1263 storeError MemoryPageAccess::pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes)
1264 {
1265   // [SECURITY:ValInput]
1266   sal_uInt8 const * src_lo = static_cast<sal_uInt8 const*>(pBuffer);
1267   if (!(src_lo != 0))
1268     return store_E_InvalidParameter;
1269 
1270   sal_uInt8 const * src_hi = src_lo + nBytes;
1271   if (!(src_lo <= src_hi))
1272     return store_E_InvalidParameter;
1273 
1274   sal_uInt64 const uSize = nOffset + nBytes;
1275   if (uSize > SAL_MAX_UINT32)
1276     return store_E_CantSeek;
1277 
1278   // ...
1279   if (uSize > m_nSize)
1280   {
1281     // increase size.
1282     storeError eErrCode = setSize (sal::static_int_cast<sal_uInt32>(uSize));
1283     if (eErrCode != store_E_None)
1284       return eErrCode;
1285   }
1286 
1287   sal_uInt8 * dst_lo = m_pData + nOffset;
1288   if (!(dst_lo <= m_pData + m_nSize))
1289     return store_E_CantSeek;
1290 
1291   sal_uInt8 * dst_hi = dst_lo + nBytes;
1292   if (!(dst_hi <= m_pData + m_nSize))
1293     return store_E_CantWrite;
1294 
1295   // copy.
1296   memcpy (dst_lo, src_lo, (src_hi - src_lo));
1297   return store_E_None;
1298 }
1299 storeError MemoryPageAccess::getSize_Impl (sal_uInt32 & rnSize)
1300 {
1301   rnSize = m_nSize;
1302   return store_E_None;
1303 }
1304 storeError MemoryPageAccess::setSize_Impl (sal_uInt32 nSize)
1305 {
1306   if (nSize != m_nSize)
1307   {
1308     sal_uInt8 * pData = static_cast<sal_uInt8*>(rtl_reallocateMemory (m_pData, nSize));
1309     if (pData != 0)
1310     {
1311       if (nSize > m_nSize)
1312 	memset (pData + m_nSize, 0, sal::static_int_cast< size_t >(nSize - m_nSize));
1313     }
1314     else
1315     {
1316       if (nSize != 0)
1317 	return store_E_OutOfMemory;
1318     }
1319     m_pData = pData, m_nSize = nSize;
1320   }
1321   return store_E_None;
1322 }
1323 void MemoryPageAccess::freeMemory (sal_uInt8 * pData, sal_uInt32 /*nSize*/)
1324 {
1325   rtl_freeMemory (pData);
1326 }
1327 
1328 /*===*/
1329 
1330 class MappedPageAccess : public MemoryPageAccess
1331 {
1332   /** @see MemoryPageAccess::destructor_type callback function.
1333    */
1334   static void unmapFile (sal_uInt8 * pData, sal_uInt32 nSize);
1335 
1336 public:
1337   MappedPageAccess (sal_uInt8 * pData, sal_uInt32 nSize);
1338 
1339   virtual storeError initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize);
1340 
1341   virtual storeError writePageAt (PageHolder const & rPage, sal_uInt32 nOffset);
1342 
1343 private:
1344   virtual storeError pokeAt_Impl (sal_uInt32 nOffset, void const * pBuffer, sal_uInt32 nBytes);
1345   virtual storeError setSize_Impl (sal_uInt32 nSize);
1346 
1347 protected:
1348   virtual ~MappedPageAccess() {}
1349 };
1350 
1351 MappedPageAccess::MappedPageAccess (sal_uInt8 * pData, sal_uInt32 nSize)
1352   : MemoryPageAccess (pData, nSize, MappedPageAccess::unmapFile)
1353 {
1354 }
1355 storeError MappedPageAccess::initialize (storeAccessMode eAccessMode, sal_uInt16 nPageSize)
1356 {
1357   OSL_PRECOND(eAccessMode == store_AccessReadOnly, "store::MappedPageAccess: invalid AccessMode");
1358   return MemoryPageAccess::initialize (eAccessMode, nPageSize);
1359 }
1360 storeError MappedPageAccess::writePageAt (PageHolder const & /*rPage*/, sal_uInt32 /*nOffset*/)
1361 {
1362   return store_E_AccessViolation;
1363 }
1364 storeError MappedPageAccess::pokeAt_Impl (sal_uInt32 /*nOffset*/, void const * /*pBuffer*/, sal_uInt32 /*nBytes*/)
1365 {
1366   return store_E_AccessViolation;
1367 }
1368 storeError MappedPageAccess::setSize_Impl (sal_uInt32 /*nSize*/)
1369 {
1370   return store_E_AccessViolation;
1371 }
1372 void MappedPageAccess::unmapFile (sal_uInt8 * pData, sal_uInt32 nSize)
1373 {
1374   (void) osl_unmapFile (pData, nSize);
1375 }
1376 
1377 #if 0  /* NYI */
1378 storeError MemoryPageAccess_createInstance (
1379   rtl::Reference< IPageAccess > & rxPageAccess,
1380   storeAccessMode                 eAccessMode,
1381   sal_uInt16                      nPageSize
1382 )
1383 {
1384   rxPageAccess = new MemoryPageAccess();
1385   if (!rxPageAccess.is())
1386     return store_E_OutOfMemory;
1387 
1388   return rxPageAccess->initialize (eAccessMode, nPageSize);
1389 }
1390 
1391 storeError FilePageAccess_createInstance (
1392   rtl::Reference< IPageAccess > & rxPageAccess,
1393   rtl_uString *                   pFilename,
1394   storeAccessMode                 eAccessMode,
1395   sal_uInt16                      nPageSize
1396 )
1397 {
1398   // Acquire file handle.
1399   ResourceHolder<FileHandle> xFile;
1400   result = xFile.get().initialize (pFilename, MODE_TO_NATIVE(eAccessMode));
1401   if (result != osl_File_E_None)
1402     return ERROR_FROM_NATIVE(result);
1403 
1404   if (eAccessMode == store_AccessReadOnly)
1405   {
1406     ResourceHolder<FileMapping> xMapping;
1407     result = xMapping.get().initialize (xFile.get());
1408     if (result == osl_File_E_None)
1409     {
1410       const sal_uInt32 nSize = sal::static_int_cast<sal_uInt32>(xMapping.get().m_uSize);
1411       rxPageAccess = new MappedPageAccess (xMapping.get().m_pAddr, nSize);
1412       if (!rxPageAccess.is())
1413 	return store_E_OutOfMemory;
1414       (void) xMapping.release();
1415     }
1416   }
1417   if (!rxPageAccess.is())
1418   {
1419     rxPageAccess = new FilePageAccess (xFile.get());
1420     if (!rxPageAccess.is())
1421       return store_E_OutOfMemory;
1422     (void) xFile.release();
1423   }
1424   return rxPageAccess->initialize (eAccessMode, nPageSize);
1425 }
1426 #endif /* NYI */
1427 
1428 /*========================================================================
1429  *
1430  * test...
1431  *
1432  *======================================================================*/
1433 #if 0  /* NYI */
1434 
1435 struct IDataBlock
1436 {
1437   virtual sal_uInt16 singleCount() const = 0;
1438   virtual sal_uInt32 singleLink (sal_uInt16 nIndex) const = 0;
1439   virtual void singleLink (sal_uInt16 nIndex, sal_uInt32 nAddr) = 0;
1440 
1441   virtual storeError get() = 0;
1442   virtual storeError put() = 0;
1443   virtual storeError truncate() = 0;
1444 };
1445 
1446 struct InodePageData : public PageData
1447 {
1448   virtual INameBlock & getNameBlock() = 0;
1449   virtual IDataBlock & getDataBlock() = 0;
1450 };
1451 
1452 template< class page_data_type >
1453 page_data_type * query (PageData *, page_data_type *);
1454 
1455 template<> InodePageDataV2*
1456 query (PageData & rData, InodePageDataV2 *)
1457 {
1458   if (rData.isKindOf(InodePageDataV2::m_nTypeId))
1459     return static_cast<InodePageDataV2*>(&rData);
1460   return 0;
1461 }
1462 
1463 class InodePageObject : public PageObject
1464 {
1465 public:
1466   static InodePageObject createInstance (PageData & rData)
1467   {
1468     if (query(&rData, static_cast<InodePageDataV2*>(0)))
1469       return InodePageObjectV2 (static_cast<InodePageDataV2&>(rData));
1470     else if (query(&rData, static_cast<InodePageDataV1*>(0)))
1471       return InodePageObjectV1 (static_cast<InodePageDataV1&>(rData));
1472   }
1473 };
1474 
1475 #endif /* NYI */
1476 
1477 /*========================================================================
1478  *
1479  * main.
1480  *
1481  *======================================================================*/
1482 
1483 #include <stdio.h>
1484 
1485 #if 0  /* EXP */
1486 class Interface
1487 {
1488 public:
1489   virtual void deallocate(void *) /* = 0 */;
1490 };
1491 
1492 class Implementation : public Interface
1493 {
1494   SharedCount m_count;
1495 
1496 public:
1497   Implementation() : Interface() { printf("Ctor(%p)\n", this); }
1498   ~Implementation() { printf("Dtor(%p)\n", this); }
1499 
1500   Implementation (Implementation const & rhs) : Interface(), m_count (rhs.m_count) { printf("CopyCtor(%p)\n", this); }
1501 
1502   virtual void deallocate(void *) {}
1503 };
1504 
1505 Interface Interface_createInstance()
1506 {
1507   Implementation aInst;
1508   return aInst;
1509 }
1510 #endif /* EXP */
1511 
1512 int SAL_CALL main (int argc, char ** argv)
1513 {
1514   OSL_PRECOND(argc >= 1, "t_page: error: insufficient number of arguments.");
1515   if (argc < 1)
1516     return 0;
1517 
1518   {
1519     void *a = (void*)1, *b = (void*)2;
1520     swap<void*>(a, b);
1521   }
1522   {
1523     PageObject a;
1524     PageObject b (a);
1525     PageObject c;
1526 
1527     c = b;
1528     a = a;
1529 
1530   }
1531   {
1532       TestBIOS aBIOS;
1533       TestClient aClient;
1534       aClient.dwim (aBIOS);
1535   }
1536 #if 0  /* EXP */
1537   {
1538     Interface aIfc1 (Interface_createInstance());
1539     Interface aIfc2 (aIfc1);
1540   }
1541 #endif /* EXP */
1542 
1543   if (argc > 1)
1544   {
1545     rtl_uString * pFilename = 0;
1546     rtl_uString_newFromAscii (&pFilename, argv[1]);
1547     storeAccessMode eAccessMode = store_AccessReadOnly;
1548 
1549     // Acquire file handle.
1550     ResourceHolder<FileHandle> h1;
1551     oslFileError result = h1.get().initialize (pFilename, FilePageAccess::MODE_TO_NATIVE(eAccessMode));
1552     if (result == osl_File_E_None)
1553     {
1554       ResourceHolder<FileHandle> h2 (h1);
1555       h1 = h2;
1556 
1557       if (eAccessMode == store_AccessReadOnly)
1558       {
1559 	ResourceHolder<FileMapping> m1;
1560 	result = m1.get().initialize (h1.get());
1561 
1562 	const sal_uInt32 nSize = sal::static_int_cast<sal_uInt32>(m1.get().m_uSize);
1563 	(void) nSize; // UNUSED
1564 
1565 	ResourceHolder<FileMapping> m2 (m1);
1566 	m1 = m2;
1567 
1568 	result = osl_File_E_None;
1569       }
1570     }
1571   }
1572 
1573   return 0;
1574 }
1575