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

Generated by: LCOV version 1.11