Branch libreoffice-5-0-4
[LibreOffice.git] / registry / source / regimpl.cxx
blob6af272039128c2e145516432bce47b264f2aed70
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 "regimpl.hxx"
23 #include <memory>
24 #include <string.h>
25 #include <stdio.h>
27 #if defined(UNX)
28 #include <unistd.h>
29 #endif
30 #ifdef __MINGW32__
31 #include <unistd.h>
32 #endif
34 #include <registry/reflread.hxx>
36 #include <registry/reflwrit.hxx>
38 #include "registry/reader.hxx"
39 #include "registry/refltype.hxx"
40 #include "registry/types.hxx"
41 #include "registry/version.h"
43 #include "reflcnst.hxx"
44 #include "keyimpl.hxx"
46 #include <osl/thread.h>
47 #include <rtl/alloc.h>
48 #include <rtl/ustring.hxx>
49 #include <rtl/ustrbuf.hxx>
50 #include <osl/file.hxx>
52 using namespace osl;
53 using namespace store;
56 namespace {
58 void printString(OUString const & s) {
59 printf("\"");
60 for (sal_Int32 i = 0; i < s.getLength(); ++i) {
61 sal_Unicode c = s[i];
62 if (c == '"' || c == '\\') {
63 printf("\\%c", static_cast< char >(c));
64 } else if (s[i] >= ' ' && s[i] <= '~') {
65 printf("%c", static_cast< char >(c));
66 } else {
67 printf("\\u%04X", static_cast< unsigned int >(c));
70 printf("\"");
73 void printFieldOrReferenceFlag(
74 RTFieldAccess * flags, RTFieldAccess flag, char const * name, bool * first)
76 if ((*flags & flag) != RTFieldAccess::NONE) {
77 if (!*first) {
78 printf("|");
80 *first = false;
81 printf("%s", name);
82 *flags &= ~flag;
86 void printFieldOrReferenceFlags(RTFieldAccess flags) {
87 if (flags == RTFieldAccess::NONE) {
88 printf("none");
89 } else {
90 bool first = true;
91 printFieldOrReferenceFlag(
92 &flags, RTFieldAccess::READONLY, "readonly", &first);
93 printFieldOrReferenceFlag(
94 &flags, RTFieldAccess::OPTIONAL, "optional", &first);
95 printFieldOrReferenceFlag(
96 &flags, RTFieldAccess::MAYBEVOID, "maybevoid", &first);
97 printFieldOrReferenceFlag(&flags, RTFieldAccess::BOUND, "bound", &first);
98 printFieldOrReferenceFlag(
99 &flags, RTFieldAccess::CONSTRAINED, "constrained", &first);
100 printFieldOrReferenceFlag(
101 &flags, RTFieldAccess::TRANSIENT, "transient", &first);
102 printFieldOrReferenceFlag(
103 &flags, RTFieldAccess::MAYBEAMBIGUOUS, "maybeambiguous", &first);
104 printFieldOrReferenceFlag(
105 &flags, RTFieldAccess::MAYBEDEFAULT, "maybedefault", &first);
106 printFieldOrReferenceFlag(
107 &flags, RTFieldAccess::REMOVABLE, "removable", &first);
108 printFieldOrReferenceFlag(
109 &flags, RTFieldAccess::ATTRIBUTE, "attribute", &first);
110 printFieldOrReferenceFlag(
111 &flags, RTFieldAccess::PROPERTY, "property", &first);
112 printFieldOrReferenceFlag(&flags, RTFieldAccess::CONST, "const", &first);
113 printFieldOrReferenceFlag(
114 &flags, RTFieldAccess::READWRITE, "readwrite", &first);
115 printFieldOrReferenceFlag(
116 &flags, RTFieldAccess::PARAMETERIZED_TYPE, "parameterized type", &first);
117 printFieldOrReferenceFlag(
118 &flags, RTFieldAccess::PUBLISHED, "published", &first);
119 if (flags != RTFieldAccess::NONE) {
120 if (!first) {
121 printf("|");
123 printf("<invalid (0x%04X)>", static_cast< unsigned int >(flags));
128 void dumpType(typereg::Reader const & reader, OString const & indent) {
129 if (reader.isValid()) {
130 printf("version: %ld\n", static_cast< long >(reader.getVersion()));
131 printf("%sdocumentation: ", indent.getStr());
132 printString(reader.getDocumentation());
133 printf("\n");
134 printf("%sfile name: ", indent.getStr());
135 printString(reader.getFileName());
136 printf("\n");
137 printf("%stype class: ", indent.getStr());
138 if (reader.isPublished()) {
139 printf("published ");
141 switch (reader.getTypeClass()) {
142 case RT_TYPE_INTERFACE:
143 printf("interface");
144 break;
146 case RT_TYPE_MODULE:
147 printf("module");
148 break;
150 case RT_TYPE_STRUCT:
151 printf("struct");
152 break;
154 case RT_TYPE_ENUM:
155 printf("enum");
156 break;
158 case RT_TYPE_EXCEPTION:
159 printf("exception");
160 break;
162 case RT_TYPE_TYPEDEF:
163 printf("typedef");
164 break;
166 case RT_TYPE_SERVICE:
167 printf("service");
168 break;
170 case RT_TYPE_SINGLETON:
171 printf("singleton");
172 break;
174 case RT_TYPE_CONSTANTS:
175 printf("constants");
176 break;
178 default:
179 printf(
180 "<invalid (%ld)>", static_cast< long >(reader.getTypeClass()));
181 break;
183 printf("\n");
184 printf("%stype name: ", indent.getStr());
185 printString(reader.getTypeName());
186 printf("\n");
187 printf(
188 "%ssuper type count: %u\n", indent.getStr(),
189 static_cast< unsigned int >(reader.getSuperTypeCount()));
190 for (sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i) {
191 printf(
192 "%ssuper type name %u: ", indent.getStr(),
193 static_cast< unsigned int >(i));
194 printString(reader.getSuperTypeName(i));
195 printf("\n");
197 printf(
198 "%sfield count: %u\n", indent.getStr(),
199 static_cast< unsigned int >(reader.getFieldCount()));
200 for (sal_uInt16 i = 0; i < reader.getFieldCount(); ++i) {
201 printf(
202 "%sfield %u:\n", indent.getStr(),
203 static_cast< unsigned int >(i));
204 printf("%s documentation: ", indent.getStr());
205 printString(reader.getFieldDocumentation(i));
206 printf("\n");
207 printf("%s file name: ", indent.getStr());
208 printString(reader.getFieldFileName(i));
209 printf("\n");
210 printf("%s flags: ", indent.getStr());
211 printFieldOrReferenceFlags(reader.getFieldFlags(i));
212 printf("\n");
213 printf("%s name: ", indent.getStr());
214 printString(reader.getFieldName(i));
215 printf("\n");
216 printf("%s type name: ", indent.getStr());
217 printString(reader.getFieldTypeName(i));
218 printf("\n");
219 printf("%s value: ", indent.getStr());
220 RTConstValue value(reader.getFieldValue(i));
221 switch (value.m_type) {
222 case RT_TYPE_NONE:
223 printf("none");
224 break;
226 case RT_TYPE_BOOL:
227 printf("boolean %s", value.m_value.aBool ? "true" : "false");
228 break;
230 case RT_TYPE_BYTE:
231 printf("byte %d", static_cast< int >(value.m_value.aByte));
232 break;
234 case RT_TYPE_INT16:
235 printf("short %d", static_cast< int >(value.m_value.aShort));
236 break;
238 case RT_TYPE_UINT16:
239 printf(
240 "unsigned short %u",
241 static_cast< unsigned int >(value.m_value.aUShort));
242 break;
244 case RT_TYPE_INT32:
245 printf("long %ld", static_cast< long >(value.m_value.aLong));
246 break;
248 case RT_TYPE_UINT32:
249 printf(
250 "unsigned long %lu",
251 static_cast< unsigned long >(value.m_value.aULong));
252 break;
254 case RT_TYPE_INT64:
255 // TODO: no portable way to print hyper values
256 printf("hyper");
257 break;
259 case RT_TYPE_UINT64:
260 // TODO: no portable way to print unsigned hyper values
261 printf("unsigned hyper");
262 break;
264 case RT_TYPE_FLOAT:
265 // TODO: no portable way to print float values
266 printf("float");
267 break;
269 case RT_TYPE_DOUBLE:
270 // TODO: no portable way to print double values
271 printf("double");
272 break;
274 case RT_TYPE_STRING:
275 printf("string ");
276 printString(value.m_value.aString);
277 break;
279 default:
280 printf("<invalid (%ld)>", static_cast< long >(value.m_type));
281 break;
283 printf("\n");
285 printf(
286 "%smethod count: %u\n", indent.getStr(),
287 static_cast< unsigned int >(reader.getMethodCount()));
288 for (sal_uInt16 i = 0; i < reader.getMethodCount(); ++i) {
289 printf(
290 "%smethod %u:\n", indent.getStr(),
291 static_cast< unsigned int >(i));
292 printf("%s documentation: ", indent.getStr());
293 printString(reader.getMethodDocumentation(i));
294 printf("\n");
295 printf("%s flags: ", indent.getStr());
296 switch (reader.getMethodFlags(i)) {
297 case RTMethodMode::ONEWAY:
298 printf("oneway");
299 break;
301 case RTMethodMode::TWOWAY:
302 printf("synchronous");
303 break;
305 case RTMethodMode::ATTRIBUTE_GET:
306 printf("attribute get");
307 break;
309 case RTMethodMode::ATTRIBUTE_SET:
310 printf("attribute set");
311 break;
313 default:
314 printf(
315 "<invalid (%ld)>",
316 static_cast< long >(reader.getMethodFlags(i)));
317 break;
319 printf("\n");
320 printf("%s name: ", indent.getStr());
321 printString(reader.getMethodName(i));
322 printf("\n");
323 printf("%s return type name: ", indent.getStr());
324 printString(reader.getMethodReturnTypeName(i));
325 printf("\n");
326 printf(
327 "%s parameter count: %u\n", indent.getStr(),
328 static_cast< unsigned int >(reader.getMethodParameterCount(i)));
329 // coverity[tainted_data] cid#1215304 unhelpfully warns about an
330 // untrusted loop bound here:
331 for (sal_uInt16 j = 0; j < reader.getMethodParameterCount(i); ++j)
333 printf(
334 "%s parameter %u:\n", indent.getStr(),
335 static_cast< unsigned int >(j));
336 printf("%s flags: ", indent.getStr());
337 RTParamMode flags = reader.getMethodParameterFlags(i, j);
338 bool rest = (flags & RT_PARAM_REST) != 0;
339 switch (flags & ~RT_PARAM_REST) {
340 case RT_PARAM_IN:
341 printf("in");
342 break;
344 case RT_PARAM_OUT:
345 printf("out");
346 break;
348 case RT_PARAM_INOUT:
349 printf("inout");
350 break;
352 default:
353 printf("<invalid (%ld)>", static_cast< long >(flags));
354 rest = false;
355 break;
357 if (rest) {
358 printf("|rest");
360 printf("\n");
361 printf("%s name: ", indent.getStr());
362 printString(reader.getMethodParameterName(i, j));
363 printf("\n");
364 printf("%s type name: ", indent.getStr());
365 printString(reader.getMethodParameterTypeName(i, j));
366 printf("\n");
368 printf(
369 "%s exception count: %u\n", indent.getStr(),
370 static_cast< unsigned int >(reader.getMethodExceptionCount(i)));
371 // coverity[tainted_data] cid#1215304 unhelpfully warns about an
372 // untrusted loop bound here:
373 for (sal_uInt16 j = 0; j < reader.getMethodExceptionCount(i); ++j)
375 printf(
376 "%s exception type name %u: ", indent.getStr(),
377 static_cast< unsigned int >(j));
378 printString(reader.getMethodExceptionTypeName(i, j));
379 printf("\n");
382 printf(
383 "%sreference count: %u\n", indent.getStr(),
384 static_cast< unsigned int >(reader.getReferenceCount()));
385 for (sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i) {
386 printf(
387 "%sreference %u:\n", indent.getStr(),
388 static_cast< unsigned int >(i));
389 printf("%s documentation: ", indent.getStr());
390 printString(reader.getReferenceDocumentation(i));
391 printf("\n");
392 printf("%s flags: ", indent.getStr());
393 printFieldOrReferenceFlags(reader.getReferenceFlags(i));
394 printf("\n");
395 printf("%s sort: ", indent.getStr());
396 switch (reader.getReferenceSort(i)) {
397 case RTReferenceType::SUPPORTS:
398 printf("supports");
399 break;
401 case RTReferenceType::EXPORTS:
402 printf("exports");
403 break;
405 case RTReferenceType::TYPE_PARAMETER:
406 printf("type parameter");
407 break;
409 default:
410 printf(
411 "<invalid (%ld)>",
412 static_cast< long >(reader.getReferenceSort(i)));
413 break;
415 printf("\n");
416 printf("%s type name: ", indent.getStr());
417 printString(reader.getReferenceTypeName(i));
418 printf("\n");
420 } else {
421 printf("<invalid>\n");
428 // ORegistry()
430 ORegistry::ORegistry()
431 : m_refCount(1)
432 , m_readOnly(false)
433 , m_isOpen(false)
434 , ROOT( "/" )
439 // ~ORegistry()
441 ORegistry::~ORegistry()
443 ORegKey* pRootKey = m_openKeyTable[ROOT];
444 if (pRootKey != 0)
445 (void) releaseKey(pRootKey);
447 if (m_file.isValid())
448 m_file.close();
453 // initRegistry
455 RegError ORegistry::initRegistry(const OUString& regName, RegAccessMode accessMode, bool bCreate)
457 RegError eRet = RegError::INVALID_REGISTRY;
458 OStoreFile rRegFile;
459 storeAccessMode sAccessMode = REG_MODE_OPEN;
460 storeError errCode;
462 if (bCreate)
464 sAccessMode = REG_MODE_CREATE;
466 else if (accessMode & RegAccessMode::READONLY)
468 sAccessMode = REG_MODE_OPENREAD;
469 m_readOnly = true;
472 if (regName.isEmpty() &&
473 store_AccessCreate == sAccessMode)
475 errCode = rRegFile.createInMemory();
477 else
479 errCode = rRegFile.create(regName, sAccessMode, REG_PAGESIZE);
482 if (errCode)
484 switch (errCode)
486 case store_E_NotExists:
487 eRet = RegError::REGISTRY_NOT_EXISTS;
488 break;
489 case store_E_LockingViolation:
490 eRet = RegError::CANNOT_OPEN_FOR_READWRITE;
491 break;
492 default:
493 eRet = RegError::INVALID_REGISTRY;
494 break;
497 else
499 OStoreDirectory rStoreDir;
500 storeError _err = rStoreDir.create(rRegFile, OUString(), OUString(), sAccessMode);
502 if ( _err == store_E_None )
504 m_file = rRegFile;
505 m_name = regName;
506 m_isOpen = true;
508 m_openKeyTable[ROOT] = new ORegKey(ROOT, this);
509 eRet = RegError::NO_ERROR;
511 else
512 eRet = RegError::INVALID_REGISTRY;
515 return eRet;
520 // closeRegistry
522 RegError ORegistry::closeRegistry()
524 REG_GUARD(m_mutex);
526 if (m_file.isValid())
528 (void) releaseKey(m_openKeyTable[ROOT]);
529 m_file.close();
530 m_isOpen = false;
531 return RegError::NO_ERROR;
532 } else
534 return RegError::REGISTRY_NOT_EXISTS;
540 // destroyRegistry
542 RegError ORegistry::destroyRegistry(const OUString& regName)
544 REG_GUARD(m_mutex);
546 if (!regName.isEmpty())
548 std::unique_ptr<ORegistry> pReg(new ORegistry());
550 if (pReg->initRegistry(regName, RegAccessMode::READWRITE) == RegError::NO_ERROR)
552 pReg.reset();
554 OUString systemName;
555 if ( FileBase::getSystemPathFromFileURL(regName, systemName) != FileBase::E_None )
556 systemName = regName;
558 OString name( OUStringToOString(systemName, osl_getThreadTextEncoding()) );
559 if (unlink(name.getStr()) != 0)
561 return RegError::DESTROY_REGISTRY_FAILED;
563 } else
565 return RegError::DESTROY_REGISTRY_FAILED;
567 } else
569 if (m_refCount != 1 || isReadOnly())
571 return RegError::DESTROY_REGISTRY_FAILED;
574 if (m_file.isValid())
576 releaseKey(m_openKeyTable[ROOT]);
577 m_file.close();
578 m_isOpen = false;
580 if (!m_name.isEmpty())
582 OUString systemName;
583 if ( FileBase::getSystemPathFromFileURL(m_name, systemName) != FileBase::E_None )
584 systemName = m_name;
586 OString name( OUStringToOString(systemName, osl_getThreadTextEncoding()) );
587 if (unlink(name.getStr()) != 0)
589 return RegError::DESTROY_REGISTRY_FAILED;
592 } else
594 return RegError::REGISTRY_NOT_EXISTS;
598 return RegError::NO_ERROR;
602 // acquireKey
604 RegError ORegistry::acquireKey (RegKeyHandle hKey)
606 ORegKey* pKey = static_cast< ORegKey* >(hKey);
607 if (!pKey)
608 return RegError::INVALID_KEY;
610 REG_GUARD(m_mutex);
611 pKey->acquire();
613 return RegError::NO_ERROR;
617 // releaseKey
619 RegError ORegistry::releaseKey (RegKeyHandle hKey)
621 ORegKey* pKey = static_cast< ORegKey* >(hKey);
622 if (!pKey)
623 return RegError::INVALID_KEY;
625 REG_GUARD(m_mutex);
626 if (pKey->release() == 0)
628 m_openKeyTable.erase(pKey->getName());
629 delete pKey;
631 return RegError::NO_ERROR;
635 // createKey
637 RegError ORegistry::createKey(RegKeyHandle hKey, const OUString& keyName,
638 RegKeyHandle* phNewKey)
640 ORegKey* pKey;
642 *phNewKey = NULL;
644 if ( keyName.isEmpty() )
645 return RegError::INVALID_KEYNAME;
647 REG_GUARD(m_mutex);
649 if (hKey)
650 pKey = static_cast<ORegKey*>(hKey);
651 else
652 pKey = m_openKeyTable[ROOT];
654 OUString sFullKeyName = pKey->getFullPath(keyName);
656 if (m_openKeyTable.count(sFullKeyName) > 0)
658 *phNewKey = m_openKeyTable[sFullKeyName];
659 static_cast<ORegKey*>(*phNewKey)->acquire();
660 static_cast<ORegKey*>(*phNewKey)->setDeleted(false);
661 return RegError::NO_ERROR;
664 OStoreDirectory rStoreDir;
665 OUStringBuffer sFullPath(sFullKeyName.getLength());
666 OUString token;
668 sFullPath.append('/');
670 sal_Int32 nIndex = 0;
673 token = sFullKeyName.getToken( 0, '/', nIndex );
674 if (!token.isEmpty())
676 if (rStoreDir.create(pKey->getStoreFile(), sFullPath.getStr(), token, KEY_MODE_CREATE))
678 return RegError::CREATE_KEY_FAILED;
681 sFullPath.append(token);
682 sFullPath.append('/');
684 } while( nIndex != -1 );
687 pKey = new ORegKey(sFullKeyName, this);
688 *phNewKey = pKey;
689 m_openKeyTable[sFullKeyName] = pKey;
691 return RegError::NO_ERROR;
696 // openKey
698 RegError ORegistry::openKey(RegKeyHandle hKey, const OUString& keyName,
699 RegKeyHandle* phOpenKey)
701 ORegKey* pKey;
703 *phOpenKey = NULL;
705 if ( keyName.isEmpty() )
707 return RegError::INVALID_KEYNAME;
710 REG_GUARD(m_mutex);
712 if (hKey)
713 pKey = static_cast<ORegKey*>(hKey);
714 else
715 pKey = m_openKeyTable[ROOT];
717 OUString path(pKey->getFullPath(keyName));
718 KeyMap::iterator i(m_openKeyTable.find(path));
719 if (i == m_openKeyTable.end()) {
720 sal_Int32 n = path.lastIndexOf('/') + 1;
721 switch (OStoreDirectory().create(
722 pKey->getStoreFile(), path.copy(0, n), path.copy(n),
723 isReadOnly() ? KEY_MODE_OPENREAD : KEY_MODE_OPEN))
725 case store_E_NotExists:
726 return RegError::KEY_NOT_EXISTS;
727 case store_E_WrongFormat:
728 return RegError::INVALID_KEY;
729 default:
730 break;
733 std::unique_ptr< ORegKey > p(new ORegKey(path, this));
734 i = m_openKeyTable.insert(std::make_pair(path, p.get())).first;
735 p.release();
736 } else {
737 i->second->acquire();
739 *phOpenKey = i->second;
740 return RegError::NO_ERROR;
745 // closeKey
747 RegError ORegistry::closeKey(RegKeyHandle hKey)
749 ORegKey* pKey = static_cast< ORegKey* >(hKey);
751 REG_GUARD(m_mutex);
753 OUString const aKeyName (pKey->getName());
754 if (!(m_openKeyTable.count(aKeyName) > 0))
755 return RegError::KEY_NOT_OPEN;
757 if (pKey->isModified())
759 ORegKey * pRootKey = getRootKey();
760 if (pKey != pRootKey)
762 // propagate "modified" state to RootKey.
763 pRootKey->setModified();
765 else
767 // closing modified RootKey, flush registry file.
768 OSL_TRACE("registry::ORegistry::closeKey(): flushing modified RootKey");
769 (void) m_file.flush();
771 pKey->setModified(false);
772 (void) releaseKey(pRootKey);
775 return releaseKey(pKey);
779 // deleteKey
781 RegError ORegistry::deleteKey(RegKeyHandle hKey, const OUString& keyName)
783 ORegKey* pKey = static_cast< ORegKey* >(hKey);
784 if ( keyName.isEmpty() )
785 return RegError::INVALID_KEYNAME;
787 REG_GUARD(m_mutex);
789 if (!pKey)
790 pKey = m_openKeyTable[ROOT];
792 OUString sFullKeyName(pKey->getFullPath(keyName));
793 return eraseKey(m_openKeyTable[ROOT], sFullKeyName);
796 RegError ORegistry::eraseKey(ORegKey* pKey, const OUString& keyName)
798 RegError _ret = RegError::NO_ERROR;
800 if ( keyName.isEmpty() )
802 return RegError::INVALID_KEYNAME;
805 OUString sFullKeyName(pKey->getName());
806 OUString sFullPath(sFullKeyName);
807 OUString sRelativKey;
808 sal_Int32 lastIndex = keyName.lastIndexOf('/');
810 if ( lastIndex >= 0 )
812 sRelativKey += keyName.copy(lastIndex + 1);
814 if (sFullKeyName.getLength() > 1)
815 sFullKeyName += keyName;
816 else
817 sFullKeyName += keyName.copy(1);
819 sFullPath = sFullKeyName.copy(0, keyName.lastIndexOf('/') + 1);
820 } else
822 if (sFullKeyName.getLength() > 1)
823 sFullKeyName += ROOT;
825 sRelativKey += keyName;
826 sFullKeyName += keyName;
828 if (sFullPath.getLength() > 1)
829 sFullPath += ROOT;
832 ORegKey* pOldKey = 0;
833 _ret = pKey->openKey(keyName, reinterpret_cast<RegKeyHandle*>(&pOldKey));
834 if (_ret != RegError::NO_ERROR)
835 return _ret;
837 _ret = deleteSubkeysAndValues(pOldKey);
838 if (_ret != RegError::NO_ERROR)
840 pKey->closeKey(pOldKey);
841 return _ret;
844 OUString tmpName(sRelativKey);
845 tmpName += ROOT;
847 OStoreFile sFile(pKey->getStoreFile());
848 if ( sFile.isValid() && sFile.remove(sFullPath, tmpName) )
850 return RegError::DELETE_KEY_FAILED;
852 pOldKey->setModified();
854 // set flag deleted !!!
855 pOldKey->setDeleted(true);
857 return pKey->closeKey(pOldKey);
861 // deleteSubKeysAndValues
863 RegError ORegistry::deleteSubkeysAndValues(ORegKey* pKey)
865 OStoreDirectory::iterator iter;
866 RegError _ret = RegError::NO_ERROR;
867 OStoreDirectory rStoreDir(pKey->getStoreDir());
868 storeError _err = rStoreDir.first(iter);
870 while ( _err == store_E_None )
872 OUString const keyName = iter.m_pszName;
874 if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
876 _ret = eraseKey(pKey, keyName);
877 if (_ret != RegError::NO_ERROR)
878 return _ret;
880 else
882 OUString sFullPath(pKey->getName());
884 if (sFullPath.getLength() > 1)
885 sFullPath += ROOT;
887 if ( ((OStoreFile&)pKey->getStoreFile()).remove(sFullPath, keyName) )
889 return RegError::DELETE_VALUE_FAILED;
891 pKey->setModified();
894 _err = rStoreDir.next(iter);
897 return RegError::NO_ERROR;
902 // loadKey
904 RegError ORegistry::loadKey(RegKeyHandle hKey, const OUString& regFileName,
905 bool bWarnings, bool bReport)
907 RegError _ret = RegError::NO_ERROR;
908 ORegKey* pKey = static_cast< ORegKey* >(hKey);
910 std::unique_ptr< ORegistry > pReg (new ORegistry());
911 _ret = pReg->initRegistry(regFileName, RegAccessMode::READONLY);
912 if (_ret != RegError::NO_ERROR)
913 return _ret;
914 ORegKey* pRootKey = pReg->getRootKey();
916 REG_GUARD(m_mutex);
918 OStoreDirectory::iterator iter;
919 OStoreDirectory rStoreDir(pRootKey->getStoreDir());
920 storeError _err = rStoreDir.first(iter);
922 while ( _err == store_E_None )
924 OUString const keyName = iter.m_pszName;
926 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
928 _ret = loadAndSaveKeys(pKey, pRootKey, keyName, 0, bWarnings, bReport);
930 else
932 _ret = loadAndSaveValue(pKey, pRootKey, keyName, 0, bWarnings, bReport);
935 if (_ret == RegError::MERGE_ERROR)
936 break;
937 if (_ret == RegError::MERGE_CONFLICT && bWarnings)
938 break;
940 _err = rStoreDir.next(iter);
943 rStoreDir = OStoreDirectory();
944 (void) pReg->releaseKey(pRootKey);
945 return _ret;
950 // saveKey
952 RegError ORegistry::saveKey(RegKeyHandle hKey, const OUString& regFileName,
953 bool bWarnings, bool bReport)
955 RegError _ret = RegError::NO_ERROR;
956 ORegKey* pKey = static_cast< ORegKey* >(hKey);
958 std::unique_ptr< ORegistry > pReg (new ORegistry());
959 _ret = pReg->initRegistry(regFileName, RegAccessMode::READWRITE, true/*bCreate*/);
960 if (_ret != RegError::NO_ERROR)
961 return _ret;
962 ORegKey* pRootKey = pReg->getRootKey();
964 REG_GUARD(m_mutex);
966 OStoreDirectory::iterator iter;
967 OStoreDirectory rStoreDir(pKey->getStoreDir());
968 storeError _err = rStoreDir.first(iter);
970 while ( _err == store_E_None )
972 OUString const keyName = iter.m_pszName;
974 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
976 _ret = loadAndSaveKeys(pRootKey, pKey, keyName,
977 pKey->getName().getLength(),
978 bWarnings, bReport);
980 else
982 _ret = loadAndSaveValue(pRootKey, pKey, keyName,
983 pKey->getName().getLength(),
984 bWarnings, bReport);
987 if (_ret != RegError::NO_ERROR)
988 break;
990 _err = rStoreDir.next(iter);
993 (void) pReg->releaseKey(pRootKey);
994 return _ret;
999 // loadAndSaveValue()
1001 RegError ORegistry::loadAndSaveValue(ORegKey* pTargetKey,
1002 ORegKey* pSourceKey,
1003 const OUString& valueName,
1004 sal_uInt32 nCut,
1005 bool bWarnings,
1006 bool bReport)
1008 OStoreStream rValue;
1009 sal_uInt8* pBuffer;
1010 RegValueType valueType;
1011 sal_uInt32 valueSize;
1012 sal_uInt32 nSize;
1013 storeAccessMode sourceAccess = VALUE_MODE_OPEN;
1014 OUString sTargetPath(pTargetKey->getName());
1015 OUString sSourcePath(pSourceKey->getName());
1017 if (pSourceKey->isReadOnly())
1019 sourceAccess = VALUE_MODE_OPENREAD;
1022 if (nCut)
1024 sTargetPath = sSourcePath.copy(nCut);
1025 } else
1027 if (sTargetPath.getLength() > 1)
1029 if (sSourcePath.getLength() > 1)
1030 sTargetPath += sSourcePath;
1031 } else
1032 sTargetPath = sSourcePath;
1035 if (sTargetPath.getLength() > 1) sTargetPath += ROOT;
1036 if (sSourcePath.getLength() > 1) sSourcePath += ROOT;
1038 if (rValue.create(pSourceKey->getStoreFile(), sSourcePath, valueName, sourceAccess))
1040 return RegError::VALUE_NOT_EXISTS;
1043 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(VALUE_HEADERSIZE));
1045 sal_uInt32 rwBytes;
1046 if (rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes))
1048 rtl_freeMemory(pBuffer);
1049 return RegError::INVALID_VALUE;
1051 if (rwBytes != VALUE_HEADERSIZE)
1053 rtl_freeMemory(pBuffer);
1054 return RegError::INVALID_VALUE;
1057 RegError _ret = RegError::NO_ERROR;
1058 sal_uInt8 type = *pBuffer;
1059 valueType = (RegValueType)type;
1060 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
1061 rtl_freeMemory(pBuffer);
1063 nSize = VALUE_HEADERSIZE + valueSize;
1064 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(nSize));
1066 if (rValue.readAt(0, pBuffer, nSize, rwBytes))
1068 rtl_freeMemory(pBuffer);
1069 return RegError::INVALID_VALUE;
1071 if (rwBytes != nSize)
1073 rtl_freeMemory(pBuffer);
1074 return RegError::INVALID_VALUE;
1077 OStoreFile rTargetFile(pTargetKey->getStoreFile());
1079 if (!rValue.create(rTargetFile, sTargetPath, valueName, VALUE_MODE_OPEN))
1081 if (valueType == RegValueType::BINARY)
1083 _ret = checkBlop(
1084 rValue, sTargetPath, valueSize, pBuffer+VALUE_HEADEROFFSET,
1085 bReport);
1086 if (_ret != RegError::NO_ERROR)
1088 if (_ret == RegError::MERGE_ERROR ||
1089 (_ret == RegError::MERGE_CONFLICT && bWarnings))
1091 rtl_freeMemory(pBuffer);
1092 return _ret;
1094 } else
1096 rtl_freeMemory(pBuffer);
1097 return _ret;
1102 // write
1103 if (rValue.create(rTargetFile, sTargetPath, valueName, VALUE_MODE_CREATE))
1105 rtl_freeMemory(pBuffer);
1106 return RegError::INVALID_VALUE;
1108 if (rValue.writeAt(0, pBuffer, nSize, rwBytes))
1110 rtl_freeMemory(pBuffer);
1111 return RegError::INVALID_VALUE;
1114 if (rwBytes != nSize)
1116 rtl_freeMemory(pBuffer);
1117 return RegError::INVALID_VALUE;
1119 pTargetKey->setModified();
1121 rtl_freeMemory(pBuffer);
1122 return _ret;
1127 // checkblop()
1129 RegError ORegistry::checkBlop(OStoreStream& rValue,
1130 const OUString& sTargetPath,
1131 sal_uInt32 srcValueSize,
1132 sal_uInt8* pSrcBuffer,
1133 bool bReport)
1135 RegistryTypeReader reader(pSrcBuffer, srcValueSize, false);
1137 if (reader.getTypeClass() == RT_TYPE_INVALID)
1139 return RegError::INVALID_VALUE;
1142 sal_uInt8* pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(VALUE_HEADERSIZE));
1143 RegValueType valueType;
1144 sal_uInt32 valueSize;
1145 sal_uInt32 rwBytes;
1146 OString targetPath( OUStringToOString(sTargetPath, RTL_TEXTENCODING_UTF8) );
1148 if (!rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes) &&
1149 (rwBytes == VALUE_HEADERSIZE))
1151 sal_uInt8 type = *pBuffer;
1152 valueType = (RegValueType)type;
1153 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
1154 rtl_freeMemory(pBuffer);
1156 if (valueType == RegValueType::BINARY)
1158 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(valueSize));
1159 if (!rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, rwBytes) &&
1160 (rwBytes == valueSize))
1162 RegistryTypeReader reader2(pBuffer, valueSize, false);
1164 if ((reader.getTypeClass() != reader2.getTypeClass())
1165 || reader2.getTypeClass() == RT_TYPE_INVALID)
1167 rtl_freeMemory(pBuffer);
1169 if (bReport)
1171 fprintf(stdout, "ERROR: values of blop from key \"%s\" has different types.\n",
1172 targetPath.getStr());
1174 return RegError::MERGE_ERROR;
1177 if (reader.getTypeClass() == RT_TYPE_MODULE)
1179 if (reader.getFieldCount() > 0 &&
1180 reader2.getFieldCount() > 0)
1182 mergeModuleValue(rValue, reader, reader2);
1184 rtl_freeMemory(pBuffer);
1185 return RegError::NO_ERROR;
1186 } else
1187 if (reader2.getFieldCount() > 0)
1189 rtl_freeMemory(pBuffer);
1190 return RegError::NO_ERROR;
1191 } else
1193 rtl_freeMemory(pBuffer);
1194 return RegError::MERGE_CONFLICT;
1196 } else
1198 rtl_freeMemory(pBuffer);
1200 if (bReport)
1202 fprintf(stderr, "WARNING: value of key \"%s\" already exists.\n",
1203 targetPath.getStr());
1205 return RegError::MERGE_CONFLICT;
1207 } else
1209 rtl_freeMemory(pBuffer);
1210 if (bReport)
1212 fprintf(stderr, "ERROR: values of key \"%s\" contains bad data.\n",
1213 targetPath.getStr());
1215 return RegError::MERGE_ERROR;
1217 } else
1219 rtl_freeMemory(pBuffer);
1220 if (bReport)
1222 fprintf(stderr, "ERROR: values of key \"%s\" has different types.\n",
1223 targetPath.getStr());
1225 return RegError::MERGE_ERROR;
1227 } else
1229 rtl_freeMemory(pBuffer);
1230 return RegError::INVALID_VALUE;
1234 static sal_uInt32 checkTypeReaders(RegistryTypeReader& reader1,
1235 RegistryTypeReader& reader2,
1236 std::set< OUString >& nameSet)
1238 sal_uInt32 count=0;
1239 sal_uInt16 i;
1240 for (i=0 ; i < reader1.getFieldCount(); i++)
1242 nameSet.insert(reader1.getFieldName(i));
1243 count++;
1245 for (i=0 ; i < reader2.getFieldCount(); i++)
1247 if (nameSet.find(reader2.getFieldName(i)) == nameSet.end())
1249 nameSet.insert(reader2.getFieldName(i));
1250 count++;
1253 return count;
1257 // mergeModuleValue()
1259 RegError ORegistry::mergeModuleValue(OStoreStream& rTargetValue,
1260 RegistryTypeReader& reader,
1261 RegistryTypeReader& reader2)
1263 std::set< OUString > nameSet;
1264 sal_uInt32 count = checkTypeReaders(reader, reader2, nameSet);
1266 if (count != reader.getFieldCount())
1268 sal_uInt16 index = 0;
1270 RegistryTypeWriter writer(reader.getTypeClass(),
1271 reader.getTypeName(),
1272 reader.getSuperTypeName(),
1273 (sal_uInt16)count,
1277 for (sal_uInt16 i=0 ; i < reader.getFieldCount(); i++)
1279 writer.setFieldData(index,
1280 reader.getFieldName(i),
1281 reader.getFieldType(i),
1282 reader.getFieldDoku(i),
1283 reader.getFieldFileName(i),
1284 reader.getFieldAccess(i),
1285 reader.getFieldConstValue(i));
1286 index++;
1288 for (sal_uInt16 i=0 ; i < reader2.getFieldCount(); i++)
1290 if (nameSet.find(reader2.getFieldName(i)) == nameSet.end())
1292 writer.setFieldData(index,
1293 reader2.getFieldName(i),
1294 reader2.getFieldType(i),
1295 reader2.getFieldDoku(i),
1296 reader2.getFieldFileName(i),
1297 reader2.getFieldAccess(i),
1298 reader2.getFieldConstValue(i));
1299 index++;
1303 const sal_uInt8* pBlop = writer.getBlop();
1304 sal_uInt32 aBlopSize = writer.getBlopSize();
1306 sal_uInt8 type = (sal_uInt8)RegValueType::BINARY;
1307 sal_uInt8* pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(VALUE_HEADERSIZE + aBlopSize));
1309 memcpy(pBuffer, &type, 1);
1310 writeUINT32(pBuffer+VALUE_TYPEOFFSET, aBlopSize);
1311 memcpy(pBuffer+VALUE_HEADEROFFSET, pBlop, aBlopSize);
1313 sal_uInt32 rwBytes;
1314 if (rTargetValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+aBlopSize, rwBytes))
1316 rtl_freeMemory(pBuffer);
1317 return RegError::INVALID_VALUE;
1320 if (rwBytes != VALUE_HEADERSIZE+aBlopSize)
1322 rtl_freeMemory(pBuffer);
1323 return RegError::INVALID_VALUE;
1326 rtl_freeMemory(pBuffer);
1328 return RegError::NO_ERROR;
1332 // loadAndSaveKeys()
1334 RegError ORegistry::loadAndSaveKeys(ORegKey* pTargetKey,
1335 ORegKey* pSourceKey,
1336 const OUString& keyName,
1337 sal_uInt32 nCut,
1338 bool bWarnings,
1339 bool bReport)
1341 RegError _ret = RegError::NO_ERROR;
1342 OUString sRelPath(pSourceKey->getName().copy(nCut));
1343 OUString sFullPath;
1345 if(pTargetKey->getName().getLength() > 1)
1346 sFullPath += pTargetKey->getName();
1347 sFullPath += sRelPath;
1348 if (sRelPath.getLength() > 1 || sFullPath.isEmpty())
1349 sFullPath += ROOT;
1351 OUString sFullKeyName = sFullPath;
1352 sFullKeyName += keyName;
1354 OStoreDirectory rStoreDir;
1355 if (rStoreDir.create(pTargetKey->getStoreFile(), sFullPath, keyName, KEY_MODE_CREATE))
1357 return RegError::CREATE_KEY_FAILED;
1360 if (m_openKeyTable.count(sFullKeyName) > 0)
1362 m_openKeyTable[sFullKeyName]->setDeleted(false);
1365 ORegKey* pTmpKey = 0;
1366 _ret = pSourceKey->openKey(keyName, reinterpret_cast<RegKeyHandle*>(&pTmpKey));
1367 if (_ret != RegError::NO_ERROR)
1368 return _ret;
1370 OStoreDirectory::iterator iter;
1371 OStoreDirectory rTmpStoreDir(pTmpKey->getStoreDir());
1372 storeError _err = rTmpStoreDir.first(iter);
1374 while ( _err == store_E_None)
1376 OUString const sName = iter.m_pszName;
1378 if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
1380 _ret = loadAndSaveKeys(pTargetKey, pTmpKey,
1381 sName, nCut, bWarnings, bReport);
1382 } else
1384 _ret = loadAndSaveValue(pTargetKey, pTmpKey,
1385 sName, nCut, bWarnings, bReport);
1388 if (_ret == RegError::MERGE_ERROR)
1389 break;
1390 if (_ret == RegError::MERGE_CONFLICT && bWarnings)
1391 break;
1393 _err = rTmpStoreDir.next(iter);
1396 pSourceKey->releaseKey(pTmpKey);
1397 return _ret;
1402 // getRootKey()
1404 ORegKey* ORegistry::getRootKey()
1406 m_openKeyTable[ROOT]->acquire();
1407 return m_openKeyTable[ROOT];
1412 // dumpRegistry()
1414 RegError ORegistry::dumpRegistry(RegKeyHandle hKey) const
1416 ORegKey *pKey = static_cast<ORegKey*>(hKey);
1417 OUString sName;
1418 RegError _ret = RegError::NO_ERROR;
1419 OStoreDirectory::iterator iter;
1420 OStoreDirectory rStoreDir(pKey->getStoreDir());
1421 storeError _err = rStoreDir.first(iter);
1423 OString regName( OUStringToOString( getName(), osl_getThreadTextEncoding() ) );
1424 OString keyName( OUStringToOString( pKey->getName(), RTL_TEXTENCODING_UTF8 ) );
1425 fprintf(stdout, "Registry \"%s\":\n\n%s\n", regName.getStr(), keyName.getStr());
1427 while ( _err == store_E_None )
1429 sName = iter.m_pszName;
1431 if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
1433 _ret = dumpKey(pKey->getName(), sName, 1);
1434 } else
1436 _ret = dumpValue(pKey->getName(), sName, 1);
1439 if (_ret != RegError::NO_ERROR)
1441 return _ret;
1444 _err = rStoreDir.next(iter);
1447 return RegError::NO_ERROR;
1451 // dumpValue()
1453 RegError ORegistry::dumpValue(const OUString& sPath, const OUString& sName, sal_Int16 nSpc) const
1455 OStoreStream rValue;
1456 sal_uInt8* pBuffer;
1457 sal_uInt32 valueSize;
1458 RegValueType valueType;
1459 OUString sFullPath(sPath);
1460 OString sIndent;
1461 storeAccessMode accessMode = VALUE_MODE_OPEN;
1463 if (isReadOnly())
1465 accessMode = VALUE_MODE_OPENREAD;
1468 for (int i= 0; i < nSpc; i++) sIndent += " ";
1470 if (sFullPath.getLength() > 1)
1472 sFullPath += ROOT;
1474 if (rValue.create(m_file, sFullPath, sName, accessMode))
1476 return RegError::VALUE_NOT_EXISTS;
1479 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(VALUE_HEADERSIZE));
1481 sal_uInt32 rwBytes;
1482 if (rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes))
1484 rtl_freeMemory(pBuffer);
1485 return RegError::INVALID_VALUE;
1487 if (rwBytes != (VALUE_HEADERSIZE))
1489 rtl_freeMemory(pBuffer);
1490 return RegError::INVALID_VALUE;
1493 sal_uInt8 type = *pBuffer;
1494 valueType = (RegValueType)type;
1495 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
1497 pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory(valueSize));
1498 if (rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, rwBytes))
1500 rtl_freeMemory(pBuffer);
1501 return RegError::INVALID_VALUE;
1503 if (rwBytes != valueSize)
1505 rtl_freeMemory(pBuffer);
1506 return RegError::INVALID_VALUE;
1509 const sal_Char* indent = sIndent.getStr();
1510 switch (valueType)
1512 case RegValueType::NOT_DEFINED:
1513 fprintf(stdout, "%sValue: Type = VALUETYPE_NOT_DEFINED\n", indent);
1514 break;
1515 case RegValueType::LONG:
1517 fprintf(stdout, "%sValue: Type = RegValueType::LONG\n", indent);
1518 fprintf(
1519 stdout, "%s Size = %lu\n", indent,
1520 sal::static_int_cast< unsigned long >(valueSize));
1521 fprintf(stdout, "%s Data = ", indent);
1523 sal_Int32 value;
1524 readINT32(pBuffer, value);
1525 fprintf(stdout, "%ld\n", sal::static_int_cast< long >(value));
1527 break;
1528 case RegValueType::STRING:
1530 sal_Char* value = static_cast<sal_Char*>(rtl_allocateMemory(valueSize));
1531 readUtf8(pBuffer, value, valueSize);
1532 fprintf(stdout, "%sValue: Type = RegValueType::STRING\n", indent);
1533 fprintf(
1534 stdout, "%s Size = %lu\n", indent,
1535 sal::static_int_cast< unsigned long >(valueSize));
1536 fprintf(stdout, "%s Data = \"%s\"\n", indent, value);
1537 rtl_freeMemory(value);
1539 break;
1540 case RegValueType::UNICODE:
1542 sal_uInt32 size = (valueSize / 2) * sizeof(sal_Unicode);
1543 fprintf(stdout, "%sValue: Type = RegValueType::UNICODE\n", indent);
1544 fprintf(
1545 stdout, "%s Size = %lu\n", indent,
1546 sal::static_int_cast< unsigned long >(valueSize));
1547 fprintf(stdout, "%s Data = ", indent);
1549 sal_Unicode* value = new sal_Unicode[size];
1550 readString(pBuffer, value, size);
1552 OString uStr = OUStringToOString(value, RTL_TEXTENCODING_UTF8);
1553 fprintf(stdout, "L\"%s\"\n", uStr.getStr());
1554 delete[] value;
1556 break;
1557 case RegValueType::BINARY:
1559 fprintf(stdout, "%sValue: Type = RegValueType::BINARY\n", indent);
1560 fprintf(
1561 stdout, "%s Size = %lu\n", indent,
1562 sal::static_int_cast< unsigned long >(valueSize));
1563 fprintf(stdout, "%s Data = ", indent);
1564 dumpType(
1565 typereg::Reader(
1566 pBuffer, valueSize, false, TYPEREG_VERSION_1),
1567 sIndent + " ");
1569 break;
1570 case RegValueType::LONGLIST:
1572 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array
1573 sal_uInt32 len = 0;
1575 readUINT32(pBuffer, len);
1577 fprintf(stdout, "%sValue: Type = RegValueType::LONGLIST\n", indent);
1578 fprintf(
1579 stdout, "%s Size = %lu\n", indent,
1580 sal::static_int_cast< unsigned long >(valueSize));
1581 fprintf(
1582 stdout, "%s Len = %lu\n", indent,
1583 sal::static_int_cast< unsigned long >(len));
1584 fprintf(stdout, "%s Data = ", indent);
1586 sal_Int32 longValue;
1587 for (sal_uInt32 i=0; i < len; i++)
1589 readINT32(pBuffer+offset, longValue);
1591 if (offset > 4)
1592 fprintf(stdout, "%s ", indent);
1594 fprintf(
1595 stdout, "%lu = %ld\n",
1596 sal::static_int_cast< unsigned long >(i),
1597 sal::static_int_cast< long >(longValue));
1598 offset += 4; // 4 Bytes fuer sal_Int32
1601 break;
1602 case RegValueType::STRINGLIST:
1604 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array
1605 sal_uInt32 sLen = 0;
1606 sal_uInt32 len = 0;
1608 readUINT32(pBuffer, len);
1610 fprintf(stdout, "%sValue: Type = RegValueType::STRINGLIST\n", indent);
1611 fprintf(
1612 stdout, "%s Size = %lu\n", indent,
1613 sal::static_int_cast< unsigned long >(valueSize));
1614 fprintf(
1615 stdout, "%s Len = %lu\n", indent,
1616 sal::static_int_cast< unsigned long >(len));
1617 fprintf(stdout, "%s Data = ", indent);
1619 for (sal_uInt32 i=0; i < len; i++)
1621 readUINT32(pBuffer+offset, sLen);
1623 offset += 4; // 4 Bytes (sal_uInt32) fuer die Groesse des strings in Bytes
1625 sal_Char *pValue = static_cast<sal_Char*>(rtl_allocateMemory(sLen));
1626 readUtf8(pBuffer+offset, pValue, sLen);
1628 if (offset > 8)
1629 fprintf(stdout, "%s ", indent);
1631 fprintf(
1632 stdout, "%lu = \"%s\"\n",
1633 sal::static_int_cast< unsigned long >(i), pValue);
1634 rtl_freeMemory(pValue);
1635 offset += sLen;
1638 break;
1639 case RegValueType::UNICODELIST:
1641 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array
1642 sal_uInt32 sLen = 0;
1643 sal_uInt32 len = 0;
1645 readUINT32(pBuffer, len);
1647 fprintf(stdout, "%sValue: Type = RegValueType::UNICODELIST\n", indent);
1648 fprintf(
1649 stdout, "%s Size = %lu\n", indent,
1650 sal::static_int_cast< unsigned long >(valueSize));
1651 fprintf(
1652 stdout, "%s Len = %lu\n", indent,
1653 sal::static_int_cast< unsigned long >(len));
1654 fprintf(stdout, "%s Data = ", indent);
1656 OString uStr;
1657 for (sal_uInt32 i=0; i < len; i++)
1659 readUINT32(pBuffer+offset, sLen);
1661 offset += 4; // 4 Bytes (sal_uInt32) fuer die Groesse des strings in Bytes
1663 sal_Unicode *pValue = static_cast<sal_Unicode*>(rtl_allocateMemory((sLen / 2) * sizeof(sal_Unicode)));
1664 readString(pBuffer+offset, pValue, sLen);
1666 if (offset > 8)
1667 fprintf(stdout, "%s ", indent);
1669 uStr = OUStringToOString(pValue, RTL_TEXTENCODING_UTF8);
1670 fprintf(
1671 stdout, "%lu = L\"%s\"\n",
1672 sal::static_int_cast< unsigned long >(i),
1673 uStr.getStr());
1675 offset += sLen;
1677 rtl_freeMemory(pValue);
1680 break;
1683 fprintf(stdout, "\n");
1685 rtl_freeMemory(pBuffer);
1686 return RegError::NO_ERROR;
1690 // dumpKey()
1692 RegError ORegistry::dumpKey(const OUString& sPath, const OUString& sName, sal_Int16 nSpace) const
1694 OStoreDirectory rStoreDir;
1695 OUString sFullPath(sPath);
1696 OString sIndent;
1697 storeAccessMode accessMode = KEY_MODE_OPEN;
1698 RegError _ret = RegError::NO_ERROR;
1700 if (isReadOnly())
1702 accessMode = KEY_MODE_OPENREAD;
1705 for (int i= 0; i < nSpace; i++) sIndent += " ";
1707 if (sFullPath.getLength() > 1)
1708 sFullPath += ROOT;
1710 storeError _err = rStoreDir.create(m_file, sFullPath, sName, accessMode);
1712 if (_err == store_E_NotExists)
1713 return RegError::KEY_NOT_EXISTS;
1714 else if (_err == store_E_WrongFormat)
1715 return RegError::INVALID_KEY;
1717 fprintf(stdout, "%s/ %s\n", sIndent.getStr(), OUStringToOString(sName, RTL_TEXTENCODING_UTF8).getStr());
1719 OUString sSubPath(sFullPath);
1720 OUString sSubName;
1721 sSubPath += sName;
1723 OStoreDirectory::iterator iter;
1725 _err = rStoreDir.first(iter);
1727 while ( _err == store_E_None)
1729 sSubName = iter.m_pszName;
1731 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
1733 _ret = dumpKey(sSubPath, sSubName, nSpace+2);
1734 } else
1736 _ret = dumpValue(sSubPath, sSubName, nSpace+2);
1739 if (_ret != RegError::NO_ERROR)
1741 return _ret;
1744 _err = rStoreDir.next(iter);
1747 return RegError::NO_ERROR;
1750 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */