LCOV - code coverage report
Current view: top level - store/source - storpage.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 142 398 35.7 %
Date: 2012-08-25 Functions: 13 23 56.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 168 831 20.2 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       5                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       6                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : 
      21                 :            : #include "storpage.hxx"
      22                 :            : 
      23                 :            : #include "sal/types.h"
      24                 :            : #include "rtl/string.h"
      25                 :            : #include "rtl/ref.hxx"
      26                 :            : #include "osl/diagnose.h"
      27                 :            : #include "osl/mutex.hxx"
      28                 :            : 
      29                 :            : #include "store/types.h"
      30                 :            : 
      31                 :            : #include "object.hxx"
      32                 :            : #include "lockbyte.hxx"
      33                 :            : 
      34                 :            : #include "storbase.hxx"
      35                 :            : #include "stordata.hxx"
      36                 :            : #include "stortree.hxx"
      37                 :            : 
      38                 :            : using namespace store;
      39                 :            : 
      40                 :            : /*========================================================================
      41                 :            :  *
      42                 :            :  * OStorePageManager implementation.
      43                 :            :  *
      44                 :            :  *======================================================================*/
      45                 :            : const sal_uInt32 OStorePageManager::m_nTypeId = sal_uInt32(0x62190120);
      46                 :            : 
      47                 :            : /*
      48                 :            :  * OStorePageManager.
      49                 :            :  */
      50 [ +  - ][ +  - ]:      17794 : OStorePageManager::OStorePageManager (void)
         [ +  - ][ +  - ]
      51                 :            : {
      52                 :      17794 : }
      53                 :            : 
      54                 :            : /*
      55                 :            :  * ~OStorePageManager.
      56                 :            :  */
      57         [ +  - ]:      17043 : OStorePageManager::~OStorePageManager (void)
      58                 :            : {
      59         [ -  + ]:      34086 : }
      60                 :            : 
      61                 :            : /*
      62                 :            :  * isKindOf.
      63                 :            :  */
      64                 :    1921909 : sal_Bool SAL_CALL OStorePageManager::isKindOf (sal_uInt32 nTypeId)
      65                 :            : {
      66                 :    1921909 :     return (nTypeId == m_nTypeId);
      67                 :            : }
      68                 :            : 
      69                 :            : /*
      70                 :            :  * initialize (two-phase construction).
      71                 :            :  * Precond: none.
      72                 :            :  */
      73                 :      17794 : storeError OStorePageManager::initialize (
      74                 :            :     ILockBytes *    pLockBytes,
      75                 :            :     storeAccessMode eAccessMode,
      76                 :            :     sal_uInt16 &    rnPageSize)
      77                 :            : {
      78                 :            :     // Acquire exclusive access.
      79         [ +  - ]:      17794 :     osl::MutexGuard aGuard(*this);
      80                 :            : 
      81                 :            :     // Check arguments.
      82         [ -  + ]:      17794 :     if (!pLockBytes)
      83                 :          0 :         return store_E_InvalidParameter;
      84                 :            : 
      85                 :            :     // Initialize base.
      86         [ +  - ]:      17794 :     storeError eErrCode = base::initialize (pLockBytes, eAccessMode, rnPageSize);
      87         [ +  + ]:      17794 :     if (eErrCode != store_E_None)
      88                 :        403 :         return eErrCode;
      89                 :            : 
      90                 :            :     // Check for (not) writeable.
      91         [ +  + ]:      17391 :     if (!base::isWriteable())
      92                 :            :     {
      93                 :            :         // Readonly. Load RootNode.
      94         [ +  - ]:      11011 :         return base::loadObjectAt (m_aRoot, rnPageSize);
      95                 :            :     }
      96                 :            : 
      97                 :            :     // Writeable. Load or Create RootNode.
      98         [ +  - ]:       6380 :     eErrCode = m_aRoot.loadOrCreate (rnPageSize, *this);
      99         [ +  + ]:       6380 :     if (eErrCode == store_E_Pending)
     100                 :            :     {
     101                 :            :         // Creation notification.
     102         [ +  - ]:       6251 :         PageHolderObject< page > xRoot (m_aRoot.get());
     103                 :            : 
     104                 :            :         // Pre-allocate left most entry (ugly, but we can't insert to left).
     105                 :       6251 :         OStorePageKey aKey (rtl_crc32 (0, "/", 1), 0);
     106 [ +  - ][ +  - ]:       6251 :         xRoot->insert (0, entry(aKey));
     107                 :            : 
     108                 :            :         // Save RootNode.
     109 [ +  - ][ +  - ]:       6251 :         eErrCode = base::saveObjectAt (m_aRoot, rnPageSize);
     110                 :            :     }
     111                 :            : 
     112                 :            :     // Done.
     113         [ +  - ]:      17794 :     return eErrCode;
     114                 :            : }
     115                 :            : 
     116                 :            : /*
     117                 :            :  * find_lookup (w/o split()).
     118                 :            :  * Internal: Precond: initialized, readable, exclusive access.
     119                 :            :  */
     120                 :    1905203 : storeError OStorePageManager::find_lookup (
     121                 :            :     OStoreBTreeNodeObject & rNode,
     122                 :            :     sal_uInt16 &            rIndex,
     123                 :            :     OStorePageKey const &   rKey)
     124                 :            : {
     125                 :            :     // Find Node and Index.
     126         [ +  - ]:    1905203 :     storeError eErrCode = m_aRoot.find_lookup (rNode, rIndex, rKey, *this);
     127         [ -  + ]:    1905203 :     if (eErrCode != store_E_None)
     128                 :          0 :         return eErrCode;
     129                 :            : 
     130                 :            :     // Greater or Equal.
     131         [ +  - ]:    1905203 :     PageHolderObject< page > xPage (rNode.get());
     132                 :            :     OSL_POSTCOND(rIndex < xPage->usageCount(), "store::PageManager::find_lookup(): logic error");
     133         [ +  - ]:    1905203 :     entry e (xPage->m_pData[rIndex]);
     134                 :            : 
     135                 :            :     // Check for exact match.
     136         [ +  + ]:    1905203 :     if (e.compare(entry(rKey)) != entry::COMPARE_EQUAL)
     137                 :            :     {
     138                 :            :         // Page not present.
     139                 :     792805 :         return store_E_NotExists;
     140                 :            :     }
     141                 :            : 
     142                 :            :     // Check address.
     143         [ +  + ]:    1112398 :     if (e.m_aLink.location() == STORE_PAGE_NULL)
     144                 :            :     {
     145                 :            :         // Page not present.
     146                 :       6251 :         return store_E_NotExists;
     147                 :            :     }
     148                 :            : 
     149         [ +  - ]:    1905203 :     return store_E_None;
     150                 :            : }
     151                 :            : 
     152                 :            : /*
     153                 :            :  * remove_Impl (possibly down from root).
     154                 :            :  * Internal: Precond: initialized, writeable, exclusive access.
     155                 :            :  */
     156                 :            : 
     157                 :         18 : storeError OStorePageManager::remove_Impl (entry & rEntry)
     158                 :            : {
     159         [ +  - ]:         18 :     OStoreBTreeNodeObject aNode (m_aRoot.get());
     160                 :            : 
     161                 :            :     // Check current page index.
     162         [ +  - ]:         18 :     PageHolderObject< page > xPage (aNode.get());
     163 [ +  - ][ +  - ]:         18 :     sal_uInt16 i = xPage->find (rEntry), n = xPage->usageCount();
                 [ +  - ]
     164         [ -  + ]:         18 :     if (!(i < n))
     165                 :            :     {
     166                 :            :         // Path to entry not exists (Must not happen(?)).
     167                 :          0 :         return store_E_NotExists;
     168                 :            :     }
     169                 :            : 
     170                 :            :     // Compare entry.
     171         [ +  - ]:         18 :     entry::CompareResult result = rEntry.compare (xPage->m_pData[i]);
     172                 :            : 
     173                 :            :     // Iterate down until equal match.
     174 [ -  + ][ #  # ]:         18 :     while ((result == entry::COMPARE_GREATER) && (xPage->depth() > 0))
         [ #  # ][ -  + ]
     175                 :            :     {
     176                 :            :         // Check link address.
     177         [ #  # ]:          0 :         sal_uInt32 const nAddr = xPage->m_pData[i].m_aLink.location();
     178         [ #  # ]:          0 :         if (nAddr == STORE_PAGE_NULL)
     179                 :            :         {
     180                 :            :             // Path to entry not exists (Must not happen(?)).
     181                 :          0 :             return store_E_NotExists;
     182                 :            :         }
     183                 :            : 
     184                 :            :         // Load link page.
     185         [ #  # ]:          0 :         storeError eErrCode = loadObjectAt (aNode, nAddr);
     186         [ #  # ]:          0 :         if (eErrCode != store_E_None)
     187                 :          0 :             return eErrCode;
     188                 :            : 
     189         [ #  # ]:          0 :         PageHolderObject< page > xNext (aNode.get());
     190         [ #  # ]:          0 :         xNext.swap (xPage);
     191                 :            : 
     192                 :            :         // Check index.
     193 [ #  # ][ #  # ]:          0 :         i = xPage->find (rEntry), n = xPage->usageCount();
                 [ #  # ]
     194         [ #  # ]:          0 :         if (!(i < n))
     195                 :            :         {
     196                 :            :             // Path to entry not exists (Must not happen(?)).
     197                 :          0 :             return store_E_NotExists;
     198                 :            :         }
     199                 :            : 
     200                 :            :         // Compare entry.
     201 [ #  # ][ #  # ]:          0 :         result = rEntry.compare (xPage->m_pData[i]);
     202         [ #  # ]:          0 :     }
     203                 :            : 
     204                 :            :     OSL_POSTCOND(
     205                 :            :         result != entry::COMPARE_LESS,
     206                 :            :         "OStorePageManager::remove(): find failed");
     207                 :            : 
     208                 :            :     // Check entry comparison.
     209         [ -  + ]:         18 :     if (result == entry::COMPARE_LESS)
     210                 :            :     {
     211                 :            :         // Must not happen.
     212                 :          0 :         return store_E_Unknown;
     213                 :            :     }
     214                 :            : 
     215                 :            :     // Remove down from current page (recursive).
     216 [ +  - ][ +  - ]:         18 :     return aNode.remove (i, rEntry, *this);
                 [ +  - ]
     217                 :            : }
     218                 :            : 
     219                 :            : /*
     220                 :            :  * namei.
     221                 :            :  * Precond: none (static).
     222                 :            :  */
     223                 :    1905203 : storeError OStorePageManager::namei (
     224                 :            :     const rtl_String *pPath, const rtl_String *pName, OStorePageKey &rKey)
     225                 :            : {
     226                 :            :     // Check parameter.
     227 [ +  - ][ -  + ]:    1905203 :     if (!(pPath && pName))
     228                 :          0 :         return store_E_InvalidParameter;
     229                 :            : 
     230                 :            :     // Check name length.
     231         [ -  + ]:    1905203 :     if (!(pName->length < STORE_MAXIMUM_NAMESIZE))
     232                 :          0 :         return store_E_NameTooLong;
     233                 :            : 
     234                 :            :     // Transform pathname into key.
     235                 :    1905203 :     rKey.m_nLow  = store::htonl(rtl_crc32 (0, pName->buffer, pName->length));
     236                 :    1905203 :     rKey.m_nHigh = store::htonl(rtl_crc32 (0, pPath->buffer, pPath->length));
     237                 :            : 
     238                 :            :     // Done.
     239                 :    1905203 :     return store_E_None;
     240                 :            : }
     241                 :            : 
     242                 :            : /*
     243                 :            :  * iget.
     244                 :            :  * Precond: initialized.
     245                 :            :  */
     246                 :    1905185 : storeError OStorePageManager::iget (
     247                 :            :     OStoreDirectoryPageObject & rPage,
     248                 :            :     sal_uInt32                  nAttrib,
     249                 :            :     const rtl_String          * pPath,
     250                 :            :     const rtl_String          * pName,
     251                 :            :     storeAccessMode             eMode)
     252                 :            : {
     253                 :            :     // Acquire exclusive access.
     254         [ +  - ]:    1905185 :     osl::MutexGuard aGuard(*this);
     255                 :            : 
     256                 :            :     // Check precond.
     257 [ +  - ][ -  + ]:    1905185 :     if (!self::isValid())
     258                 :          0 :         return store_E_InvalidAccess;
     259                 :            : 
     260                 :            :     // Setup inode page key.
     261                 :    1905185 :     OStorePageKey aKey;
     262                 :    1905185 :     storeError eErrCode = namei (pPath, pName, aKey);
     263         [ -  + ]:    1905185 :     if (eErrCode != store_E_None)
     264                 :          0 :         return eErrCode;
     265                 :            : 
     266                 :            :     // Check for directory.
     267         [ +  + ]:    1905185 :     if (nAttrib & STORE_ATTRIB_ISDIR)
     268                 :            :     {
     269                 :            :         // Ugly, but necessary (backward compatibility).
     270                 :    1253445 :         aKey.m_nLow = store::htonl(rtl_crc32 (store::ntohl(aKey.m_nLow), "/", 1));
     271                 :            :     }
     272                 :            : 
     273                 :            :     // Load inode page.
     274         [ +  - ]:    1905185 :     eErrCode = load_dirpage_Impl (aKey, rPage);
     275         [ +  + ]:    1905185 :     if (eErrCode != store_E_None)
     276                 :            :     {
     277                 :            :         // Check mode and reason.
     278         [ -  + ]:     799056 :         if (eErrCode != store_E_NotExists)
     279                 :          0 :             return eErrCode;
     280                 :            : 
     281         [ +  + ]:     799056 :         if (eMode == store_AccessReadWrite)
     282                 :      12500 :             return store_E_NotExists;
     283         [ +  + ]:     786556 :         if (eMode == store_AccessReadOnly)
     284                 :     693718 :             return store_E_NotExists;
     285                 :            : 
     286         [ -  + ]:      92838 :         if (!base::isWriteable())
     287                 :          0 :             return store_E_AccessViolation;
     288                 :            : 
     289                 :            :         // Create inode page.
     290         [ +  - ]:      92838 :         eErrCode = rPage.construct< inode >(base::allocator());
     291         [ -  + ]:      92838 :         if (eErrCode != store_E_None)
     292                 :          0 :             return eErrCode;
     293                 :            : 
     294                 :            :         // Setup inode nameblock.
     295         [ +  - ]:      92838 :         PageHolderObject< inode > xPage (rPage.get());
     296                 :            : 
     297         [ +  - ]:      92838 :         rPage.key (aKey);
     298         [ +  - ]:      92838 :         rPage.attrib (nAttrib);
     299                 :            : 
     300                 :            :         memcpy (
     301         [ +  - ]:      92838 :             &(xPage->m_aNameBlock.m_pData[0]),
     302                 :     185676 :             pName->buffer, pName->length);
     303                 :            : 
     304                 :            :         // Save inode page.
     305         [ +  - ]:      92838 :         eErrCode = save_dirpage_Impl (aKey, rPage);
     306         [ -  + ]:      92838 :         if (eErrCode != store_E_None)
     307 [ +  - ][ +  - ]:     799056 :             return eErrCode;
     308                 :            :     }
     309                 :            : 
     310                 :            :     // Check for symbolic link.
     311 [ +  - ][ -  + ]:    1198967 :     if (rPage.attrib() & STORE_ATTRIB_ISLINK)
     312                 :            :     {
     313                 :            :         // Obtain 'Destination' page key.
     314         [ #  # ]:          0 :         PageHolderObject< inode > xPage (rPage.get());
     315                 :          0 :         OStorePageKey aDstKey;
     316         [ #  # ]:          0 :         memcpy (&aDstKey, &(xPage->m_pData[0]), sizeof(aDstKey));
     317                 :            : 
     318                 :            :         // Load 'Destination' inode.
     319         [ #  # ]:          0 :         eErrCode = load_dirpage_Impl (aDstKey, rPage);
     320         [ #  # ]:          0 :         if (eErrCode != store_E_None)
     321 [ #  # ][ #  # ]:          0 :             return eErrCode;
     322                 :            :     }
     323                 :            : 
     324                 :            :     // Done.
     325         [ +  - ]:    1905185 :     return store_E_None;
     326                 :            : }
     327                 :            : 
     328                 :            : /*
     329                 :            :  * iterate.
     330                 :            :  * Precond: initialized.
     331                 :            :  * ToDo: skip hardlink entries.
     332                 :            :  */
     333                 :     480957 : storeError OStorePageManager::iterate (
     334                 :            :     OStorePageKey &  rKey,
     335                 :            :     OStorePageLink & rLink,
     336                 :            :     sal_uInt32 &     rAttrib)
     337                 :            : {
     338                 :            :     // Acquire exclusive access.
     339         [ +  - ]:     480957 :     osl::MutexGuard aGuard(*this);
     340                 :            : 
     341                 :            :     // Check precond.
     342 [ +  - ][ -  + ]:     480957 :     if (!self::isValid())
     343                 :          0 :         return store_E_InvalidAccess;
     344                 :            : 
     345                 :            :     // Find NodePage and Index.
     346 [ +  - ][ +  - ]:     480957 :     OStoreBTreeNodeObject aNode;
         [ +  - ][ +  - ]
     347                 :     480957 :     sal_uInt16 i = 0;
     348         [ +  - ]:     480957 :     storeError eErrCode = m_aRoot.find_lookup (aNode, i, rKey, *this);
     349         [ -  + ]:     480957 :     if (eErrCode != store_E_None)
     350                 :          0 :         return eErrCode;
     351                 :            : 
     352                 :            :     // GreaterEqual. Found next entry.
     353         [ +  - ]:     480957 :     PageHolderObject< page > xNode (aNode.get());
     354         [ +  - ]:     480957 :     entry e (xNode->m_pData[i]);
     355                 :            : 
     356                 :            :     // Setup result.
     357                 :     480957 :     rKey    = e.m_aKey;
     358                 :     480957 :     rLink   = e.m_aLink;
     359                 :     480957 :     rAttrib = store::ntohl(e.m_nAttrib);
     360                 :            : 
     361                 :            :     // Done.
     362 [ +  - ][ +  - ]:     480957 :     return store_E_None;
                 [ +  - ]
     363                 :            : }
     364                 :            : 
     365                 :            : /*
     366                 :            :  * load => private: iget() @@@
     367                 :            :  * Internal: Precond: initialized, exclusive access.
     368                 :            :  */
     369                 :    1905185 : storeError OStorePageManager::load_dirpage_Impl (
     370                 :            :     const OStorePageKey       &rKey,
     371                 :            :     OStoreDirectoryPageObject &rPage)
     372                 :            : {
     373                 :            :     // Find Node and Index.
     374 [ +  - ][ +  - ]:    1905185 :     OStoreBTreeNodeObject aNode;
         [ +  - ][ +  - ]
     375                 :    1905185 :     sal_uInt16 i = 0;
     376         [ +  - ]:    1905185 :     storeError eErrCode = find_lookup (aNode, i, rKey);
     377         [ +  + ]:    1905185 :     if (eErrCode != store_E_None)
     378                 :     799056 :         return eErrCode;
     379                 :            : 
     380                 :            :     // Existing entry. Load page.
     381         [ +  - ]:    1106129 :     PageHolderObject< page > xNode (aNode.get());
     382         [ +  - ]:    1106129 :     entry e (xNode->m_pData[i]);
     383 [ +  - ][ +  - ]:    1905185 :     return loadObjectAt (rPage, e.m_aLink.location());
                 [ +  - ]
     384                 :            : }
     385                 :            : 
     386                 :            : /*
     387                 :            :  * save => private: iget(), rebuild() @@@
     388                 :            :  * Internal: Precond: initialized, writeable, exclusive access.
     389                 :            :  */
     390                 :      92838 : storeError OStorePageManager::save_dirpage_Impl (
     391                 :            :     const OStorePageKey       &rKey,
     392                 :            :     OStoreDirectoryPageObject &rPage)
     393                 :            : {
     394                 :            :     // Find NodePage and Index.
     395 [ +  - ][ +  - ]:      92838 :     node aNode;
         [ +  - ][ +  - ]
     396                 :      92838 :     sal_uInt16 i = 0;
     397                 :            : 
     398         [ +  - ]:      92838 :     storeError eErrCode = m_aRoot.find_insert (aNode, i, rKey, *this);
     399         [ +  - ]:      92838 :     PageHolderObject< page > xNode (aNode.get());
     400         [ +  + ]:      92838 :     if (eErrCode != store_E_None)
     401                 :            :     {
     402         [ -  + ]:       6251 :         if (eErrCode != store_E_AlreadyExists)
     403                 :          0 :             return eErrCode;
     404                 :            : 
     405                 :            :         // Existing entry.
     406         [ +  - ]:       6251 :         entry e (xNode->m_pData[i]);
     407         [ -  + ]:       6251 :         if (e.m_aLink.location() != STORE_PAGE_NULL)
     408                 :            :         {
     409                 :            :             // Save page to existing location.
     410         [ #  # ]:          0 :             return saveObjectAt (rPage, e.m_aLink.location());
     411                 :            :         }
     412                 :            : 
     413                 :            :         // Allocate page.
     414         [ +  - ]:       6251 :         eErrCode = base::allocate (rPage);
     415         [ -  + ]:       6251 :         if (eErrCode != store_E_None)
     416                 :          0 :             return eErrCode;
     417                 :            : 
     418                 :            :         // Update page location.
     419         [ +  - ]:       6251 :         xNode->m_pData[i].m_aLink = rPage.location();
     420                 :            : 
     421                 :            :         // Save modified NodePage.
     422         [ +  - ]:       6251 :         return saveObjectAt (aNode, aNode.location());
     423                 :            :     }
     424                 :            : 
     425                 :            :     // Allocate page.
     426         [ +  - ]:      86587 :     eErrCode = base::allocate (rPage);
     427         [ -  + ]:      86587 :     if (eErrCode != store_E_None)
     428                 :          0 :         return eErrCode;
     429                 :            : 
     430                 :            :     // Insert.
     431                 :      86587 :     OStorePageLink aLink (rPage.location());
     432 [ +  - ][ +  - ]:      86587 :     xNode->insert (i + 1, entry (rKey, aLink));
     433                 :            : 
     434                 :            :     // Save modified NodePage.
     435 [ +  - ][ +  - ]:      92838 :     return saveObjectAt (aNode, aNode.location());
                 [ +  - ]
     436                 :            : }
     437                 :            : 
     438                 :            : /*
     439                 :            :  * attrib [nAttrib = ((nAttrib & ~nMask1) | nMask2)].
     440                 :            :  * Precond: initialized.
     441                 :            :  */
     442                 :          0 : storeError OStorePageManager::attrib (
     443                 :            :     const OStorePageKey &rKey,
     444                 :            :     sal_uInt32           nMask1,
     445                 :            :     sal_uInt32           nMask2,
     446                 :            :     sal_uInt32          &rAttrib)
     447                 :            : {
     448                 :            :     // Acquire exclusive access.
     449         [ #  # ]:          0 :     osl::MutexGuard aGuard(*this);
     450                 :            : 
     451                 :            :     // Check precond.
     452 [ #  # ][ #  # ]:          0 :     if (!self::isValid())
     453                 :          0 :         return store_E_InvalidAccess;
     454                 :            : 
     455                 :            :     // Find NodePage and index.
     456 [ #  # ][ #  # ]:          0 :     OStoreBTreeNodeObject aNode;
         [ #  # ][ #  # ]
     457                 :          0 :     sal_uInt16 i = 0;
     458         [ #  # ]:          0 :     storeError eErrCode = find_lookup (aNode, i, rKey);
     459         [ #  # ]:          0 :     if (eErrCode != store_E_None)
     460                 :          0 :         return eErrCode;
     461                 :            : 
     462                 :            :     // Existing entry.
     463         [ #  # ]:          0 :     PageHolderObject< page > xNode (aNode.get());
     464         [ #  # ]:          0 :     entry e (xNode->m_pData[i]);
     465         [ #  # ]:          0 :     if (nMask1 != nMask2)
     466                 :            :     {
     467                 :            :         // Evaluate new attributes.
     468                 :          0 :         sal_uInt32 nAttrib = store::ntohl(e.m_nAttrib);
     469                 :            : 
     470                 :          0 :         nAttrib &= ~nMask1;
     471                 :          0 :         nAttrib |=  nMask2;
     472                 :            : 
     473         [ #  # ]:          0 :         if (store::htonl(nAttrib) != e.m_nAttrib)
     474                 :            :         {
     475                 :            :             // Check access mode.
     476         [ #  # ]:          0 :             if (base::isWriteable())
     477                 :            :             {
     478                 :            :                 // Set new attributes.
     479                 :          0 :                 e.m_nAttrib = store::htonl(nAttrib);
     480         [ #  # ]:          0 :                 xNode->m_pData[i] = e;
     481                 :            : 
     482                 :            :                 // Save modified NodePage.
     483         [ #  # ]:          0 :                 eErrCode = saveObjectAt (aNode, aNode.location());
     484                 :            :             }
     485                 :            :             else
     486                 :            :             {
     487                 :            :                 // Access denied.
     488                 :          0 :                 eErrCode = store_E_AccessViolation;
     489                 :            :             }
     490                 :            :         }
     491                 :            :     }
     492                 :            : 
     493                 :            :     // Obtain current attributes.
     494                 :          0 :     rAttrib = store::ntohl(e.m_nAttrib);
     495 [ #  # ][ #  # ]:          0 :     return eErrCode;
                 [ #  # ]
     496                 :            : }
     497                 :            : 
     498                 :            : /*
     499                 :            :  * link (insert 'Source' as hardlink to 'Destination').
     500                 :            :  * Precond: initialized, writeable.
     501                 :            :  */
     502                 :          0 : storeError OStorePageManager::link (
     503                 :            :     const OStorePageKey &rSrcKey,
     504                 :            :     const OStorePageKey &rDstKey)
     505                 :            : {
     506                 :            :     // Acquire exclusive access.
     507         [ #  # ]:          0 :     osl::MutexGuard aGuard(*this);
     508                 :            : 
     509                 :            :     // Check precond.
     510 [ #  # ][ #  # ]:          0 :     if (!self::isValid())
     511                 :          0 :         return store_E_InvalidAccess;
     512                 :            : 
     513         [ #  # ]:          0 :     if (!base::isWriteable())
     514                 :          0 :         return store_E_AccessViolation;
     515                 :            : 
     516                 :            :     // Find 'Destination' NodePage and Index.
     517 [ #  # ][ #  # ]:          0 :     OStoreBTreeNodeObject aDstNode;
         [ #  # ][ #  # ]
     518                 :          0 :     sal_uInt16 i = 0;
     519         [ #  # ]:          0 :     storeError eErrCode = find_lookup (aDstNode, i, rDstKey);
     520         [ #  # ]:          0 :     if (eErrCode != store_E_None)
     521                 :          0 :         return eErrCode;
     522                 :            : 
     523                 :            :     // Existing 'Destination' entry.
     524         [ #  # ]:          0 :     PageHolderObject< page > xDstNode (aDstNode.get());
     525         [ #  # ]:          0 :     entry e (xDstNode->m_pData[i]);
     526                 :          0 :     OStorePageLink aDstLink (e.m_aLink);
     527                 :            : 
     528                 :            :     // Find 'Source' NodePage and Index.
     529 [ #  # ][ #  # ]:          0 :     OStoreBTreeNodeObject aSrcNode;
         [ #  # ][ #  # ]
     530         [ #  # ]:          0 :     eErrCode = m_aRoot.find_insert (aSrcNode, i, rSrcKey, *this);
     531         [ #  # ]:          0 :     if (eErrCode != store_E_None)
     532                 :          0 :         return eErrCode;
     533                 :            : 
     534                 :            :     // Insert 'Source' entry.
     535         [ #  # ]:          0 :     PageHolderObject< page > xSrcNode (aSrcNode.get());
     536 [ #  # ][ #  # ]:          0 :     xSrcNode->insert (i + 1, entry (rSrcKey, aDstLink, STORE_ATTRIB_ISLINK));
     537 [ #  # ][ #  # ]:          0 :     return saveObjectAt (aSrcNode, aSrcNode.location());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     538                 :            : }
     539                 :            : 
     540                 :            : /*
     541                 :            :  * symlink (insert 'Source' DirectoryPage as symlink to 'Destination').
     542                 :            :  * Precond: initialized, writeable.
     543                 :            :  */
     544                 :          0 : storeError OStorePageManager::symlink (
     545                 :            :     const rtl_String    *pSrcPath,
     546                 :            :     const rtl_String    *pSrcName,
     547                 :            :     const OStorePageKey &rDstKey)
     548                 :            : {
     549                 :            :     // Acquire exclusive access.
     550         [ #  # ]:          0 :     osl::MutexGuard aGuard(*this);
     551                 :            : 
     552                 :            :     // Check precond.
     553 [ #  # ][ #  # ]:          0 :     if (!self::isValid())
     554                 :          0 :         return store_E_InvalidAccess;
     555                 :            : 
     556         [ #  # ]:          0 :     if (!base::isWriteable())
     557                 :          0 :         return store_E_AccessViolation;
     558                 :            : 
     559                 :            :     // Check 'Source' parameter.
     560                 :          0 :     storeError eErrCode = store_E_InvalidParameter;
     561 [ #  # ][ #  # ]:          0 :     if (!(pSrcPath && pSrcName))
     562                 :          0 :         return eErrCode;
     563                 :            : 
     564                 :            :     // Setup 'Source' page key.
     565                 :          0 :     OStorePageKey aSrcKey;
     566                 :          0 :     eErrCode = namei (pSrcPath, pSrcName, aSrcKey);
     567         [ #  # ]:          0 :     if (eErrCode != store_E_None)
     568                 :          0 :         return eErrCode;
     569                 :            : 
     570                 :            :     // Find 'Source' NodePage and Index.
     571 [ #  # ][ #  # ]:          0 :     OStoreBTreeNodeObject aSrcNode;
         [ #  # ][ #  # ]
     572                 :          0 :     sal_uInt16 i = 0;
     573         [ #  # ]:          0 :     eErrCode = m_aRoot.find_insert (aSrcNode, i, aSrcKey, *this);
     574         [ #  # ]:          0 :     if (eErrCode != store_E_None)
     575                 :          0 :         return eErrCode;
     576                 :            : 
     577                 :            :     // Initialize directory page.
     578 [ #  # ][ #  # ]:          0 :     OStoreDirectoryPageObject aPage;
         [ #  # ][ #  # ]
     579         [ #  # ]:          0 :     eErrCode = aPage.construct< inode >(base::allocator());
     580         [ #  # ]:          0 :     if (eErrCode != store_E_None)
     581                 :          0 :         return eErrCode;
     582                 :            : 
     583                 :            :     // Setup as 'Source' directory page.
     584         [ #  # ]:          0 :     inode_holder_type xNode (aPage.get());
     585         [ #  # ]:          0 :     aPage.key (aSrcKey);
     586                 :            :     memcpy (
     587         [ #  # ]:          0 :         &(xNode->m_aNameBlock.m_pData[0]),
     588                 :          0 :         pSrcName->buffer, pSrcName->length);
     589                 :            : 
     590                 :            :     // Store 'Destination' page key.
     591                 :          0 :     OStorePageKey aDstKey (rDstKey);
     592         [ #  # ]:          0 :     memcpy (&(xNode->m_pData[0]), &aDstKey, sizeof(aDstKey));
     593                 :            : 
     594                 :            :     // Mark 'Source' as symbolic link to 'Destination'.
     595         [ #  # ]:          0 :     aPage.attrib (STORE_ATTRIB_ISLINK);
     596         [ #  # ]:          0 :     aPage.dataLength (sal_uInt32(sizeof(aDstKey)));
     597                 :            : 
     598                 :            :     // Allocate and save 'Source' directory page.
     599         [ #  # ]:          0 :     eErrCode = base::allocate (aPage);
     600         [ #  # ]:          0 :     if (eErrCode != store_E_None)
     601                 :          0 :         return eErrCode;
     602                 :            : 
     603                 :            :     // Insert 'Source' entry.
     604         [ #  # ]:          0 :     PageHolderObject< page > xSrcNode (aSrcNode.get());
     605                 :          0 :     OStorePageLink aSrcLink (aPage.location());
     606 [ #  # ][ #  # ]:          0 :     xSrcNode->insert (i + 1, entry(aSrcKey, aSrcLink));
     607                 :            : 
     608                 :            :     // Save modified NodePage.
     609 [ #  # ][ #  # ]:          0 :     return saveObjectAt (aSrcNode, aSrcNode.location());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     610                 :            : }
     611                 :            : 
     612                 :            : /*
     613                 :            :  * rename.
     614                 :            :  * Precond: initialized, writeable.
     615                 :            :  */
     616                 :          0 : storeError OStorePageManager::rename (
     617                 :            :     const OStorePageKey &rSrcKey,
     618                 :            :     const rtl_String    *pDstPath,
     619                 :            :     const rtl_String    *pDstName)
     620                 :            : {
     621                 :            :     // Acquire exclusive access.
     622         [ #  # ]:          0 :     osl::MutexGuard aGuard(*this);
     623                 :            : 
     624                 :            :     // Check precond.
     625 [ #  # ][ #  # ]:          0 :     if (!self::isValid())
     626                 :          0 :         return store_E_InvalidAccess;
     627                 :            : 
     628         [ #  # ]:          0 :     if (!base::isWriteable())
     629                 :          0 :         return store_E_AccessViolation;
     630                 :            : 
     631                 :            :     // Check 'Destination' parameter.
     632                 :          0 :     storeError eErrCode = store_E_InvalidParameter;
     633 [ #  # ][ #  # ]:          0 :     if (!(pDstPath && pDstName))
     634                 :          0 :         return eErrCode;
     635                 :            : 
     636                 :            :     // Setup 'Destination' page key.
     637                 :          0 :     OStorePageKey aDstKey;
     638                 :          0 :     eErrCode = namei (pDstPath, pDstName, aDstKey);
     639         [ #  # ]:          0 :     if (eErrCode != store_E_None)
     640                 :          0 :         return eErrCode;
     641                 :            : 
     642                 :            :     // Find 'Source' NodePage and Index.
     643 [ #  # ][ #  # ]:          0 :     OStoreBTreeNodeObject aSrcNode;
         [ #  # ][ #  # ]
     644                 :          0 :     sal_uInt16 i = 0;
     645         [ #  # ]:          0 :     eErrCode = find_lookup (aSrcNode, i, rSrcKey);
     646         [ #  # ]:          0 :     if (eErrCode != store_E_None)
     647                 :          0 :         return eErrCode;
     648                 :            : 
     649                 :            :     // Existing 'Source' entry.
     650         [ #  # ]:          0 :     PageHolderObject< page > xSrcNode (aSrcNode.get());
     651         [ #  # ]:          0 :     entry e (xSrcNode->m_pData[i]);
     652                 :            : 
     653                 :            :     // Check for (not a) hardlink.
     654 [ #  # ][ #  # ]:          0 :     OStoreDirectoryPageObject aPage;
         [ #  # ][ #  # ]
     655         [ #  # ]:          0 :     if (!(store::ntohl(e.m_nAttrib) & STORE_ATTRIB_ISLINK))
     656                 :            :     {
     657                 :            :         // Load directory page.
     658         [ #  # ]:          0 :         eErrCode = base::loadObjectAt (aPage, e.m_aLink.location());
     659         [ #  # ]:          0 :         if (eErrCode != store_E_None)
     660                 :          0 :             return eErrCode;
     661                 :            : 
     662                 :            :         // Check for directory.
     663 [ #  # ][ #  # ]:          0 :         if (aPage.attrib() & STORE_ATTRIB_ISDIR)
     664                 :            :         {
     665                 :            :             // Ugly, but necessary (backward compatibility).
     666                 :          0 :             aDstKey.m_nLow = store::htonl(rtl_crc32 (store::ntohl(aDstKey.m_nLow), "/", 1));
     667                 :            :         }
     668                 :            :     }
     669                 :            : 
     670                 :            :     // Let 'Source' entry be 'Destination' entry.
     671                 :          0 :     e.m_aKey = aDstKey;
     672                 :            : 
     673                 :            :     // Find 'Destination' NodePage and Index.
     674 [ #  # ][ #  # ]:          0 :     OStoreBTreeNodeObject aDstNode;
         [ #  # ][ #  # ]
     675         [ #  # ]:          0 :     eErrCode = m_aRoot.find_insert (aDstNode, i, e.m_aKey, *this);
     676         [ #  # ]:          0 :     if (eErrCode != store_E_None)
     677                 :          0 :         return eErrCode;
     678                 :            : 
     679                 :            :     // Insert 'Destination' entry.
     680         [ #  # ]:          0 :     PageHolderObject< page > xDstNode (aDstNode.get());
     681 [ #  # ][ #  # ]:          0 :     xDstNode->insert (i + 1, e);
     682                 :            : 
     683         [ #  # ]:          0 :     eErrCode = saveObjectAt (aDstNode, aDstNode.location());
     684         [ #  # ]:          0 :     if (eErrCode != store_E_None)
     685                 :          0 :         return eErrCode;
     686                 :            : 
     687                 :            :     // Check for (not a) hardlink.
     688         [ #  # ]:          0 :     if (!(store::ntohl(e.m_nAttrib) & STORE_ATTRIB_ISLINK))
     689                 :            :     {
     690                 :            :         // Modify 'Source' directory page.
     691         [ #  # ]:          0 :         inode_holder_type xNode (aPage.get());
     692                 :            : 
     693                 :            :         // Setup 'Destination' NameBlock.
     694                 :          0 :         sal_Int32 nDstLen = pDstName->length;
     695                 :            :         memcpy (
     696         [ #  # ]:          0 :             &(xNode->m_aNameBlock.m_pData[0]),
     697                 :          0 :             pDstName->buffer, pDstName->length);
     698                 :            :         memset (
     699         [ #  # ]:          0 :             &(xNode->m_aNameBlock.m_pData[nDstLen]),
     700                 :          0 :             0, STORE_MAXIMUM_NAMESIZE - nDstLen);
     701         [ #  # ]:          0 :         aPage.key (e.m_aKey);
     702                 :            : 
     703                 :            :         // Save directory page.
     704         [ #  # ]:          0 :         eErrCode = base::saveObjectAt (aPage, e.m_aLink.location());
     705         [ #  # ]:          0 :         if (eErrCode != store_E_None)
     706 [ #  # ][ #  # ]:          0 :             return eErrCode;
     707                 :            :     }
     708                 :            : 
     709                 :            :     // Remove 'Source' entry.
     710                 :          0 :     e.m_aKey = rSrcKey;
     711 [ #  # ][ #  # ]:          0 :     return remove_Impl (e);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     712                 :            : }
     713                 :            : 
     714                 :            : /*
     715                 :            :  * remove.
     716                 :            :  * Precond: initialized, writeable.
     717                 :            :  */
     718                 :         18 : storeError OStorePageManager::remove (const OStorePageKey &rKey)
     719                 :            : {
     720                 :            :     // Acquire exclusive access.
     721         [ +  - ]:         18 :     osl::MutexGuard aGuard(*this);
     722                 :            : 
     723                 :            :     // Check precond.
     724 [ +  - ][ -  + ]:         18 :     if (!self::isValid())
     725                 :          0 :         return store_E_InvalidAccess;
     726                 :            : 
     727         [ -  + ]:         18 :     if (!base::isWriteable())
     728                 :          0 :         return store_E_AccessViolation;
     729                 :            : 
     730                 :            :     // Find NodePage and index.
     731 [ +  - ][ +  - ]:         18 :     OStoreBTreeNodeObject aNodePage;
         [ +  - ][ +  - ]
     732                 :         18 :     sal_uInt16 i = 0;
     733         [ +  - ]:         18 :     storeError eErrCode = find_lookup (aNodePage, i, rKey);
     734         [ -  + ]:         18 :     if (eErrCode != store_E_None)
     735                 :          0 :         return eErrCode;
     736                 :            : 
     737                 :            :     // Existing entry.
     738         [ +  - ]:         18 :     PageHolderObject< page > xNodePage (aNodePage.get());
     739         [ +  - ]:         18 :     entry e (xNodePage->m_pData[i]);
     740                 :            : 
     741                 :            :     // Check for (not a) hardlink.
     742         [ +  - ]:         18 :     if (!(store::ntohl(e.m_nAttrib) & STORE_ATTRIB_ISLINK))
     743                 :            :     {
     744                 :            :         // Load directory page.
     745 [ +  - ][ +  - ]:         18 :         OStoreDirectoryPageObject aPage;
         [ +  - ][ +  - ]
     746         [ +  - ]:         18 :         eErrCode = base::loadObjectAt (aPage, e.m_aLink.location());
     747         [ -  + ]:         18 :         if (eErrCode != store_E_None)
     748                 :          0 :             return eErrCode;
     749                 :            : 
     750         [ +  - ]:         18 :         inode_holder_type xNode (aPage.get());
     751                 :            : 
     752                 :            :         // Acquire page write access.
     753         [ +  - ]:         18 :         OStorePageDescriptor aDescr (xNode->m_aDescr);
     754         [ +  - ]:         18 :         eErrCode = base::acquirePage (aDescr, store_AccessReadWrite);
     755         [ -  + ]:         18 :         if (eErrCode != store_E_None)
     756                 :          0 :             return eErrCode;
     757                 :            : 
     758                 :            :         // Check for symbolic link.
     759 [ +  - ][ +  - ]:         18 :         if (!(aPage.attrib() & STORE_ATTRIB_ISLINK))
     760                 :            :         {
     761                 :            :             // Ordinary inode. Determine 'Data' scope.
     762 [ +  - ][ +  - ]:         18 :             inode::ChunkScope eScope = xNode->scope (aPage.dataLength());
     763         [ +  + ]:         18 :             if (eScope == inode::SCOPE_EXTERNAL)
     764                 :            :             {
     765                 :            :                 // External 'Data' scope. Truncate all external data pages.
     766         [ +  - ]:          2 :                 eErrCode = aPage.truncate (0, *this);
     767         [ -  + ]:          2 :                 if (eErrCode != store_E_None)
     768                 :          0 :                     return eErrCode;
     769                 :            :             }
     770                 :            : 
     771                 :            :             // Truncate internal data page.
     772 [ +  - ][ +  - ]:         18 :             memset (&(xNode->m_pData[0]), 0, xNode->capacity());
     773         [ +  - ]:         18 :             aPage.dataLength (0);
     774                 :            :         }
     775                 :            : 
     776                 :            :         // Release page write access.
     777         [ +  - ]:         18 :         eErrCode = base::releasePage (aDescr);
     778                 :            : 
     779                 :            :         // Release and free directory page.
     780 [ +  - ][ +  - ]:         18 :         eErrCode = base::free (aPage.location());
         [ -  + ][ +  - ]
                 [ +  - ]
     781                 :            :     }
     782                 :            : 
     783                 :            :     // Remove entry.
     784 [ +  - ][ +  - ]:         18 :     return remove_Impl (e);
         [ +  - ][ +  - ]
     785                 :            : }
     786                 :            : 
     787                 :            : /*
     788                 :            :  * RebuildContext.
     789                 :            :  */
     790                 :          0 : struct RebuildContext
     791                 :            : {
     792                 :            :     /** Representation.
     793                 :            :     */
     794                 :            :     rtl::Reference<OStorePageBIOS> m_xBIOS;
     795                 :            :     OStorePageBIOS::ScanContext    m_aCtx;
     796                 :            :     sal_uInt16                     m_nPageSize;
     797                 :            : 
     798                 :            :     /** Construction.
     799                 :            :      */
     800                 :          0 :     RebuildContext (void)
     801                 :          0 :         : m_xBIOS     (new OStorePageBIOS()),
     802         [ #  # ]:          0 :           m_nPageSize (0)
     803                 :          0 :     {}
     804                 :            : 
     805                 :            :     /** initialize (PageBIOS and ScanContext).
     806                 :            :     */
     807                 :          0 :     storeError initialize (ILockBytes *pLockBytes, sal_uInt32 nMagic = 0)
     808                 :            :     {
     809                 :          0 :         storeError eErrCode = store_E_InvalidParameter;
     810         [ #  # ]:          0 :         if (pLockBytes)
     811                 :            :         {
     812                 :          0 :             m_xBIOS->initialize (pLockBytes, store_AccessReadOnly, m_nPageSize);
     813                 :          0 :             eErrCode = m_xBIOS->scanBegin (m_aCtx, nMagic);
     814                 :            :         }
     815                 :          0 :         return eErrCode;
     816                 :            :     }
     817                 :            : 
     818                 :            :     /** initialize (ScanContext).
     819                 :            :     */
     820                 :          0 :     storeError initialize (sal_uInt32 nMagic = 0)
     821                 :            :     {
     822                 :          0 :         return m_xBIOS->scanBegin (m_aCtx, nMagic);
     823                 :            :     }
     824                 :            : 
     825                 :            :     /** load (next ScanContext matching page).
     826                 :            :     */
     827                 :          0 :     storeError load (OStorePageObject &rPage)
     828                 :            :     {
     829         [ #  # ]:          0 :         if (m_aCtx.isValid())
     830                 :          0 :             return m_xBIOS->scanNext (m_aCtx, rPage);
     831                 :            :         else
     832                 :          0 :             return store_E_CantSeek;
     833                 :            :     }
     834                 :            : };
     835                 :            : 
     836                 :            : /*
     837                 :            :  * rebuild.
     838                 :            :  * Precond: none.
     839                 :            :  */
     840                 :          0 : storeError OStorePageManager::rebuild (
     841                 :            :     ILockBytes *pSrcLB, ILockBytes *pDstLB)
     842                 :            : {
     843                 :            :     // Acquire exclusive access.
     844         [ #  # ]:          0 :     osl::MutexGuard aGuard(*this);
     845                 :            : 
     846                 :            :     // Check arguments.
     847                 :          0 :     storeError eErrCode = store_E_InvalidParameter;
     848 [ #  # ][ #  # ]:          0 :     if (!(pSrcLB && pDstLB))
     849                 :          0 :         return eErrCode;
     850                 :            : 
     851                 :            :     // Initialize 'Source' rebuild context.
     852         [ #  # ]:          0 :     RebuildContext aCtx;
     853         [ #  # ]:          0 :     eErrCode = aCtx.initialize (pSrcLB, STORE_MAGIC_DIRECTORYPAGE);
     854         [ #  # ]:          0 :     if (eErrCode != store_E_None)
     855                 :          0 :         return eErrCode;
     856         [ #  # ]:          0 :     rtl::Reference<OStorePageBIOS> xSrcBIOS (aCtx.m_xBIOS);
     857                 :            : 
     858                 :            :     // Initialize as 'Destination' with 'Source' page size.
     859         [ #  # ]:          0 :     eErrCode = self::initialize (pDstLB, store_AccessCreate, aCtx.m_nPageSize);
     860         [ #  # ]:          0 :     if (eErrCode != store_E_None)
     861                 :          0 :         return eErrCode;
     862                 :            : 
     863                 :            :     // Pass One: Scan 'Source' directory pages.
     864                 :            :     {
     865                 :            :         // Scan 'Source' directory pages.
     866 [ #  # ][ #  # ]:          0 :         OStoreDirectoryPageObject aSrcPage;
         [ #  # ][ #  # ]
     867 [ #  # ][ #  # ]:          0 :         while ((eErrCode = aCtx.load(aSrcPage)) == store_E_None)
     868                 :            :         {
     869 [ #  # ][ #  # ]:          0 :             OStoreDirectoryPageObject aDstPage;
         [ #  # ][ #  # ]
     870         [ #  # ]:          0 :             eErrCode = aDstPage.construct< inode >(base::allocator());
     871         [ #  # ]:          0 :             if (eErrCode != store_E_None)
     872                 :            :                 break;
     873                 :            : 
     874         [ #  # ]:          0 :             inode_holder_type xSrcDir (aSrcPage.get());
     875         [ #  # ]:          0 :             inode_holder_type xDstDir (aDstPage.get());
     876                 :            : 
     877                 :            :             // Copy NameBlock @@@ OLD @@@
     878 [ #  # ][ #  # ]:          0 :             memcpy (&(xDstDir->m_aNameBlock), &(xSrcDir->m_aNameBlock), sizeof(xSrcDir->m_aNameBlock));
     879                 :            : 
     880                 :            :             // Obtain 'Source' data length.
     881         [ #  # ]:          0 :             sal_uInt32 nDataLen = aSrcPage.dataLength();
     882         [ #  # ]:          0 :             if (nDataLen > 0)
     883                 :            :             {
     884                 :            :                 // Copy internal data area @@@ OLD @@@
     885 [ #  # ][ #  # ]:          0 :                 memcpy (&(xDstDir->m_pData[0]), &(xSrcDir->m_pData[0]), xSrcDir->capacity());
                 [ #  # ]
     886                 :            :             }
     887                 :            : 
     888                 :            :             // Insert 'Destination' directory page.
     889 [ #  # ][ #  # ]:          0 :             eErrCode = save_dirpage_Impl (aDstPage.key(), aDstPage);
     890         [ #  # ]:          0 :             if (eErrCode != store_E_None)
     891                 :            :                 break;
     892                 :            : 
     893                 :            :             // Check for external data page scope.
     894 [ #  # ][ #  # ]:          0 :             if (xSrcDir->scope(nDataLen) != inode::SCOPE_INTERNAL)
     895                 :            :             {
     896                 :            :                 // Initialize 'Destination' data page.
     897                 :            :                 typedef OStoreDataPageData data;
     898 [ #  # ][ #  # ]:          0 :                 PageHolderObject< data > xData;
         [ #  # ][ #  # ]
     899 [ #  # ][ #  # ]:          0 :                 if (!xData.construct(base::allocator()))
     900                 :          0 :                     return store_E_OutOfMemory;
     901                 :            : 
     902                 :            :                 // Determine data page count.
     903                 :            :                 inode::ChunkDescriptor aDescr (
     904 [ #  # ][ #  # ]:          0 :                     nDataLen - xDstDir->capacity(), xData->capacity());
     905                 :            : 
     906                 :          0 :                 sal_uInt32 i, n = aDescr.m_nPage;
     907         [ #  # ]:          0 :                 if (aDescr.m_nOffset) n += 1;
     908                 :            : 
     909                 :            :                 // Copy data pages.
     910 [ #  # ][ #  # ]:          0 :                 OStoreDataPageObject aData;
         [ #  # ][ #  # ]
     911         [ #  # ]:          0 :                 for (i = 0; i < n; i++)
     912                 :            :                 {
     913                 :            :                     // Read 'Source' data page.
     914         [ #  # ]:          0 :                     osl::MutexGuard aSrcGuard (*xSrcBIOS);
     915                 :            : 
     916         [ #  # ]:          0 :                     eErrCode = aSrcPage.read (i, aData, *xSrcBIOS);
     917         [ #  # ]:          0 :                     if (eErrCode != store_E_None)
     918                 :          0 :                         continue;
     919                 :            : 
     920                 :            :                     // Write 'Destination' data page. @@@ READONLY @@@
     921 [ #  # ][ #  # ]:          0 :                     eErrCode = aDstPage.write (i, aData, *this);
     922 [ #  # ][ #  # ]:          0 :                 }
         [ #  # ][ #  # ]
     923                 :            :             }
     924                 :            : 
     925                 :            :             // Update 'Destination' directory page.
     926         [ #  # ]:          0 :             aDstPage.dataLength (nDataLen);
     927         [ #  # ]:          0 :             eErrCode = base::saveObjectAt (aDstPage, aDstPage.location());
              [ #  #  # ]
     928 [ #  # ][ #  # ]:          0 :         }
              [ #  #  # ]
                 [ #  # ]
              [ #  #  # ]
     929                 :            : 
     930                 :            :         // Save directory scan results.
     931 [ #  # ][ #  # ]:          0 :         flush();
                 [ #  # ]
     932                 :            :     }
     933                 :            : 
     934                 :            :     // Pass Two: Scan 'Source' BTree nodes.
     935                 :            :     {
     936                 :            :         // Re-start 'Source' rebuild context.
     937         [ #  # ]:          0 :         aCtx.initialize (STORE_MAGIC_BTREENODE);
     938                 :            : 
     939                 :            :         // Scan 'Source' BTree nodes.
     940 [ #  # ][ #  # ]:          0 :         OStoreBTreeNodeObject aNode;
         [ #  # ][ #  # ]
     941 [ #  # ][ #  # ]:          0 :         while ((eErrCode = aCtx.load(aNode)) == store_E_None)
     942                 :            :         {
     943                 :            :             // Check for leaf node.
     944         [ #  # ]:          0 :             PageHolderObject< page > xNode (aNode.get());
     945 [ #  # ][ #  # ]:          0 :             if (xNode->depth() == 0)
     946                 :            :             {
     947         [ #  # ]:          0 :                 sal_uInt16 i, n = xNode->usageCount();
     948         [ #  # ]:          0 :                 for (i = 0; i < n; i++)
     949                 :            :                 {
     950         [ #  # ]:          0 :                     entry e (xNode->m_pData[i]);
     951                 :            : 
     952                 :            :                     // Check for Hard link.
     953         [ #  # ]:          0 :                     if (e.m_nAttrib & STORE_ATTRIB_ISLINK)
     954                 :            :                     {
     955                 :            :                         // Load the hard link destination.
     956 [ #  # ][ #  # ]:          0 :                         OStoreDirectoryPageObject aSrcPage;
         [ #  # ][ #  # ]
     957         [ #  # ]:          0 :                         eErrCode = xSrcBIOS->loadObjectAt (aSrcPage, e.m_aLink.location());
     958         [ #  # ]:          0 :                         if (eErrCode == store_E_None)
     959                 :            :                         {
     960         [ #  # ]:          0 :                             OStorePageKey aDstKey (aSrcPage.key());
     961         [ #  # ]:          0 :                             eErrCode = link (e.m_aKey, aDstKey);
     962                 :            :                         }
     963         [ #  # ]:          0 :                         e.m_nAttrib &= ~STORE_ATTRIB_ISLINK;
     964                 :            :                     }
     965                 :            : 
     966         [ #  # ]:          0 :                     if (e.m_nAttrib)
     967                 :            :                     {
     968                 :            :                         // Ordinary attributes.
     969                 :          0 :                         sal_uInt32 nAttrib = 0;
     970         [ #  # ]:          0 :                         eErrCode = attrib (e.m_aKey, 0, e.m_nAttrib, nAttrib);
     971                 :            :                     }
     972                 :            :                 }
     973                 :            :             }
     974         [ #  # ]:          0 :         }
     975                 :            : 
     976                 :            :         // Save BTree node scan results.
     977 [ #  # ][ #  # ]:          0 :         flush();
     978                 :            :     }
     979                 :            : 
     980                 :            :     // Done.
     981 [ #  # ][ #  # ]:          0 :     return store_E_None;
                 [ #  # ]
     982                 :            : }
     983                 :            : 
     984                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10