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