lok: 14pt font is too large for the context menus.
[LibreOffice.git] / registry / source / keyimpl.cxx
blob1a511a5e2a44a15a5b770d6320080e479e0dcc0c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <string.h>
23 #include "keyimpl.hxx"
25 #include "reflcnst.hxx"
26 #include <rtl/alloc.h>
27 #include <rtl/ustrbuf.hxx>
28 #include <osl/diagnose.h>
29 #include <sal/log.hxx>
31 using namespace store;
33 namespace { static char const VALUE_PREFIX[] = "$VL_"; }
36 // ORegKey()
38 ORegKey::ORegKey(const OUString& keyName, ORegistry* pReg)
39 : m_refCount(1)
40 , m_name(keyName)
41 , m_bDeleted(false)
42 , m_bModified(false)
43 , m_pRegistry(pReg)
48 // ~ORegKey()
50 ORegKey::~ORegKey()
52 SAL_WARN_IF(m_refCount != 0, "registry", "registry::ORegKey::dtor(): refcount not zero.");
56 // releaseKey
58 RegError ORegKey::releaseKey(RegKeyHandle hKey)
60 return m_pRegistry->releaseKey(hKey);
64 // createKey
66 RegError ORegKey::createKey(const OUString& keyName, RegKeyHandle* phNewKey)
68 return m_pRegistry->createKey(this, keyName, phNewKey);
72 // openKey
74 RegError ORegKey::openKey(const OUString& keyName, RegKeyHandle* phOpenKey)
76 return m_pRegistry->openKey(this, keyName, phOpenKey);
80 // openSubKeys
82 RegError ORegKey::openSubKeys(const OUString& keyName, RegKeyHandle** phOpenSubKeys, sal_uInt32* pnSubKeys)
84 RegError _ret = RegError::NO_ERROR;
86 *phOpenSubKeys = nullptr;
87 *pnSubKeys = 0;
89 ORegKey* pKey = this;
90 if ( !keyName.isEmpty() )
92 _ret = openKey(keyName, reinterpret_cast<RegKeyHandle*>(&pKey));
93 if (_ret != RegError::NO_ERROR)
94 return _ret;
97 sal_uInt32 nSubKeys = pKey->countSubKeys();
98 *pnSubKeys = nSubKeys;
100 ORegKey** pSubKeys;
101 pSubKeys = static_cast<ORegKey**>(rtl_allocateZeroMemory(nSubKeys * sizeof(ORegKey*)));
103 OStoreDirectory::iterator iter;
104 OStoreDirectory rStoreDir(pKey->getStoreDir());
105 storeError _err = rStoreDir.first(iter);
107 nSubKeys = 0;
108 while ( _err == store_E_None )
110 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
112 OUString const sSubKeyName = iter.m_pszName;
114 ORegKey* pOpenSubKey = nullptr;
115 _ret = pKey->openKey(sSubKeyName, reinterpret_cast<RegKeyHandle*>(&pOpenSubKey));
116 if (_ret != RegError::NO_ERROR)
118 *phOpenSubKeys = nullptr;
119 *pnSubKeys = 0;
120 rtl_freeMemory(pSubKeys); // @@@ leaking 'pSubKeys[0...nSubkeys-1]'
121 return _ret; // @@@ leaking 'pKey'
124 pSubKeys[nSubKeys] = pOpenSubKey;
126 nSubKeys++;
129 _err = rStoreDir.next(iter);
132 *phOpenSubKeys = reinterpret_cast<RegKeyHandle*>(pSubKeys);
133 if (!keyName.isEmpty())
135 (void) releaseKey(pKey);
137 return RegError::NO_ERROR;
141 // getKeyNames
143 RegError ORegKey::getKeyNames(const OUString& keyName,
144 rtl_uString*** pSubKeyNames,
145 sal_uInt32* pnSubKeys)
147 RegError _ret = RegError::NO_ERROR;
149 *pSubKeyNames = nullptr;
150 *pnSubKeys = 0;
152 ORegKey* pKey = this;
153 if (!keyName.isEmpty())
155 _ret = openKey(keyName, reinterpret_cast<RegKeyHandle*>(&pKey));
156 if (_ret != RegError::NO_ERROR)
157 return _ret;
160 sal_uInt32 nSubKeys = pKey->countSubKeys();
161 *pnSubKeys = nSubKeys;
163 rtl_uString** pSubKeys = nullptr;
164 pSubKeys = static_cast<rtl_uString**>(rtl_allocateZeroMemory(nSubKeys * sizeof(rtl_uString*)));
166 OStoreDirectory::iterator iter;
167 OStoreDirectory rStoreDir(pKey->getStoreDir());
168 storeError _err = rStoreDir.first(iter);
170 nSubKeys = 0;
172 while ( _err == store_E_None )
174 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR)
176 OUString const sSubKeyName = iter.m_pszName;
178 OUString sFullKeyName(pKey->getName());
179 if (sFullKeyName.getLength() > 1)
180 sFullKeyName += m_pRegistry->ROOT;
181 sFullKeyName += sSubKeyName;
183 rtl_uString_newFromString(&pSubKeys[nSubKeys], sFullKeyName.pData);
185 nSubKeys++;
188 _err = rStoreDir.next(iter);
191 *pSubKeyNames = pSubKeys;
192 if (!keyName.isEmpty())
194 releaseKey(pKey);
196 return RegError::NO_ERROR;
200 // closeKey
202 RegError ORegKey::closeKey(RegKeyHandle hKey)
204 return m_pRegistry->closeKey(hKey);
208 // deleteKey
210 RegError ORegKey::deleteKey(const OUString& keyName)
212 return m_pRegistry->deleteKey(this, keyName);
216 // getValueType
218 RegError ORegKey::getValueInfo(const OUString& valueName, RegValueType* pValueType, sal_uInt32* pValueSize) const
220 OStoreStream rValue;
221 sal_uInt8* pBuffer;
222 storeAccessMode accessMode = storeAccessMode::ReadWrite;
224 if (m_pRegistry->isReadOnly())
226 accessMode = storeAccessMode::ReadOnly;
229 OUString sImplValueName( VALUE_PREFIX );
230 sImplValueName += valueName;
232 REG_GUARD(m_pRegistry->m_mutex);
234 if ( rValue.create(m_pRegistry->getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) )
236 *pValueType = RegValueType::NOT_DEFINED;
237 *pValueSize = 0;
238 return RegError::VALUE_NOT_EXISTS;
241 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(VALUE_HEADERSIZE));
243 sal_uInt32 readBytes;
244 if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) )
246 rtl_freeMemory(pBuffer);
247 return RegError::INVALID_VALUE;
249 if (readBytes != VALUE_HEADERSIZE)
251 rtl_freeMemory(pBuffer);
252 return RegError::INVALID_VALUE;
255 sal_uInt32 size;
256 sal_uInt8 type = *pBuffer;
257 readUINT32(pBuffer+VALUE_TYPEOFFSET, size);
259 *pValueType = static_cast<RegValueType>(type);
260 // if (*pValueType == RegValueType::UNICODE)
261 // {
262 // *pValueSize = (size / 2) * sizeof(sal_Unicode);
263 // } else
264 // {
265 if (*pValueType > RegValueType::BINARY)
267 rtl_freeMemory(pBuffer);
268 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(4));
269 rValue.readAt(VALUE_HEADEROFFSET, pBuffer, 4, readBytes);
271 readUINT32(pBuffer, size);
274 *pValueSize = size;
275 // }
277 rtl_freeMemory(pBuffer);
278 return RegError::NO_ERROR;
282 // setValue
284 RegError ORegKey::setValue(const OUString& valueName, RegValueType vType, RegValue value, sal_uInt32 vSize)
286 OStoreStream rValue;
287 sal_uInt8* pBuffer;
289 if (m_pRegistry->isReadOnly())
291 return RegError::REGISTRY_READONLY;
294 if (vType > RegValueType::BINARY)
296 return RegError::INVALID_VALUE;
299 OUString sImplValueName( VALUE_PREFIX );
300 sImplValueName += valueName;
302 REG_GUARD(m_pRegistry->m_mutex);
304 if ( rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT , sImplValueName, storeAccessMode::Create) )
306 return RegError::SET_VALUE_FAILED;
309 sal_uInt32 size = vSize;
311 sal_uInt8 type = static_cast<sal_uInt8>(vType);
312 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(VALUE_HEADERSIZE + size));
313 memcpy(pBuffer, &type, 1);
315 writeUINT32(pBuffer+VALUE_TYPEOFFSET, size);
317 switch (vType)
319 case RegValueType::NOT_DEFINED:
320 memcpy(pBuffer+VALUE_HEADEROFFSET, value, size);
321 break;
322 case RegValueType::LONG:
323 writeINT32(pBuffer+VALUE_HEADEROFFSET, *static_cast<sal_Int32*>(value));
324 break;
325 case RegValueType::STRING:
326 writeUtf8(pBuffer+VALUE_HEADEROFFSET, static_cast<const sal_Char*>(value));
327 break;
328 case RegValueType::UNICODE:
329 writeString(pBuffer+VALUE_HEADEROFFSET, static_cast<const sal_Unicode*>(value));
330 break;
331 case RegValueType::BINARY:
332 memcpy(pBuffer+VALUE_HEADEROFFSET, value, size);
333 break;
334 default:
335 OSL_ASSERT(false);
336 break;
339 sal_uInt32 writenBytes;
340 if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) )
342 rtl_freeMemory(pBuffer);
343 return RegError::SET_VALUE_FAILED;
345 if (writenBytes != (VALUE_HEADERSIZE+size))
347 rtl_freeMemory(pBuffer);
348 return RegError::SET_VALUE_FAILED;
350 setModified();
352 rtl_freeMemory(pBuffer);
353 return RegError::NO_ERROR;
357 // setLongListValue
359 RegError ORegKey::setLongListValue(const OUString& valueName, sal_Int32 const * pValueList, sal_uInt32 len)
361 OStoreStream rValue;
362 sal_uInt8* pBuffer;
364 if (m_pRegistry->isReadOnly())
366 return RegError::REGISTRY_READONLY;
369 OUString sImplValueName( VALUE_PREFIX );
370 sImplValueName += valueName;
372 REG_GUARD(m_pRegistry->m_mutex);
374 if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, storeAccessMode::Create) )
376 return RegError::SET_VALUE_FAILED;
379 sal_uInt32 size = 4; // 4 bytes (sal_uInt32) for the length
381 size += len * 4;
383 sal_uInt8 type = sal_uInt8(RegValueType::LONGLIST);
384 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(VALUE_HEADERSIZE + size));
385 memcpy(pBuffer, &type, 1);
387 writeUINT32(pBuffer+VALUE_TYPEOFFSET, size);
388 writeUINT32(pBuffer+VALUE_HEADEROFFSET, len);
390 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array
392 for (sal_uInt32 i=0; i < len; i++)
394 writeINT32(pBuffer+VALUE_HEADEROFFSET+offset, pValueList[i]);
395 offset += 4;
398 sal_uInt32 writenBytes;
399 if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) )
401 rtl_freeMemory(pBuffer);
402 return RegError::SET_VALUE_FAILED;
404 if (writenBytes != (VALUE_HEADEROFFSET+size))
406 rtl_freeMemory(pBuffer);
407 return RegError::SET_VALUE_FAILED;
409 setModified();
411 rtl_freeMemory(pBuffer);
412 return RegError::NO_ERROR;
416 // setStringListValue
418 RegError ORegKey::setStringListValue(const OUString& valueName, sal_Char** pValueList, sal_uInt32 len)
420 OStoreStream rValue;
421 sal_uInt8* pBuffer;
423 if (m_pRegistry->isReadOnly())
425 return RegError::REGISTRY_READONLY;
428 OUString sImplValueName( VALUE_PREFIX );
429 sImplValueName += valueName;
431 REG_GUARD(m_pRegistry->m_mutex);
433 if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, storeAccessMode::Create) )
435 return RegError::SET_VALUE_FAILED;
438 sal_uInt32 size = 4; // 4 bytes (sal_uInt32) for the length
440 sal_uInt32 i;
441 for (i=0; i < len; i++)
443 size += 4 + strlen(pValueList[i]) + 1;
446 sal_uInt8 type = sal_uInt8(RegValueType::STRINGLIST);
447 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(VALUE_HEADERSIZE + size));
448 memcpy(pBuffer, &type, 1);
450 writeUINT32(pBuffer+VALUE_TYPEOFFSET, size);
451 writeUINT32(pBuffer+VALUE_HEADEROFFSET, len);
453 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
454 sal_uInt32 sLen = 0;
456 for (i=0; i < len; i++)
458 sLen = strlen(pValueList[i]) + 1;
459 writeUINT32(pBuffer+VALUE_HEADEROFFSET+offset, sLen);
461 offset += 4;
462 writeUtf8(pBuffer+VALUE_HEADEROFFSET+offset, pValueList[i]);
463 offset += sLen;
466 sal_uInt32 writenBytes;
467 if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) )
469 rtl_freeMemory(pBuffer);
470 return RegError::SET_VALUE_FAILED;
472 if (writenBytes != (VALUE_HEADERSIZE+size))
474 rtl_freeMemory(pBuffer);
475 return RegError::SET_VALUE_FAILED;
477 setModified();
479 rtl_freeMemory(pBuffer);
480 return RegError::NO_ERROR;
484 // setUnicodeListValue
486 RegError ORegKey::setUnicodeListValue(const OUString& valueName, sal_Unicode** pValueList, sal_uInt32 len)
488 OStoreStream rValue;
489 sal_uInt8* pBuffer;
491 if (m_pRegistry->isReadOnly())
493 return RegError::REGISTRY_READONLY;
496 OUString sImplValueName( VALUE_PREFIX );
497 sImplValueName += valueName;
499 REG_GUARD(m_pRegistry->m_mutex);
501 if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, storeAccessMode::Create) )
503 return RegError::SET_VALUE_FAILED;
506 sal_uInt32 size = 4; // 4 bytes (sal_uInt32) for the length
508 sal_uInt32 i;
509 for (i=0; i < len; i++)
511 size += 4 + ((rtl_ustr_getLength(pValueList[i]) +1) * 2);
514 sal_uInt8 type = sal_uInt8(RegValueType::UNICODELIST);
515 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(VALUE_HEADERSIZE + size));
516 memcpy(pBuffer, &type, 1);
518 writeUINT32(pBuffer+VALUE_TYPEOFFSET, size);
519 writeUINT32(pBuffer+VALUE_HEADEROFFSET, len);
521 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
522 sal_uInt32 sLen = 0;
524 for (i=0; i < len; i++)
526 sLen = (rtl_ustr_getLength(pValueList[i]) + 1) * 2;
527 writeUINT32(pBuffer+VALUE_HEADEROFFSET+offset, sLen);
529 offset += 4;
530 writeString(pBuffer+VALUE_HEADEROFFSET+offset, pValueList[i]);
531 offset += sLen;
534 sal_uInt32 writenBytes;
535 if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) )
537 rtl_freeMemory(pBuffer);
538 return RegError::SET_VALUE_FAILED;
540 if (writenBytes != (VALUE_HEADERSIZE+size))
542 rtl_freeMemory(pBuffer);
543 return RegError::SET_VALUE_FAILED;
545 setModified();
547 rtl_freeMemory(pBuffer);
548 return RegError::NO_ERROR;
552 // getValue
554 RegError ORegKey::getValue(const OUString& valueName, RegValue value) const
556 OStoreStream rValue;
557 sal_uInt8* pBuffer;
558 RegValueType valueType;
559 sal_uInt32 valueSize;
560 storeAccessMode accessMode = storeAccessMode::ReadWrite;
562 if (m_pRegistry->isReadOnly())
564 accessMode = storeAccessMode::ReadOnly;
567 OUString sImplValueName( VALUE_PREFIX );
568 sImplValueName += valueName;
570 REG_GUARD(m_pRegistry->m_mutex);
572 if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) )
574 return RegError::VALUE_NOT_EXISTS;
577 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(VALUE_HEADERSIZE));
579 sal_uInt32 readBytes;
580 if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) )
582 rtl_freeMemory(pBuffer);
583 return RegError::INVALID_VALUE;
585 if (readBytes != VALUE_HEADERSIZE)
587 rtl_freeMemory(pBuffer);
588 return RegError::INVALID_VALUE;
591 sal_uInt8 type = *pBuffer;
592 valueType = static_cast<RegValueType>(type);
593 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
595 rtl_freeMemory(pBuffer);
597 if (valueType > RegValueType::BINARY)
599 return RegError::INVALID_VALUE;
602 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(valueSize));
604 if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) )
606 rtl_freeMemory(pBuffer);
607 return RegError::INVALID_VALUE;
609 if (readBytes != valueSize)
611 rtl_freeMemory(pBuffer);
612 return RegError::INVALID_VALUE;
615 switch (valueType)
617 case RegValueType::NOT_DEFINED:
618 memcpy(value, pBuffer, valueSize);
619 break;
620 case RegValueType::LONG:
621 readINT32(pBuffer, *static_cast<sal_Int32*>(value));
622 break;
623 case RegValueType::STRING:
624 readUtf8(pBuffer, static_cast<sal_Char*>(value), valueSize);
625 break;
626 case RegValueType::UNICODE:
627 readString(pBuffer, static_cast<sal_Unicode*>(value), valueSize);
628 break;
629 case RegValueType::BINARY:
630 memcpy(value, pBuffer, valueSize);
631 break;
632 // coverity[dead_error_begin] - following conditions exist to avoid compiler warning
633 case RegValueType::LONGLIST:
634 case RegValueType::STRINGLIST:
635 case RegValueType::UNICODELIST:
636 memcpy(value, pBuffer, valueSize);
637 break;
641 rtl_freeMemory(pBuffer);
642 return RegError::NO_ERROR;
646 // getLongListValue
648 RegError ORegKey::getLongListValue(const OUString& valueName, sal_Int32** pValueList, sal_uInt32* pLen) const
650 OStoreStream rValue;
651 sal_uInt8* pBuffer;
652 RegValueType valueType;
653 sal_uInt32 valueSize;
654 storeAccessMode accessMode = storeAccessMode::ReadWrite;
656 if (m_pRegistry->isReadOnly())
658 accessMode = storeAccessMode::ReadOnly;
661 OUString sImplValueName( VALUE_PREFIX );
662 sImplValueName += valueName;
664 REG_GUARD(m_pRegistry->m_mutex);
666 if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) )
668 pValueList = nullptr;
669 *pLen = 0;
670 return RegError::VALUE_NOT_EXISTS;
673 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(VALUE_HEADERSIZE));
675 sal_uInt32 readBytes;
676 if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) )
678 pValueList = nullptr;
679 *pLen = 0;
680 rtl_freeMemory(pBuffer);
681 return RegError::INVALID_VALUE;
683 if (readBytes != VALUE_HEADERSIZE)
685 pValueList = nullptr;
686 *pLen = 0;
687 rtl_freeMemory(pBuffer);
688 return RegError::INVALID_VALUE;
691 sal_uInt8 type = *pBuffer;
692 valueType = static_cast<RegValueType>(type);
694 if (valueType != RegValueType::LONGLIST)
696 pValueList = nullptr;
697 *pLen = 0;
698 rtl_freeMemory(pBuffer);
699 return RegError::INVALID_VALUE;
702 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
704 rtl_freeMemory(pBuffer);
706 /* check for 'reasonable' value */
707 /* surely 10 millions entry in a registry list should be enough */
708 if(valueSize > 40000000)
710 pValueList = nullptr;
711 *pLen = 0;
712 rtl_freeMemory(pBuffer);
713 return RegError::INVALID_VALUE;
715 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(valueSize));
717 if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) )
719 pValueList = nullptr;
720 *pLen = 0;
721 rtl_freeMemory(pBuffer);
722 return RegError::INVALID_VALUE;
724 if (readBytes != valueSize)
726 pValueList = nullptr;
727 *pLen = 0;
728 rtl_freeMemory(pBuffer);
729 return RegError::INVALID_VALUE;
732 sal_uInt32 len = 0;
733 readUINT32(pBuffer, len);
735 /* make sure the declared size of the arry is consistent with the amount of data we have read */
736 if(len > (valueSize - 4) / 4)
738 pValueList = nullptr;
739 *pLen = 0;
740 rtl_freeMemory(pBuffer);
741 return RegError::INVALID_VALUE;
743 *pLen = len;
744 sal_Int32* pVList = static_cast<sal_Int32*>(rtl_allocateZeroMemory(len * sizeof(sal_Int32)));
746 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
748 for (sal_uInt32 i = 0; i < len; i++)
750 readINT32(pBuffer+offset, pVList[i]);
751 offset += 4;
754 *pValueList = pVList;
755 rtl_freeMemory(pBuffer);
756 return RegError::NO_ERROR;
760 // getStringListValue
762 RegError ORegKey::getStringListValue(const OUString& valueName, sal_Char*** pValueList, sal_uInt32* pLen) const
764 OStoreStream rValue;
765 sal_uInt8* pBuffer;
766 RegValueType valueType;
767 sal_uInt32 valueSize;
768 storeAccessMode accessMode = storeAccessMode::ReadWrite;
770 if (m_pRegistry->isReadOnly())
772 accessMode = storeAccessMode::ReadOnly;
775 OUString sImplValueName( VALUE_PREFIX );
776 sImplValueName += valueName;
778 REG_GUARD(m_pRegistry->m_mutex);
780 if ( rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) )
782 pValueList = nullptr;
783 *pLen = 0;
784 return RegError::VALUE_NOT_EXISTS;
787 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(VALUE_HEADERSIZE));
789 sal_uInt32 readBytes;
790 if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) )
792 pValueList = nullptr;
793 *pLen = 0;
794 rtl_freeMemory(pBuffer);
795 return RegError::INVALID_VALUE;
797 if (readBytes != VALUE_HEADERSIZE)
799 pValueList = nullptr;
800 *pLen = 0;
801 rtl_freeMemory(pBuffer);
802 return RegError::INVALID_VALUE;
805 sal_uInt8 type = *pBuffer;
806 valueType = static_cast<RegValueType>(type);
808 if (valueType != RegValueType::STRINGLIST)
810 pValueList = nullptr;
811 *pLen = 0;
812 rtl_freeMemory(pBuffer);
813 return RegError::INVALID_VALUE;
816 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
818 rtl_freeMemory(pBuffer);
820 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(valueSize));
822 if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) )
824 pValueList = nullptr;
825 *pLen = 0;
826 rtl_freeMemory(pBuffer);
827 return RegError::INVALID_VALUE;
829 if (readBytes != valueSize)
831 pValueList = nullptr;
832 *pLen = 0;
833 rtl_freeMemory(pBuffer);
834 return RegError::INVALID_VALUE;
837 sal_uInt32 len = 0;
838 readUINT32(pBuffer, len);
840 *pLen = len;
841 sal_Char** pVList = static_cast<sal_Char**>(rtl_allocateZeroMemory(len * sizeof(sal_Char*)));
843 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
844 sal_uInt32 sLen = 0;
846 sal_Char *pValue;
847 for (sal_uInt32 i=0; i < len; i++)
849 readUINT32(pBuffer+offset, sLen);
851 offset += 4;
853 pValue = static_cast<sal_Char*>(rtl_allocateMemory(sLen));
854 readUtf8(pBuffer+offset, pValue, sLen);
855 pVList[i] = pValue;
857 offset += sLen;
860 *pValueList = pVList;
861 rtl_freeMemory(pBuffer);
862 return RegError::NO_ERROR;
866 // getUnicodeListValue
868 RegError ORegKey::getUnicodeListValue(const OUString& valueName, sal_Unicode*** pValueList, sal_uInt32* pLen) const
870 OStoreStream rValue;
871 sal_uInt8* pBuffer;
872 RegValueType valueType;
873 sal_uInt32 valueSize;
874 storeAccessMode accessMode = storeAccessMode::ReadWrite;
876 if (m_pRegistry->isReadOnly())
878 accessMode = storeAccessMode::ReadOnly;
881 OUString sImplValueName( VALUE_PREFIX );
882 sImplValueName += valueName;
884 REG_GUARD(m_pRegistry->m_mutex);
886 if ( rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) )
888 pValueList = nullptr;
889 *pLen = 0;
890 return RegError::VALUE_NOT_EXISTS;
893 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(VALUE_HEADERSIZE));
895 sal_uInt32 readBytes;
896 if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) )
898 pValueList = nullptr;
899 *pLen = 0;
900 rtl_freeMemory(pBuffer);
901 return RegError::INVALID_VALUE;
903 if (readBytes != VALUE_HEADERSIZE)
905 pValueList = nullptr;
906 *pLen = 0;
907 rtl_freeMemory(pBuffer);
908 return RegError::INVALID_VALUE;
911 sal_uInt8 type = *pBuffer;
912 valueType = static_cast<RegValueType>(type);
914 if (valueType != RegValueType::UNICODELIST)
916 pValueList = nullptr;
917 *pLen = 0;
918 rtl_freeMemory(pBuffer);
919 return RegError::INVALID_VALUE;
922 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
924 rtl_freeMemory(pBuffer);
926 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(valueSize));
928 if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) )
930 pValueList = nullptr;
931 *pLen = 0;
932 rtl_freeMemory(pBuffer);
933 return RegError::INVALID_VALUE;
935 if (readBytes != valueSize)
937 pValueList = nullptr;
938 *pLen = 0;
939 rtl_freeMemory(pBuffer);
940 return RegError::INVALID_VALUE;
943 sal_uInt32 len = 0;
944 readUINT32(pBuffer, len);
946 *pLen = len;
947 sal_Unicode** pVList = static_cast<sal_Unicode**>(rtl_allocateZeroMemory(len * sizeof(sal_Unicode*)));
949 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
950 sal_uInt32 sLen = 0;
952 sal_Unicode *pValue;
953 for (sal_uInt32 i=0; i < len; i++)
955 readUINT32(pBuffer+offset, sLen);
957 offset += 4;
959 pValue = static_cast<sal_Unicode*>(rtl_allocateMemory((sLen / 2) * sizeof(sal_Unicode)));
960 readString(pBuffer+offset, pValue, sLen);
961 pVList[i] = pValue;
963 offset += sLen;
966 *pValueList = pVList;
967 rtl_freeMemory(pBuffer);
968 return RegError::NO_ERROR;
972 RegError ORegKey::getResolvedKeyName(const OUString& keyName,
973 OUString& resolvedName) const
975 if (keyName.isEmpty())
976 return RegError::INVALID_KEYNAME;
978 resolvedName = getFullPath(keyName);
979 return RegError::NO_ERROR;
983 // countSubKeys()
985 sal_uInt32 ORegKey::countSubKeys()
987 REG_GUARD(m_pRegistry->m_mutex);
989 OStoreDirectory::iterator iter;
990 OStoreDirectory rStoreDir = getStoreDir();
991 storeError _err = rStoreDir.first(iter);
992 sal_uInt32 count = 0;
994 while ( _err == store_E_None )
996 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
998 count++;
1001 _err = rStoreDir.next(iter);
1004 return count;
1007 OStoreDirectory ORegKey::getStoreDir() const
1009 OStoreDirectory rStoreDir;
1010 OUString fullPath;
1011 OUString relativName;
1012 storeAccessMode accessMode = storeAccessMode::ReadWrite;
1014 if ( m_name == m_pRegistry->ROOT )
1016 fullPath.clear();
1017 relativName.clear();
1018 } else
1020 fullPath = m_name.copy(0, m_name.lastIndexOf('/') + 1);
1021 relativName = m_name.copy(m_name.lastIndexOf('/') + 1);
1024 if (m_pRegistry->isReadOnly())
1026 accessMode = storeAccessMode::ReadOnly;
1029 rStoreDir.create(getStoreFile(), fullPath, relativName, accessMode);
1031 return rStoreDir;
1034 OUString ORegKey::getFullPath(OUString const & path) const {
1035 OSL_ASSERT(!m_name.isEmpty() && !path.isEmpty());
1036 OUStringBuffer b(m_name);
1037 if (!b.isEmpty() && b[b.getLength() - 1] == '/') {
1038 if (path[0] == '/') {
1039 b.append(path.copy(1));
1040 } else {
1041 b.append(path);
1043 } else {
1044 if (path[0] != '/') {
1045 b.append('/');
1047 b.append(path);
1049 return b.makeStringAndClear();
1052 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */