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

Generated by: LCOV version 1.10