1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
26 #include <string_view>
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>
48 using namespace store
;
53 void printString(std::u16string_view s
) {
55 for (std::size_t i
= 0; i
< s
.size(); ++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
));
62 printf("\\u%04X", static_cast< unsigned int >(c
));
68 void printFieldOrReferenceFlag(
69 RTFieldAccess
* flags
, RTFieldAccess flag
, char const * name
, bool * first
)
71 if ((*flags
& flag
) != RTFieldAccess::NONE
) {
81 void printFieldOrReferenceFlags(RTFieldAccess flags
) {
82 if (flags
== RTFieldAccess::NONE
) {
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
) {
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());
129 printf("%sfile name: ", indent
.getStr());
130 printString(reader
.getFileName());
132 printf("%stype class: ", indent
.getStr());
133 if (reader
.isPublished()) {
134 printf("published ");
136 switch (reader
.getTypeClass()) {
137 case RT_TYPE_INTERFACE
:
153 case RT_TYPE_EXCEPTION
:
157 case RT_TYPE_TYPEDEF
:
161 case RT_TYPE_SERVICE
:
165 case RT_TYPE_SINGLETON
:
169 case RT_TYPE_CONSTANTS
:
175 "<invalid (%ld)>", static_cast< long >(reader
.getTypeClass()));
179 printf("%stype name: ", indent
.getStr());
180 printString(reader
.getTypeName());
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
) {
187 "%ssuper type name %u: ", indent
.getStr(),
188 static_cast< unsigned int >(i
));
189 printString(reader
.getSuperTypeName(i
));
193 "%sfield count: %u\n", indent
.getStr(),
194 static_cast< unsigned int >(reader
.getFieldCount()));
195 for (sal_uInt16 i
= 0; i
< reader
.getFieldCount(); ++i
) {
197 "%sfield %u:\n", indent
.getStr(),
198 static_cast< unsigned int >(i
));
199 printf("%s documentation: ", indent
.getStr());
200 printString(reader
.getFieldDocumentation(i
));
202 printf("%s file name: ", indent
.getStr());
203 printString(reader
.getFieldFileName(i
));
205 printf("%s flags: ", indent
.getStr());
206 printFieldOrReferenceFlags(reader
.getFieldFlags(i
));
208 printf("%s name: ", indent
.getStr());
209 printString(reader
.getFieldName(i
));
211 printf("%s type name: ", indent
.getStr());
212 printString(reader
.getFieldTypeName(i
));
214 printf("%s value: ", indent
.getStr());
215 RTConstValue
value(reader
.getFieldValue(i
));
216 switch (value
.m_type
) {
222 printf("boolean %s", value
.m_value
.aBool
? "true" : "false");
226 printf("byte %d", static_cast< int >(value
.m_value
.aByte
));
230 printf("short %d", static_cast< int >(value
.m_value
.aShort
));
236 static_cast< unsigned int >(value
.m_value
.aUShort
));
240 printf("long %ld", static_cast< long >(value
.m_value
.aLong
));
246 static_cast< unsigned long >(value
.m_value
.aULong
));
250 // TODO: no portable way to print hyper values
255 // TODO: no portable way to print unsigned hyper values
256 printf("unsigned hyper");
260 // TODO: no portable way to print float values
265 // TODO: no portable way to print double values
271 printString(value
.m_value
.aString
);
275 printf("<invalid (%ld)>", static_cast< long >(value
.m_type
));
281 "%smethod count: %u\n", indent
.getStr(),
282 static_cast< unsigned int >(reader
.getMethodCount()));
283 for (sal_uInt16 i
= 0; i
< reader
.getMethodCount(); ++i
) {
285 "%smethod %u:\n", indent
.getStr(),
286 static_cast< unsigned int >(i
));
287 printf("%s documentation: ", indent
.getStr());
288 printString(reader
.getMethodDocumentation(i
));
290 printf("%s flags: ", indent
.getStr());
291 switch (reader
.getMethodFlags(i
)) {
292 case RTMethodMode::ONEWAY
:
296 case RTMethodMode::TWOWAY
:
297 printf("synchronous");
300 case RTMethodMode::ATTRIBUTE_GET
:
301 printf("attribute get");
304 case RTMethodMode::ATTRIBUTE_SET
:
305 printf("attribute set");
311 static_cast< long >(reader
.getMethodFlags(i
)));
315 printf("%s name: ", indent
.getStr());
316 printString(reader
.getMethodName(i
));
318 printf("%s return type name: ", indent
.getStr());
319 printString(reader
.getMethodReturnTypeName(i
));
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
)
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
) {
347 printf("<invalid (%ld)>", static_cast< long >(flags
));
355 printf("%s name: ", indent
.getStr());
356 printString(reader
.getMethodParameterName(i
, j
));
358 printf("%s type name: ", indent
.getStr());
359 printString(reader
.getMethodParameterTypeName(i
, j
));
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
)
369 "%s exception type name %u: ", indent
.getStr(),
370 static_cast< unsigned int >(j
));
371 printString(reader
.getMethodExceptionTypeName(i
, j
));
376 "%sreference count: %u\n", indent
.getStr(),
377 static_cast< unsigned int >(reader
.getReferenceCount()));
378 for (sal_uInt16 i
= 0; i
< reader
.getReferenceCount(); ++i
) {
380 "%sreference %u:\n", indent
.getStr(),
381 static_cast< unsigned int >(i
));
382 printf("%s documentation: ", indent
.getStr());
383 printString(reader
.getReferenceDocumentation(i
));
385 printf("%s flags: ", indent
.getStr());
386 printFieldOrReferenceFlags(reader
.getReferenceFlags(i
));
388 printf("%s sort: ", indent
.getStr());
389 switch (reader
.getReferenceSort(i
)) {
390 case RTReferenceType::SUPPORTS
:
394 case RTReferenceType::EXPORTS
:
398 case RTReferenceType::TYPE_PARAMETER
:
399 printf("type parameter");
405 static_cast< long >(reader
.getReferenceSort(i
)));
409 printf("%s type name: ", indent
.getStr());
410 printString(reader
.getReferenceTypeName(i
));
414 printf("<invalid>\n");
420 ORegistry::ORegistry()
427 ORegistry::~ORegistry()
429 ORegKey
* pRootKey
= m_openKeyTable
[ROOT
];
430 if (pRootKey
!= nullptr)
431 (void) releaseKey(pRootKey
);
433 if (m_file
.isValid())
437 RegError
ORegistry::initRegistry(const OUString
& regName
, RegAccessMode accessMode
, bool bCreate
)
439 RegError eRet
= RegError::INVALID_REGISTRY
;
441 storeAccessMode sAccessMode
= storeAccessMode::ReadWrite
;
446 sAccessMode
= storeAccessMode::Create
;
448 else if (accessMode
& RegAccessMode::READONLY
)
450 sAccessMode
= storeAccessMode::ReadOnly
;
454 if (regName
.isEmpty() &&
455 storeAccessMode::Create
== sAccessMode
)
457 errCode
= rRegFile
.createInMemory();
461 errCode
= rRegFile
.create(regName
, sAccessMode
);
468 case store_E_NotExists
:
469 eRet
= RegError::REGISTRY_NOT_EXISTS
;
471 case store_E_LockingViolation
:
472 eRet
= RegError::CANNOT_OPEN_FOR_READWRITE
;
475 eRet
= RegError::INVALID_REGISTRY
;
481 OStoreDirectory rStoreDir
;
482 storeError _err
= rStoreDir
.create(rRegFile
, OUString(), OUString(), sAccessMode
);
484 if (_err
== store_E_None
)
490 m_openKeyTable
[ROOT
] = new ORegKey(ROOT
, this);
491 eRet
= RegError::NO_ERROR
;
494 eRet
= RegError::INVALID_REGISTRY
;
500 RegError
ORegistry::closeRegistry()
504 if (m_file
.isValid())
506 (void) releaseKey(m_openKeyTable
[ROOT
]);
509 return RegError::NO_ERROR
;
512 return RegError::REGISTRY_NOT_EXISTS
;
516 RegError
ORegistry::destroyRegistry(const OUString
& regName
)
520 if (!regName
.isEmpty())
522 std::unique_ptr
<ORegistry
> pReg(new ORegistry());
524 if (pReg
->initRegistry(regName
, RegAccessMode::READWRITE
) == RegError::NO_ERROR
)
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
;
539 return RegError::DESTROY_REGISTRY_FAILED
;
543 if (m_refCount
!= 1 || isReadOnly())
545 return RegError::DESTROY_REGISTRY_FAILED
;
548 if (m_file
.isValid())
550 releaseKey(m_openKeyTable
[ROOT
]);
554 if (!m_name
.isEmpty())
557 if (FileBase::getSystemPathFromFileURL(m_name
, systemName
) != FileBase::E_None
)
560 OString
name(OUStringToOString(systemName
, osl_getThreadTextEncoding()));
561 if (unlink(name
.getStr()) != 0)
563 return RegError::DESTROY_REGISTRY_FAILED
;
568 return RegError::REGISTRY_NOT_EXISTS
;
572 return RegError::NO_ERROR
;
575 RegError
ORegistry::acquireKey (RegKeyHandle hKey
)
577 ORegKey
* pKey
= static_cast< ORegKey
* >(hKey
);
579 return RegError::INVALID_KEY
;
584 return RegError::NO_ERROR
;
587 RegError
ORegistry::releaseKey (RegKeyHandle hKey
)
589 ORegKey
* pKey
= static_cast< ORegKey
* >(hKey
);
591 return RegError::INVALID_KEY
;
594 if (pKey
->release() == 0)
596 m_openKeyTable
.erase(pKey
->getName());
599 return RegError::NO_ERROR
;
602 RegError
ORegistry::createKey(RegKeyHandle hKey
, std::u16string_view keyName
,
603 RegKeyHandle
* phNewKey
)
610 return RegError::INVALID_KEYNAME
;
615 pKey
= static_cast<ORegKey
*>(hKey
);
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);
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
+ "/");
648 } while(nIndex
!= -1);
651 pKey
= new ORegKey(sFullKeyName
, this);
653 m_openKeyTable
[sFullKeyName
] = pKey
;
655 return RegError::NO_ERROR
;
658 RegError
ORegistry::openKey(RegKeyHandle hKey
, std::u16string_view keyName
,
659 RegKeyHandle
* phOpenKey
)
663 *phOpenKey
= nullptr;
667 return RegError::INVALID_KEYNAME
;
673 pKey
= static_cast<ORegKey
*>(hKey
);
675 pKey
= m_openKeyTable
[ROOT
];
677 OUString
path(pKey
->getFullPath(keyName
));
678 KeyMap::iterator
i(m_openKeyTable
.find(path
));
679 if (i
== m_openKeyTable
.end()) {
680 sal_Int32 n
= path
.lastIndexOf('/') + 1;
681 switch (OStoreDirectory().create(
682 pKey
->getStoreFile(), path
.copy(0, n
), path
.copy(n
),
683 isReadOnly() ? storeAccessMode::ReadOnly
: storeAccessMode::ReadWrite
))
685 case store_E_NotExists
:
686 return RegError::KEY_NOT_EXISTS
;
687 case store_E_WrongFormat
:
688 return RegError::INVALID_KEY
;
693 std::unique_ptr
< ORegKey
> p(new ORegKey(path
, this));
694 i
= m_openKeyTable
.insert(std::make_pair(path
, p
.get())).first
;
695 // coverity[leaked_storage : FALSE] - ownership transferred to m_openKeyTable
698 i
->second
->acquire();
700 *phOpenKey
= i
->second
;
701 return RegError::NO_ERROR
;
704 RegError
ORegistry::closeKey(RegKeyHandle hKey
)
706 ORegKey
* pKey
= static_cast< ORegKey
* >(hKey
);
710 OUString
const aKeyName (pKey
->getName());
711 if (m_openKeyTable
.count(aKeyName
) <= 0)
712 return RegError::KEY_NOT_OPEN
;
714 if (pKey
->isModified())
716 ORegKey
* pRootKey
= getRootKey();
717 if (pKey
!= pRootKey
)
719 // propagate "modified" state to RootKey.
720 pRootKey
->setModified();
724 // closing modified RootKey, flush registry file.
725 (void) m_file
.flush();
727 pKey
->setModified(false);
728 (void) releaseKey(pRootKey
);
731 return releaseKey(pKey
);
734 RegError
ORegistry::deleteKey(RegKeyHandle hKey
, std::u16string_view keyName
)
736 ORegKey
* pKey
= static_cast< ORegKey
* >(hKey
);
738 return RegError::INVALID_KEYNAME
;
743 pKey
= m_openKeyTable
[ROOT
];
745 OUString
sFullKeyName(pKey
->getFullPath(keyName
));
746 return eraseKey(m_openKeyTable
[ROOT
], sFullKeyName
);
749 RegError
ORegistry::eraseKey(ORegKey
* pKey
, std::u16string_view keyName
)
751 RegError _ret
= RegError::NO_ERROR
;
755 return RegError::INVALID_KEYNAME
;
758 OUString
sFullKeyName(pKey
->getName());
759 OUString
sFullPath(sFullKeyName
);
760 OUString sRelativKey
;
761 size_t lastIndex
= keyName
.rfind('/');
763 if (lastIndex
!= std::u16string_view::npos
)
765 sRelativKey
+= keyName
.substr(lastIndex
+ 1);
767 if (sFullKeyName
.getLength() > 1)
768 sFullKeyName
+= keyName
;
770 sFullKeyName
+= keyName
.substr(1);
772 sFullPath
= sFullKeyName
.copy(0, keyName
.rfind('/') + 1);
775 if (sFullKeyName
.getLength() > 1)
776 sFullKeyName
+= ROOT
;
778 sRelativKey
+= keyName
;
779 sFullKeyName
+= keyName
;
781 if (sFullPath
.getLength() > 1)
785 ORegKey
* pOldKey
= nullptr;
786 _ret
= pKey
->openKey(keyName
, reinterpret_cast<RegKeyHandle
*>(&pOldKey
));
787 if (_ret
!= RegError::NO_ERROR
)
790 _ret
= deleteSubkeysAndValues(pOldKey
);
791 if (_ret
!= RegError::NO_ERROR
)
793 pKey
->closeKey(pOldKey
);
797 OUString tmpName
= sRelativKey
+ ROOT
;
799 OStoreFile
sFile(pKey
->getStoreFile());
800 if (sFile
.isValid() && sFile
.remove(sFullPath
, tmpName
))
802 return RegError::DELETE_KEY_FAILED
;
804 pOldKey
->setModified();
806 // set flag deleted !!!
807 pOldKey
->setDeleted(true);
809 return pKey
->closeKey(pOldKey
);
812 RegError
ORegistry::deleteSubkeysAndValues(ORegKey
* pKey
)
814 OStoreDirectory::iterator iter
;
815 RegError _ret
= RegError::NO_ERROR
;
816 OStoreDirectory
rStoreDir(pKey
->getStoreDir());
817 storeError _err
= rStoreDir
.first(iter
);
819 while (_err
== store_E_None
)
821 OUString
const keyName(iter
.m_pszName
, iter
.m_nLength
);
823 if (iter
.m_nAttrib
& STORE_ATTRIB_ISDIR
)
825 _ret
= eraseKey(pKey
, keyName
);
826 if (_ret
!= RegError::NO_ERROR
)
831 OUString
sFullPath(pKey
->getName());
833 if (sFullPath
.getLength() > 1)
836 if (const_cast<OStoreFile
&>(pKey
->getStoreFile()).remove(sFullPath
, keyName
))
838 return RegError::DELETE_VALUE_FAILED
;
843 _err
= rStoreDir
.next(iter
);
846 return RegError::NO_ERROR
;
849 ORegKey
* ORegistry::getRootKey()
851 m_openKeyTable
[ROOT
]->acquire();
852 return m_openKeyTable
[ROOT
];
855 RegError
ORegistry::dumpRegistry(RegKeyHandle hKey
) const
857 ORegKey
*pKey
= static_cast<ORegKey
*>(hKey
);
859 RegError _ret
= RegError::NO_ERROR
;
860 OStoreDirectory::iterator iter
;
861 OStoreDirectory
rStoreDir(pKey
->getStoreDir());
862 storeError _err
= rStoreDir
.first(iter
);
864 OString
regName(OUStringToOString(getName(), osl_getThreadTextEncoding()));
865 OString
keyName(OUStringToOString(pKey
->getName(), RTL_TEXTENCODING_UTF8
));
866 fprintf(stdout
, "Registry \"%s\":\n\n%s\n", regName
.getStr(), keyName
.getStr());
868 while (_err
== store_E_None
)
870 sName
= OUString(iter
.m_pszName
, iter
.m_nLength
);
872 if (iter
.m_nAttrib
& STORE_ATTRIB_ISDIR
)
874 _ret
= dumpKey(pKey
->getName(), sName
, 1);
877 _ret
= dumpValue(pKey
->getName(), sName
, 1);
880 if (_ret
!= RegError::NO_ERROR
)
885 _err
= rStoreDir
.next(iter
);
888 return RegError::NO_ERROR
;
891 RegError
ORegistry::dumpValue(const OUString
& sPath
, const OUString
& sName
, sal_Int16 nSpc
) const
894 sal_uInt32 valueSize
;
895 RegValueType valueType
;
896 OUString
sFullPath(sPath
);
898 storeAccessMode accessMode
= storeAccessMode::ReadWrite
;
902 accessMode
= storeAccessMode::ReadOnly
;
905 for (int i
= 0; i
< nSpc
; i
++) sIndent
+= " ";
907 if (sFullPath
.getLength() > 1)
911 if (rValue
.create(m_file
, sFullPath
, sName
, accessMode
))
913 return RegError::VALUE_NOT_EXISTS
;
916 std::vector
<sal_uInt8
> aBuffer(VALUE_HEADERSIZE
);
919 if (rValue
.readAt(0, aBuffer
.data(), VALUE_HEADERSIZE
, rwBytes
))
921 return RegError::INVALID_VALUE
;
923 if (rwBytes
!= (VALUE_HEADERSIZE
))
925 return RegError::INVALID_VALUE
;
928 sal_uInt8 type
= aBuffer
[0];
929 valueType
= static_cast<RegValueType
>(type
);
930 readUINT32(aBuffer
.data() + VALUE_TYPEOFFSET
, valueSize
);
932 aBuffer
.resize(valueSize
);
933 if (rValue
.readAt(VALUE_HEADEROFFSET
, aBuffer
.data(), valueSize
, rwBytes
))
935 return RegError::INVALID_VALUE
;
937 if (rwBytes
!= valueSize
)
939 return RegError::INVALID_VALUE
;
942 const char* indent
= sIndent
.getStr();
945 case RegValueType::NOT_DEFINED
:
946 fprintf(stdout
, "%sValue: Type = VALUETYPE_NOT_DEFINED\n", indent
);
948 case RegValueType::LONG
:
950 fprintf(stdout
, "%sValue: Type = RegValueType::LONG\n", indent
);
952 stdout
, "%s Size = %lu\n", indent
,
953 sal::static_int_cast
< unsigned long >(valueSize
));
954 fprintf(stdout
, "%s Data = ", indent
);
957 readINT32(aBuffer
.data(), value
);
958 fprintf(stdout
, "%ld\n", sal::static_int_cast
< long >(value
));
961 case RegValueType::STRING
:
963 char* value
= static_cast<char*>(std::malloc(valueSize
));
964 readUtf8(aBuffer
.data(), value
, valueSize
);
965 fprintf(stdout
, "%sValue: Type = RegValueType::STRING\n", indent
);
967 stdout
, "%s Size = %lu\n", indent
,
968 sal::static_int_cast
< unsigned long >(valueSize
));
969 fprintf(stdout
, "%s Data = \"%s\"\n", indent
, value
);
973 case RegValueType::UNICODE
:
975 sal_uInt32 size
= (valueSize
/ 2) * sizeof(sal_Unicode
);
976 fprintf(stdout
, "%sValue: Type = RegValueType::UNICODE\n", indent
);
978 stdout
, "%s Size = %lu\n", indent
,
979 sal::static_int_cast
< unsigned long >(valueSize
));
980 fprintf(stdout
, "%s Data = ", indent
);
982 std::unique_ptr
<sal_Unicode
[]> value(new sal_Unicode
[size
]);
983 readString(aBuffer
.data(), value
.get(), size
);
985 OString
uStr(value
.get(), rtl_ustr_getLength(value
.get()), RTL_TEXTENCODING_UTF8
);
986 fprintf(stdout
, "L\"%s\"\n", uStr
.getStr());
989 case RegValueType::BINARY
:
991 fprintf(stdout
, "%sValue: Type = RegValueType::BINARY\n", indent
);
993 stdout
, "%s Size = %lu\n", indent
,
994 sal::static_int_cast
< unsigned long >(valueSize
));
995 fprintf(stdout
, "%s Data = ", indent
);
997 typereg::Reader(aBuffer
.data(), valueSize
),
1001 case RegValueType::LONGLIST
:
1003 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array
1006 readUINT32(aBuffer
.data(), len
);
1008 fprintf(stdout
, "%sValue: Type = RegValueType::LONGLIST\n", indent
);
1010 stdout
, "%s Size = %lu\n", indent
,
1011 sal::static_int_cast
< unsigned long >(valueSize
));
1013 stdout
, "%s Len = %lu\n", indent
,
1014 sal::static_int_cast
< unsigned long >(len
));
1015 fprintf(stdout
, "%s Data = ", indent
);
1017 sal_Int32 longValue
;
1018 for (sal_uInt32 i
=0; i
< len
; i
++)
1020 readINT32(aBuffer
.data() + offset
, longValue
);
1023 fprintf(stdout
, "%s ", indent
);
1026 stdout
, "%lu = %ld\n",
1027 sal::static_int_cast
< unsigned long >(i
),
1028 sal::static_int_cast
< long >(longValue
));
1029 offset
+= 4; // 4 Bytes for sal_Int32
1033 case RegValueType::STRINGLIST
:
1035 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array
1036 sal_uInt32 sLen
= 0;
1039 readUINT32(aBuffer
.data(), len
);
1041 fprintf(stdout
, "%sValue: Type = RegValueType::STRINGLIST\n", indent
);
1043 stdout
, "%s Size = %lu\n", indent
,
1044 sal::static_int_cast
< unsigned long >(valueSize
));
1046 stdout
, "%s Len = %lu\n", indent
,
1047 sal::static_int_cast
< unsigned long >(len
));
1048 fprintf(stdout
, "%s Data = ", indent
);
1050 for (sal_uInt32 i
=0; i
< len
; i
++)
1052 readUINT32(aBuffer
.data() + offset
, sLen
);
1054 offset
+= 4; // 4 bytes (sal_uInt32) for the string size
1056 char *pValue
= static_cast<char*>(std::malloc(sLen
));
1057 readUtf8(aBuffer
.data() + offset
, pValue
, sLen
);
1060 fprintf(stdout
, "%s ", indent
);
1063 stdout
, "%lu = \"%s\"\n",
1064 sal::static_int_cast
< unsigned long >(i
), pValue
);
1070 case RegValueType::UNICODELIST
:
1072 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array
1073 sal_uInt32 sLen
= 0;
1076 readUINT32(aBuffer
.data(), len
);
1078 fprintf(stdout
, "%sValue: Type = RegValueType::UNICODELIST\n", indent
);
1080 stdout
, "%s Size = %lu\n", indent
,
1081 sal::static_int_cast
< unsigned long >(valueSize
));
1083 stdout
, "%s Len = %lu\n", indent
,
1084 sal::static_int_cast
< unsigned long >(len
));
1085 fprintf(stdout
, "%s Data = ", indent
);
1088 for (sal_uInt32 i
=0; i
< len
; i
++)
1090 readUINT32(aBuffer
.data() + offset
, sLen
);
1092 offset
+= 4; // 4 bytes (sal_uInt32) for the string size
1094 sal_Unicode
*pValue
= static_cast<sal_Unicode
*>(std::malloc((sLen
/ 2) * sizeof(sal_Unicode
)));
1095 readString(aBuffer
.data() + offset
, pValue
, sLen
);
1098 fprintf(stdout
, "%s ", indent
);
1100 uStr
= OString(pValue
, rtl_ustr_getLength(pValue
), RTL_TEXTENCODING_UTF8
);
1102 stdout
, "%lu = L\"%s\"\n",
1103 sal::static_int_cast
< unsigned long >(i
),
1114 fprintf(stdout
, "\n");
1116 return RegError::NO_ERROR
;
1119 RegError
ORegistry::dumpKey(const OUString
& sPath
, const OUString
& sName
, sal_Int16 nSpace
) const
1121 OStoreDirectory rStoreDir
;
1122 OUString
sFullPath(sPath
);
1124 storeAccessMode accessMode
= storeAccessMode::ReadWrite
;
1125 RegError _ret
= RegError::NO_ERROR
;
1129 accessMode
= storeAccessMode::ReadOnly
;
1132 for (int i
= 0; i
< nSpace
; i
++) sIndent
+= " ";
1134 if (sFullPath
.getLength() > 1)
1137 storeError _err
= rStoreDir
.create(m_file
, sFullPath
, sName
, accessMode
);
1139 if (_err
== store_E_NotExists
)
1140 return RegError::KEY_NOT_EXISTS
;
1141 else if (_err
== store_E_WrongFormat
)
1142 return RegError::INVALID_KEY
;
1144 fprintf(stdout
, "%s/ %s\n", sIndent
.getStr(), OUStringToOString(sName
, RTL_TEXTENCODING_UTF8
).getStr());
1146 OUString
sSubPath(sFullPath
);
1150 OStoreDirectory::iterator iter
;
1152 _err
= rStoreDir
.first(iter
);
1154 while (_err
== store_E_None
)
1156 sSubName
= OUString(iter
.m_pszName
, iter
.m_nLength
);
1158 if (iter
.m_nAttrib
& STORE_ATTRIB_ISDIR
)
1160 _ret
= dumpKey(sSubPath
, sSubName
, nSpace
+2);
1163 _ret
= dumpValue(sSubPath
, sSubName
, nSpace
+2);
1166 if (_ret
!= RegError::NO_ERROR
)
1171 _err
= rStoreDir
.next(iter
);
1174 return RegError::NO_ERROR
;
1177 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */