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