LCOV - code coverage report
Current view: top level - registry/source - keyimpl.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 204 518 39.4 %
Date: 2014-11-03 Functions: 17 23 73.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <string.h>
      22             : 
      23             : #include "keyimpl.hxx"
      24             : 
      25             : #include "reflcnst.hxx"
      26             : #include "rtl/alloc.h"
      27             : #include "rtl/ustrbuf.hxx"
      28             : 
      29             : using namespace store;
      30             : 
      31             : namespace { static char const VALUE_PREFIX[] = "$VL_"; }
      32             : 
      33             : 
      34             : //  ORegKey()
      35             : 
      36        1164 : ORegKey::ORegKey(const OUString& keyName, ORegistry* pReg)
      37             :     : m_refCount(1)
      38             :     , m_name(keyName)
      39             :     , m_bDeleted(false)
      40             :     , m_bModified(false)
      41        1164 :     , m_pRegistry(pReg)
      42             : {
      43        1164 : }
      44             : 
      45             : 
      46             : //  ~ORegKey()
      47             : 
      48        1150 : ORegKey::~ORegKey()
      49             : {
      50             :     SAL_WARN_IF(m_refCount != 0, "registry", "registry::ORegKey::dtor(): refcount not zero.");
      51        1150 : }
      52             : 
      53             : 
      54             : //  releaseKey
      55             : 
      56          14 : RegError ORegKey::releaseKey(RegKeyHandle hKey)
      57             : {
      58          14 :     return m_pRegistry->releaseKey(hKey);
      59             : }
      60             : 
      61             : 
      62             : //  createKey
      63             : 
      64         816 : RegError ORegKey::createKey(const OUString& keyName, RegKeyHandle* phNewKey)
      65             : {
      66         816 :     return m_pRegistry->createKey(this, keyName, phNewKey);
      67             : }
      68             : 
      69             : 
      70             : 
      71             : //  openKey
      72             : 
      73          82 : RegError ORegKey::openKey(const OUString& keyName, RegKeyHandle* phOpenKey)
      74             : {
      75          82 :     return m_pRegistry->openKey(this, keyName, phOpenKey);
      76             : }
      77             : 
      78             : 
      79             : 
      80             : //  openSubKeys
      81             : 
      82          14 : RegError ORegKey::openSubKeys(const OUString& keyName, RegKeyHandle** phOpenSubKeys, sal_uInt32* pnSubKeys)
      83             : {
      84          14 :     RegError _ret = REG_NO_ERROR;
      85             : 
      86          14 :     *phOpenSubKeys = 0;
      87          14 :     *pnSubKeys = 0;
      88             : 
      89          14 :     ORegKey* pKey = this;
      90          14 :     if ( !keyName.isEmpty() )
      91             :     {
      92           0 :         _ret = openKey(keyName, (RegKeyHandle*)&pKey);
      93           0 :         if (_ret != REG_NO_ERROR)
      94           0 :             return _ret;
      95             :     }
      96             : 
      97          14 :     sal_uInt32 nSubKeys = pKey->countSubKeys();
      98          14 :     *pnSubKeys = nSubKeys;
      99             : 
     100             :     ORegKey** pSubKeys;
     101          14 :     pSubKeys = (ORegKey**)rtl_allocateZeroMemory(nSubKeys * sizeof(ORegKey*));
     102             : 
     103             :     OStoreDirectory::iterator   iter;
     104          14 :     OStoreDirectory             rStoreDir(pKey->getStoreDir());
     105          14 :     storeError                  _err = rStoreDir.first(iter);
     106             : 
     107          14 :     nSubKeys = 0;
     108          44 :     while ( _err == store_E_None )
     109             :     {
     110          16 :         if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
     111             :         {
     112          16 :             OUString const sSubKeyName = iter.m_pszName;
     113             : 
     114          16 :             ORegKey* pOpenSubKey = 0;
     115          16 :             _ret = pKey->openKey(sSubKeyName, (RegKeyHandle*)&pOpenSubKey);
     116          16 :             if (_ret != REG_NO_ERROR)
     117             :             {
     118           0 :                 *phOpenSubKeys = NULL;
     119           0 :                 *pnSubKeys = 0;
     120           0 :                 rtl_freeMemory(pSubKeys); // @@@ leaking 'pSubKeys[0...nSubkeys-1]'
     121           0 :                 return _ret;              // @@@ leaking 'pKey'
     122             :             }
     123             : 
     124          16 :             pSubKeys[nSubKeys] = pOpenSubKey;
     125             : 
     126          16 :             nSubKeys++;
     127             :         }
     128             : 
     129          16 :         _err = rStoreDir.next(iter);
     130             :     }
     131             : 
     132          14 :     *phOpenSubKeys = (RegKeyHandle*)pSubKeys;
     133          14 :     if (!keyName.isEmpty())
     134             :     {
     135           0 :         (void) releaseKey(pKey);
     136             :     }
     137          14 :     return REG_NO_ERROR;
     138             : }
     139             : 
     140             : 
     141             : 
     142             : //  getKeyNames
     143             : 
     144          16 : RegError ORegKey::getKeyNames(const OUString& keyName,
     145             :                               rtl_uString*** pSubKeyNames,
     146             :                               sal_uInt32* pnSubKeys)
     147             : {
     148          16 :     RegError _ret = REG_NO_ERROR;
     149             : 
     150          16 :     *pSubKeyNames = 0;
     151          16 :     *pnSubKeys = 0;
     152             : 
     153          16 :     ORegKey* pKey = this;
     154          16 :     if (!keyName.isEmpty())
     155             :     {
     156           0 :         _ret = openKey(keyName, (RegKeyHandle*)&pKey);
     157           0 :         if (_ret != REG_NO_ERROR)
     158           0 :             return _ret;
     159             :     }
     160             : 
     161          16 :     sal_uInt32 nSubKeys = pKey->countSubKeys();
     162          16 :     *pnSubKeys = nSubKeys;
     163             : 
     164          16 :     rtl_uString** pSubKeys = 0;
     165          16 :     pSubKeys = (rtl_uString**)rtl_allocateZeroMemory(nSubKeys * sizeof(rtl_uString*));
     166             : 
     167             :     OStoreDirectory::iterator   iter;
     168          16 :     OStoreDirectory             rStoreDir(pKey->getStoreDir());
     169          16 :     storeError                  _err = rStoreDir.first(iter);
     170             : 
     171          16 :     nSubKeys = 0;
     172             : 
     173          50 :     while ( _err == store_E_None )
     174             :     {
     175          18 :         if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR)
     176             :         {
     177          14 :             OUString const sSubKeyName = iter.m_pszName;
     178             : 
     179          28 :             OUString sFullKeyName(pKey->getName());
     180          14 :             if (sFullKeyName.getLength() > 1)
     181          12 :                 sFullKeyName += m_pRegistry->ROOT;
     182          14 :             sFullKeyName += sSubKeyName;
     183             : 
     184          14 :             rtl_uString_newFromString(&pSubKeys[nSubKeys], sFullKeyName.pData);
     185             : 
     186          28 :             nSubKeys++;
     187             :         }
     188             : 
     189          18 :         _err = rStoreDir.next(iter);
     190             :     }
     191             : 
     192          16 :     *pSubKeyNames = pSubKeys;
     193          16 :     if (!keyName.isEmpty())
     194             :     {
     195           0 :         releaseKey(pKey);
     196             :     }
     197          16 :     return REG_NO_ERROR;
     198             : }
     199             : 
     200             : 
     201             : 
     202             : //  closeKey
     203             : 
     204          54 : RegError ORegKey::closeKey(RegKeyHandle hKey)
     205             : {
     206          54 :     return (m_pRegistry->closeKey(hKey));
     207             : }
     208             : 
     209             : 
     210             : 
     211             : //  deleteKey
     212             : 
     213           4 : RegError ORegKey::deleteKey(const OUString& keyName)
     214             : {
     215           4 :     return (m_pRegistry->deleteKey(this, keyName));
     216             : }
     217             : 
     218             : 
     219             : 
     220             : //  getValueType
     221             : 
     222          28 : RegError ORegKey::getValueInfo(const OUString& valueName, RegValueType* pValueType, sal_uInt32* pValueSize) const
     223             : {
     224          28 :     OStoreStream    rValue;
     225             :     sal_uInt8*      pBuffer;
     226          28 :     storeAccessMode accessMode = VALUE_MODE_OPEN;
     227             : 
     228          28 :     if (m_pRegistry->isReadOnly())
     229             :     {
     230           0 :         accessMode = VALUE_MODE_OPENREAD;
     231             :     }
     232             : 
     233          56 :     OUString sImplValueName( VALUE_PREFIX );
     234          28 :     sImplValueName += valueName;
     235             : 
     236          56 :     REG_GUARD(m_pRegistry->m_mutex);
     237             : 
     238          28 :     if ( rValue.create(m_pRegistry->getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) )
     239             :     {
     240          16 :         *pValueType = RG_VALUETYPE_NOT_DEFINED;
     241          16 :         *pValueSize = 0;
     242          16 :         return REG_VALUE_NOT_EXISTS;
     243             :     }
     244             : 
     245          12 :     pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE);
     246             : 
     247             :     sal_uInt32  readBytes;
     248          12 :     if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) )
     249             :     {
     250           0 :         rtl_freeMemory(pBuffer);
     251           0 :         return REG_INVALID_VALUE;
     252             :     }
     253          12 :     if (readBytes != VALUE_HEADERSIZE)
     254             :     {
     255           0 :         rtl_freeMemory(pBuffer);
     256           0 :         return REG_INVALID_VALUE;
     257             :     }
     258             : 
     259             :     sal_uInt32  size;
     260          12 :     sal_uInt8   type = *((sal_uInt8*)pBuffer);
     261          12 :     readUINT32(pBuffer+VALUE_TYPEOFFSET, size);
     262             : 
     263          12 :     *pValueType = (RegValueType)type;
     264             : //    if (*pValueType == RG_VALUETYPE_UNICODE)
     265             : //    {
     266             : //        *pValueSize = (size / 2) * sizeof(sal_Unicode);
     267             : //    } else
     268             : //    {
     269          12 :         if (*pValueType > 4)
     270             :         {
     271           0 :             rtl_freeMemory(pBuffer);
     272           0 :             pBuffer = (sal_uInt8*)rtl_allocateMemory(4);
     273           0 :             rValue.readAt(VALUE_HEADEROFFSET, pBuffer, 4, readBytes);
     274             : 
     275           0 :             readUINT32(pBuffer, size);
     276             :         }
     277             : 
     278          12 :         *pValueSize = size;
     279             : //    }
     280             : 
     281          12 :     rtl_freeMemory(pBuffer);
     282          40 :     return REG_NO_ERROR;
     283             : }
     284             : 
     285             : 
     286             : 
     287             : //  setValue
     288             : 
     289         794 : RegError ORegKey::setValue(const OUString& valueName, RegValueType vType, RegValue value, sal_uInt32 vSize)
     290             : {
     291         794 :     OStoreStream    rValue;
     292             :     sal_uInt8*      pBuffer;
     293             : 
     294         794 :     if (m_pRegistry->isReadOnly())
     295             :     {
     296           0 :         return REG_REGISTRY_READONLY;
     297             :     }
     298             : 
     299         794 :     if (vType > 4)
     300             :     {
     301           0 :         return REG_INVALID_VALUE;
     302             :     }
     303             : 
     304        1588 :     OUString sImplValueName( VALUE_PREFIX );
     305         794 :     sImplValueName += valueName;
     306             : 
     307        1588 :     REG_GUARD(m_pRegistry->m_mutex);
     308             : 
     309         794 :     if ( rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT , sImplValueName, VALUE_MODE_CREATE) )
     310             :     {
     311           0 :         return REG_SET_VALUE_FAILED;
     312             :     }
     313             : 
     314         794 :     sal_uInt32 size = vSize;
     315             : 
     316         794 :     sal_uInt8 type = (sal_uInt8)vType;
     317         794 :     pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size);
     318         794 :     memcpy(pBuffer, &type, 1);
     319             : 
     320         794 :     writeUINT32(pBuffer+VALUE_TYPEOFFSET, size);
     321             : 
     322         794 :     switch (vType)
     323             :     {
     324             :         case RG_VALUETYPE_NOT_DEFINED:
     325           0 :             memcpy(pBuffer+VALUE_HEADEROFFSET, value, size);
     326           0 :             break;
     327             :         case RG_VALUETYPE_LONG:
     328           0 :             writeINT32(pBuffer+VALUE_HEADEROFFSET, *((sal_Int32*)value));
     329           0 :             break;
     330             :         case RG_VALUETYPE_STRING:
     331           8 :             writeUtf8(pBuffer+VALUE_HEADEROFFSET, (const sal_Char*)value);
     332           8 :             break;
     333             :         case RG_VALUETYPE_UNICODE:
     334           0 :             writeString(pBuffer+VALUE_HEADEROFFSET, (const sal_Unicode*)value);
     335           0 :             break;
     336             :         case RG_VALUETYPE_BINARY:
     337         786 :             memcpy(pBuffer+VALUE_HEADEROFFSET, value, size);
     338         786 :             break;
     339             :         default:
     340             :             OSL_ASSERT(false);
     341           0 :             break;
     342             :     }
     343             : 
     344             :     sal_uInt32  writenBytes;
     345         794 :     if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) )
     346             :     {
     347           0 :         rtl_freeMemory(pBuffer);
     348           0 :         return REG_SET_VALUE_FAILED;
     349             :     }
     350         794 :     if (writenBytes != (VALUE_HEADERSIZE+size))
     351             :     {
     352           0 :         rtl_freeMemory(pBuffer);
     353           0 :         return REG_SET_VALUE_FAILED;
     354             :     }
     355         794 :     setModified();
     356             : 
     357         794 :     rtl_freeMemory(pBuffer);
     358        1588 :     return REG_NO_ERROR;
     359             : }
     360             : 
     361             : 
     362             : //  setLongListValue
     363             : 
     364           0 : RegError ORegKey::setLongListValue(const OUString& valueName, sal_Int32* pValueList, sal_uInt32 len)
     365             : {
     366           0 :     OStoreStream    rValue;
     367             :     sal_uInt8*      pBuffer;
     368             : 
     369           0 :     if (m_pRegistry->isReadOnly())
     370             :     {
     371           0 :         return REG_REGISTRY_READONLY;
     372             :     }
     373             : 
     374           0 :     OUString sImplValueName( VALUE_PREFIX );
     375           0 :     sImplValueName += valueName;
     376             : 
     377           0 :     REG_GUARD(m_pRegistry->m_mutex);
     378             : 
     379           0 :     if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, VALUE_MODE_CREATE) )
     380             :     {
     381           0 :         return REG_SET_VALUE_FAILED;
     382             :     }
     383             : 
     384           0 :     sal_uInt32 size = 4; // 4 bytes (sal_uInt32) for the length
     385             : 
     386           0 :     size += len * 4;
     387             : 
     388           0 :     sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_LONGLIST;
     389           0 :     pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size);
     390           0 :     memcpy(pBuffer, &type, 1);
     391             : 
     392           0 :     writeUINT32(pBuffer+VALUE_TYPEOFFSET, size);
     393           0 :     writeUINT32(pBuffer+VALUE_HEADEROFFSET, len);
     394             : 
     395           0 :     sal_uInt32 offset = 4; // initial 4 bytes for the size of the array
     396             : 
     397           0 :     for (sal_uInt32 i=0; i < len; i++)
     398             :     {
     399           0 :         writeINT32(pBuffer+VALUE_HEADEROFFSET+offset, pValueList[i]);
     400           0 :         offset += 4;
     401             :     }
     402             : 
     403             :     sal_uInt32  writenBytes;
     404           0 :     if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) )
     405             :     {
     406           0 :         rtl_freeMemory(pBuffer);
     407           0 :         return REG_SET_VALUE_FAILED;
     408             :     }
     409           0 :     if (writenBytes != (VALUE_HEADEROFFSET+size))
     410             :     {
     411           0 :         rtl_freeMemory(pBuffer);
     412           0 :         return REG_SET_VALUE_FAILED;
     413             :     }
     414           0 :     setModified();
     415             : 
     416           0 :     rtl_freeMemory(pBuffer);
     417           0 :     return REG_NO_ERROR;
     418             : }
     419             : 
     420             : 
     421             : //  setStringListValue
     422             : 
     423           2 : RegError ORegKey::setStringListValue(const OUString& valueName, sal_Char** pValueList, sal_uInt32 len)
     424             : {
     425           2 :     OStoreStream    rValue;
     426             :     sal_uInt8*      pBuffer;
     427             : 
     428           2 :     if (m_pRegistry->isReadOnly())
     429             :     {
     430           0 :         return REG_REGISTRY_READONLY;
     431             :     }
     432             : 
     433           4 :     OUString sImplValueName( VALUE_PREFIX );
     434           2 :     sImplValueName += valueName;
     435             : 
     436           4 :     REG_GUARD(m_pRegistry->m_mutex);
     437             : 
     438           2 :     if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, VALUE_MODE_CREATE) )
     439             :     {
     440           0 :         return REG_SET_VALUE_FAILED;
     441             :     }
     442             : 
     443           2 :     sal_uInt32 size = 4; // 4 bytes (sal_uInt32) for the length
     444             : 
     445             :     sal_uInt32 i;
     446           4 :     for (i=0; i < len; i++)
     447             :     {
     448           2 :         size +=  4 + strlen(pValueList[i]) + 1;
     449             :     }
     450             : 
     451           2 :     sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_STRINGLIST;
     452           2 :     pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size);
     453           2 :     memcpy(pBuffer, &type, 1);
     454             : 
     455           2 :     writeUINT32(pBuffer+VALUE_TYPEOFFSET, size);
     456           2 :     writeUINT32(pBuffer+VALUE_HEADEROFFSET, len);
     457             : 
     458           2 :     sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
     459           2 :     sal_uInt32 sLen = 0;
     460             : 
     461           4 :     for (i=0; i < len; i++)
     462             :     {
     463           2 :         sLen = strlen(pValueList[i]) + 1;
     464           2 :         writeUINT32(pBuffer+VALUE_HEADEROFFSET+offset, sLen);
     465             : 
     466           2 :         offset += 4;
     467           2 :         writeUtf8(pBuffer+VALUE_HEADEROFFSET+offset, pValueList[i]);
     468           2 :         offset += sLen;
     469             :     }
     470             : 
     471             :     sal_uInt32  writenBytes;
     472           2 :     if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) )
     473             :     {
     474           0 :         rtl_freeMemory(pBuffer);
     475           0 :         return REG_SET_VALUE_FAILED;
     476             :     }
     477           2 :     if (writenBytes != (VALUE_HEADERSIZE+size))
     478             :     {
     479           0 :         rtl_freeMemory(pBuffer);
     480           0 :         return REG_SET_VALUE_FAILED;
     481             :     }
     482           2 :     setModified();
     483             : 
     484           2 :     rtl_freeMemory(pBuffer);
     485           4 :     return REG_NO_ERROR;
     486             : }
     487             : 
     488             : 
     489             : //  setUnicodeListValue
     490             : 
     491           0 : RegError ORegKey::setUnicodeListValue(const OUString& valueName, sal_Unicode** pValueList, sal_uInt32 len)
     492             : {
     493           0 :     OStoreStream    rValue;
     494             :     sal_uInt8*      pBuffer;
     495             : 
     496           0 :     if (m_pRegistry->isReadOnly())
     497             :     {
     498           0 :         return REG_REGISTRY_READONLY;
     499             :     }
     500             : 
     501           0 :     OUString sImplValueName( VALUE_PREFIX );
     502           0 :     sImplValueName += valueName;
     503             : 
     504           0 :     REG_GUARD(m_pRegistry->m_mutex);
     505             : 
     506           0 :     if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, VALUE_MODE_CREATE) )
     507             :     {
     508           0 :         return REG_SET_VALUE_FAILED;
     509             :     }
     510             : 
     511           0 :     sal_uInt32 size = 4; // 4 bytes (sal_uInt32) for the length
     512             : 
     513             :     sal_uInt32 i;
     514           0 :     for (i=0; i < len; i++)
     515             :     {
     516           0 :         size +=  4 + ((rtl_ustr_getLength(pValueList[i]) +1) * 2);
     517             :     }
     518             : 
     519           0 :     sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_UNICODELIST;
     520           0 :     pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size);
     521           0 :     memcpy(pBuffer, &type, 1);
     522             : 
     523           0 :     writeUINT32(pBuffer+VALUE_TYPEOFFSET, size);
     524           0 :     writeUINT32(pBuffer+VALUE_HEADEROFFSET, len);
     525             : 
     526           0 :     sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
     527           0 :     sal_uInt32 sLen = 0;
     528             : 
     529           0 :     for (i=0; i < len; i++)
     530             :     {
     531           0 :         sLen = (rtl_ustr_getLength(pValueList[i]) + 1) * 2;
     532           0 :         writeUINT32(pBuffer+VALUE_HEADEROFFSET+offset, sLen);
     533             : 
     534           0 :         offset += 4;
     535           0 :         writeString(pBuffer+VALUE_HEADEROFFSET+offset, pValueList[i]);
     536           0 :         offset += sLen;
     537             :     }
     538             : 
     539             :     sal_uInt32  writenBytes;
     540           0 :     if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) )
     541             :     {
     542           0 :         rtl_freeMemory(pBuffer);
     543           0 :         return REG_SET_VALUE_FAILED;
     544             :     }
     545           0 :     if (writenBytes != (VALUE_HEADERSIZE+size))
     546             :     {
     547           0 :         rtl_freeMemory(pBuffer);
     548           0 :         return REG_SET_VALUE_FAILED;
     549             :     }
     550           0 :     setModified();
     551             : 
     552           0 :     rtl_freeMemory(pBuffer);
     553           0 :     return REG_NO_ERROR;
     554             : }
     555             : 
     556             : 
     557             : //  getValue
     558             : 
     559           6 : RegError ORegKey::getValue(const OUString& valueName, RegValue value) const
     560             : {
     561           6 :     OStoreStream    rValue;
     562             :     sal_uInt8*      pBuffer;
     563             :     RegValueType    valueType;
     564             :     sal_uInt32      valueSize;
     565           6 :     storeAccessMode accessMode = VALUE_MODE_OPEN;
     566             : 
     567           6 :     if (m_pRegistry->isReadOnly())
     568             :     {
     569           0 :         accessMode = VALUE_MODE_OPENREAD;
     570             :     }
     571             : 
     572          12 :     OUString sImplValueName( VALUE_PREFIX );
     573           6 :     sImplValueName += valueName;
     574             : 
     575          12 :     REG_GUARD(m_pRegistry->m_mutex);
     576             : 
     577           6 :     if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) )
     578             :     {
     579           0 :         return REG_VALUE_NOT_EXISTS;
     580             :     }
     581             : 
     582           6 :     pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE);
     583             : 
     584             :     sal_uInt32  readBytes;
     585           6 :     if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) )
     586             :     {
     587           0 :         rtl_freeMemory(pBuffer);
     588           0 :         return REG_INVALID_VALUE;
     589             :     }
     590           6 :     if (readBytes != VALUE_HEADERSIZE)
     591             :     {
     592           0 :         rtl_freeMemory(pBuffer);
     593           0 :         return REG_INVALID_VALUE;
     594             :     }
     595             : 
     596           6 :     sal_uInt8   type = *((sal_uInt8*)pBuffer);
     597           6 :     valueType = (RegValueType)type;
     598           6 :     readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
     599             : 
     600           6 :     rtl_freeMemory(pBuffer);
     601             : 
     602           6 :     if (valueType > 4)
     603             :     {
     604           0 :         return REG_INVALID_VALUE;
     605             :     }
     606             : 
     607           6 :     pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
     608             : 
     609           6 :     if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) )
     610             :     {
     611           0 :         rtl_freeMemory(pBuffer);
     612           0 :         return REG_INVALID_VALUE;
     613             :     }
     614           6 :     if (readBytes != valueSize)
     615             :     {
     616           0 :         rtl_freeMemory(pBuffer);
     617           0 :         return REG_INVALID_VALUE;
     618             :     }
     619             : 
     620           6 :     switch (valueType)
     621             :     {
     622             :         case RG_VALUETYPE_NOT_DEFINED:
     623           0 :             memcpy(value, pBuffer, valueSize);
     624           0 :             break;
     625             :         case RG_VALUETYPE_LONG:
     626           0 :             readINT32(pBuffer, *((sal_Int32*)value));
     627           0 :             break;
     628             :         case RG_VALUETYPE_STRING:
     629           6 :             readUtf8(pBuffer, (sal_Char*)value, valueSize);
     630           6 :             break;
     631             :         case RG_VALUETYPE_UNICODE:
     632           0 :             readString(pBuffer, (sal_Unicode*)value, valueSize);
     633           0 :             break;
     634             :         case RG_VALUETYPE_BINARY:
     635           0 :             memcpy(value, pBuffer, valueSize);
     636           0 :             break;
     637             :         case RG_VALUETYPE_LONGLIST:
     638             :         case RG_VALUETYPE_STRINGLIST:
     639             :         case RG_VALUETYPE_UNICODELIST:
     640           0 :             memcpy(value, pBuffer, valueSize);
     641           0 :             break;
     642             :     }
     643             : 
     644             : 
     645           6 :     rtl_freeMemory(pBuffer);
     646          12 :     return REG_NO_ERROR;
     647             : }
     648             : 
     649             : 
     650             : //  getLongListValue
     651             : 
     652           0 : RegError ORegKey::getLongListValue(const OUString& valueName, sal_Int32** pValueList, sal_uInt32* pLen) const
     653             : {
     654           0 :     OStoreStream    rValue;
     655             :     sal_uInt8*      pBuffer;
     656             :     RegValueType    valueType;
     657             :     sal_uInt32      valueSize;
     658           0 :     storeAccessMode accessMode = VALUE_MODE_OPEN;
     659             : 
     660           0 :     if (m_pRegistry->isReadOnly())
     661             :     {
     662           0 :         accessMode = VALUE_MODE_OPENREAD;
     663             :     }
     664             : 
     665           0 :     OUString sImplValueName( VALUE_PREFIX );
     666           0 :     sImplValueName += valueName;
     667             : 
     668           0 :     REG_GUARD(m_pRegistry->m_mutex);
     669             : 
     670           0 :     if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) )
     671             :     {
     672           0 :         pValueList = NULL;
     673           0 :         *pLen = 0;
     674           0 :         return REG_VALUE_NOT_EXISTS;
     675             :     }
     676             : 
     677           0 :     pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE);
     678             : 
     679             :     sal_uInt32  readBytes;
     680           0 :     if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) )
     681             :     {
     682           0 :         pValueList = NULL;
     683           0 :         *pLen = 0;
     684           0 :         rtl_freeMemory(pBuffer);
     685           0 :         return REG_INVALID_VALUE;
     686             :     }
     687           0 :     if (readBytes != VALUE_HEADERSIZE)
     688             :     {
     689           0 :         pValueList = NULL;
     690           0 :         *pLen = 0;
     691           0 :         rtl_freeMemory(pBuffer);
     692           0 :         return REG_INVALID_VALUE;
     693             :     }
     694             : 
     695           0 :     sal_uInt8   type = *((sal_uInt8*)pBuffer);
     696           0 :     valueType = (RegValueType)type;
     697             : 
     698           0 :     if (valueType != RG_VALUETYPE_LONGLIST)
     699             :     {
     700           0 :         pValueList = NULL;
     701           0 :         *pLen = 0;
     702           0 :         rtl_freeMemory(pBuffer);
     703           0 :         return REG_INVALID_VALUE;
     704             :     }
     705             : 
     706           0 :     readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
     707             : 
     708           0 :     rtl_freeMemory(pBuffer);
     709             : 
     710             :     /* check for 'reasonable' value */
     711             :     /* surely 10 millions entry in a registry list should be enough */
     712           0 :     if(valueSize > 40000000)
     713             :     {
     714           0 :         pValueList = NULL;
     715           0 :         *pLen = 0;
     716           0 :         rtl_freeMemory(pBuffer);
     717           0 :         return REG_INVALID_VALUE;
     718             :     }
     719           0 :     pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
     720             : 
     721           0 :     if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) )
     722             :     {
     723           0 :         pValueList = NULL;
     724           0 :         *pLen = 0;
     725           0 :         rtl_freeMemory(pBuffer);
     726           0 :         return REG_INVALID_VALUE;
     727             :     }
     728           0 :     if (readBytes != valueSize)
     729             :     {
     730           0 :         pValueList = NULL;
     731           0 :         *pLen = 0;
     732           0 :         rtl_freeMemory(pBuffer);
     733           0 :         return REG_INVALID_VALUE;
     734             :     }
     735             : 
     736           0 :     sal_uInt32 len = 0;
     737           0 :     readUINT32(pBuffer, len);
     738             : 
     739             :     /* make sure the declared size of the arry is consistant with the amount of data we have read */
     740           0 :     if(len > (valueSize - 4) / 4)
     741             :     {
     742           0 :         pValueList = NULL;
     743           0 :         *pLen = 0;
     744           0 :         rtl_freeMemory(pBuffer);
     745           0 :         return REG_INVALID_VALUE;
     746             :     }
     747           0 :     *pLen = len;
     748           0 :     sal_Int32* pVList = (sal_Int32*)rtl_allocateZeroMemory(len * sizeof(sal_Int32));
     749             : 
     750           0 :     sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
     751             : 
     752           0 :     for (sal_uInt32 i = 0; i < len; i++)
     753             :     {
     754           0 :         readINT32(pBuffer+offset, pVList[i]);
     755           0 :         offset += 4;
     756             :     }
     757             : 
     758           0 :     *pValueList = pVList;
     759           0 :     rtl_freeMemory(pBuffer);
     760           0 :     return REG_NO_ERROR;
     761             : }
     762             : 
     763             : 
     764             : //  getStringListValue
     765             : 
     766           0 : RegError ORegKey::getStringListValue(const OUString& valueName, sal_Char*** pValueList, sal_uInt32* pLen) const
     767             : {
     768           0 :     OStoreStream    rValue;
     769             :     sal_uInt8*      pBuffer;
     770             :     RegValueType    valueType;
     771             :     sal_uInt32      valueSize;
     772           0 :     storeAccessMode accessMode = VALUE_MODE_OPEN;
     773             : 
     774           0 :     if (m_pRegistry->isReadOnly())
     775             :     {
     776           0 :         accessMode = VALUE_MODE_OPENREAD;
     777             :     }
     778             : 
     779           0 :     OUString sImplValueName( VALUE_PREFIX );
     780           0 :     sImplValueName += valueName;
     781             : 
     782           0 :     REG_GUARD(m_pRegistry->m_mutex);
     783             : 
     784           0 :     if ( rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) )
     785             :     {
     786           0 :         pValueList = NULL;
     787           0 :         *pLen = 0;
     788           0 :         return REG_VALUE_NOT_EXISTS;
     789             :     }
     790             : 
     791           0 :     pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE);
     792             : 
     793             :     sal_uInt32  readBytes;
     794           0 :     if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) )
     795             :     {
     796           0 :         pValueList = NULL;
     797           0 :         *pLen = 0;
     798           0 :         rtl_freeMemory(pBuffer);
     799           0 :         return REG_INVALID_VALUE;
     800             :     }
     801           0 :     if (readBytes != VALUE_HEADERSIZE)
     802             :     {
     803           0 :         pValueList = NULL;
     804           0 :         *pLen = 0;
     805           0 :         rtl_freeMemory(pBuffer);
     806           0 :         return REG_INVALID_VALUE;
     807             :     }
     808             : 
     809           0 :     sal_uInt8   type = *((sal_uInt8*)pBuffer);
     810           0 :     valueType = (RegValueType)type;
     811             : 
     812           0 :     if (valueType != RG_VALUETYPE_STRINGLIST)
     813             :     {
     814           0 :         pValueList = NULL;
     815           0 :         *pLen = 0;
     816           0 :         rtl_freeMemory(pBuffer);
     817           0 :         return REG_INVALID_VALUE;
     818             :     }
     819             : 
     820           0 :     readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
     821             : 
     822           0 :     rtl_freeMemory(pBuffer);
     823             : 
     824           0 :     pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
     825             : 
     826           0 :     if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) )
     827             :     {
     828           0 :         pValueList = NULL;
     829           0 :         *pLen = 0;
     830           0 :         rtl_freeMemory(pBuffer);
     831           0 :         return REG_INVALID_VALUE;
     832             :     }
     833           0 :     if (readBytes != valueSize)
     834             :     {
     835           0 :         pValueList = NULL;
     836           0 :         *pLen = 0;
     837           0 :         rtl_freeMemory(pBuffer);
     838           0 :         return REG_INVALID_VALUE;
     839             :     }
     840             : 
     841           0 :     sal_uInt32 len = 0;
     842           0 :     readUINT32(pBuffer, len);
     843             : 
     844           0 :     *pLen = len;
     845           0 :     sal_Char** pVList = (sal_Char**)rtl_allocateZeroMemory(len * sizeof(sal_Char*));
     846             : 
     847           0 :     sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
     848           0 :     sal_uInt32 sLen = 0;
     849             : 
     850             :     sal_Char *pValue;
     851           0 :     for (sal_uInt32 i=0; i < len; i++)
     852             :     {
     853           0 :         readUINT32(pBuffer+offset, sLen);
     854             : 
     855           0 :         offset += 4;
     856             : 
     857           0 :         pValue = (sal_Char*)rtl_allocateMemory(sLen);
     858           0 :         readUtf8(pBuffer+offset, pValue, sLen);
     859           0 :         pVList[i] = pValue;
     860             : 
     861           0 :         offset += sLen;
     862             :     }
     863             : 
     864           0 :     *pValueList = pVList;
     865           0 :     rtl_freeMemory(pBuffer);
     866           0 :     return REG_NO_ERROR;
     867             : }
     868             : 
     869             : 
     870             : //  getUnicodeListValue
     871             : 
     872           0 : RegError ORegKey::getUnicodeListValue(const OUString& valueName, sal_Unicode*** pValueList, sal_uInt32* pLen) const
     873             : {
     874           0 :     OStoreStream    rValue;
     875             :     sal_uInt8*      pBuffer;
     876             :     RegValueType    valueType;
     877             :     sal_uInt32      valueSize;
     878           0 :     storeAccessMode accessMode = VALUE_MODE_OPEN;
     879             : 
     880           0 :     if (m_pRegistry->isReadOnly())
     881             :     {
     882           0 :         accessMode = VALUE_MODE_OPENREAD;
     883             :     }
     884             : 
     885           0 :     OUString sImplValueName( VALUE_PREFIX );
     886           0 :     sImplValueName += valueName;
     887             : 
     888           0 :     REG_GUARD(m_pRegistry->m_mutex);
     889             : 
     890           0 :     if ( rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) )
     891             :     {
     892           0 :         pValueList = NULL;
     893           0 :         *pLen = 0;
     894           0 :         return REG_VALUE_NOT_EXISTS;
     895             :     }
     896             : 
     897           0 :     pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE);
     898             : 
     899             :     sal_uInt32  readBytes;
     900           0 :     if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) )
     901             :     {
     902           0 :         pValueList = NULL;
     903           0 :         *pLen = 0;
     904           0 :         rtl_freeMemory(pBuffer);
     905           0 :         return REG_INVALID_VALUE;
     906             :     }
     907           0 :     if (readBytes != VALUE_HEADERSIZE)
     908             :     {
     909           0 :         pValueList = NULL;
     910           0 :         *pLen = 0;
     911           0 :         rtl_freeMemory(pBuffer);
     912           0 :         return REG_INVALID_VALUE;
     913             :     }
     914             : 
     915           0 :     sal_uInt8   type = *((sal_uInt8*)pBuffer);
     916           0 :     valueType = (RegValueType)type;
     917             : 
     918           0 :     if (valueType != RG_VALUETYPE_UNICODELIST)
     919             :     {
     920           0 :         pValueList = NULL;
     921           0 :         *pLen = 0;
     922           0 :         rtl_freeMemory(pBuffer);
     923           0 :         return REG_INVALID_VALUE;
     924             :     }
     925             : 
     926           0 :     readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
     927             : 
     928           0 :     rtl_freeMemory(pBuffer);
     929             : 
     930           0 :     pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
     931             : 
     932           0 :     if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) )
     933             :     {
     934           0 :         pValueList = NULL;
     935           0 :         *pLen = 0;
     936           0 :         rtl_freeMemory(pBuffer);
     937           0 :         return REG_INVALID_VALUE;
     938             :     }
     939           0 :     if (readBytes != valueSize)
     940             :     {
     941           0 :         pValueList = NULL;
     942           0 :         *pLen = 0;
     943           0 :         rtl_freeMemory(pBuffer);
     944           0 :         return REG_INVALID_VALUE;
     945             :     }
     946             : 
     947           0 :     sal_uInt32 len = 0;
     948           0 :     readUINT32(pBuffer, len);
     949             : 
     950           0 :     *pLen = len;
     951           0 :     sal_Unicode** pVList = (sal_Unicode**)rtl_allocateZeroMemory(len * sizeof(sal_Unicode*));
     952             : 
     953           0 :     sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
     954           0 :     sal_uInt32 sLen = 0;
     955             : 
     956             :     sal_Unicode *pValue;
     957           0 :     for (sal_uInt32 i=0; i < len; i++)
     958             :     {
     959           0 :         readUINT32(pBuffer+offset, sLen);
     960             : 
     961           0 :         offset += 4;
     962             : 
     963           0 :         pValue = (sal_Unicode*)rtl_allocateMemory((sLen / 2) * sizeof(sal_Unicode));
     964           0 :         readString(pBuffer+offset, pValue, sLen);
     965           0 :         pVList[i] = pValue;
     966             : 
     967           0 :         offset += sLen;
     968             :     }
     969             : 
     970           0 :     *pValueList = pVList;
     971           0 :     rtl_freeMemory(pBuffer);
     972           0 :     return REG_NO_ERROR;
     973             : }
     974             : 
     975             : 
     976             : //  getKeyType()
     977             : 
     978          14 : RegError ORegKey::getKeyType(const OUString& name, RegKeyType* pKeyType) const
     979             : {
     980          14 :     *pKeyType = RG_KEYTYPE;
     981             : 
     982          14 :     REG_GUARD(m_pRegistry->m_mutex);
     983             : 
     984          14 :     if ( !name.isEmpty() )
     985             :     {
     986          14 :         ORegKey* pThis = const_cast< ORegKey* >(this);
     987             : 
     988          14 :         RegKeyHandle hKey = 0;
     989          14 :         RegError _ret = pThis->openKey(name, &hKey);
     990          14 :         if (_ret != REG_NO_ERROR)
     991           0 :             return _ret;
     992          14 :         (void) pThis->releaseKey(hKey);
     993             :     }
     994             : 
     995          14 :     return REG_NO_ERROR;
     996             : }
     997             : 
     998           0 : RegError ORegKey::getResolvedKeyName(const OUString& keyName,
     999             :                                      OUString& resolvedName)
    1000             : {
    1001           0 :     if (keyName.isEmpty())
    1002           0 :         return REG_INVALID_KEYNAME;
    1003             : 
    1004           0 :     resolvedName = getFullPath(keyName);
    1005           0 :     return REG_NO_ERROR;
    1006             : }
    1007             : 
    1008             : 
    1009             : //  countSubKeys()
    1010             : 
    1011          30 : sal_uInt32 ORegKey::countSubKeys()
    1012             : {
    1013          30 :     REG_GUARD(m_pRegistry->m_mutex);
    1014             : 
    1015             :     OStoreDirectory::iterator   iter;
    1016          60 :     OStoreDirectory             rStoreDir = getStoreDir();
    1017          30 :     storeError                  _err = rStoreDir.first(iter);
    1018          30 :     sal_uInt32                  count = 0;
    1019             : 
    1020          94 :     while ( _err == store_E_None )
    1021             :     {
    1022          34 :         if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
    1023             :         {
    1024          30 :             count++;
    1025             :         }
    1026             : 
    1027          34 :         _err = rStoreDir.next(iter);
    1028             :     }
    1029             : 
    1030          60 :     return count;
    1031             : }
    1032             : 
    1033          74 : OStoreDirectory ORegKey::getStoreDir()
    1034             : {
    1035          74 :     OStoreDirectory rStoreDir;
    1036         148 :     OUString        fullPath;
    1037         148 :     OUString        relativName;
    1038          74 :     storeAccessMode accessMode = KEY_MODE_OPEN;
    1039             : 
    1040          74 :     if ( m_name.equals(m_pRegistry->ROOT) )
    1041             :     {
    1042           8 :         fullPath = OUString();
    1043           8 :         relativName = OUString();
    1044             :     } else
    1045             :     {
    1046          66 :         fullPath = m_name.copy(0, m_name.lastIndexOf('/') + 1);
    1047          66 :         relativName = m_name.copy(m_name.lastIndexOf('/') + 1);
    1048             :     }
    1049             : 
    1050          74 :     if (m_pRegistry->isReadOnly())
    1051             :     {
    1052           0 :         accessMode = KEY_MODE_OPENREAD;
    1053             :     }
    1054             : 
    1055          74 :     rStoreDir.create(getStoreFile(), fullPath, relativName, accessMode);
    1056             : 
    1057         148 :     return rStoreDir;
    1058             : }
    1059             : 
    1060         902 : OUString ORegKey::getFullPath(OUString const & path) const {
    1061             :     OSL_ASSERT(!m_name.isEmpty() && !path.isEmpty());
    1062         902 :     OUStringBuffer b(m_name);
    1063         902 :     if (!b.isEmpty() && b[b.getLength() - 1] == '/') {
    1064         816 :         if (path[0] == '/') {
    1065         806 :             b.append(path.getStr() + 1, path.getLength() - 1);
    1066             :         } else {
    1067          10 :             b.append(path);
    1068             :         }
    1069             :     } else {
    1070          86 :         if (path[0] != '/') {
    1071          68 :             b.append('/');
    1072             :         }
    1073          86 :         b.append(path);
    1074             :     }
    1075         902 :     return b.makeStringAndClear();
    1076             : }
    1077             : 
    1078             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10