tdf#151548 ContentControls: Add Delete()
[LibreOffice.git] / registry / source / regimpl.cxx
blob5f5bf335edb4f81a3b5dd049130066585b8d8f80
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 <cstddef>
24 #include <memory>
25 #include <set>
26 #include <string_view>
27 #include <vector>
28 #include <string.h>
29 #include <stdio.h>
31 #if defined(UNX)
32 #include <unistd.h>
33 #endif
35 #include <registry/reader.hxx>
36 #include <registry/refltype.hxx>
37 #include <registry/types.hxx>
39 #include "reflcnst.hxx"
40 #include "keyimpl.hxx"
42 #include <osl/thread.h>
43 #include <rtl/ustring.hxx>
44 #include <rtl/ustrbuf.hxx>
45 #include <osl/file.hxx>
47 using namespace osl;
48 using namespace store;
51 namespace {
53 void printString(std::u16string_view s) {
54 printf("\"");
55 for (std::size_t i = 0; i < s.size(); ++i) {
56 sal_Unicode c = s[i];
57 if (c == '"' || c == '\\') {
58 printf("\\%c", static_cast< char >(c));
59 } else if (s[i] >= ' ' && s[i] <= '~') {
60 printf("%c", static_cast< char >(c));
61 } else {
62 printf("\\u%04X", static_cast< unsigned int >(c));
65 printf("\"");
68 void printFieldOrReferenceFlag(
69 RTFieldAccess * flags, RTFieldAccess flag, char const * name, bool * first)
71 if ((*flags & flag) != RTFieldAccess::NONE) {
72 if (!*first) {
73 printf("|");
75 *first = false;
76 printf("%s", name);
77 *flags &= ~flag;
81 void printFieldOrReferenceFlags(RTFieldAccess flags) {
82 if (flags == RTFieldAccess::NONE) {
83 printf("none");
84 } else {
85 bool first = true;
86 printFieldOrReferenceFlag(
87 &flags, RTFieldAccess::READONLY, "readonly", &first);
88 printFieldOrReferenceFlag(
89 &flags, RTFieldAccess::OPTIONAL, "optional", &first);
90 printFieldOrReferenceFlag(
91 &flags, RTFieldAccess::MAYBEVOID, "maybevoid", &first);
92 printFieldOrReferenceFlag(&flags, RTFieldAccess::BOUND, "bound", &first);
93 printFieldOrReferenceFlag(
94 &flags, RTFieldAccess::CONSTRAINED, "constrained", &first);
95 printFieldOrReferenceFlag(
96 &flags, RTFieldAccess::TRANSIENT, "transient", &first);
97 printFieldOrReferenceFlag(
98 &flags, RTFieldAccess::MAYBEAMBIGUOUS, "maybeambiguous", &first);
99 printFieldOrReferenceFlag(
100 &flags, RTFieldAccess::MAYBEDEFAULT, "maybedefault", &first);
101 printFieldOrReferenceFlag(
102 &flags, RTFieldAccess::REMOVABLE, "removable", &first);
103 printFieldOrReferenceFlag(
104 &flags, RTFieldAccess::ATTRIBUTE, "attribute", &first);
105 printFieldOrReferenceFlag(
106 &flags, RTFieldAccess::PROPERTY, "property", &first);
107 printFieldOrReferenceFlag(&flags, RTFieldAccess::CONST, "const", &first);
108 printFieldOrReferenceFlag(
109 &flags, RTFieldAccess::READWRITE, "readwrite", &first);
110 printFieldOrReferenceFlag(
111 &flags, RTFieldAccess::PARAMETERIZED_TYPE, "parameterized type", &first);
112 printFieldOrReferenceFlag(
113 &flags, RTFieldAccess::PUBLISHED, "published", &first);
114 if (flags != RTFieldAccess::NONE) {
115 if (!first) {
116 printf("|");
118 printf("<invalid (0x%04X)>", static_cast< unsigned int >(flags));
123 void dumpType(typereg::Reader const & reader, OString const & indent) {
124 if (reader.isValid()) {
125 printf("version: %ld\n", static_cast< long >(reader.getVersion()));
126 printf("%sdocumentation: ", indent.getStr());
127 printString(reader.getDocumentation());
128 printf("\n");
129 printf("%sfile name: ", indent.getStr());
130 printString(reader.getFileName());
131 printf("\n");
132 printf("%stype class: ", indent.getStr());
133 if (reader.isPublished()) {
134 printf("published ");
136 switch (reader.getTypeClass()) {
137 case RT_TYPE_INTERFACE:
138 printf("interface");
139 break;
141 case RT_TYPE_MODULE:
142 printf("module");
143 break;
145 case RT_TYPE_STRUCT:
146 printf("struct");
147 break;
149 case RT_TYPE_ENUM:
150 printf("enum");
151 break;
153 case RT_TYPE_EXCEPTION:
154 printf("exception");
155 break;
157 case RT_TYPE_TYPEDEF:
158 printf("typedef");
159 break;
161 case RT_TYPE_SERVICE:
162 printf("service");
163 break;
165 case RT_TYPE_SINGLETON:
166 printf("singleton");
167 break;
169 case RT_TYPE_CONSTANTS:
170 printf("constants");
171 break;
173 default:
174 printf(
175 "<invalid (%ld)>", static_cast< long >(reader.getTypeClass()));
176 break;
178 printf("\n");
179 printf("%stype name: ", indent.getStr());
180 printString(reader.getTypeName());
181 printf("\n");
182 printf(
183 "%ssuper type count: %u\n", indent.getStr(),
184 static_cast< unsigned int >(reader.getSuperTypeCount()));
185 for (sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i) {
186 printf(
187 "%ssuper type name %u: ", indent.getStr(),
188 static_cast< unsigned int >(i));
189 printString(reader.getSuperTypeName(i));
190 printf("\n");
192 printf(
193 "%sfield count: %u\n", indent.getStr(),
194 static_cast< unsigned int >(reader.getFieldCount()));
195 for (sal_uInt16 i = 0; i < reader.getFieldCount(); ++i) {
196 printf(
197 "%sfield %u:\n", indent.getStr(),
198 static_cast< unsigned int >(i));
199 printf("%s documentation: ", indent.getStr());
200 printString(reader.getFieldDocumentation(i));
201 printf("\n");
202 printf("%s file name: ", indent.getStr());
203 printString(reader.getFieldFileName(i));
204 printf("\n");
205 printf("%s flags: ", indent.getStr());
206 printFieldOrReferenceFlags(reader.getFieldFlags(i));
207 printf("\n");
208 printf("%s name: ", indent.getStr());
209 printString(reader.getFieldName(i));
210 printf("\n");
211 printf("%s type name: ", indent.getStr());
212 printString(reader.getFieldTypeName(i));
213 printf("\n");
214 printf("%s value: ", indent.getStr());
215 RTConstValue value(reader.getFieldValue(i));
216 switch (value.m_type) {
217 case RT_TYPE_NONE:
218 printf("none");
219 break;
221 case RT_TYPE_BOOL:
222 printf("boolean %s", value.m_value.aBool ? "true" : "false");
223 break;
225 case RT_TYPE_BYTE:
226 printf("byte %d", static_cast< int >(value.m_value.aByte));
227 break;
229 case RT_TYPE_INT16:
230 printf("short %d", static_cast< int >(value.m_value.aShort));
231 break;
233 case RT_TYPE_UINT16:
234 printf(
235 "unsigned short %u",
236 static_cast< unsigned int >(value.m_value.aUShort));
237 break;
239 case RT_TYPE_INT32:
240 printf("long %ld", static_cast< long >(value.m_value.aLong));
241 break;
243 case RT_TYPE_UINT32:
244 printf(
245 "unsigned long %lu",
246 static_cast< unsigned long >(value.m_value.aULong));
247 break;
249 case RT_TYPE_INT64:
250 // TODO: no portable way to print hyper values
251 printf("hyper");
252 break;
254 case RT_TYPE_UINT64:
255 // TODO: no portable way to print unsigned hyper values
256 printf("unsigned hyper");
257 break;
259 case RT_TYPE_FLOAT:
260 // TODO: no portable way to print float values
261 printf("float");
262 break;
264 case RT_TYPE_DOUBLE:
265 // TODO: no portable way to print double values
266 printf("double");
267 break;
269 case RT_TYPE_STRING:
270 printf("string ");
271 printString(value.m_value.aString);
272 break;
274 default:
275 printf("<invalid (%ld)>", static_cast< long >(value.m_type));
276 break;
278 printf("\n");
280 printf(
281 "%smethod count: %u\n", indent.getStr(),
282 static_cast< unsigned int >(reader.getMethodCount()));
283 for (sal_uInt16 i = 0; i < reader.getMethodCount(); ++i) {
284 printf(
285 "%smethod %u:\n", indent.getStr(),
286 static_cast< unsigned int >(i));
287 printf("%s documentation: ", indent.getStr());
288 printString(reader.getMethodDocumentation(i));
289 printf("\n");
290 printf("%s flags: ", indent.getStr());
291 switch (reader.getMethodFlags(i)) {
292 case RTMethodMode::ONEWAY:
293 printf("oneway");
294 break;
296 case RTMethodMode::TWOWAY:
297 printf("synchronous");
298 break;
300 case RTMethodMode::ATTRIBUTE_GET:
301 printf("attribute get");
302 break;
304 case RTMethodMode::ATTRIBUTE_SET:
305 printf("attribute set");
306 break;
308 default:
309 printf(
310 "<invalid (%ld)>",
311 static_cast< long >(reader.getMethodFlags(i)));
312 break;
314 printf("\n");
315 printf("%s name: ", indent.getStr());
316 printString(reader.getMethodName(i));
317 printf("\n");
318 printf("%s return type name: ", indent.getStr());
319 printString(reader.getMethodReturnTypeName(i));
320 printf("\n");
321 printf(
322 "%s parameter count: %u\n", indent.getStr(),
323 static_cast< unsigned int >(reader.getMethodParameterCount(i)));
324 // coverity[tainted_data] - cid#1215304 unhelpfully warns about untrusted loop bound
325 for (sal_uInt16 j = 0; j < reader.getMethodParameterCount(i); ++j)
327 printf(
328 "%s parameter %u:\n", indent.getStr(),
329 static_cast< unsigned int >(j));
330 printf("%s flags: ", indent.getStr());
331 RTParamMode flags = reader.getMethodParameterFlags(i, j);
332 bool rest = (flags & RT_PARAM_REST) != 0;
333 switch (flags & ~RT_PARAM_REST) {
334 case RT_PARAM_IN:
335 printf("in");
336 break;
338 case RT_PARAM_OUT:
339 printf("out");
340 break;
342 case RT_PARAM_INOUT:
343 printf("inout");
344 break;
346 default:
347 printf("<invalid (%ld)>", static_cast< long >(flags));
348 rest = false;
349 break;
351 if (rest) {
352 printf("|rest");
354 printf("\n");
355 printf("%s name: ", indent.getStr());
356 printString(reader.getMethodParameterName(i, j));
357 printf("\n");
358 printf("%s type name: ", indent.getStr());
359 printString(reader.getMethodParameterTypeName(i, j));
360 printf("\n");
362 printf(
363 "%s exception count: %u\n", indent.getStr(),
364 static_cast< unsigned int >(reader.getMethodExceptionCount(i)));
365 // coverity[tainted_data] - cid#1215304 unhelpfully warns about untrusted loop bound
366 for (sal_uInt16 j = 0; j < reader.getMethodExceptionCount(i); ++j)
368 printf(
369 "%s exception type name %u: ", indent.getStr(),
370 static_cast< unsigned int >(j));
371 printString(reader.getMethodExceptionTypeName(i, j));
372 printf("\n");
375 printf(
376 "%sreference count: %u\n", indent.getStr(),
377 static_cast< unsigned int >(reader.getReferenceCount()));
378 for (sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i) {
379 printf(
380 "%sreference %u:\n", indent.getStr(),
381 static_cast< unsigned int >(i));
382 printf("%s documentation: ", indent.getStr());
383 printString(reader.getReferenceDocumentation(i));
384 printf("\n");
385 printf("%s flags: ", indent.getStr());
386 printFieldOrReferenceFlags(reader.getReferenceFlags(i));
387 printf("\n");
388 printf("%s sort: ", indent.getStr());
389 switch (reader.getReferenceSort(i)) {
390 case RTReferenceType::SUPPORTS:
391 printf("supports");
392 break;
394 case RTReferenceType::EXPORTS:
395 printf("exports");
396 break;
398 case RTReferenceType::TYPE_PARAMETER:
399 printf("type parameter");
400 break;
402 default:
403 printf(
404 "<invalid (%ld)>",
405 static_cast< long >(reader.getReferenceSort(i)));
406 break;
408 printf("\n");
409 printf("%s type name: ", indent.getStr());
410 printString(reader.getReferenceTypeName(i));
411 printf("\n");
413 } else {
414 printf("<invalid>\n");
420 ORegistry::ORegistry()
421 : m_refCount(1)
422 , m_readOnly(false)
423 , m_isOpen(false)
427 ORegistry::~ORegistry()
429 ORegKey* pRootKey = m_openKeyTable[ROOT];
430 if (pRootKey != nullptr)
431 (void) releaseKey(pRootKey);
433 if (m_file.isValid())
434 m_file.close();
437 RegError ORegistry::initRegistry(const OUString& regName, RegAccessMode accessMode, bool bCreate)
439 RegError eRet = RegError::INVALID_REGISTRY;
440 OStoreFile rRegFile;
441 storeAccessMode sAccessMode = storeAccessMode::ReadWrite;
442 storeError errCode;
444 if (bCreate)
446 sAccessMode = storeAccessMode::Create;
448 else if (accessMode & RegAccessMode::READONLY)
450 sAccessMode = storeAccessMode::ReadOnly;
451 m_readOnly = true;
454 if (regName.isEmpty() &&
455 storeAccessMode::Create == sAccessMode)
457 errCode = rRegFile.createInMemory();
459 else
461 errCode = rRegFile.create(regName, sAccessMode);
464 if (errCode)
466 switch (errCode)
468 case store_E_NotExists:
469 eRet = RegError::REGISTRY_NOT_EXISTS;
470 break;
471 case store_E_LockingViolation:
472 eRet = RegError::CANNOT_OPEN_FOR_READWRITE;
473 break;
474 default:
475 eRet = RegError::INVALID_REGISTRY;
476 break;
479 else
481 OStoreDirectory rStoreDir;
482 storeError _err = rStoreDir.create(rRegFile, OUString(), OUString(), sAccessMode);
484 if (_err == store_E_None)
486 m_file = rRegFile;
487 m_name = regName;
488 m_isOpen = true;
490 m_openKeyTable[ROOT] = new ORegKey(ROOT, this);
491 eRet = RegError::NO_ERROR;
493 else
494 eRet = RegError::INVALID_REGISTRY;
497 return eRet;
500 RegError ORegistry::closeRegistry()
502 REG_GUARD(m_mutex);
504 if (m_file.isValid())
506 (void) releaseKey(m_openKeyTable[ROOT]);
507 m_file.close();
508 m_isOpen = false;
509 return RegError::NO_ERROR;
510 } else
512 return RegError::REGISTRY_NOT_EXISTS;
516 RegError ORegistry::destroyRegistry(const OUString& regName)
518 REG_GUARD(m_mutex);
520 if (!regName.isEmpty())
522 std::unique_ptr<ORegistry> pReg(new ORegistry());
524 if (pReg->initRegistry(regName, RegAccessMode::READWRITE) == RegError::NO_ERROR)
526 pReg.reset();
528 OUString systemName;
529 if (FileBase::getSystemPathFromFileURL(regName, systemName) != FileBase::E_None)
530 systemName = regName;
532 OString name(OUStringToOString(systemName, osl_getThreadTextEncoding()));
533 if (unlink(name.getStr()) != 0)
535 return RegError::DESTROY_REGISTRY_FAILED;
537 } else
539 return RegError::DESTROY_REGISTRY_FAILED;
541 } else
543 if (m_refCount != 1 || isReadOnly())
545 return RegError::DESTROY_REGISTRY_FAILED;
548 if (m_file.isValid())
550 releaseKey(m_openKeyTable[ROOT]);
551 m_file.close();
552 m_isOpen = false;
554 if (!m_name.isEmpty())
556 OUString systemName;
557 if (FileBase::getSystemPathFromFileURL(m_name, systemName) != FileBase::E_None)
558 systemName = m_name;
560 OString name(OUStringToOString(systemName, osl_getThreadTextEncoding()));
561 if (unlink(name.getStr()) != 0)
563 return RegError::DESTROY_REGISTRY_FAILED;
566 } else
568 return RegError::REGISTRY_NOT_EXISTS;
572 return RegError::NO_ERROR;
575 RegError ORegistry::acquireKey (RegKeyHandle hKey)
577 ORegKey* pKey = static_cast< ORegKey* >(hKey);
578 if (!pKey)
579 return RegError::INVALID_KEY;
581 REG_GUARD(m_mutex);
582 pKey->acquire();
584 return RegError::NO_ERROR;
587 RegError ORegistry::releaseKey (RegKeyHandle hKey)
589 ORegKey* pKey = static_cast< ORegKey* >(hKey);
590 if (!pKey)
591 return RegError::INVALID_KEY;
593 REG_GUARD(m_mutex);
594 if (pKey->release() == 0)
596 m_openKeyTable.erase(pKey->getName());
597 delete pKey;
599 return RegError::NO_ERROR;
602 RegError ORegistry::createKey(RegKeyHandle hKey, std::u16string_view keyName,
603 RegKeyHandle* phNewKey)
605 ORegKey* pKey;
607 *phNewKey = nullptr;
609 if (keyName.empty())
610 return RegError::INVALID_KEYNAME;
612 REG_GUARD(m_mutex);
614 if (hKey)
615 pKey = static_cast<ORegKey*>(hKey);
616 else
617 pKey = m_openKeyTable[ROOT];
619 OUString sFullKeyName = pKey->getFullPath(keyName);
621 if (m_openKeyTable.count(sFullKeyName) > 0)
623 *phNewKey = m_openKeyTable[sFullKeyName];
624 static_cast<ORegKey*>(*phNewKey)->acquire();
625 static_cast<ORegKey*>(*phNewKey)->setDeleted(false);
626 return RegError::NO_ERROR;
629 OStoreDirectory rStoreDir;
630 OUStringBuffer sFullPath(sFullKeyName.getLength()+16);
631 OUString token;
633 sFullPath.append('/');
635 sal_Int32 nIndex = 0;
638 token = sFullKeyName.getToken(0, '/', nIndex);
639 if (!token.isEmpty())
641 if (rStoreDir.create(pKey->getStoreFile(), sFullPath.toString(), token, storeAccessMode::Create))
643 return RegError::CREATE_KEY_FAILED;
646 sFullPath.append(token);
647 sFullPath.append('/');
649 } while(nIndex != -1);
652 pKey = new ORegKey(sFullKeyName, this);
653 *phNewKey = pKey;
654 m_openKeyTable[sFullKeyName] = pKey;
656 return RegError::NO_ERROR;
659 RegError ORegistry::openKey(RegKeyHandle hKey, std::u16string_view keyName,
660 RegKeyHandle* phOpenKey)
662 ORegKey* pKey;
664 *phOpenKey = nullptr;
666 if (keyName.empty())
668 return RegError::INVALID_KEYNAME;
671 REG_GUARD(m_mutex);
673 if (hKey)
674 pKey = static_cast<ORegKey*>(hKey);
675 else
676 pKey = m_openKeyTable[ROOT];
678 OUString path(pKey->getFullPath(keyName));
679 KeyMap::iterator i(m_openKeyTable.find(path));
680 if (i == m_openKeyTable.end()) {
681 sal_Int32 n = path.lastIndexOf('/') + 1;
682 switch (OStoreDirectory().create(
683 pKey->getStoreFile(), path.copy(0, n), path.copy(n),
684 isReadOnly() ? storeAccessMode::ReadOnly : storeAccessMode::ReadWrite))
686 case store_E_NotExists:
687 return RegError::KEY_NOT_EXISTS;
688 case store_E_WrongFormat:
689 return RegError::INVALID_KEY;
690 default:
691 break;
694 std::unique_ptr< ORegKey > p(new ORegKey(path, this));
695 i = m_openKeyTable.insert(std::make_pair(path, p.get())).first;
696 // coverity[leaked_storage : FALSE] - ownership transferred to m_openKeyTable
697 p.release();
698 } else {
699 i->second->acquire();
701 *phOpenKey = i->second;
702 return RegError::NO_ERROR;
705 RegError ORegistry::closeKey(RegKeyHandle hKey)
707 ORegKey* pKey = static_cast< ORegKey* >(hKey);
709 REG_GUARD(m_mutex);
711 OUString const aKeyName (pKey->getName());
712 if (m_openKeyTable.count(aKeyName) <= 0)
713 return RegError::KEY_NOT_OPEN;
715 if (pKey->isModified())
717 ORegKey * pRootKey = getRootKey();
718 if (pKey != pRootKey)
720 // propagate "modified" state to RootKey.
721 pRootKey->setModified();
723 else
725 // closing modified RootKey, flush registry file.
726 (void) m_file.flush();
728 pKey->setModified(false);
729 (void) releaseKey(pRootKey);
732 return releaseKey(pKey);
735 RegError ORegistry::deleteKey(RegKeyHandle hKey, std::u16string_view keyName)
737 ORegKey* pKey = static_cast< ORegKey* >(hKey);
738 if (keyName.empty())
739 return RegError::INVALID_KEYNAME;
741 REG_GUARD(m_mutex);
743 if (!pKey)
744 pKey = m_openKeyTable[ROOT];
746 OUString sFullKeyName(pKey->getFullPath(keyName));
747 return eraseKey(m_openKeyTable[ROOT], sFullKeyName);
750 RegError ORegistry::eraseKey(ORegKey* pKey, std::u16string_view keyName)
752 RegError _ret = RegError::NO_ERROR;
754 if (keyName.empty())
756 return RegError::INVALID_KEYNAME;
759 OUString sFullKeyName(pKey->getName());
760 OUString sFullPath(sFullKeyName);
761 OUString sRelativKey;
762 size_t lastIndex = keyName.rfind('/');
764 if (lastIndex != std::u16string_view::npos)
766 sRelativKey += keyName.substr(lastIndex + 1);
768 if (sFullKeyName.getLength() > 1)
769 sFullKeyName += keyName;
770 else
771 sFullKeyName += keyName.substr(1);
773 sFullPath = sFullKeyName.copy(0, keyName.rfind('/') + 1);
774 } else
776 if (sFullKeyName.getLength() > 1)
777 sFullKeyName += ROOT;
779 sRelativKey += keyName;
780 sFullKeyName += keyName;
782 if (sFullPath.getLength() > 1)
783 sFullPath += ROOT;
786 ORegKey* pOldKey = nullptr;
787 _ret = pKey->openKey(keyName, reinterpret_cast<RegKeyHandle*>(&pOldKey));
788 if (_ret != RegError::NO_ERROR)
789 return _ret;
791 _ret = deleteSubkeysAndValues(pOldKey);
792 if (_ret != RegError::NO_ERROR)
794 pKey->closeKey(pOldKey);
795 return _ret;
798 OUString tmpName = sRelativKey + ROOT;
800 OStoreFile sFile(pKey->getStoreFile());
801 if (sFile.isValid() && sFile.remove(sFullPath, tmpName))
803 return RegError::DELETE_KEY_FAILED;
805 pOldKey->setModified();
807 // set flag deleted !!!
808 pOldKey->setDeleted(true);
810 return pKey->closeKey(pOldKey);
813 RegError ORegistry::deleteSubkeysAndValues(ORegKey* pKey)
815 OStoreDirectory::iterator iter;
816 RegError _ret = RegError::NO_ERROR;
817 OStoreDirectory rStoreDir(pKey->getStoreDir());
818 storeError _err = rStoreDir.first(iter);
820 while (_err == store_E_None)
822 OUString const keyName(iter.m_pszName, iter.m_nLength);
824 if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
826 _ret = eraseKey(pKey, keyName);
827 if (_ret != RegError::NO_ERROR)
828 return _ret;
830 else
832 OUString sFullPath(pKey->getName());
834 if (sFullPath.getLength() > 1)
835 sFullPath += ROOT;
837 if (const_cast<OStoreFile&>(pKey->getStoreFile()).remove(sFullPath, keyName))
839 return RegError::DELETE_VALUE_FAILED;
841 pKey->setModified();
844 _err = rStoreDir.next(iter);
847 return RegError::NO_ERROR;
850 ORegKey* ORegistry::getRootKey()
852 m_openKeyTable[ROOT]->acquire();
853 return m_openKeyTable[ROOT];
856 RegError ORegistry::dumpRegistry(RegKeyHandle hKey) const
858 ORegKey *pKey = static_cast<ORegKey*>(hKey);
859 OUString sName;
860 RegError _ret = RegError::NO_ERROR;
861 OStoreDirectory::iterator iter;
862 OStoreDirectory rStoreDir(pKey->getStoreDir());
863 storeError _err = rStoreDir.first(iter);
865 OString regName(OUStringToOString(getName(), osl_getThreadTextEncoding()));
866 OString keyName(OUStringToOString(pKey->getName(), RTL_TEXTENCODING_UTF8));
867 fprintf(stdout, "Registry \"%s\":\n\n%s\n", regName.getStr(), keyName.getStr());
869 while (_err == store_E_None)
871 sName = OUString(iter.m_pszName, iter.m_nLength);
873 if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
875 _ret = dumpKey(pKey->getName(), sName, 1);
876 } else
878 _ret = dumpValue(pKey->getName(), sName, 1);
881 if (_ret != RegError::NO_ERROR)
883 return _ret;
886 _err = rStoreDir.next(iter);
889 return RegError::NO_ERROR;
892 RegError ORegistry::dumpValue(const OUString& sPath, const OUString& sName, sal_Int16 nSpc) const
894 OStoreStream rValue;
895 sal_uInt32 valueSize;
896 RegValueType valueType;
897 OUString sFullPath(sPath);
898 OString sIndent;
899 storeAccessMode accessMode = storeAccessMode::ReadWrite;
901 if (isReadOnly())
903 accessMode = storeAccessMode::ReadOnly;
906 for (int i= 0; i < nSpc; i++) sIndent += " ";
908 if (sFullPath.getLength() > 1)
910 sFullPath += ROOT;
912 if (rValue.create(m_file, sFullPath, sName, accessMode))
914 return RegError::VALUE_NOT_EXISTS;
917 std::vector<sal_uInt8> aBuffer(VALUE_HEADERSIZE);
919 sal_uInt32 rwBytes;
920 if (rValue.readAt(0, aBuffer.data(), VALUE_HEADERSIZE, rwBytes))
922 return RegError::INVALID_VALUE;
924 if (rwBytes != (VALUE_HEADERSIZE))
926 return RegError::INVALID_VALUE;
929 sal_uInt8 type = aBuffer[0];
930 valueType = static_cast<RegValueType>(type);
931 readUINT32(aBuffer.data() + VALUE_TYPEOFFSET, valueSize);
933 aBuffer.resize(valueSize);
934 if (rValue.readAt(VALUE_HEADEROFFSET, aBuffer.data(), valueSize, rwBytes))
936 return RegError::INVALID_VALUE;
938 if (rwBytes != valueSize)
940 return RegError::INVALID_VALUE;
943 const char* indent = sIndent.getStr();
944 switch (valueType)
946 case RegValueType::NOT_DEFINED:
947 fprintf(stdout, "%sValue: Type = VALUETYPE_NOT_DEFINED\n", indent);
948 break;
949 case RegValueType::LONG:
951 fprintf(stdout, "%sValue: Type = RegValueType::LONG\n", indent);
952 fprintf(
953 stdout, "%s Size = %lu\n", indent,
954 sal::static_int_cast< unsigned long >(valueSize));
955 fprintf(stdout, "%s Data = ", indent);
957 sal_Int32 value;
958 readINT32(aBuffer.data(), value);
959 fprintf(stdout, "%ld\n", sal::static_int_cast< long >(value));
961 break;
962 case RegValueType::STRING:
964 char* value = static_cast<char*>(std::malloc(valueSize));
965 readUtf8(aBuffer.data(), value, valueSize);
966 fprintf(stdout, "%sValue: Type = RegValueType::STRING\n", indent);
967 fprintf(
968 stdout, "%s Size = %lu\n", indent,
969 sal::static_int_cast< unsigned long >(valueSize));
970 fprintf(stdout, "%s Data = \"%s\"\n", indent, value);
971 std::free(value);
973 break;
974 case RegValueType::UNICODE:
976 sal_uInt32 size = (valueSize / 2) * sizeof(sal_Unicode);
977 fprintf(stdout, "%sValue: Type = RegValueType::UNICODE\n", indent);
978 fprintf(
979 stdout, "%s Size = %lu\n", indent,
980 sal::static_int_cast< unsigned long >(valueSize));
981 fprintf(stdout, "%s Data = ", indent);
983 std::unique_ptr<sal_Unicode[]> value(new sal_Unicode[size]);
984 readString(aBuffer.data(), value.get(), size);
986 OString uStr(value.get(), rtl_ustr_getLength(value.get()), RTL_TEXTENCODING_UTF8);
987 fprintf(stdout, "L\"%s\"\n", uStr.getStr());
989 break;
990 case RegValueType::BINARY:
992 fprintf(stdout, "%sValue: Type = RegValueType::BINARY\n", indent);
993 fprintf(
994 stdout, "%s Size = %lu\n", indent,
995 sal::static_int_cast< unsigned long >(valueSize));
996 fprintf(stdout, "%s Data = ", indent);
997 dumpType(
998 typereg::Reader(aBuffer.data(), valueSize),
999 sIndent + " ");
1001 break;
1002 case RegValueType::LONGLIST:
1004 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array
1005 sal_uInt32 len = 0;
1007 readUINT32(aBuffer.data(), len);
1009 fprintf(stdout, "%sValue: Type = RegValueType::LONGLIST\n", indent);
1010 fprintf(
1011 stdout, "%s Size = %lu\n", indent,
1012 sal::static_int_cast< unsigned long >(valueSize));
1013 fprintf(
1014 stdout, "%s Len = %lu\n", indent,
1015 sal::static_int_cast< unsigned long >(len));
1016 fprintf(stdout, "%s Data = ", indent);
1018 sal_Int32 longValue;
1019 for (sal_uInt32 i=0; i < len; i++)
1021 readINT32(aBuffer.data() + offset, longValue);
1023 if (offset > 4)
1024 fprintf(stdout, "%s ", indent);
1026 fprintf(
1027 stdout, "%lu = %ld\n",
1028 sal::static_int_cast< unsigned long >(i),
1029 sal::static_int_cast< long >(longValue));
1030 offset += 4; // 4 Bytes for sal_Int32
1033 break;
1034 case RegValueType::STRINGLIST:
1036 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array
1037 sal_uInt32 sLen = 0;
1038 sal_uInt32 len = 0;
1040 readUINT32(aBuffer.data(), len);
1042 fprintf(stdout, "%sValue: Type = RegValueType::STRINGLIST\n", indent);
1043 fprintf(
1044 stdout, "%s Size = %lu\n", indent,
1045 sal::static_int_cast< unsigned long >(valueSize));
1046 fprintf(
1047 stdout, "%s Len = %lu\n", indent,
1048 sal::static_int_cast< unsigned long >(len));
1049 fprintf(stdout, "%s Data = ", indent);
1051 for (sal_uInt32 i=0; i < len; i++)
1053 readUINT32(aBuffer.data() + offset, sLen);
1055 offset += 4; // 4 bytes (sal_uInt32) for the string size
1057 char *pValue = static_cast<char*>(std::malloc(sLen));
1058 readUtf8(aBuffer.data() + offset, pValue, sLen);
1060 if (offset > 8)
1061 fprintf(stdout, "%s ", indent);
1063 fprintf(
1064 stdout, "%lu = \"%s\"\n",
1065 sal::static_int_cast< unsigned long >(i), pValue);
1066 std::free(pValue);
1067 offset += sLen;
1070 break;
1071 case RegValueType::UNICODELIST:
1073 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array
1074 sal_uInt32 sLen = 0;
1075 sal_uInt32 len = 0;
1077 readUINT32(aBuffer.data(), len);
1079 fprintf(stdout, "%sValue: Type = RegValueType::UNICODELIST\n", indent);
1080 fprintf(
1081 stdout, "%s Size = %lu\n", indent,
1082 sal::static_int_cast< unsigned long >(valueSize));
1083 fprintf(
1084 stdout, "%s Len = %lu\n", indent,
1085 sal::static_int_cast< unsigned long >(len));
1086 fprintf(stdout, "%s Data = ", indent);
1088 OString uStr;
1089 for (sal_uInt32 i=0; i < len; i++)
1091 readUINT32(aBuffer.data() + offset, sLen);
1093 offset += 4; // 4 bytes (sal_uInt32) for the string size
1095 sal_Unicode *pValue = static_cast<sal_Unicode*>(std::malloc((sLen / 2) * sizeof(sal_Unicode)));
1096 readString(aBuffer.data() + offset, pValue, sLen);
1098 if (offset > 8)
1099 fprintf(stdout, "%s ", indent);
1101 uStr = OString(pValue, rtl_ustr_getLength(pValue), RTL_TEXTENCODING_UTF8);
1102 fprintf(
1103 stdout, "%lu = L\"%s\"\n",
1104 sal::static_int_cast< unsigned long >(i),
1105 uStr.getStr());
1107 offset += sLen;
1109 std::free(pValue);
1112 break;
1115 fprintf(stdout, "\n");
1117 return RegError::NO_ERROR;
1120 RegError ORegistry::dumpKey(const OUString& sPath, const OUString& sName, sal_Int16 nSpace) const
1122 OStoreDirectory rStoreDir;
1123 OUString sFullPath(sPath);
1124 OString sIndent;
1125 storeAccessMode accessMode = storeAccessMode::ReadWrite;
1126 RegError _ret = RegError::NO_ERROR;
1128 if (isReadOnly())
1130 accessMode = storeAccessMode::ReadOnly;
1133 for (int i= 0; i < nSpace; i++) sIndent += " ";
1135 if (sFullPath.getLength() > 1)
1136 sFullPath += ROOT;
1138 storeError _err = rStoreDir.create(m_file, sFullPath, sName, accessMode);
1140 if (_err == store_E_NotExists)
1141 return RegError::KEY_NOT_EXISTS;
1142 else if (_err == store_E_WrongFormat)
1143 return RegError::INVALID_KEY;
1145 fprintf(stdout, "%s/ %s\n", sIndent.getStr(), OUStringToOString(sName, RTL_TEXTENCODING_UTF8).getStr());
1147 OUString sSubPath(sFullPath);
1148 OUString sSubName;
1149 sSubPath += sName;
1151 OStoreDirectory::iterator iter;
1153 _err = rStoreDir.first(iter);
1155 while (_err == store_E_None)
1157 sSubName = OUString(iter.m_pszName, iter.m_nLength);
1159 if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
1161 _ret = dumpKey(sSubPath, sSubName, nSpace+2);
1162 } else
1164 _ret = dumpValue(sSubPath, sSubName, nSpace+2);
1167 if (_ret != RegError::NO_ERROR)
1169 return _ret;
1172 _err = rStoreDir.next(iter);
1175 return RegError::NO_ERROR;
1178 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */