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