Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef _STORE_STORBASE_HXX_
21 : #define _STORE_STORBASE_HXX_
22 :
23 : #include "sal/config.h"
24 :
25 : #include "boost/static_assert.hpp"
26 : #include "sal/types.h"
27 :
28 : #include "rtl/alloc.h"
29 : #include "rtl/crc.h"
30 : #include "rtl/ref.hxx"
31 :
32 : #include "osl/diagnose.h"
33 : #include "osl/endian.h"
34 :
35 : #include "store/types.h"
36 :
37 : #include <stddef.h>
38 : #include <string.h>
39 :
40 : /*========================================================================
41 : *
42 : * store common internals.
43 : *
44 : *======================================================================*/
45 :
46 : #ifndef STORE_IMPL_ISP2
47 : #define STORE_IMPL_ISP2(value) (((value) & ((value) - 1)) == 0)
48 : #endif
49 :
50 : #ifndef STORE_IMPL_CONCAT
51 : #define STORE_IMPL_CONCAT(x, y) STORE_IMPL_CONCAT2(x,y)
52 : #define STORE_IMPL_CONCAT2(x, y) x##y
53 : #endif
54 :
55 : namespace store
56 : {
57 :
58 : #ifdef htons
59 : #undef htons
60 : #endif
61 : #ifdef ntohs
62 : #undef ntohs
63 : #endif
64 :
65 : #ifdef htonl
66 : #undef htonl
67 : #endif
68 : #ifdef ntohl
69 : #undef ntohl
70 : #endif
71 :
72 : #ifdef OSL_BIGENDIAN
73 : inline sal_uInt16 htons (sal_uInt16 h) { return OSL_SWAPWORD(h); }
74 : inline sal_uInt16 ntohs (sal_uInt16 n) { return OSL_SWAPWORD(n); }
75 :
76 : inline sal_uInt32 htonl (sal_uInt32 h) { return OSL_SWAPDWORD(h); }
77 : inline sal_uInt32 ntohl (sal_uInt32 n) { return OSL_SWAPDWORD(n); }
78 : #else
79 0 : inline sal_uInt16 htons (sal_uInt16 h) { return (h); }
80 0 : inline sal_uInt16 ntohs (sal_uInt16 n) { return (n); }
81 :
82 0 : inline sal_uInt32 htonl (sal_uInt32 h) { return (h); }
83 0 : inline sal_uInt32 ntohl (sal_uInt32 n) { return (n); }
84 : #endif /* OSL_BIGENDIAN */
85 :
86 : /** swap.
87 : */
88 0 : template< typename T > void swap (T & lhs, T & rhs)
89 : {
90 0 : T tmp = lhs; lhs = rhs; rhs = tmp;
91 0 : }
92 :
93 : /*========================================================================
94 : *
95 : * SharedCount.
96 : *
97 : *======================================================================*/
98 : class SharedCount
99 : {
100 : long * m_pCount;
101 :
102 : class Allocator
103 : {
104 : rtl_cache_type * m_cache;
105 :
106 : public:
107 : static Allocator & get();
108 :
109 0 : long * alloc()
110 : {
111 0 : return static_cast<long*>(rtl_cache_alloc (m_cache));
112 : }
113 0 : void free (long * pCount)
114 : {
115 0 : rtl_cache_free (m_cache, pCount);
116 0 : }
117 :
118 : protected:
119 : Allocator();
120 : ~Allocator();
121 : };
122 :
123 : public:
124 0 : SharedCount()
125 0 : : m_pCount(Allocator::get().alloc())
126 : {
127 0 : if (m_pCount != 0) (*m_pCount) = 1;
128 0 : }
129 :
130 0 : ~SharedCount()
131 : {
132 0 : if (m_pCount != 0)
133 : {
134 0 : long new_count = --(*m_pCount);
135 0 : if (new_count == 0)
136 0 : Allocator::get().free(m_pCount);
137 : }
138 0 : }
139 :
140 0 : void swap (SharedCount & rhs) // nothrow
141 : {
142 0 : store::swap(m_pCount, rhs.m_pCount);
143 0 : }
144 :
145 0 : SharedCount (SharedCount const & rhs) // nothrow
146 0 : : m_pCount (rhs.m_pCount)
147 : {
148 0 : if (m_pCount != 0) ++(*m_pCount);
149 0 : }
150 : SharedCount & operator= (SharedCount const & rhs) // nothrow
151 : {
152 : SharedCount tmp(rhs);
153 : swap(tmp);
154 : return *this;
155 : }
156 :
157 0 : bool operator== (long count) const
158 : {
159 0 : return (m_pCount != 0) ? *m_pCount == count : false;
160 : }
161 : };
162 :
163 : /*========================================================================
164 : *
165 : * OStorePageGuard.
166 : *
167 : *======================================================================*/
168 : struct OStorePageGuard
169 : {
170 : /** Representation.
171 : */
172 : sal_uInt32 m_nMagic;
173 : sal_uInt32 m_nCRC32;
174 :
175 : /** Construction.
176 : */
177 0 : explicit OStorePageGuard (sal_uInt32 nMagic = 0, sal_uInt32 nCRC32 = 0)
178 0 : : m_nMagic (store::htonl(nMagic)),
179 0 : m_nCRC32 (store::htonl(nCRC32))
180 0 : {}
181 :
182 : void swap (OStorePageGuard & rhs)
183 : {
184 : store::swap(m_nMagic, rhs.m_nMagic);
185 : store::swap(m_nCRC32, rhs.m_nCRC32);
186 : }
187 :
188 : OStorePageGuard (OStorePageGuard const & rhs)
189 : : m_nMagic (rhs.m_nMagic),
190 : m_nCRC32 (rhs.m_nCRC32)
191 : {}
192 :
193 0 : OStorePageGuard& operator= (const OStorePageGuard& rhs)
194 : {
195 0 : m_nMagic = rhs.m_nMagic;
196 0 : m_nCRC32 = rhs.m_nCRC32;
197 0 : return *this;
198 : }
199 :
200 : /** Comparison.
201 : */
202 0 : bool operator== (const OStorePageGuard& rhs) const
203 : {
204 0 : return ((m_nMagic == rhs.m_nMagic) &&
205 0 : (m_nCRC32 == rhs.m_nCRC32) );
206 : }
207 : };
208 :
209 : /*========================================================================
210 : *
211 : * OStorePageDescriptor.
212 : *
213 : *======================================================================*/
214 : #define STORE_PAGE_NULL ((sal_uInt32)(~0))
215 :
216 : struct OStorePageDescriptor
217 : {
218 : /** Representation.
219 : */
220 : sal_uInt32 m_nAddr;
221 : sal_uInt16 m_nSize;
222 : sal_uInt16 m_nUsed;
223 :
224 : /** Construction.
225 : */
226 0 : explicit OStorePageDescriptor (
227 : sal_uInt32 nAddr = STORE_PAGE_NULL,
228 : sal_uInt16 nSize = 0,
229 : sal_uInt16 nUsed = 0)
230 0 : : m_nAddr (store::htonl(nAddr)),
231 0 : m_nSize (store::htons(nSize)),
232 0 : m_nUsed (store::htons(nUsed))
233 0 : {}
234 :
235 : void swap (OStorePageDescriptor & rhs)
236 : {
237 : store::swap(m_nAddr, rhs.m_nAddr);
238 : store::swap(m_nSize, rhs.m_nSize);
239 : store::swap(m_nUsed, rhs.m_nUsed);
240 : }
241 :
242 0 : OStorePageDescriptor (const OStorePageDescriptor & rhs)
243 : : m_nAddr (rhs.m_nAddr),
244 : m_nSize (rhs.m_nSize),
245 0 : m_nUsed (rhs.m_nUsed)
246 0 : {}
247 :
248 0 : OStorePageDescriptor & operator= (const OStorePageDescriptor & rhs)
249 : {
250 0 : m_nAddr = rhs.m_nAddr;
251 0 : m_nSize = rhs.m_nSize;
252 0 : m_nUsed = rhs.m_nUsed;
253 0 : return *this;
254 : }
255 :
256 : /** Comparison.
257 : */
258 0 : bool operator== (const OStorePageDescriptor & rhs) const
259 : {
260 0 : return ((m_nAddr == rhs.m_nAddr) &&
261 0 : (m_nSize == rhs.m_nSize) );
262 : }
263 :
264 : bool operator<= (const OStorePageDescriptor & rhs) const
265 : {
266 : return ((m_nAddr == rhs.m_nAddr ) &&
267 : (store::ntohs(m_nSize) <= store::ntohs(rhs.m_nSize)) );
268 : }
269 :
270 : bool operator< (const OStorePageDescriptor & rhs) const
271 : {
272 : if (m_nAddr == rhs.m_nAddr)
273 : return (store::ntohs(m_nSize) < store::ntohs(rhs.m_nSize));
274 : else
275 : return (store::ntohl(m_nAddr) < store::ntohl(rhs.m_nAddr));
276 : }
277 : };
278 :
279 : /*========================================================================
280 : *
281 : * OStorePageKey.
282 : *
283 : *======================================================================*/
284 : struct OStorePageKey
285 : {
286 : /** Representation.
287 : */
288 : sal_uInt32 m_nLow;
289 : sal_uInt32 m_nHigh;
290 :
291 : /** Construction.
292 : */
293 0 : explicit OStorePageKey (sal_uInt32 nLow = 0, sal_uInt32 nHigh = 0)
294 0 : : m_nLow (store::htonl(nLow)),
295 0 : m_nHigh (store::htonl(nHigh))
296 0 : {}
297 :
298 : void swap (OStorePageKey & rhs)
299 : {
300 : store::swap(m_nLow, rhs.m_nLow);
301 : store::swap(m_nHigh, rhs.m_nHigh);
302 : }
303 :
304 0 : OStorePageKey (const OStorePageKey & rhs)
305 0 : : m_nLow (rhs.m_nLow), m_nHigh (rhs.m_nHigh)
306 0 : {}
307 :
308 0 : OStorePageKey & operator= (const OStorePageKey & rhs)
309 : {
310 0 : m_nLow = rhs.m_nLow;
311 0 : m_nHigh = rhs.m_nHigh;
312 0 : return *this;
313 : }
314 :
315 : /** Comparison.
316 : */
317 0 : bool operator== (const OStorePageKey & rhs) const
318 : {
319 0 : return ((m_nLow == rhs.m_nLow ) &&
320 0 : (m_nHigh == rhs.m_nHigh) );
321 : }
322 :
323 0 : bool operator< (const OStorePageKey & rhs) const
324 : {
325 0 : if (m_nHigh == rhs.m_nHigh)
326 0 : return (store::ntohl(m_nLow) < store::ntohl(rhs.m_nLow));
327 : else
328 0 : return (store::ntohl(m_nHigh) < store::ntohl(rhs.m_nHigh));
329 : }
330 : };
331 :
332 : /*========================================================================
333 : *
334 : * OStorePageLink.
335 : *
336 : *======================================================================*/
337 : struct OStorePageLink
338 : {
339 : /** Representation.
340 : */
341 : sal_uInt32 m_nAddr;
342 :
343 : /** Construction.
344 : */
345 0 : explicit OStorePageLink (sal_uInt32 nAddr = STORE_PAGE_NULL)
346 0 : : m_nAddr (store::htonl(nAddr))
347 0 : {}
348 :
349 : void swap (OStorePageLink & rhs)
350 : {
351 : store::swap(m_nAddr, rhs.m_nAddr);
352 : }
353 :
354 0 : OStorePageLink (const OStorePageLink & rhs)
355 0 : : m_nAddr (rhs.m_nAddr)
356 0 : {}
357 :
358 0 : OStorePageLink & operator= (const OStorePageLink & rhs)
359 : {
360 0 : m_nAddr = rhs.m_nAddr;
361 0 : return *this;
362 : }
363 :
364 0 : OStorePageLink & operator= (sal_uInt32 nAddr)
365 : {
366 0 : m_nAddr = store::htonl(nAddr);
367 0 : return *this;
368 : }
369 :
370 : /** Comparison.
371 : */
372 0 : bool operator== (const OStorePageLink & rhs) const
373 : {
374 0 : return (m_nAddr == rhs.m_nAddr);
375 : }
376 :
377 : bool operator< (const OStorePageLink& rhs) const
378 : {
379 : return (store::ntohl(m_nAddr) < store::ntohl(rhs.m_nAddr));
380 : }
381 :
382 : /** Operation.
383 : */
384 0 : sal_uInt32 location() const
385 : {
386 0 : return store::ntohl(m_nAddr);
387 : }
388 :
389 : void link (OStorePageLink & rPred)
390 : {
391 : // @@@ swap (rPred); @@@
392 : OStorePageLink tmp (rPred);
393 : rPred = *this;
394 : *this = tmp;
395 : }
396 :
397 : void unlink (OStorePageLink& rPred)
398 : {
399 : rPred = *this;
400 : *this = OStorePageLink();
401 : }
402 : };
403 :
404 : /*========================================================================
405 : *
406 : * PageData.
407 : *
408 : *======================================================================*/
409 : typedef struct PageData OStorePageData; // backward compat.
410 : struct PageData
411 : {
412 : typedef OStorePageGuard G;
413 : typedef OStorePageDescriptor D;
414 : typedef OStorePageLink L;
415 :
416 : /** Representation.
417 : */
418 : G m_aGuard;
419 : D m_aDescr;
420 : L m_aMarked;
421 : L m_aUnused;
422 :
423 : /** theSize.
424 : */
425 : static const size_t theSize = sizeof(G) + sizeof(D) + 2 * sizeof(L);
426 : static const sal_uInt16 thePageSize = theSize;
427 : BOOST_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= thePageSize);
428 :
429 : /** location.
430 : */
431 0 : sal_uInt32 location() const
432 : {
433 0 : return store::ntohl(m_aDescr.m_nAddr);
434 : }
435 0 : void location (sal_uInt32 nAddr)
436 : {
437 0 : m_aDescr.m_nAddr = store::htonl(nAddr);
438 0 : }
439 :
440 : /** size.
441 : */
442 0 : sal_uInt16 size() const
443 : {
444 0 : return store::ntohs(m_aDescr.m_nSize);
445 : }
446 :
447 : /** type.
448 : */
449 0 : sal_uInt32 type() const
450 : {
451 0 : return store::ntohl(m_aGuard.m_nMagic);
452 : }
453 :
454 : /** Allocation.
455 : */
456 : class Allocator_Impl;
457 0 : class Allocator : public rtl::IReference
458 : {
459 : public:
460 0 : template< class T > T * construct()
461 : {
462 0 : void * page = 0; sal_uInt16 size = 0;
463 0 : if (allocate (&page, &size))
464 : {
465 0 : return new(page) T(size);
466 : }
467 0 : return 0;
468 : }
469 :
470 0 : bool allocate (void ** ppPage, sal_uInt16 * pnSize)
471 : {
472 0 : allocate_Impl (ppPage, pnSize);
473 0 : return ((*ppPage != 0) && (*pnSize != 0));
474 : }
475 :
476 0 : void deallocate (void * pPage)
477 : {
478 0 : if (pPage != 0)
479 0 : deallocate_Impl (pPage);
480 0 : }
481 :
482 : static storeError createInstance (
483 : rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize);
484 :
485 : protected:
486 0 : ~Allocator() {}
487 :
488 : private:
489 : /** Implementation (abstract).
490 : */
491 : virtual void allocate_Impl (void ** ppPage, sal_uInt16 * pnSize) = 0;
492 : virtual void deallocate_Impl (void * pPage) = 0;
493 : };
494 :
495 0 : static void* operator new (size_t, void * p) { return p; }
496 : static void operator delete (void * , void *) {}
497 :
498 : /** Construction.
499 : */
500 0 : explicit PageData (sal_uInt16 nPageSize = thePageSize)
501 : : m_aGuard(),
502 : m_aDescr(STORE_PAGE_NULL, nPageSize, thePageSize),
503 : m_aMarked(),
504 0 : m_aUnused()
505 0 : {}
506 :
507 : void swap (PageData & rhs) // nothrow
508 : {
509 : m_aGuard.swap(rhs.m_aGuard);
510 : m_aDescr.swap(rhs.m_aDescr);
511 : m_aMarked.swap(rhs.m_aMarked);
512 : m_aUnused.swap(rhs.m_aUnused);
513 : }
514 :
515 : PageData (PageData const & rhs) // nothrow
516 : : m_aGuard (rhs.m_aGuard),
517 : m_aDescr (rhs.m_aDescr),
518 : m_aMarked(rhs.m_aMarked),
519 : m_aUnused(rhs.m_aUnused)
520 : {}
521 :
522 : PageData & operator= (PageData const & rhs) // nothrow
523 : {
524 : PageData tmp (rhs);
525 : swap (tmp);
526 : return *this;
527 : }
528 :
529 : /** guard (external representation).
530 : */
531 0 : void guard (sal_uInt32 nAddr)
532 : {
533 0 : sal_uInt32 nCRC32 = 0;
534 0 : nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
535 0 : m_aDescr.m_nAddr = store::htonl(nAddr);
536 0 : nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G));
537 0 : m_aGuard.m_nCRC32 = store::htonl(nCRC32);
538 0 : }
539 :
540 : /** verify (external representation).
541 : */
542 0 : storeError verify (sal_uInt32 nAddr) const
543 : {
544 0 : sal_uInt32 nCRC32 = 0;
545 0 : nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
546 0 : nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G));
547 0 : if (m_aGuard.m_nCRC32 != store::htonl(nCRC32))
548 0 : return store_E_InvalidChecksum;
549 0 : if (m_aDescr.m_nAddr != store::htonl(nAddr))
550 0 : return store_E_InvalidAccess;
551 0 : return store_E_None;
552 : }
553 :
554 : storeError verifyVersion (sal_uInt32 nMagic) const
555 : {
556 : if (m_aGuard.m_nMagic != store::htonl(nMagic))
557 : return store_E_WrongVersion;
558 : else
559 : return store_E_None;
560 : }
561 : };
562 :
563 : /*========================================================================
564 : *
565 : * PageHolder.
566 : *
567 : *======================================================================*/
568 : class PageHolder
569 : {
570 : SharedCount m_refcount;
571 : PageData * m_pagedata;
572 :
573 : typedef rtl::Reference< PageData::Allocator > allocator_type;
574 : allocator_type m_allocator;
575 :
576 : public:
577 0 : explicit PageHolder (PageData * pagedata = 0, allocator_type const & allocator = allocator_type())
578 : : m_refcount (),
579 : m_pagedata (pagedata),
580 0 : m_allocator(allocator)
581 : {
582 : OSL_ENSURE((m_pagedata == 0) || m_allocator.is(), "store::PageHolder::ctor(): pagedata w/o allocator.");
583 0 : }
584 :
585 0 : ~PageHolder()
586 0 : {
587 0 : if ((m_refcount == 1) && (m_pagedata != 0))
588 : {
589 : // free pagedata.
590 : OSL_ENSURE(m_allocator.is(), "store::PageHolder::dtor(): pagedata w/o allocator.");
591 0 : m_allocator->deallocate (m_pagedata);
592 : }
593 0 : }
594 :
595 0 : void swap (PageHolder & rhs) // nothrow
596 : {
597 0 : m_refcount.swap(rhs.m_refcount);
598 0 : store::swap(m_pagedata, rhs.m_pagedata);
599 0 : store::swap(m_allocator, rhs.m_allocator);
600 0 : }
601 :
602 0 : PageHolder (PageHolder const & rhs) // nothrow
603 : : m_refcount (rhs.m_refcount),
604 : m_pagedata (rhs.m_pagedata),
605 0 : m_allocator(rhs.m_allocator)
606 0 : {}
607 :
608 0 : PageHolder & operator= (PageHolder const & rhs) // nothrow
609 : {
610 0 : PageHolder tmp (rhs);
611 0 : swap(tmp);
612 0 : return *this;
613 : }
614 :
615 0 : PageData * get() { return m_pagedata; }
616 0 : PageData const * get() const { return m_pagedata; }
617 :
618 0 : PageData * operator->()
619 : {
620 : OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator->(): Null pointer");
621 0 : return m_pagedata;
622 : }
623 0 : PageData const * operator->() const
624 : {
625 : OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator->(): Null pointer");
626 0 : return m_pagedata;
627 : }
628 :
629 : PageData & operator*()
630 : {
631 : OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator*(): Null pointer");
632 : return *m_pagedata;
633 : }
634 : PageData const & operator*() const
635 : {
636 : OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator*(): Null pointer");
637 : return *m_pagedata;
638 : }
639 : };
640 :
641 : /*========================================================================
642 : *
643 : * PageHolderObject.
644 : *
645 : *======================================================================*/
646 : template< class T >
647 0 : class PageHolderObject
648 : {
649 : /** Representation.
650 : */
651 : PageHolder m_xPage;
652 :
653 : /** Checked cast.
654 : */
655 : template< class U >
656 0 : static bool isA (PageData const * p)
657 : {
658 0 : return ((p != 0) && (p->type() == U::theTypeId));
659 : }
660 :
661 : template< class U >
662 0 : static U * dynamic_page_cast (PageData * p)
663 : {
664 0 : return isA<U>(p) ? static_cast<U*>(p) : 0;
665 : }
666 :
667 : template< class U >
668 0 : static U const * dynamic_page_cast (PageData const * p)
669 : {
670 0 : return isA<U>(p) ? static_cast<U const *>(p) : 0;
671 : }
672 :
673 : public:
674 0 : bool construct (rtl::Reference< PageData::Allocator > const & rxAllocator)
675 : {
676 0 : if ((m_xPage.get() == 0) && rxAllocator.is())
677 : {
678 0 : PageHolder tmp (rxAllocator->construct<T>(), rxAllocator);
679 0 : m_xPage.swap (tmp);
680 : }
681 0 : return (m_xPage.get() != 0);
682 : }
683 :
684 : static PageHolderObject<T> createInstance (rtl::Reference< PageData::Allocator > const & rxAllocator)
685 : {
686 : PageHolderObject<T> tmp;
687 : (void) tmp.construct (rxAllocator);
688 : return tmp;
689 : }
690 :
691 0 : explicit PageHolderObject (PageHolder const & rxPage = PageHolder())
692 0 : : m_xPage (rxPage)
693 0 : {}
694 :
695 0 : void swap (PageHolderObject<T> & rhs)
696 : {
697 0 : m_xPage.swap (rhs.m_xPage);
698 0 : }
699 :
700 0 : PageHolderObject (PageHolderObject<T> const & rhs)
701 0 : : m_xPage (rhs.m_xPage)
702 0 : {}
703 :
704 0 : PageHolderObject<T> & operator= (PageHolderObject<T> const & rhs)
705 : {
706 0 : PageHolderObject<T> tmp (rhs);
707 0 : this->swap (tmp);
708 0 : return *this;
709 : }
710 :
711 0 : bool is() const
712 : {
713 0 : return (m_xPage.get() != 0);
714 : }
715 :
716 : #if 1 /* EXP */
717 0 : PageHolder & get() { return m_xPage; }
718 : PageHolder const & get() const { return m_xPage; }
719 : #endif /* EXP */
720 :
721 0 : T * operator->()
722 : {
723 0 : T * pImpl = dynamic_page_cast<T>(m_xPage.get());
724 : OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
725 0 : return pImpl;
726 : }
727 : T const * operator->() const
728 : {
729 : T const * pImpl = dynamic_page_cast<T>(m_xPage.get());
730 : OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
731 : return pImpl;
732 : }
733 :
734 0 : T & operator*()
735 : {
736 0 : T * pImpl = dynamic_page_cast<T>(m_xPage.get());
737 : OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
738 0 : return (*pImpl);
739 : }
740 : T const & operator*() const
741 : {
742 : T const * pImpl = dynamic_page_cast<T>(m_xPage.get());
743 : OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
744 : return (*pImpl);
745 : }
746 :
747 0 : static storeError guard (PageHolder & rxPage, sal_uInt32 nAddr)
748 : {
749 0 : PageData * pHead = rxPage.get();
750 0 : if (!pHead)
751 0 : return store_E_InvalidAccess;
752 0 : pHead->guard(nAddr);
753 :
754 0 : T * pImpl = dynamic_page_cast<T>(pHead);
755 : OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::guard(): Null pointer");
756 0 : pImpl->guard();
757 :
758 0 : return store_E_None;
759 : }
760 0 : static storeError verify (PageHolder const & rxPage, sal_uInt32 nAddr)
761 : {
762 0 : PageData const * pHead = rxPage.get();
763 0 : if (!pHead)
764 0 : return store_E_InvalidAccess;
765 :
766 0 : storeError eErrCode = pHead->verify(nAddr);
767 0 : if (eErrCode != store_E_None)
768 0 : return eErrCode;
769 :
770 0 : T const * pImpl = dynamic_page_cast<T>(pHead);
771 0 : if (!pImpl)
772 0 : return store_E_WrongVersion;
773 :
774 0 : return pImpl->verify();
775 : }
776 : };
777 :
778 : /*========================================================================
779 : *
780 : * PageObject.
781 : *
782 : *======================================================================*/
783 : #if 1 /* EXP */
784 : class PageObject
785 : {
786 : public:
787 : explicit PageObject (PageHolder const & rxPage = PageHolder())
788 : : m_xPage (rxPage), m_bDirty (false)
789 : {}
790 :
791 : virtual ~PageObject()
792 : {}
793 :
794 : PageHolder & get() { return m_xPage; }
795 : PageHolder const & get() const { return m_xPage; }
796 :
797 : void clean() { m_bDirty = false; }
798 : void touch() { m_bDirty = true; }
799 :
800 : sal_uInt32 location() const
801 : {
802 : PageData const * pagedata = m_xPage.get();
803 : return (pagedata != 0) ? pagedata->location() : STORE_PAGE_NULL;
804 : }
805 : void location (sal_uInt32 nAddr)
806 : {
807 : PageData * pagedata = m_xPage.get();
808 : if (pagedata != 0)
809 : pagedata->location (nAddr);
810 : }
811 :
812 : protected:
813 : PageHolder m_xPage;
814 : bool m_bDirty;
815 :
816 : virtual storeError guard (sal_uInt32 nAddr) = 0;
817 : virtual storeError verify (sal_uInt32 nAddr) const = 0;
818 : };
819 : #endif /* EXP */
820 :
821 : class OStorePageBIOS;
822 :
823 : class OStorePageObject
824 : {
825 : typedef OStorePageData page;
826 :
827 : public:
828 : /** Allocation.
829 : */
830 : static void * operator new (size_t n) SAL_THROW(())
831 : {
832 : return rtl_allocateMemory (sal_uInt32(n));
833 : }
834 0 : static void operator delete (void * p) SAL_THROW(())
835 : {
836 0 : rtl_freeMemory (p);
837 0 : }
838 :
839 : /** State.
840 : */
841 : inline bool dirty (void) const;
842 : inline void clean (void);
843 : inline void touch (void);
844 :
845 : /** Location.
846 : */
847 : inline sal_uInt32 location (void) const;
848 : inline void location (sal_uInt32 nAddr);
849 :
850 : protected:
851 : /** Representation.
852 : */
853 : PageHolder m_xPage;
854 : bool m_bDirty;
855 :
856 : /** Construction.
857 : */
858 0 : explicit OStorePageObject (PageHolder const & rxPage = PageHolder())
859 0 : : m_xPage (rxPage), m_bDirty (false)
860 0 : {}
861 :
862 : /** Destruction.
863 : */
864 : virtual ~OStorePageObject (void);
865 :
866 : public:
867 : template< class U >
868 0 : PageHolderObject<U> makeHolder() const
869 : {
870 0 : return PageHolderObject<U>(m_xPage);
871 : }
872 :
873 : template< class U >
874 0 : storeError construct (rtl::Reference< PageData::Allocator > const & rxAllocator)
875 : {
876 0 : if (!rxAllocator.is())
877 0 : return store_E_InvalidAccess;
878 :
879 0 : PageHolder tmp (rxAllocator->construct<U>(), rxAllocator);
880 0 : if (!tmp.get())
881 0 : return store_E_OutOfMemory;
882 :
883 0 : m_xPage.swap (tmp);
884 0 : return store_E_None;
885 : }
886 :
887 0 : PageHolder & get() { return m_xPage; }
888 : PageHolder const & get() const { return m_xPage; }
889 :
890 : virtual storeError guard (sal_uInt32 nAddr) = 0;
891 : virtual storeError verify (sal_uInt32 nAddr) const = 0;
892 : };
893 :
894 0 : inline bool OStorePageObject::dirty (void) const
895 : {
896 0 : return m_bDirty;
897 : }
898 :
899 0 : inline void OStorePageObject::clean (void)
900 : {
901 0 : m_bDirty = false;
902 0 : }
903 :
904 0 : inline void OStorePageObject::touch (void)
905 : {
906 0 : m_bDirty = true;
907 0 : }
908 :
909 0 : inline sal_uInt32 OStorePageObject::location (void) const
910 : {
911 0 : return m_xPage->location();
912 : }
913 :
914 : inline void OStorePageObject::location (sal_uInt32 nAddr)
915 : {
916 : m_xPage->location(nAddr);
917 : touch();
918 : }
919 :
920 : /*========================================================================
921 : *
922 : * The End.
923 : *
924 : *======================================================================*/
925 :
926 : } // namespace store
927 :
928 : #endif /* !_STORE_STORBASE_HXX_ */
929 :
930 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|