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

Generated by: LCOV version 1.11