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