LCOV - code coverage report
Current view: top level - store/source - storbase.hxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 241 0.0 %
Date: 2014-04-14 Functions: 0 120 0.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 _STORE_STORBASE_HXX_
      21             : #define _STORE_STORBASE_HXX_
      22             : 
      23             : #include "sal/config.h"
      24             : 
      25             : #include "boost/static_assert.hpp"
      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           0 : inline sal_uInt16 htons (sal_uInt16 h) { return (h); }
      80           0 : inline sal_uInt16 ntohs (sal_uInt16 n) { return (n); }
      81             : 
      82           0 : inline sal_uInt32 htonl (sal_uInt32 h) { return (h); }
      83           0 : inline sal_uInt32 ntohl (sal_uInt32 n) { return (n); }
      84             : #endif /* OSL_BIGENDIAN */
      85             : 
      86             : /** swap.
      87             :  */
      88           0 : template< typename T > void swap (T & lhs, T & rhs)
      89             : {
      90           0 :     T tmp = lhs; lhs = rhs; rhs = tmp;
      91           0 : }
      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           0 :         long * alloc()
     110             :         {
     111           0 :             return static_cast<long*>(rtl_cache_alloc (m_cache));
     112             :         }
     113           0 :         void free (long * pCount)
     114             :         {
     115           0 :             rtl_cache_free (m_cache, pCount);
     116           0 :         }
     117             : 
     118             :     protected:
     119             :         Allocator();
     120             :         ~Allocator();
     121             :     };
     122             : 
     123             : public:
     124           0 :     SharedCount()
     125           0 :         : m_pCount(Allocator::get().alloc())
     126             :     {
     127           0 :         if (m_pCount != 0) (*m_pCount) = 1;
     128           0 :     }
     129             : 
     130           0 :     ~SharedCount()
     131             :     {
     132           0 :         if (m_pCount != 0)
     133             :         {
     134           0 :             long new_count = --(*m_pCount);
     135           0 :             if (new_count == 0)
     136           0 :                 Allocator::get().free(m_pCount);
     137             :         }
     138           0 :     }
     139             : 
     140           0 :     void swap (SharedCount & rhs) // nothrow
     141             :     {
     142           0 :         store::swap(m_pCount, rhs.m_pCount);
     143           0 :     }
     144             : 
     145           0 :     SharedCount (SharedCount const & rhs) // nothrow
     146           0 :         : m_pCount (rhs.m_pCount)
     147             :     {
     148           0 :         if (m_pCount != 0) ++(*m_pCount);
     149           0 :     }
     150             :     SharedCount & operator= (SharedCount const & rhs) // nothrow
     151             :     {
     152             :         SharedCount tmp(rhs);
     153             :         swap(tmp);
     154             :         return *this;
     155             :     }
     156             : 
     157           0 :     bool operator== (long count) const
     158             :     {
     159           0 :         return (m_pCount != 0) ? *m_pCount == count : false;
     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           0 :     explicit OStorePageGuard (sal_uInt32 nMagic = 0, sal_uInt32 nCRC32 = 0)
     178           0 :         : m_nMagic (store::htonl(nMagic)),
     179           0 :           m_nCRC32 (store::htonl(nCRC32))
     180           0 :     {}
     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           0 :     OStorePageGuard& operator= (const OStorePageGuard& rhs)
     194             :     {
     195           0 :         m_nMagic = rhs.m_nMagic;
     196           0 :         m_nCRC32 = rhs.m_nCRC32;
     197           0 :         return *this;
     198             :     }
     199             : 
     200             :     /** Comparison.
     201             :      */
     202           0 :     bool operator== (const OStorePageGuard& rhs) const
     203             :     {
     204           0 :         return ((m_nMagic == rhs.m_nMagic) &&
     205           0 :                 (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           0 :     explicit OStorePageDescriptor (
     227             :         sal_uInt32 nAddr = STORE_PAGE_NULL,
     228             :         sal_uInt16 nSize = 0,
     229             :         sal_uInt16 nUsed = 0)
     230           0 :         : m_nAddr (store::htonl(nAddr)),
     231           0 :           m_nSize (store::htons(nSize)),
     232           0 :           m_nUsed (store::htons(nUsed))
     233           0 :     {}
     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           0 :     OStorePageDescriptor (const OStorePageDescriptor & rhs)
     243             :         : m_nAddr (rhs.m_nAddr),
     244             :           m_nSize (rhs.m_nSize),
     245           0 :           m_nUsed (rhs.m_nUsed)
     246           0 :     {}
     247             : 
     248           0 :     OStorePageDescriptor & operator= (const OStorePageDescriptor & rhs)
     249             :     {
     250           0 :         m_nAddr = rhs.m_nAddr;
     251           0 :         m_nSize = rhs.m_nSize;
     252           0 :         m_nUsed = rhs.m_nUsed;
     253           0 :         return *this;
     254             :     }
     255             : 
     256             :     /** Comparison.
     257             :      */
     258           0 :     bool operator== (const OStorePageDescriptor & rhs) const
     259             :     {
     260           0 :         return ((m_nAddr == rhs.m_nAddr) &&
     261           0 :                 (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           0 :     explicit OStorePageKey (sal_uInt32 nLow = 0, sal_uInt32 nHigh = 0)
     294           0 :         : m_nLow  (store::htonl(nLow)),
     295           0 :           m_nHigh (store::htonl(nHigh))
     296           0 :     {}
     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           0 :     OStorePageKey (const OStorePageKey & rhs)
     305           0 :         : m_nLow (rhs.m_nLow), m_nHigh (rhs.m_nHigh)
     306           0 :     {}
     307             : 
     308           0 :     OStorePageKey & operator= (const OStorePageKey & rhs)
     309             :     {
     310           0 :         m_nLow  = rhs.m_nLow;
     311           0 :         m_nHigh = rhs.m_nHigh;
     312           0 :         return *this;
     313             :     }
     314             : 
     315             :     /** Comparison.
     316             :      */
     317           0 :     bool operator== (const OStorePageKey & rhs) const
     318             :     {
     319           0 :         return ((m_nLow  == rhs.m_nLow ) &&
     320           0 :                 (m_nHigh == rhs.m_nHigh)    );
     321             :     }
     322             : 
     323           0 :     bool operator< (const OStorePageKey & rhs) const
     324             :     {
     325           0 :         if (m_nHigh == rhs.m_nHigh)
     326           0 :             return (store::ntohl(m_nLow) < store::ntohl(rhs.m_nLow));
     327             :         else
     328           0 :             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           0 :     explicit OStorePageLink (sal_uInt32 nAddr = STORE_PAGE_NULL)
     346           0 :         : m_nAddr (store::htonl(nAddr))
     347           0 :     {}
     348             : 
     349             :     void swap (OStorePageLink & rhs)
     350             :     {
     351             :         store::swap(m_nAddr, rhs.m_nAddr);
     352             :     }
     353             : 
     354           0 :     OStorePageLink (const OStorePageLink & rhs)
     355           0 :         : m_nAddr (rhs.m_nAddr)
     356           0 :     {}
     357             : 
     358           0 :     OStorePageLink & operator= (const OStorePageLink & rhs)
     359             :     {
     360           0 :         m_nAddr = rhs.m_nAddr;
     361           0 :         return *this;
     362             :     }
     363             : 
     364           0 :     OStorePageLink & operator= (sal_uInt32 nAddr)
     365             :     {
     366           0 :         m_nAddr = store::htonl(nAddr);
     367           0 :         return *this;
     368             :     }
     369             : 
     370             :     /** Comparison.
     371             :      */
     372           0 :     bool operator== (const OStorePageLink & rhs) const
     373             :     {
     374           0 :         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           0 :     sal_uInt32 location() const
     385             :     {
     386           0 :         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             :     BOOST_STATIC_ASSERT(STORE_MINIMUM_PAGESIZE >= thePageSize);
     428             : 
     429             :     /** location.
     430             :      */
     431           0 :     sal_uInt32 location() const
     432             :     {
     433           0 :         return store::ntohl(m_aDescr.m_nAddr);
     434             :     }
     435           0 :     void location (sal_uInt32 nAddr)
     436             :     {
     437           0 :         m_aDescr.m_nAddr = store::htonl(nAddr);
     438           0 :     }
     439             : 
     440             :     /** size.
     441             :      */
     442           0 :     sal_uInt16 size() const
     443             :     {
     444           0 :         return store::ntohs(m_aDescr.m_nSize);
     445             :     }
     446             : 
     447             :     /** type.
     448             :      */
     449           0 :     sal_uInt32 type() const
     450             :     {
     451           0 :         return store::ntohl(m_aGuard.m_nMagic);
     452             :     }
     453             : 
     454             :     /** Allocation.
     455             :      */
     456             :     class Allocator_Impl;
     457           0 :     class Allocator : public rtl::IReference
     458             :     {
     459             :     public:
     460           0 :         template< class T > T * construct()
     461             :         {
     462           0 :             void * page = 0; sal_uInt16 size = 0;
     463           0 :             if (allocate (&page, &size))
     464             :             {
     465           0 :                 return new(page) T(size);
     466             :             }
     467           0 :             return 0;
     468             :         }
     469             : 
     470           0 :         bool allocate (void ** ppPage, sal_uInt16 * pnSize)
     471             :         {
     472           0 :             allocate_Impl (ppPage, pnSize);
     473           0 :             return ((*ppPage != 0) && (*pnSize != 0));
     474             :         }
     475             : 
     476           0 :         void deallocate (void * pPage)
     477             :         {
     478           0 :             if (pPage != 0)
     479           0 :                 deallocate_Impl (pPage);
     480           0 :         }
     481             : 
     482             :         static storeError createInstance (
     483             :             rtl::Reference< PageData::Allocator > & rxAllocator, sal_uInt16 nPageSize);
     484             : 
     485             :     protected:
     486           0 :         ~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           0 :     static void* operator new (size_t, void * p) { return p; }
     496             :     static void  operator delete (void * , void *) {}
     497             : 
     498             :     /** Construction.
     499             :      */
     500           0 :     explicit PageData (sal_uInt16 nPageSize = thePageSize)
     501             :         : m_aGuard(),
     502             :           m_aDescr(STORE_PAGE_NULL, nPageSize, thePageSize),
     503             :           m_aMarked(),
     504           0 :           m_aUnused()
     505           0 :     {}
     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           0 :     void guard (sal_uInt32 nAddr)
     532             :     {
     533           0 :         sal_uInt32 nCRC32 = 0;
     534           0 :         nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
     535           0 :         m_aDescr.m_nAddr = store::htonl(nAddr);
     536           0 :         nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G));
     537           0 :         m_aGuard.m_nCRC32 = store::htonl(nCRC32);
     538           0 :     }
     539             : 
     540             :     /** verify (external representation).
     541             :      */
     542           0 :     storeError verify (sal_uInt32 nAddr) const
     543             :     {
     544           0 :         sal_uInt32 nCRC32 = 0;
     545           0 :         nCRC32 = rtl_crc32 (nCRC32, &m_aGuard.m_nMagic, sizeof(sal_uInt32));
     546           0 :         nCRC32 = rtl_crc32 (nCRC32, &m_aDescr, theSize - sizeof(G));
     547           0 :         if (m_aGuard.m_nCRC32 != store::htonl(nCRC32))
     548           0 :             return store_E_InvalidChecksum;
     549           0 :         if (m_aDescr.m_nAddr != store::htonl(nAddr))
     550           0 :             return store_E_InvalidAccess;
     551           0 :         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           0 :     explicit PageHolder (PageData * pagedata = 0, allocator_type const & allocator = allocator_type())
     578             :         : m_refcount (),
     579             :           m_pagedata (pagedata),
     580           0 :           m_allocator(allocator)
     581             :     {
     582             :         OSL_ENSURE((m_pagedata == 0) || m_allocator.is(), "store::PageHolder::ctor(): pagedata w/o allocator.");
     583           0 :     }
     584             : 
     585           0 :     ~PageHolder()
     586           0 :     {
     587           0 :         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           0 :             m_allocator->deallocate (m_pagedata);
     592             :         }
     593           0 :     }
     594             : 
     595           0 :     void swap (PageHolder & rhs) // nothrow
     596             :     {
     597           0 :         m_refcount.swap(rhs.m_refcount);
     598           0 :         store::swap(m_pagedata,  rhs.m_pagedata);
     599           0 :         store::swap(m_allocator, rhs.m_allocator);
     600           0 :     }
     601             : 
     602           0 :     PageHolder (PageHolder const & rhs) // nothrow
     603             :         : m_refcount (rhs.m_refcount),
     604             :           m_pagedata (rhs.m_pagedata),
     605           0 :           m_allocator(rhs.m_allocator)
     606           0 :     {}
     607             : 
     608           0 :     PageHolder & operator= (PageHolder const & rhs) // nothrow
     609             :     {
     610           0 :         PageHolder tmp (rhs);
     611           0 :         swap(tmp);
     612           0 :         return *this;
     613             :     }
     614             : 
     615           0 :     PageData * get() { return m_pagedata; }
     616           0 :     PageData const * get() const { return m_pagedata; }
     617             : 
     618           0 :     PageData * operator->()
     619             :     {
     620             :         OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator->(): Null pointer");
     621           0 :         return m_pagedata;
     622             :     }
     623           0 :     PageData const * operator->() const
     624             :     {
     625             :         OSL_PRECOND(m_pagedata != 0, "store::PageHolder::operator->(): Null pointer");
     626           0 :         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           0 : class PageHolderObject
     648             : {
     649             :     /** Representation.
     650             :      */
     651             :     PageHolder m_xPage;
     652             : 
     653             :     /** Checked cast.
     654             :      */
     655             :     template< class U >
     656           0 :     static bool isA (PageData const * p)
     657             :     {
     658           0 :         return ((p != 0) && (p->type() == U::theTypeId));
     659             :     }
     660             : 
     661             :     template< class U >
     662           0 :     static U * dynamic_page_cast (PageData * p)
     663             :     {
     664           0 :         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           0 :     explicit PageHolderObject (PageHolder const & rxPage = PageHolder())
     692           0 :         : m_xPage (rxPage)
     693           0 :     {}
     694             : 
     695           0 :     void swap (PageHolderObject<T> & rhs)
     696             :     {
     697           0 :         m_xPage.swap (rhs.m_xPage);
     698           0 :     }
     699             : 
     700           0 :     PageHolderObject (PageHolderObject<T> const & rhs)
     701           0 :         : m_xPage (rhs.m_xPage)
     702           0 :     {}
     703             : 
     704           0 :     PageHolderObject<T> & operator= (PageHolderObject<T> const & rhs)
     705             :     {
     706           0 :         PageHolderObject<T> tmp (rhs);
     707           0 :         this->swap (tmp);
     708           0 :         return *this;
     709             :     }
     710             : 
     711           0 :     bool is() const
     712             :     {
     713           0 :         return (m_xPage.get() != 0);
     714             :     }
     715             : 
     716             : #if 1  /* EXP */
     717           0 :     PageHolder & get() { return m_xPage; }
     718             :     PageHolder const & get() const { return m_xPage; }
     719             : #endif /* EXP */
     720             : 
     721           0 :     T * operator->()
     722             :     {
     723           0 :         T * pImpl = dynamic_page_cast<T>(m_xPage.get());
     724             :         OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
     725           0 :         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           0 :     T & operator*()
     735             :     {
     736           0 :         T * pImpl = dynamic_page_cast<T>(m_xPage.get());
     737             :         OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::operator*(): Null pointer");
     738           0 :         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           0 :     static storeError guard (PageHolder & rxPage, sal_uInt32 nAddr)
     748             :     {
     749           0 :         PageData * pHead = rxPage.get();
     750           0 :         if (!pHead)
     751           0 :             return store_E_InvalidAccess;
     752           0 :         pHead->guard(nAddr);
     753             : 
     754           0 :         T * pImpl = dynamic_page_cast<T>(pHead);
     755             :         OSL_PRECOND(pImpl != 0, "store::PageHolder<T>::guard(): Null pointer");
     756           0 :         pImpl->guard();
     757             : 
     758           0 :         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             :  *
     780             :  * PageObject.
     781             :  *
     782             :  *======================================================================*/
     783             : #if 1  /* EXP */
     784             : class PageObject
     785             : {
     786             : public:
     787             :     explicit PageObject (PageHolder const & rxPage = PageHolder())
     788             :         : m_xPage (rxPage), m_bDirty (false)
     789             :     {}
     790             : 
     791             :     virtual ~PageObject()
     792             :     {}
     793             : 
     794             :     PageHolder & get() { return m_xPage; }
     795             :     PageHolder const & get() const { return m_xPage; }
     796             : 
     797             :     void clean() { m_bDirty = false; }
     798             :     void touch() { m_bDirty = true; }
     799             : 
     800             :     sal_uInt32 location() const
     801             :     {
     802             :         PageData const * pagedata = m_xPage.get();
     803             :         return (pagedata != 0) ? pagedata->location() : STORE_PAGE_NULL;
     804             :     }
     805             :     void location (sal_uInt32 nAddr)
     806             :     {
     807             :         PageData * pagedata = m_xPage.get();
     808             :         if (pagedata != 0)
     809             :             pagedata->location (nAddr);
     810             :     }
     811             : 
     812             : protected:
     813             :     PageHolder m_xPage;
     814             :     bool       m_bDirty;
     815             : 
     816             :     virtual storeError guard  (sal_uInt32 nAddr) = 0;
     817             :     virtual storeError verify (sal_uInt32 nAddr) const = 0;
     818             : };
     819             : #endif /* EXP */
     820             : 
     821             : class OStorePageBIOS;
     822             : 
     823             : class OStorePageObject
     824             : {
     825             :     typedef OStorePageData       page;
     826             : 
     827             : public:
     828             :     /** Allocation.
     829             :      */
     830             :     static void * operator new (size_t n) SAL_THROW(())
     831             :     {
     832             :         return rtl_allocateMemory (sal_uInt32(n));
     833             :     }
     834           0 :     static void operator delete (void * p) SAL_THROW(())
     835             :     {
     836           0 :         rtl_freeMemory (p);
     837           0 :     }
     838             : 
     839             :     /** State.
     840             :      */
     841             :     inline bool dirty (void) const;
     842             :     inline void clean (void);
     843             :     inline void touch (void);
     844             : 
     845             :     /** Location.
     846             :      */
     847             :     inline sal_uInt32 location (void) const;
     848             :     inline void       location (sal_uInt32 nAddr);
     849             : 
     850             : protected:
     851             :     /** Representation.
     852             :      */
     853             :     PageHolder m_xPage;
     854             :     bool       m_bDirty;
     855             : 
     856             :     /** Construction.
     857             :      */
     858           0 :     explicit OStorePageObject (PageHolder const & rxPage = PageHolder())
     859           0 :         : m_xPage (rxPage), m_bDirty (false)
     860           0 :     {}
     861             : 
     862             :     /** Destruction.
     863             :      */
     864             :     virtual ~OStorePageObject (void);
     865             : 
     866             : public:
     867             :     template< class U >
     868           0 :     PageHolderObject<U> makeHolder() const
     869             :     {
     870           0 :         return PageHolderObject<U>(m_xPage);
     871             :     }
     872             : 
     873             :     template< class U >
     874           0 :     storeError construct (rtl::Reference< PageData::Allocator > const & rxAllocator)
     875             :     {
     876           0 :         if (!rxAllocator.is())
     877           0 :             return store_E_InvalidAccess;
     878             : 
     879           0 :         PageHolder tmp (rxAllocator->construct<U>(), rxAllocator);
     880           0 :         if (!tmp.get())
     881           0 :             return store_E_OutOfMemory;
     882             : 
     883           0 :         m_xPage.swap (tmp);
     884           0 :         return store_E_None;
     885             :     }
     886             : 
     887           0 :     PageHolder & get() { return m_xPage; }
     888             :     PageHolder const & get() const { return m_xPage; }
     889             : 
     890             :     virtual storeError guard  (sal_uInt32 nAddr) = 0;
     891             :     virtual storeError verify (sal_uInt32 nAddr) const = 0;
     892             : };
     893             : 
     894           0 : inline bool OStorePageObject::dirty (void) const
     895             : {
     896           0 :     return m_bDirty;
     897             : }
     898             : 
     899           0 : inline void OStorePageObject::clean (void)
     900             : {
     901           0 :     m_bDirty = false;
     902           0 : }
     903             : 
     904           0 : inline void OStorePageObject::touch (void)
     905             : {
     906           0 :     m_bDirty = true;
     907           0 : }
     908             : 
     909           0 : inline sal_uInt32 OStorePageObject::location (void) const
     910             : {
     911           0 :     return m_xPage->location();
     912             : }
     913             : 
     914             : inline void OStorePageObject::location (sal_uInt32 nAddr)
     915             : {
     916             :     m_xPage->location(nAddr);
     917             :     touch();
     918             : }
     919             : 
     920             : /*========================================================================
     921             :  *
     922             :  * The End.
     923             :  *
     924             :  *======================================================================*/
     925             : 
     926             : } // namespace store
     927             : 
     928             : #endif /* !_STORE_STORBASE_HXX_ */
     929             : 
     930             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10