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
24 #ifndef _STORE_STORBASE_HXX_
25 #define _STORE_STORBASE_HXX_ "$Revision$"
26
27 #include "sal/types.h"
28
29 #include "rtl/alloc.h"
30 #include "rtl/crc.h"
31 #include "rtl/ref.hxx"
32
33 #include "osl/diagnose.h"
34 #include "osl/endian.h"
35
36 #include "store/types.h"
37
38 #ifndef INCLUDED_STDDEF_H
39 #include <stddef.h>
40 #define INCLUDED_STDDEF_H
41 #endif
42
43 #ifndef INCLUDED_STRING_H
44 #include <string.h>
45 #define INCLUDED_STRING_H
46 #endif
47
48 /*========================================================================
49 *
50 * store common internals.
51 *
52 *======================================================================*/
53
54 #ifndef STORE_IMPL_ISP2
55 #define STORE_IMPL_ISP2(value) (((value) & ((value) - 1)) == 0)
56 #endif
57
58 #ifndef STORE_IMPL_CONCAT
59 #define STORE_IMPL_CONCAT(x, y) STORE_IMPL_CONCAT2(x,y)
60 #define STORE_IMPL_CONCAT2(x, y) x##y
61 #endif
62
63 #ifndef STORE_STATIC_ASSERT /* Compile time assertion */
64 namespace store
65 {
66 template< bool x > struct STATIC_ASSERTION_FAILURE;
67 template<> struct STATIC_ASSERTION_FAILURE< true > { enum { value = 1 }; };
68
69 template< int x > struct static_assert_test{};
70 } // namespace store
71
72 #define STORE_STATIC_ASSERT(pred) \
73 typedef \
74 store::static_assert_test< sizeof( store::STATIC_ASSERTION_FAILURE< (bool)(pred) > ) > \
75 STORE_IMPL_CONCAT(static_assert_typedef_, __LINE__)
76
77 #endif /* !STORE_STATIC_ASSERT */
78
79 namespace store
80 {
81
82 #ifdef htons
83 #undef htons
84 #endif
85 #ifdef ntohs
86 #undef ntohs
87 #endif
88
89 #ifdef htonl
90 #undef htonl
91 #endif
92 #ifdef ntohl
93 #undef ntohl
94 #endif
95
96 #ifdef OSL_BIGENDIAN
htons(sal_uInt16 h)97 inline sal_uInt16 htons (sal_uInt16 h) { return OSL_SWAPWORD(h); }
ntohs(sal_uInt16 n)98 inline sal_uInt16 ntohs (sal_uInt16 n) { return OSL_SWAPWORD(n); }
99
htonl(sal_uInt32 h)100 inline sal_uInt32 htonl (sal_uInt32 h) { return OSL_SWAPDWORD(h); }
ntohl(sal_uInt32 n)101 inline sal_uInt32 ntohl (sal_uInt32 n) { return OSL_SWAPDWORD(n); }
102 #else
103 inline sal_uInt16 htons (sal_uInt16 h) { return (h); }
104 inline sal_uInt16 ntohs (sal_uInt16 n) { return (n); }
105
106 inline sal_uInt32 htonl (sal_uInt32 h) { return (h); }
107 inline sal_uInt32 ntohl (sal_uInt32 n) { return (n); }
108 #endif /* OSL_BIGENDIAN */
109
110 /** swap.
111 */
swap(T & lhs,T & rhs)112 template< typename T > void swap (T & lhs, T & rhs)
113 {
114 T tmp = lhs; lhs = rhs; rhs = tmp;
115 }
116
117 /*========================================================================
118 *
119 * SharedCount.
120 *
121 *======================================================================*/
122 class SharedCount
123 {
124 long * m_pCount;
125
126 class Allocator
127 {
128 rtl_cache_type * m_cache;
129
130 public:
131 static Allocator & get();
132
alloc()133 long * alloc()
134 {
135 return static_cast<long*>(rtl_cache_alloc (m_cache));
136 }
free(long * pCount)137 void free (long * pCount)
138 {
139 rtl_cache_free (m_cache, pCount);
140 }
141
142 protected:
143 Allocator();
144 ~Allocator();
145 };
146
147 public:
SharedCount()148 SharedCount()
149 : m_pCount(Allocator::get().alloc())
150 {
151 if (m_pCount != 0) (*m_pCount) = 1;
152 }
153
~SharedCount()154 ~SharedCount()
155 {
156 if (m_pCount != 0)
157 {
158 long new_count = --(*m_pCount);
159 if (new_count == 0)
160 Allocator::get().free(m_pCount);
161 }
162 }
163
swap(SharedCount & rhs)164 void swap (SharedCount & rhs) // nothrow
165 {
166 store::swap(m_pCount, rhs.m_pCount);
167 }
168
SharedCount(SharedCount const & rhs)169 SharedCount (SharedCount const & rhs) // nothrow
170 : m_pCount (rhs.m_pCount)
171 {
172 if (m_pCount != 0) ++(*m_pCount);
173 }
operator =(SharedCount const & rhs)174 SharedCount & operator= (SharedCount const & rhs) // nothrow
175 {
176 SharedCount tmp(rhs);
177 swap(tmp);
178 return *this;
179 }
180
operator ==(long count) const181 bool operator== (long count) const
182 {
183 return (m_pCount != 0) ? *m_pCount == count : false;
184 }
185 };
186
187 /*========================================================================
188 *
189 * OStorePageGuard.
190 *
191 *======================================================================*/
192 struct OStorePageGuard
193 {
194 /** Representation.
195 */
196 sal_uInt32 m_nMagic;
197 sal_uInt32 m_nCRC32;
198
199 /** Construction.
200 */
OStorePageGuardstore::OStorePageGuard201 explicit OStorePageGuard (sal_uInt32 nMagic = 0, sal_uInt32 nCRC32 = 0)
202 : m_nMagic (store::htonl(nMagic)),
203 m_nCRC32 (store::htonl(nCRC32))
204 {}
205
swapstore::OStorePageGuard206 void swap (OStorePageGuard & rhs)
207 {
208 store::swap(m_nMagic, rhs.m_nMagic);
209 store::swap(m_nCRC32, rhs.m_nCRC32);
210 }
211
OStorePageGuardstore::OStorePageGuard212 OStorePageGuard (OStorePageGuard const & rhs)
213 : m_nMagic (rhs.m_nMagic),
214 m_nCRC32 (rhs.m_nCRC32)
215 {}
216
operator =store::OStorePageGuard217 OStorePageGuard& operator= (const OStorePageGuard& rhs)
218 {
219 m_nMagic = rhs.m_nMagic;
220 m_nCRC32 = rhs.m_nCRC32;
221 return *this;
222 }
223
224 /** Comparison.
225 */
operator ==store::OStorePageGuard226 bool operator== (const OStorePageGuard& rhs) const
227 {
228 return ((m_nMagic == rhs.m_nMagic) &&
229 (m_nCRC32 == rhs.m_nCRC32) );
230 }
231 };
232
233 /*========================================================================
234 *
235 * OStorePageDescriptor.
236 *
237 *======================================================================*/
238 #define STORE_PAGE_NULL ((sal_uInt32)(~0))
239
240 struct OStorePageDescriptor
241 {
242 /** Representation.
243 */
244 sal_uInt32 m_nAddr;
245 sal_uInt16 m_nSize;
246 sal_uInt16 m_nUsed;
247
248 /** Construction.
249 */
OStorePageDescriptorstore::OStorePageDescriptor250 explicit OStorePageDescriptor (
251 sal_uInt32 nAddr = STORE_PAGE_NULL,
252 sal_uInt16 nSize = 0,
253 sal_uInt16 nUsed = 0)
254 : m_nAddr (store::htonl(nAddr)),
255 m_nSize (store::htons(nSize)),
256 m_nUsed (store::htons(nUsed))
257 {}
258
swapstore::OStorePageDescriptor259 void swap (OStorePageDescriptor & rhs)
260 {
261 store::swap(m_nAddr, rhs.m_nAddr);
262 store::swap(m_nSize, rhs.m_nSize);
263 store::swap(m_nUsed, rhs.m_nUsed);
264 }
265
OStorePageDescriptorstore::OStorePageDescriptor266 OStorePageDescriptor (const OStorePageDescriptor & rhs)
267 : m_nAddr (rhs.m_nAddr),
268 m_nSize (rhs.m_nSize),
269 m_nUsed (rhs.m_nUsed)
270 {}
271
operator =store::OStorePageDescriptor272 OStorePageDescriptor & operator= (const OStorePageDescriptor & rhs)
273 {
274 m_nAddr = rhs.m_nAddr;
275 m_nSize = rhs.m_nSize;
276 m_nUsed = rhs.m_nUsed;
277 return *this;
278 }
279
280 /** Comparison.
281 */
operator ==store::OStorePageDescriptor282 bool operator== (const OStorePageDescriptor & rhs) const
283 {
284 return ((m_nAddr == rhs.m_nAddr) &&
285 (m_nSize == rhs.m_nSize) );
286 }
287
operator <=store::OStorePageDescriptor288 bool operator<= (const OStorePageDescriptor & rhs) const
289 {
290 return ((m_nAddr == rhs.m_nAddr ) &&
291 (store::ntohs(m_nSize) <= store::ntohs(rhs.m_nSize)) );
292 }
293
operator <store::OStorePageDescriptor294 bool operator< (const OStorePageDescriptor & rhs) const
295 {
296 if (m_nAddr == rhs.m_nAddr)
297 return (store::ntohs(m_nSize) < store::ntohs(rhs.m_nSize));
298 else
299 return (store::ntohl(m_nAddr) < store::ntohl(rhs.m_nAddr));
300 }
301 };
302
303 /*========================================================================
304 *
305 * OStorePageKey.
306 *
307 *======================================================================*/
308 struct OStorePageKey
309 {
310 /** Representation.
311 */
312 sal_uInt32 m_nLow;
313 sal_uInt32 m_nHigh;
314
315 /** Construction.
316 */
OStorePageKeystore::OStorePageKey317 explicit OStorePageKey (sal_uInt32 nLow = 0, sal_uInt32 nHigh = 0)
318 : m_nLow (store::htonl(nLow)),
319 m_nHigh (store::htonl(nHigh))
320 {}
321
swapstore::OStorePageKey322 void swap (OStorePageKey & rhs)
323 {
324 store::swap(m_nLow, rhs.m_nLow);
325 store::swap(m_nHigh, rhs.m_nHigh);
326 }
327
OStorePageKeystore::OStorePageKey328 OStorePageKey (const OStorePageKey & rhs)
329 : m_nLow (rhs.m_nLow), m_nHigh (rhs.m_nHigh)
330 {}
331
operator =store::OStorePageKey332 OStorePageKey & operator= (const OStorePageKey & rhs)
333 {
334 m_nLow = rhs.m_nLow;
335 m_nHigh = rhs.m_nHigh;
336 return *this;
337 }
338
339 /** Comparison.
340 */
operator ==store::OStorePageKey341 bool operator== (const OStorePageKey & rhs) const
342 {
343 return ((m_nLow == rhs.m_nLow ) &&
344 (m_nHigh == rhs.m_nHigh) );
345 }
346
operator <store::OStorePageKey347 bool operator< (const OStorePageKey & rhs) const
348 {
349 if (m_nHigh == rhs.m_nHigh)
350 return (store::ntohl(m_nLow) < store::ntohl(rhs.m_nLow));
351 else
352 return (store::ntohl(m_nHigh) < store::ntohl(rhs.m_nHigh));
353 }
354 };
355
356 /*========================================================================
357 *
358 * OStorePageLink.
359 *
360 *======================================================================*/
361 struct OStorePageLink
362 {
363 /** Representation.
364 */
365 sal_uInt32 m_nAddr;
366
367 /** Construction.
368 */
OStorePageLinkstore::OStorePageLink369 explicit OStorePageLink (sal_uInt32 nAddr = STORE_PAGE_NULL)
370 : m_nAddr (store::htonl(nAddr))
371 {}
372
swapstore::OStorePageLink373 void swap (OStorePageLink & rhs)
374 {
375 store::swap(m_nAddr, rhs.m_nAddr);
376 }
377
OStorePageLinkstore::OStorePageLink378 OStorePageLink (const OStorePageLink & rhs)
379 : m_nAddr (rhs.m_nAddr)
380 {}
381
operator =store::OStorePageLink382 OStorePageLink & operator= (const OStorePageLink & rhs)
383 {
384 m_nAddr = rhs.m_nAddr;
385 return *this;
386 }
387
operator =store::OStorePageLink388 OStorePageLink & operator= (sal_uInt32 nAddr)
389 {
390 m_nAddr = store::htonl(nAddr);
391 return *this;
392 }
393
394 /** Comparison.
395 */
operator ==store::OStorePageLink396 bool operator== (const OStorePageLink & rhs) const
397 {
398 return (m_nAddr == rhs.m_nAddr);
399 }
400
operator <store::OStorePageLink401 bool operator< (const OStorePageLink& rhs) const
402 {
403 return (store::ntohl(m_nAddr) < store::ntohl(rhs.m_nAddr));
404 }
405
406 /** Operation.
407 */
locationstore::OStorePageLink408 sal_uInt32 location() const
409 {
410 return store::ntohl(m_nAddr);
411 }
412
linkstore::OStorePageLink413 void link (OStorePageLink & rPred)
414 {
415 // @@@ swap (rPred); @@@
416 OStorePageLink tmp (rPred);
417 rPred = *this;
418 *this = tmp;
419 }
420
unlinkstore::OStorePageLink421 void unlink (OStorePageLink& rPred)
422 {
423 rPred = *this;
424 *this = OStorePageLink();
425 }
426 };
427
428 /*========================================================================
429 *
430 * PageData.
431 *
432 *======================================================================*/
433 typedef struct PageData OStorePageData; // backward compat.
434 struct PageData
435 {
436 typedef OStorePageGuard G;
437 typedef OStorePageDescriptor D;
438 typedef OStorePageLink L;
439
440 /** Representation.
441 */
442 G m_aGuard;
443 D m_aDescr;
444 L m_aMarked;
445 L m_aUnused;
446
447 /** theSize.
448 */
449 static const size_t theSize = sizeof(G) + sizeof(D) + 2 * sizeof(L);
450 static const sal_uInt16 thePageSize = theSize;
451 STORE_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= thePageSize);
452
453 /** location.
454 */
locationstore::PageData455 sal_uInt32 location() const
456 {
457 return store::ntohl(m_aDescr.m_nAddr);
458 }
locationstore::PageData459 void location (sal_uInt32 nAddr)
460 {
461 m_aDescr.m_nAddr = store::htonl(nAddr);
462 }
463
464 /** size.
465 */
sizestore::PageData466 sal_uInt16 size() const
467 {
468 return store::ntohs(m_aDescr.m_nSize);
469 }
470
471 /** type.
472 */
typestore::PageData473 sal_uInt32 type() const
474 {
475 return store::ntohl(m_aGuard.m_nMagic);
476 }
477
478 /** Allocation.
479 */
480 class Allocator_Impl;
481 class Allocator : public rtl::IReference
482 {
483 public:
construct()484 template< class T > T * construct()
485 {
486 void * page = 0; sal_uInt16 size = 0;
487 if (allocate (&page, &size))
488 {
489 return new(page) T(size);
490 }
491 return 0;
492 }
493
allocate(void ** ppPage,sal_uInt16 * pnSize)494 bool allocate (void ** ppPage, sal_uInt16 * pnSize)
495 {
496 allocate_Impl (ppPage, pnSize);
497 return ((*ppPage != 0) && (*pnSize != 0));
498 }
499
deallocate(void * pPage)500 void deallocate (void * pPage)
501 {
502 if (pPage != 0)
503 deallocate_Impl (pPage);
504 }
505
506 static storeError createInstance (
507 rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize);
508
509 private:
510 /** Implementation (abstract).
511 */
512 virtual void allocate_Impl (void ** ppPage, sal_uInt16 * pnSize) = 0;
513 virtual void deallocate_Impl (void * pPage) = 0;
514 };
515
operator newstore::PageData516 static void* operator new (size_t, void * p) { return p; }
operator deletestore::PageData517 static void operator delete (void * , void *) {}
518
519 /** Construction.
520 */
PageDatastore::PageData521 explicit PageData (sal_uInt16 nPageSize = thePageSize)
522 : m_aGuard(),
523 m_aDescr(STORE_PAGE_NULL, nPageSize, thePageSize),
524 m_aMarked(),
525 m_aUnused()
526 {}
527
swapstore::PageData528 void swap (PageData & rhs) // nothrow
529 {
530 m_aGuard.swap(rhs.m_aGuard);
531 m_aDescr.swap(rhs.m_aDescr);
532 m_aMarked.swap(rhs.m_aMarked);
533 m_aUnused.swap(rhs.m_aUnused);
534 }
535
PageDatastore::PageData536 PageData (PageData const & rhs) // nothrow
537 : m_aGuard (rhs.m_aGuard),
538 m_aDescr (rhs.m_aDescr),
539 m_aMarked(rhs.m_aMarked),
540 m_aUnused(rhs.m_aUnused)
541 {}
542
operator =store::PageData543 PageData & operator= (PageData const & rhs) // nothrow
544 {
545 PageData tmp (rhs);
546 swap (tmp);
547 return *this;
548 }
549
550 /** guard (external representation).
551 */
guardstore::PageData552 void guard (sal_uInt32 nAddr)
553 {
554 sal_uInt32 nCRC32 = 0;
555 nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
556 m_aDescr.m_nAddr = store::htonl(nAddr);
557 nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G));
558 m_aGuard.m_nCRC32 = store::htonl(nCRC32);
559 }
560
561 /** verify (external representation).
562 */
verifystore::PageData563 storeError verify (sal_uInt32 nAddr) const
564 {
565 sal_uInt32 nCRC32 = 0;
566 nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
567 nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G));
568 if (m_aGuard.m_nCRC32 != store::htonl(nCRC32))
569 return store_E_InvalidChecksum;
570 if (m_aDescr.m_nAddr != store::htonl(nAddr))
571 return store_E_InvalidAccess;
572 return store_E_None;
573 }
574
verifyVersionstore::PageData575 storeError verifyVersion (sal_uInt32 nMagic) const
576 {
577 if (m_aGuard.m_nMagic != store::htonl(nMagic))
578 return store_E_WrongVersion;
579 else
580 return store_E_None;
581 }
582 };
583
584 /*========================================================================
585 *
586 * PageHolder.
587 *
588 *======================================================================*/
589 class PageHolder
590 {
591 SharedCount m_refcount;
592 PageData * m_pagedata;
593
594 typedef rtl::Reference< PageData::Allocator > allocator_type;
595 allocator_type m_allocator;
596
597 public:
PageHolder(PageData * pagedata=0,allocator_type const & allocator=allocator_type ())598 explicit PageHolder (PageData * pagedata = 0, allocator_type const & allocator = allocator_type())
599 : m_refcount (),
600 m_pagedata (pagedata),
601 m_allocator(allocator)
602 {
603 OSL_ENSURE((m_pagedata == 0) || m_allocator.is(), "store::PageHolder::ctor(): pagedata w/o allocator.");
604 }
605
~PageHolder()606 ~PageHolder()
607 {
608 if ((m_refcount == 1) && (m_pagedata != 0))
609 {
610 // free pagedata.
611 OSL_ENSURE(m_allocator.is(), "store::PageHolder::dtor(): pagedata w/o allocator.");
612 m_allocator->deallocate (m_pagedata);
613 }
614 }
615
swap(PageHolder & rhs)616 void swap (PageHolder & rhs) // nothrow
617 {
618 m_refcount.swap(rhs.m_refcount);
619 store::swap(m_pagedata, rhs.m_pagedata);
620 store::swap(m_allocator, rhs.m_allocator);
621 }
622
PageHolder(PageHolder const & rhs)623 PageHolder (PageHolder const & rhs) // nothrow
624 : m_refcount (rhs.m_refcount),
625 m_pagedata (rhs.m_pagedata),
626 m_allocator(rhs.m_allocator)
627 {}
628
operator =(PageHolder const & rhs)629 PageHolder & operator= (PageHolder const & rhs) // nothrow
630 {
631 PageHolder tmp (rhs);
632 swap(tmp);
633 return *this;
634 }
635
get()636 PageData * get() { return m_pagedata; }
get() const637 PageData const * get() const { return m_pagedata; }
638
operator ->()639 PageData * operator->()
640 {
641 OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator->(): Null pointer");
642 return m_pagedata;
643 }
operator ->() const644 PageData const * operator->() const
645 {
646 OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator->(): Null pointer");
647 return m_pagedata;
648 }
649
operator *()650 PageData & operator*()
651 {
652 OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator*(): Null pointer");
653 return *m_pagedata;
654 }
operator *() const655 PageData const & operator*() const
656 {
657 OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator*(): Null pointer");
658 return *m_pagedata;
659 }
660 };
661
662 /*========================================================================
663 *
664 * PageHolderObject.
665 *
666 *======================================================================*/
667 template< class T >
668 class PageHolderObject
669 {
670 /** Representation.
671 */
672 PageHolder m_xPage;
673
674 /** Checked cast.
675 */
676 template< class U >
isA(PageData const * p)677 static bool isA (PageData const * p)
678 {
679 return ((p != 0) && (p->type() == U::theTypeId));
680 }
681
682 template< class U >
dynamic_page_cast(PageData * p)683 static U * dynamic_page_cast (PageData * p)
684 {
685 return isA<U>(p) ? static_cast<U*>(p) : 0;
686 }
687
688 template< class U >
dynamic_page_cast(PageData const * p)689 static U const * dynamic_page_cast (PageData const * p)
690 {
691 return isA<U>(p) ? static_cast<U const *>(p) : 0;
692 }
693
694 public:
construct(rtl::Reference<PageData::Allocator> const & rxAllocator)695 bool construct (rtl::Reference< PageData::Allocator > const & rxAllocator)
696 {
697 if ((m_xPage.get() == 0) && rxAllocator.is())
698 {
699 PageHolder tmp (rxAllocator->construct<T>(), rxAllocator);
700 m_xPage.swap (tmp);
701 }
702 return (m_xPage.get() != 0);
703 }
704
createInstance(rtl::Reference<PageData::Allocator> const & rxAllocator)705 static PageHolderObject<T> createInstance (rtl::Reference< PageData::Allocator > const & rxAllocator)
706 {
707 PageHolderObject<T> tmp;
708 (void) tmp.construct (rxAllocator);
709 return tmp;
710 }
711
PageHolderObject(PageHolder const & rxPage=PageHolder ())712 explicit PageHolderObject (PageHolder const & rxPage = PageHolder())
713 : m_xPage (rxPage)
714 {}
715
swap(PageHolderObject<T> & rhs)716 void swap (PageHolderObject<T> & rhs)
717 {
718 m_xPage.swap (rhs.m_xPage);
719 }
720
PageHolderObject(PageHolderObject<T> const & rhs)721 PageHolderObject (PageHolderObject<T> const & rhs)
722 : m_xPage (rhs.m_xPage)
723 {}
724
operator =(PageHolderObject<T> const & rhs)725 PageHolderObject<T> & operator= (PageHolderObject<T> const & rhs)
726 {
727 PageHolderObject<T> tmp (rhs);
728 this->swap (tmp);
729 return *this;
730 }
731
is() const732 bool is() const
733 {
734 return (m_xPage.get() != 0);
735 }
736
737 #if 1 /* EXP */
get()738 PageHolder & get() { return m_xPage; }
get() const739 PageHolder const & get() const { return m_xPage; }
740 #endif /* EXP */
741
operator ->()742 T * operator->()
743 {
744 T * pImpl = dynamic_page_cast<T>(m_xPage.get());
745 OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
746 return pImpl;
747 }
operator ->() const748 T const * operator->() const
749 {
750 T const * pImpl = dynamic_page_cast<T>(m_xPage.get());
751 OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
752 return pImpl;
753 }
754
operator *()755 T & operator*()
756 {
757 T * pImpl = dynamic_page_cast<T>(m_xPage.get());
758 OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
759 return (*pImpl);
760 }
operator *() const761 T const & operator*() const
762 {
763 T const * pImpl = dynamic_page_cast<T>(m_xPage.get());
764 OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
765 return (*pImpl);
766 }
767
guard(PageHolder & rxPage,sal_uInt32 nAddr)768 static storeError guard (PageHolder & rxPage, sal_uInt32 nAddr)
769 {
770 PageData * pHead = rxPage.get();
771 if (!pHead)
772 return store_E_InvalidAccess;
773 pHead->guard(nAddr);
774
775 T * pImpl = dynamic_page_cast<T>(pHead);
776 OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::guard(): Null pointer");
777 pImpl->guard();
778
779 return store_E_None;
780 }
verify(PageHolder const & rxPage,sal_uInt32 nAddr)781 static storeError verify (PageHolder const & rxPage, sal_uInt32 nAddr)
782 {
783 PageData const * pHead = rxPage.get();
784 if (!pHead)
785 return store_E_InvalidAccess;
786
787 storeError eErrCode = pHead->verify(nAddr);
788 if (eErrCode != store_E_None)
789 return eErrCode;
790
791 T const * pImpl = dynamic_page_cast<T>(pHead);
792 if (!pImpl)
793 return store_E_WrongVersion;
794
795 return pImpl->verify();
796 }
797 };
798
799 /*========================================================================
800 *
801 * PageObject.
802 *
803 *======================================================================*/
804 #if 1 /* EXP */
805 class PageObject
806 {
807 public:
PageObject(PageHolder const & rxPage=PageHolder ())808 explicit PageObject (PageHolder const & rxPage = PageHolder())
809 : m_xPage (rxPage), m_bDirty (false)
810 {}
811
~PageObject()812 virtual ~PageObject()
813 {}
814
get()815 PageHolder & get() { return m_xPage; }
get() const816 PageHolder const & get() const { return m_xPage; }
817
clean()818 void clean() { m_bDirty = false; }
touch()819 void touch() { m_bDirty = true; }
820
location() const821 sal_uInt32 location() const
822 {
823 PageData const * pagedata = m_xPage.get();
824 return (pagedata != 0) ? pagedata->location() : STORE_PAGE_NULL;
825 }
location(sal_uInt32 nAddr)826 void location (sal_uInt32 nAddr)
827 {
828 PageData * pagedata = m_xPage.get();
829 if (pagedata != 0)
830 pagedata->location (nAddr);
831 }
832
833 protected:
834 PageHolder m_xPage;
835 bool m_bDirty;
836
837 virtual storeError guard (sal_uInt32 nAddr) = 0;
838 virtual storeError verify (sal_uInt32 nAddr) const = 0;
839 };
840 #endif /* EXP */
841
842 class OStorePageBIOS;
843
844 class OStorePageObject
845 {
846 typedef OStorePageData page;
847
848 public:
849 /** Allocation.
850 */
operator new(size_t n)851 static void * operator new (size_t n) SAL_THROW(())
852 {
853 return rtl_allocateMemory (sal_uInt32(n));
854 }
operator delete(void * p,size_t)855 static void operator delete (void * p, size_t) SAL_THROW(())
856 {
857 rtl_freeMemory (p);
858 }
859
860 /** State.
861 */
862 inline bool dirty (void) const;
863 inline void clean (void);
864 inline void touch (void);
865
866 /** Location.
867 */
868 inline sal_uInt32 location (void) const;
869 inline void location (sal_uInt32 nAddr);
870
871 protected:
872 /** Representation.
873 */
874 PageHolder m_xPage;
875 bool m_bDirty;
876
877 /** Construction.
878 */
OStorePageObject(PageHolder const & rxPage=PageHolder ())879 explicit OStorePageObject (PageHolder const & rxPage = PageHolder())
880 : m_xPage (rxPage), m_bDirty (false)
881 {}
882
883 /** Destruction.
884 */
885 virtual ~OStorePageObject (void);
886
887 public:
888 template< class U >
makeHolder() const889 PageHolderObject<U> makeHolder() const
890 {
891 return PageHolderObject<U>(m_xPage);
892 }
893
894 template< class U >
construct(rtl::Reference<PageData::Allocator> const & rxAllocator)895 storeError construct (rtl::Reference< PageData::Allocator > const & rxAllocator)
896 {
897 if (!rxAllocator.is())
898 return store_E_InvalidAccess;
899
900 PageHolder tmp (rxAllocator->construct<U>(), rxAllocator);
901 if (!tmp.get())
902 return store_E_OutOfMemory;
903
904 m_xPage.swap (tmp);
905 return store_E_None;
906 }
907
908
get()909 PageHolder & get() { return m_xPage; }
get() const910 PageHolder const & get() const { return m_xPage; }
911
912 virtual storeError guard (sal_uInt32 nAddr) = 0;
913 virtual storeError verify (sal_uInt32 nAddr) const = 0;
914 };
915
dirty(void) const916 inline bool OStorePageObject::dirty (void) const
917 {
918 return m_bDirty;
919 }
920
clean(void)921 inline void OStorePageObject::clean (void)
922 {
923 m_bDirty = false;
924 }
925
touch(void)926 inline void OStorePageObject::touch (void)
927 {
928 m_bDirty = true;
929 }
930
location(void) const931 inline sal_uInt32 OStorePageObject::location (void) const
932 {
933 return m_xPage->location();
934 }
935
location(sal_uInt32 nAddr)936 inline void OStorePageObject::location (sal_uInt32 nAddr)
937 {
938 m_xPage->location(nAddr);
939 touch();
940 }
941
942 /*========================================================================
943 *
944 * The End.
945 *
946 *======================================================================*/
947
948 } // namespace store
949
950 #endif /* !_STORE_STORBASE_HXX_ */
951