Branch data 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 : 3440901 : inline sal_uInt16 htons (sal_uInt16 h) { return (h); }
93 : 27469502 : inline sal_uInt16 ntohs (sal_uInt16 n) { return (n); }
94 : :
95 : 28125176 : inline sal_uInt32 htonl (sal_uInt32 h) { return (h); }
96 : 112145375 : inline sal_uInt32 ntohl (sal_uInt32 n) { return (n); }
97 : : #endif /* OSL_BIGENDIAN */
98 : :
99 : : /** swap.
100 : : */
101 : 38837358 : template< typename T > void swap (T & lhs, T & rhs)
102 : : {
103 [ + - ][ + - ]: 12945786 : T tmp = lhs; lhs = rhs; rhs = tmp;
[ + - ][ + - ]
104 : 38837358 : }
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 : 7083133 : long * alloc()
123 : : {
124 : 7083133 : return static_cast<long*>(rtl_cache_alloc (m_cache));
125 : : }
126 : 6791498 : void free (long * pCount)
127 : : {
128 : 6791498 : rtl_cache_free (m_cache, pCount);
129 : 6791498 : }
130 : :
131 : : protected:
132 : : Allocator();
133 : : ~Allocator();
134 : : };
135 : :
136 : : public:
137 : 7083133 : SharedCount()
138 : 7083133 : : m_pCount(Allocator::get().alloc())
139 : : {
140 [ + - ]: 7083133 : if (m_pCount != 0) (*m_pCount) = 1;
141 : 7083133 : }
142 : :
143 : 39009386 : ~SharedCount()
144 : : {
145 [ + - ]: 39009386 : if (m_pCount != 0)
146 : : {
147 : 39009386 : long new_count = --(*m_pCount);
148 [ + + ]: 39009386 : if (new_count == 0)
149 : 6791498 : Allocator::get().free(m_pCount);
150 : : }
151 : 39009386 : }
152 : :
153 : 12945786 : void swap (SharedCount & rhs) // nothrow
154 : : {
155 : 12945786 : store::swap(m_pCount, rhs.m_pCount);
156 : 12945786 : }
157 : :
158 : 32218639 : SharedCount (SharedCount const & rhs) // nothrow
159 : 32218639 : : m_pCount (rhs.m_pCount)
160 : : {
161 [ + - ]: 32218639 : if (m_pCount != 0) ++(*m_pCount);
162 : 32218639 : }
163 : : SharedCount & operator= (SharedCount const & rhs) // nothrow
164 : : {
165 : : SharedCount tmp(rhs);
166 : : swap(tmp);
167 : : return *this;
168 : : }
169 : :
170 : 39009386 : bool operator== (long count) const
171 : : {
172 [ + - ][ + + ]: 39009386 : 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 : 543696 : explicit OStorePageGuard (sal_uInt32 nMagic = 0, sal_uInt32 nCRC32 = 0)
191 : 543696 : : m_nMagic (store::htonl(nMagic)),
192 : 543696 : m_nCRC32 (store::htonl(nCRC32))
193 : 543696 : {}
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 : 30403 : OStorePageGuard& operator= (const OStorePageGuard& rhs)
207 : : {
208 : 30403 : m_nMagic = rhs.m_nMagic;
209 : 30403 : m_nCRC32 = rhs.m_nCRC32;
210 : 30403 : return *this;
211 : : }
212 : :
213 : : /** Comparison.
214 : : */
215 : 159662 : bool operator== (const OStorePageGuard& rhs) const
216 : : {
217 : : return ((m_nMagic == rhs.m_nMagic) &&
218 [ + - ][ + - ]: 159662 : (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 : 1603867 : explicit OStorePageDescriptor (
240 : : sal_uInt32 nAddr = STORE_PAGE_NULL,
241 : : sal_uInt16 nSize = 0,
242 : : sal_uInt16 nUsed = 0)
243 : 1603867 : : m_nAddr (store::htonl(nAddr)),
244 : 1603867 : m_nSize (store::htons(nSize)),
245 : 1603867 : m_nUsed (store::htons(nUsed))
246 : 1603867 : {}
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 : 18 : OStorePageDescriptor (const OStorePageDescriptor & rhs)
256 : : : m_nAddr (rhs.m_nAddr),
257 : : m_nSize (rhs.m_nSize),
258 : 18 : m_nUsed (rhs.m_nUsed)
259 : 18 : {}
260 : :
261 : 589816 : OStorePageDescriptor & operator= (const OStorePageDescriptor & rhs)
262 : : {
263 : 589816 : m_nAddr = rhs.m_nAddr;
264 : 589816 : m_nSize = rhs.m_nSize;
265 : 589816 : m_nUsed = rhs.m_nUsed;
266 : 589816 : return *this;
267 : : }
268 : :
269 : : /** Comparison.
270 : : */
271 : 159662 : bool operator== (const OStorePageDescriptor & rhs) const
272 : : {
273 : : return ((m_nAddr == rhs.m_nAddr) &&
274 [ + - ][ + - ]: 159662 : (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 : 2502955 : explicit OStorePageKey (sal_uInt32 nLow = 0, sal_uInt32 nHigh = 0)
307 : 2502955 : : m_nLow (store::htonl(nLow)),
308 : 2502955 : m_nHigh (store::htonl(nHigh))
309 : 2502955 : {}
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 : 7994586 : OStorePageKey (const OStorePageKey & rhs)
318 : 7994586 : : m_nLow (rhs.m_nLow), m_nHigh (rhs.m_nHigh)
319 : 7994586 : {}
320 : :
321 : 929834 : OStorePageKey & operator= (const OStorePageKey & rhs)
322 : : {
323 : 929834 : m_nLow = rhs.m_nLow;
324 : 929834 : m_nHigh = rhs.m_nHigh;
325 : 929834 : return *this;
326 : : }
327 : :
328 : : /** Comparison.
329 : : */
330 : 24366383 : bool operator== (const OStorePageKey & rhs) const
331 : : {
332 : : return ((m_nLow == rhs.m_nLow ) &&
333 [ + + ][ + + ]: 24366383 : (m_nHigh == rhs.m_nHigh) );
334 : : }
335 : :
336 : 30167510 : bool operator< (const OStorePageKey & rhs) const
337 : : {
338 [ + + ]: 30167510 : if (m_nHigh == rhs.m_nHigh)
339 : 8412970 : return (store::ntohl(m_nLow) < store::ntohl(rhs.m_nLow));
340 : : else
341 : 30167510 : 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 : 5701981 : explicit OStorePageLink (sal_uInt32 nAddr = STORE_PAGE_NULL)
359 : 5701981 : : m_nAddr (store::htonl(nAddr))
360 : 5701981 : {}
361 : :
362 : : void swap (OStorePageLink & rhs)
363 : : {
364 : : store::swap(m_nAddr, rhs.m_nAddr);
365 : : }
366 : :
367 : 8131021 : OStorePageLink (const OStorePageLink & rhs)
368 : 8131021 : : m_nAddr (rhs.m_nAddr)
369 : 8131021 : {}
370 : :
371 : 934041 : OStorePageLink & operator= (const OStorePageLink & rhs)
372 : : {
373 : 934041 : m_nAddr = rhs.m_nAddr;
374 : 934041 : return *this;
375 : : }
376 : :
377 : 6278 : OStorePageLink & operator= (sal_uInt32 nAddr)
378 : : {
379 : 6278 : m_nAddr = store::htonl(nAddr);
380 : 6278 : return *this;
381 : : }
382 : :
383 : : /** Comparison.
384 : : */
385 : 319324 : bool operator== (const OStorePageLink & rhs) const
386 : : {
387 : 319324 : 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 : 6560699 : sal_uInt32 location() const
398 : : {
399 : 6560699 : 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 : 6869463 : sal_uInt32 location() const
445 : : {
446 : 6869463 : return store::ntohl(m_aDescr.m_nAddr);
447 : : }
448 : 124370 : void location (sal_uInt32 nAddr)
449 : : {
450 : 124370 : m_aDescr.m_nAddr = store::htonl(nAddr);
451 : 124370 : }
452 : :
453 : : /** size.
454 : : */
455 : 5364476 : sal_uInt16 size() const
456 : : {
457 : 5364476 : return store::ntohs(m_aDescr.m_nSize);
458 : : }
459 : :
460 : : /** type.
461 : : */
462 : 24450026 : sal_uInt32 type() const
463 : : {
464 : 24450026 : return store::ntohl(m_aGuard.m_nMagic);
465 : : }
466 : :
467 : : /** Allocation.
468 : : */
469 : : class Allocator_Impl;
470 : 17790 : class Allocator : public rtl::IReference
471 : : {
472 : : public:
473 : 166312 : template< class T > T * construct()
474 : : {
475 : 166312 : void * page = 0; sal_uInt16 size = 0;
476 [ + - ][ + - ]: 166312 : if (allocate (&page, &size))
[ + - ][ + - ]
477 : : {
478 : 166312 : return new(page) T(size);
479 : : }
480 : 166312 : return 0;
481 : : }
482 : :
483 : 166312 : bool allocate (void ** ppPage, sal_uInt16 * pnSize)
484 : : {
485 : 166312 : allocate_Impl (ppPage, pnSize);
486 [ + - ][ + - ]: 166312 : return ((*ppPage != 0) && (*pnSize != 0));
487 : : }
488 : :
489 : 508866 : void deallocate (void * pPage)
490 : : {
491 [ + - ]: 508866 : if (pPage != 0)
492 : 508866 : deallocate_Impl (pPage);
493 : 508866 : }
494 : :
495 : : static storeError createInstance (
496 : : rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize);
497 : :
498 : : protected:
499 : 17039 : ~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 : 166312 : static void* operator new (size_t, void * p) { return p; }
509 : : static void operator delete (void * , void *) {}
510 : :
511 : : /** Construction.
512 : : */
513 : 314834 : explicit PageData (sal_uInt16 nPageSize = thePageSize)
514 : : : m_aGuard(),
515 : : m_aDescr(STORE_PAGE_NULL, nPageSize, thePageSize),
516 : : m_aMarked(),
517 : 314834 : m_aUnused()
518 : 314834 : {}
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 : 388636 : void guard (sal_uInt32 nAddr)
545 : : {
546 : 388636 : sal_uInt32 nCRC32 = 0;
547 : 388636 : nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
548 : 388636 : m_aDescr.m_nAddr = store::htonl(nAddr);
549 : 388636 : nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G));
550 : 388636 : m_aGuard.m_nCRC32 = store::htonl(nCRC32);
551 : 388636 : }
552 : :
553 : : /** verify (external representation).
554 : : */
555 : 681967 : storeError verify (sal_uInt32 nAddr) const
556 : : {
557 : 681967 : sal_uInt32 nCRC32 = 0;
558 : 681967 : nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
559 : 681967 : nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G));
560 [ - + ]: 681967 : if (m_aGuard.m_nCRC32 != store::htonl(nCRC32))
561 : 0 : return store_E_InvalidChecksum;
562 [ - + ]: 681967 : if (m_aDescr.m_nAddr != store::htonl(nAddr))
563 : 0 : return store_E_InvalidAccess;
564 : 681967 : 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 : 7083133 : explicit PageHolder (PageData * pagedata = 0, allocator_type const & allocator = allocator_type())
591 : : : m_refcount (),
592 : : m_pagedata (pagedata),
593 [ + - ]: 7083133 : m_allocator(allocator)
594 : : {
595 : : OSL_ENSURE((m_pagedata == 0) || m_allocator.is(), "store::PageHolder::ctor(): pagedata w/o allocator.");
596 : 7083133 : }
597 : :
598 : 39009386 : ~PageHolder()
599 [ + - ]: 39009386 : {
600 [ + + ][ + + ]: 39009386 : 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 [ + - ]: 508866 : m_allocator->deallocate (m_pagedata);
605 : : }
606 : 39009386 : }
607 : :
608 : 12945786 : void swap (PageHolder & rhs) // nothrow
609 : : {
610 : 12945786 : m_refcount.swap(rhs.m_refcount);
611 : 12945786 : store::swap(m_pagedata, rhs.m_pagedata);
612 : 12945786 : store::swap(m_allocator, rhs.m_allocator);
613 : 12945786 : }
614 : :
615 : 32218639 : PageHolder (PageHolder const & rhs) // nothrow
616 : : : m_refcount (rhs.m_refcount),
617 : : m_pagedata (rhs.m_pagedata),
618 [ + - ]: 32218639 : m_allocator(rhs.m_allocator)
619 : 32218639 : {}
620 : :
621 : 5139159 : PageHolder & operator= (PageHolder const & rhs) // nothrow
622 : : {
623 [ + - ]: 5139159 : PageHolder tmp (rhs);
624 [ + - ]: 5139159 : swap(tmp);
625 [ + - ]: 5139159 : return *this;
626 : : }
627 : :
628 : 24523578 : PageData * get() { return m_pagedata; }
629 : 8693775 : PageData const * get() const { return m_pagedata; }
630 : :
631 : 9916100 : PageData * operator->()
632 : : {
633 : : OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator->(): Null pointer");
634 : 9916100 : return m_pagedata;
635 : : }
636 : 362728 : PageData const * operator->() const
637 : : {
638 : : OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator->(): Null pointer");
639 : 362728 : 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 : 17122908 : class PageHolderObject
661 : : {
662 : : /** Representation.
663 : : */
664 : : PageHolder m_xPage;
665 : :
666 : : /** Checked cast.
667 : : */
668 : : template< class U >
669 : 24450026 : static bool isA (PageData const * p)
670 : : {
671 [ + - ][ + - ]: 24450026 : return ((p != 0) && (p->type() == U::theTypeId));
[ + - ][ + - ]
[ + - ][ + - ]
672 : : }
673 : :
674 : : template< class U >
675 : 23792211 : static U * dynamic_page_cast (PageData * p)
676 : : {
677 [ + - ][ + - ]: 23792211 : return isA<U>(p) ? static_cast<U*>(p) : 0;
[ + - ]
678 : : }
679 : :
680 : : template< class U >
681 : 657815 : static U const * dynamic_page_cast (PageData const * p)
682 : : {
683 [ + - ][ + - ]: 657815 : return isA<U>(p) ? static_cast<U const *>(p) : 0;
[ + - ]
684 : : }
685 : :
686 : : public:
687 : 1310 : bool construct (rtl::Reference< PageData::Allocator > const & rxAllocator)
688 : : {
689 [ + - ][ + - ]: 1310 : if ((m_xPage.get() == 0) && rxAllocator.is())
[ + - ]
690 : : {
691 [ + - ][ + - ]: 1310 : PageHolder tmp (rxAllocator->construct<T>(), rxAllocator);
692 [ + - ][ + - ]: 1310 : m_xPage.swap (tmp);
693 : : }
694 : 1310 : 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 : 12637514 : explicit PageHolderObject (PageHolder const & rxPage = PageHolder())
705 : 12637514 : : m_xPage (rxPage)
706 : 12637514 : {}
707 : :
708 : 4485421 : void swap (PageHolderObject<T> & rhs)
709 : : {
710 : 4485421 : m_xPage.swap (rhs.m_xPage);
711 : 4485421 : }
712 : :
713 : 4485394 : PageHolderObject (PageHolderObject<T> const & rhs)
714 : 4485394 : : m_xPage (rhs.m_xPage)
715 : 4485394 : {}
716 : :
717 : 4485394 : PageHolderObject<T> & operator= (PageHolderObject<T> const & rhs)
718 : : {
719 [ + - ][ + - ]: 4485394 : PageHolderObject<T> tmp (rhs);
720 [ + - ][ + - ]: 4485394 : this->swap (tmp);
721 [ + - ][ + - ]: 4485394 : return *this;
722 : : }
723 : :
724 : 678119 : bool is() const
725 : : {
726 : 678119 : return (m_xPage.get() != 0);
727 : : }
728 : :
729 : : #if 1 /* EXP */
730 : 1012044 : PageHolder & get() { return m_xPage; }
731 : : PageHolder const & get() const { return m_xPage; }
732 : : #endif /* EXP */
733 : :
734 : 17094520 : T * operator->()
735 : : {
736 : 17094520 : T * pImpl = dynamic_page_cast<T>(m_xPage.get());
737 : : OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
738 : 17094520 : 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 : 6321142 : T & operator*()
748 : : {
749 : 6321142 : T * pImpl = dynamic_page_cast<T>(m_xPage.get());
750 : : OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
751 : 6321142 : 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 : 376549 : static storeError guard (PageHolder & rxPage, sal_uInt32 nAddr)
761 : : {
762 : 376549 : PageData * pHead = rxPage.get();
763 [ - + - + : 376549 : if (!pHead)
- + ]
764 : 0 : return store_E_InvalidAccess;
765 : 376549 : pHead->guard(nAddr);
766 : :
767 : 376549 : T * pImpl = dynamic_page_cast<T>(pHead);
768 : : OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::guard(): Null pointer");
769 : 376549 : pImpl->guard();
770 : :
771 : 376549 : return store_E_None;
772 : : }
773 : 657815 : static storeError verify (PageHolder const & rxPage, sal_uInt32 nAddr)
774 : : {
775 : 657815 : PageData const * pHead = rxPage.get();
776 [ - + - + : 657815 : if (!pHead)
- + ]
777 : 0 : return store_E_InvalidAccess;
778 : :
779 : 657815 : storeError eErrCode = pHead->verify(nAddr);
780 [ - + - + : 657815 : if (eErrCode != store_E_None)
- + ]
781 : 0 : return eErrCode;
782 : :
783 : 657815 : T const * pImpl = dynamic_page_cast<T>(pHead);
784 [ - + - + : 657815 : if (!pImpl)
- + ]
785 : 0 : return store_E_WrongVersion;
786 : :
787 : 657815 : 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 : 6641617 : explicit OStorePageObject (PageHolder const & rxPage = PageHolder())
872 : 6641617 : : m_xPage (rxPage), m_bDirty (false)
873 : 6641617 : {}
874 : :
875 : : /** Destruction.
876 : : */
877 : : virtual ~OStorePageObject (void);
878 : :
879 : : public:
880 : : template< class U >
881 : 4165720 : PageHolderObject<U> makeHolder() const
882 : : {
883 : 4165720 : return PageHolderObject<U>(m_xPage);
884 : : }
885 : :
886 : : template< class U >
887 : 135125 : storeError construct (rtl::Reference< PageData::Allocator > const & rxAllocator)
888 : : {
889 [ - + ]: 135125 : if (!rxAllocator.is())
890 : 0 : return store_E_InvalidAccess;
891 : :
892 [ + - ][ + - ]: 135125 : PageHolder tmp (rxAllocator->construct<U>(), rxAllocator);
893 [ - + ]: 135125 : if (!tmp.get())
894 : 0 : return store_E_OutOfMemory;
895 : :
896 [ + - ]: 135125 : m_xPage.swap (tmp);
897 [ + - ]: 135125 : return store_E_None;
898 : : }
899 : :
900 : :
901 : 17920523 : 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 : 90125 : inline bool OStorePageObject::dirty (void) const
909 : : {
910 : 90125 : return m_bDirty;
911 : : }
912 : :
913 : 1034364 : inline void OStorePageObject::clean (void)
914 : : {
915 : 1034364 : m_bDirty = false;
916 : 1034364 : }
917 : :
918 : 587805 : inline void OStorePageObject::touch (void)
919 : : {
920 : 587805 : m_bDirty = true;
921 : 587805 : }
922 : :
923 : 362728 : inline sal_uInt32 OStorePageObject::location (void) const
924 : : {
925 : 362728 : 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: */
|