27#include <com/sun/star/uno/Any.hxx>
28#include <com/sun/star/uno/RuntimeException.hpp>
29#include <com/sun/star/uno/Sequence.hxx>
32#include <osl/file.hxx>
33#include <rtl/string.h>
34#include <rtl/string.hxx>
35#include <rtl/textcvt.h>
36#include <rtl/textenc.h>
37#include <rtl/ustring.hxx>
38#include <rtl/strbuf.hxx>
60OString convertToUtf8(std::u16string_view text) {
63 if (!rtl_convertUStringToString(
65 RTL_TEXTENCODING_UTF8,
66 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
67 RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
69 throw css::uno::RuntimeException(
70 "cannot convert to UTF-8");
82 oslFileError e = osl_closeFile(
handle);
83 if (e != osl_File_E_None) {
84 SAL_WARN(
"configmgr",
"osl_closeFile failed with " << +e);
87 osl::FileBase::RC e = osl::File::remove(
url);
88 if (e != osl::FileBase::E_None) {
91 "osl::File::remove(" <<
url <<
") failed with " << +e);
96oslFileError TempFile::closeWithoutUnlink() {
98 oslFileError e = osl_closeFile(
handle);
106 oslFileError e =
flush();
107 if (e != osl_File_E_None) {
108 throw css::uno::RuntimeException(
109 "cannot write to " +
url);
111 e = osl_closeFile(
handle);
113 if (e != osl_File_E_None) {
114 throw css::uno::RuntimeException(
115 "cannot close " +
url);
117 if (osl::File::replace(
url, _url) != osl::FileBase::E_None) {
118 throw css::uno::RuntimeException(
119 "cannot move " +
url);
125 oslFileError e = osl_File_E_None;
127 sal_uInt64 nBytesWritten = 0;
129 static_cast< sal_uInt32
>(
buffer.getLength()),
131 if (nBytesWritten !=
static_cast< sal_uInt32
>(
buffer.getLength())) {
133 buffer.remove(0,
static_cast< sal_Int32
>( nBytesWritten ) );
143 if (
buffer.getLength() > 0x10000)
149void writeValueContent_(
TempFile &,
bool) =
delete;
159void writeValueContent_(TempFile &handle, sal_Int16 value) {
160 handle.writeString(OString::number(value));
163void writeValueContent_(TempFile &handle, sal_Int32 value) {
164 handle.writeString(OString::number(value));
167void writeValueContent_(TempFile &handle, sal_Int64 value) {
168 handle.writeString(OString::number(value));
171void writeValueContent_(TempFile &handle,
double value) {
172 handle.writeString(OString::number(value));
175void writeValueContent_(TempFile &handle, std::u16string_view value) {
179void writeValueContent_(
180 TempFile &handle, css::uno::Sequence< sal_Int8 >
const & value)
182 for (
const auto & v : value) {
183 static char const hexDigit[16] = {
184 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
187 std::string_view(hexDigit + ((v >> 4) & 0xF), 1));
188 handle.writeString(std::string_view(hexDigit + (v & 0xF), 1));
192template<
typename T >
void writeSingleValue(
193 TempFile &handle, css::uno::Any
const & value)
195 handle.writeString(
">");
198 writeValueContent_(handle, val);
199 handle.writeString(
"</value>");
202template<
typename T >
void writeListValue(
203 TempFile &handle, css::uno::Any
const & value)
205 handle.writeString(
">");
206 css::uno::Sequence< T > val;
208 for (sal_Int32 i = 0;
i < val.getLength(); ++
i) {
210 handle.writeString(
" ");
212 writeValueContent_(handle, std::as_const(val)[i]);
214 handle.writeString(
"</value>");
217template<
typename T >
void writeItemListValue(
218 TempFile &handle, css::uno::Any
const & value)
220 handle.writeString(
">");
221 css::uno::Sequence< T > val;
223 for (
const auto & i : std::as_const(val)) {
224 handle.writeString(
"<it>");
225 writeValueContent_(handle, i);
226 handle.writeString(
"</it>");
228 handle.writeString(
"</value>");
231void writeValue(TempFile &handle,
Type type, css::uno::Any
const & value) {
234 writeSingleValue< sal_Bool >(handle, value);
237 writeSingleValue< sal_Int16 >(handle, value);
240 writeSingleValue< sal_Int32 >(handle, value);
243 writeSingleValue< sal_Int64 >(handle, value);
246 writeSingleValue< double >(handle, value);
249 writeSingleValue< OUString >(handle, value);
252 writeSingleValue< css::uno::Sequence< sal_Int8 > >(handle,
value);
255 writeListValue< sal_Bool >(handle, value);
258 writeListValue< sal_Int16 >(handle, value);
261 writeListValue< sal_Int32 >(handle, value);
264 writeListValue< sal_Int64 >(handle, value);
267 writeListValue< double >(handle, value);
270 writeItemListValue< OUString >(handle, value);
273 writeItemListValue< css::uno::Sequence< sal_Int8 > >(handle,
value);
302 switch (node->kind()) {
305 PropertyNode * prop =
static_cast< PropertyNode *
>(node.get());
306 handle.writeString(
"<prop oor:name=\"");
308 handle.writeString(
"\" oor:op=\"fuse\"");
315 handle.writeString(
" oor:type=\"");
318 typeNames[type].begin, typeNames[type].length));
319 handle.writeString(
"\"");
322 handle.writeString(
"><value");
324 handle.writeString(
" xsi:nil=\"true\"/>");
326 writeValue(handle, type, prop->getValue(components));
328 handle.writeString(
"</prop>");
332 handle.writeString(
"<prop oor:name=\"");
334 handle.writeString(
"\" oor:op=\"fuse\">");
335 for (
auto const& member : node->getMembers())
337 writeNode(components, handle, node, member.first, member.second);
339 handle.writeString(
"</prop>");
343 handle.writeString(
"<value");
345 handle.writeString(
" xml:lang=\"");
347 handle.writeString(
"\"");
349 Type type =
static_cast< LocalizedPropertyNode *
>(parent.get())->
352 static_cast< LocalizedValueNode *
>(node.get())->getValue());
358 handle.writeString(
" oor:type=\"");
361 typeNames[type].begin, typeNames[type].length));
362 handle.writeString(
"\"");
366 handle.writeString(
" xsi:nil=\"true\"/>");
368 writeValue(handle, type, value);
374 handle.writeString(
"<node oor:name=\"");
376 if (!node->getTemplateName().isEmpty()) {
377 handle.writeString(
"\" oor:op=\"replace");
379 handle.writeString(
"\">");
380 for (
auto const& member : node->getMembers())
382 writeNode(components, handle, node, member.first, member.second);
384 handle.writeString(
"</node>");
393typedef std::pair< const OUString, configmgr::Modifications::Node > ModNodePairEntry;
394struct PairEntrySorter
396 bool operator() (
const ModNodePairEntry* pValue1,
const ModNodePairEntry* pValue2)
const
398 return pValue1->first.compareTo(pValue2->first) < 0;
404 std::u16string_view parentPathRepresentation,
407 Modifications::Node
const & modifications)
411 if (modifications.children.empty()) {
414 handle.writeString(
"<item oor:path=\"");
416 handle.writeString(
"\">");
418 writeNode(components, handle, parent, nodeName, node);
420 switch (parent->kind()) {
422 handle.writeString(
"<value");
423 if (!nodeName.isEmpty()) {
424 handle.writeString(
" xml:lang=\"");
426 handle.writeString(
"\"");
428 handle.writeString(
" oor:op=\"remove\"/>");
432 static_cast< GroupNode *
>(parent.get())->isExtensible());
433 handle.writeString(
"<prop oor:name=\"");
435 handle.writeString(
"\" oor:op=\"remove\"/>");
438 handle.writeString(
"<node oor:name=\"");
440 handle.writeString(
"\" oor:op=\"remove\"/>");
447 handle.writeString(
"</item>\n");
451 OUString::Concat(parentPathRepresentation) +
"/" +
456 std::vector< const ModNodePairEntry* > ModNodePairEntryVector;
457 ModNodePairEntryVector.reserve(modifications.children.size());
459 for (
const auto& rCand : modifications.children)
461 ModNodePairEntryVector.push_back(&rCand);
465 std::sort(ModNodePairEntryVector.begin(), ModNodePairEntryVector.end(), PairEntrySorter());
469 for (
const auto & i : ModNodePairEntryVector)
472 components, handle, pathRep, node,
i->first,
473 node->getMember(
i->first),
i->second);
483 for (; j !=
value.size(); ++j) {
528 for (; j !=
value.size(); ++j) {
529 char16_t c =
value[j];
530 if ((c < 0x0020 && c != 0x0009 && c != 0x000A && c != 0x000D) ||
531 c == 0xFFFE || c == 0xFFFF)
538 }
else if (c ==
'\x0D') {
542 }
else if (c ==
'&') {
546 }
else if (c ==
'<') {
550 }
else if (c ==
'>') {
564 sal_Int32
i = url.lastIndexOf(
'/');
566 OUString dir(url.copy(0,
i));
567 switch (osl::Directory::createPath(dir)) {
568 case osl::FileBase::E_None:
569 case osl::FileBase::E_EXIST:
571 case osl::FileBase::E_ACCES:
574 (
"cannot create registrymodifications.xcu path (E_ACCES); changes"
578 throw css::uno::RuntimeException(
579 "cannot create directory " + dir);
582 switch (osl::FileBase::createTempFile(&dir, &tmp.
handle, &tmp.
url)) {
583 case osl::FileBase::E_None:
585 case osl::FileBase::E_ACCES:
588 (
"cannot create temp registrymodifications.xcu (E_ACCES); changes"
592 throw css::uno::RuntimeException(
593 "cannot create temporary file in " + dir);
596 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<oor:items"
597 " xmlns:oor=\"http://openoffice.org/2001/registry\""
598 " xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
599 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n");
614 std::vector< const ModNodePairEntry* > ModNodePairEntryVector;
619 ModNodePairEntryVector.push_back(&rCand);
623 std::sort(ModNodePairEntryVector.begin(), ModNodePairEntryVector.end(), PairEntrySorter());
627 for (
const auto& j : ModNodePairEntryVector)
Node const & getRoot() const
rtl::Reference< Node > findNode(int layer, OUString const &name) const
@ KIND_LOCALIZED_PROPERTY
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
void writeModifications(Components &components, Data &data)
void writeValueContent(TempFile &handle, std::u16string_view value)
void writeModFile(Components &components, OUString const &url, Data const &data)
Type getDynamicType(css::uno::Any const &value)
void writeAttributeValue(TempFile &handle, std::u16string_view value)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
Modifications modifications
NodeMap & getComponents() const
static OUString createSegment(std::u16string_view templateName, OUString const &name)
void writeString(std::string_view text)
void closeAndRename(const OUString &url)
std::vector< uno::Reference< sheet::XSpreadsheetDocument > > Components