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
);
647 sFullPath
.append('/');
649 } while(nIndex
!= -1);
652 pKey
= new ORegKey(sFullKeyName
, this);
654 m_openKeyTable
[sFullKeyName
] = pKey
;
656 return RegError::NO_ERROR
;
659 RegError
ORegistry::openKey(RegKeyHandle hKey
, std::u16string_view keyName
,
660 RegKeyHandle
* phOpenKey
)
664 *phOpenKey
= nullptr;
668 return RegError::INVALID_KEYNAME
;
674 pKey
= static_cast<ORegKey
*>(hKey
);
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
;
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
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
);
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();
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
);
739 return RegError::INVALID_KEYNAME
;
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
;
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
;
771 sFullKeyName
+= keyName
.substr(1);
773 sFullPath
= sFullKeyName
.copy(0, keyName
.rfind('/') + 1);
776 if (sFullKeyName
.getLength() > 1)
777 sFullKeyName
+= ROOT
;
779 sRelativKey
+= keyName
;
780 sFullKeyName
+= keyName
;
782 if (sFullPath
.getLength() > 1)
786 ORegKey
* pOldKey
= nullptr;
787 _ret
= pKey
->openKey(keyName
, reinterpret_cast<RegKeyHandle
*>(&pOldKey
));
788 if (_ret
!= RegError::NO_ERROR
)
791 _ret
= deleteSubkeysAndValues(pOldKey
);
792 if (_ret
!= RegError::NO_ERROR
)
794 pKey
->closeKey(pOldKey
);
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
)
832 OUString
sFullPath(pKey
->getName());
834 if (sFullPath
.getLength() > 1)
837 if (const_cast<OStoreFile
&>(pKey
->getStoreFile()).remove(sFullPath
, keyName
))
839 return RegError::DELETE_VALUE_FAILED
;
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
);
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);
878 _ret
= dumpValue(pKey
->getName(), sName
, 1);
881 if (_ret
!= RegError::NO_ERROR
)
886 _err
= rStoreDir
.next(iter
);
889 return RegError::NO_ERROR
;
892 RegError
ORegistry::dumpValue(const OUString
& sPath
, const OUString
& sName
, sal_Int16 nSpc
) const
895 sal_uInt32 valueSize
;
896 RegValueType valueType
;
897 OUString
sFullPath(sPath
);
899 storeAccessMode accessMode
= storeAccessMode::ReadWrite
;
903 accessMode
= storeAccessMode::ReadOnly
;
906 for (int i
= 0; i
< nSpc
; i
++) sIndent
+= " ";
908 if (sFullPath
.getLength() > 1)
912 if (rValue
.create(m_file
, sFullPath
, sName
, accessMode
))
914 return RegError::VALUE_NOT_EXISTS
;
917 std::vector
<sal_uInt8
> aBuffer(VALUE_HEADERSIZE
);
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();
946 case RegValueType::NOT_DEFINED
:
947 fprintf(stdout
, "%sValue: Type = VALUETYPE_NOT_DEFINED\n", indent
);
949 case RegValueType::LONG
:
951 fprintf(stdout
, "%sValue: Type = RegValueType::LONG\n", indent
);
953 stdout
, "%s Size = %lu\n", indent
,
954 sal::static_int_cast
< unsigned long >(valueSize
));
955 fprintf(stdout
, "%s Data = ", indent
);
958 readINT32(aBuffer
.data(), value
);
959 fprintf(stdout
, "%ld\n", sal::static_int_cast
< long >(value
));
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
);
968 stdout
, "%s Size = %lu\n", indent
,
969 sal::static_int_cast
< unsigned long >(valueSize
));
970 fprintf(stdout
, "%s Data = \"%s\"\n", indent
, value
);
974 case RegValueType::UNICODE
:
976 sal_uInt32 size
= (valueSize
/ 2) * sizeof(sal_Unicode
);
977 fprintf(stdout
, "%sValue: Type = RegValueType::UNICODE\n", indent
);
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());
990 case RegValueType::BINARY
:
992 fprintf(stdout
, "%sValue: Type = RegValueType::BINARY\n", indent
);
994 stdout
, "%s Size = %lu\n", indent
,
995 sal::static_int_cast
< unsigned long >(valueSize
));
996 fprintf(stdout
, "%s Data = ", indent
);
998 typereg::Reader(aBuffer
.data(), valueSize
),
1002 case RegValueType::LONGLIST
:
1004 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array
1007 readUINT32(aBuffer
.data(), len
);
1009 fprintf(stdout
, "%sValue: Type = RegValueType::LONGLIST\n", indent
);
1011 stdout
, "%s Size = %lu\n", indent
,
1012 sal::static_int_cast
< unsigned long >(valueSize
));
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
);
1024 fprintf(stdout
, "%s ", indent
);
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
1034 case RegValueType::STRINGLIST
:
1036 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array
1037 sal_uInt32 sLen
= 0;
1040 readUINT32(aBuffer
.data(), len
);
1042 fprintf(stdout
, "%sValue: Type = RegValueType::STRINGLIST\n", indent
);
1044 stdout
, "%s Size = %lu\n", indent
,
1045 sal::static_int_cast
< unsigned long >(valueSize
));
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
);
1061 fprintf(stdout
, "%s ", indent
);
1064 stdout
, "%lu = \"%s\"\n",
1065 sal::static_int_cast
< unsigned long >(i
), pValue
);
1071 case RegValueType::UNICODELIST
:
1073 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array
1074 sal_uInt32 sLen
= 0;
1077 readUINT32(aBuffer
.data(), len
);
1079 fprintf(stdout
, "%sValue: Type = RegValueType::UNICODELIST\n", indent
);
1081 stdout
, "%s Size = %lu\n", indent
,
1082 sal::static_int_cast
< unsigned long >(valueSize
));
1084 stdout
, "%s Len = %lu\n", indent
,
1085 sal::static_int_cast
< unsigned long >(len
));
1086 fprintf(stdout
, "%s Data = ", indent
);
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
);
1099 fprintf(stdout
, "%s ", indent
);
1101 uStr
= OString(pValue
, rtl_ustr_getLength(pValue
), RTL_TEXTENCODING_UTF8
);
1103 stdout
, "%lu = L\"%s\"\n",
1104 sal::static_int_cast
< unsigned long >(i
),
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
);
1125 storeAccessMode accessMode
= storeAccessMode::ReadWrite
;
1126 RegError _ret
= RegError::NO_ERROR
;
1130 accessMode
= storeAccessMode::ReadOnly
;
1133 for (int i
= 0; i
< nSpace
; i
++) sIndent
+= " ";
1135 if (sFullPath
.getLength() > 1)
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
);
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);
1164 _ret
= dumpValue(sSubPath
, sSubName
, nSpace
+2);
1167 if (_ret
!= RegError::NO_ERROR
)
1172 _err
= rStoreDir
.next(iter
);
1175 return RegError::NO_ERROR
;
1178 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */