LCOV - code coverage report
Current view: top level - store/source - storbase.hxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 212 239 88.7 %
Date: 2014-11-03 Functions: 94 119 79.0 %
Legend: Lines: hit not hit

          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: */

Generated by: LCOV version 1.10