Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <sal/config.h>
21 :
22 : #include <cassert>
23 :
24 : #include <com/sun/star/uno/Any.hxx>
25 : #include <com/sun/star/uno/Reference.hxx>
26 : #include <com/sun/star/uno/RuntimeException.hpp>
27 : #include <com/sun/star/uno/Sequence.hxx>
28 : #include <com/sun/star/uno/XInterface.hpp>
29 : #include <osl/file.h>
30 : #include <osl/file.hxx>
31 : #include <rtl/string.h>
32 : #include <rtl/string.hxx>
33 : #include <rtl/textcvt.h>
34 : #include <rtl/textenc.h>
35 : #include <rtl/ustrbuf.hxx>
36 : #include <rtl/ustring.h>
37 : #include <rtl/ustring.hxx>
38 : #include <sal/log.hxx>
39 : #include <sal/types.h>
40 : #include <xmlreader/span.hxx>
41 :
42 : #include "data.hxx"
43 : #include "groupnode.hxx"
44 : #include "localizedpropertynode.hxx"
45 : #include "localizedvaluenode.hxx"
46 : #include "modifications.hxx"
47 : #include "node.hxx"
48 : #include "nodemap.hxx"
49 : #include "propertynode.hxx"
50 : #include "type.hxx"
51 : #include "writemodfile.hxx"
52 :
53 : namespace configmgr {
54 :
55 : class Components;
56 :
57 : namespace {
58 :
59 220512 : OString convertToUtf8(
60 : OUString const & text, sal_Int32 offset, sal_Int32 length)
61 : {
62 : assert(offset <= text.getLength() && text.getLength() - offset >= length);
63 220512 : OString s;
64 220512 : if (!rtl_convertUStringToString(
65 220512 : &s.pData, text.pData->buffer + offset, length,
66 : RTL_TEXTENCODING_UTF8,
67 : (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
68 220512 : RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
69 : {
70 : throw css::uno::RuntimeException(
71 0 : "cannot convert to UTF-8");
72 : }
73 220512 : return s;
74 : }
75 :
76 : struct TempFile {
77 : OUString url;
78 : oslFileHandle handle;
79 : bool closed;
80 :
81 1222 : TempFile(): handle(0), closed(false) {}
82 :
83 : ~TempFile();
84 : private:
85 : TempFile(const TempFile&) SAL_DELETED_FUNCTION;
86 : TempFile& operator=(const TempFile&) SAL_DELETED_FUNCTION;
87 : };
88 :
89 2444 : TempFile::~TempFile() {
90 1222 : if (handle != 0) {
91 0 : if (!closed) {
92 0 : oslFileError e = osl_closeFile(handle);
93 0 : if (e != osl_File_E_None) {
94 : SAL_WARN("configmgr", "osl_closeFile failed with " << +e);
95 : }
96 : }
97 0 : osl::FileBase::RC e = osl::File::remove(url);
98 0 : if (e != osl::FileBase::E_None) {
99 : SAL_WARN(
100 : "configmgr",
101 : "osl::File::remove(" << url << ") failed with " << +e);
102 : }
103 : }
104 1222 : }
105 :
106 1161485 : void writeData_(oslFileHandle handle, char const * begin, sal_Int32 length) {
107 : assert(length >= 0);
108 : sal_uInt64 n;
109 2322970 : if ((osl_writeFile(handle, begin, static_cast< sal_uInt32 >(length), &n) !=
110 2322970 : osl_File_E_None) ||
111 1161485 : n != static_cast< sal_uInt32 >(length))
112 : {
113 : throw css::uno::RuntimeException(
114 0 : "write failure");
115 : }
116 1161485 : }
117 :
118 : void writeValueContent_(oslFileHandle, bool) SAL_DELETED_FUNCTION;
119 : // silence lopluign:salbool
120 33146 : void writeValueContent_(oslFileHandle handle, sal_Bool value) {
121 33146 : if (value) {
122 16118 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("true"));
123 : } else {
124 17028 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("false"));
125 : }
126 33146 : }
127 :
128 2428 : void writeValueContent_(oslFileHandle handle, sal_Int16 value) {
129 2428 : writeData(handle, OString::number(value));
130 2428 : }
131 :
132 5478 : void writeValueContent_(oslFileHandle handle, sal_Int32 value) {
133 5478 : writeData(handle, OString::number(value));
134 5478 : }
135 :
136 0 : void writeValueContent_(oslFileHandle handle, sal_Int64 value) {
137 0 : writeData(handle, OString::number(value));
138 0 : }
139 :
140 0 : void writeValueContent_(oslFileHandle handle, double value) {
141 0 : writeData(handle, OString::number(value));
142 0 : }
143 :
144 38750 : void writeValueContent_(oslFileHandle handle, const OUString& value) {
145 38750 : writeValueContent(handle, value);
146 38750 : }
147 :
148 0 : void writeValueContent_(
149 : oslFileHandle handle, css::uno::Sequence< sal_Int8 > const & value)
150 : {
151 0 : for (sal_Int32 i = 0; i < value.getLength(); ++i) {
152 : static char const hexDigit[16] = {
153 : '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
154 : 'D', 'E', 'F' };
155 0 : writeData_(handle, hexDigit + ((value[i] >> 4) & 0xF), 1);
156 0 : writeData_(handle, hexDigit + (value[i] & 0xF), 1);
157 : }
158 0 : }
159 :
160 66530 : template< typename T > void writeSingleValue(
161 : oslFileHandle handle, css::uno::Any const & value)
162 : {
163 66530 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM(">"));
164 66530 : T val = T();
165 66530 : value >>= val;
166 66530 : writeValueContent_(handle, val);
167 66530 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</value>"));
168 66530 : }
169 :
170 2 : template< typename T > void writeListValue(
171 : oslFileHandle handle, css::uno::Any const & value)
172 : {
173 2 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM(">"));
174 2 : css::uno::Sequence< T > val;
175 2 : value >>= val;
176 12 : for (sal_Int32 i = 0; i < val.getLength(); ++i) {
177 10 : if (i != 0) {
178 8 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM(" "));
179 : }
180 10 : writeValueContent_(handle, val[i]);
181 : }
182 2 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</value>"));
183 2 : }
184 :
185 13238 : template< typename T > void writeItemListValue(
186 : oslFileHandle handle, css::uno::Any const & value)
187 : {
188 13238 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM(">"));
189 13238 : css::uno::Sequence< T > val;
190 13238 : value >>= val;
191 26500 : for (sal_Int32 i = 0; i < val.getLength(); ++i) {
192 13262 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<it>"));
193 13262 : writeValueContent_(handle, val[i]);
194 13262 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</it>"));
195 : }
196 13238 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</value>"));
197 13238 : }
198 :
199 79770 : void writeValue(oslFileHandle handle, Type type, css::uno::Any const & value) {
200 79770 : switch (type) {
201 : case TYPE_BOOLEAN:
202 33146 : writeSingleValue< sal_Bool >(handle, value);
203 33146 : break;
204 : case TYPE_SHORT:
205 2428 : writeSingleValue< sal_Int16 >(handle, value);
206 2428 : break;
207 : case TYPE_INT:
208 5468 : writeSingleValue< sal_Int32 >(handle, value);
209 5468 : break;
210 : case TYPE_LONG:
211 0 : writeSingleValue< sal_Int64 >(handle, value);
212 0 : break;
213 : case TYPE_DOUBLE:
214 0 : writeSingleValue< double >(handle, value);
215 0 : break;
216 : case TYPE_STRING:
217 25488 : writeSingleValue< OUString >(handle, value);
218 25488 : break;
219 : case TYPE_HEXBINARY:
220 0 : writeSingleValue< css::uno::Sequence< sal_Int8 > >(handle, value);
221 0 : break;
222 : case TYPE_BOOLEAN_LIST:
223 0 : writeListValue< sal_Bool >(handle, value);
224 0 : break;
225 : case TYPE_SHORT_LIST:
226 0 : writeListValue< sal_Int16 >(handle, value);
227 0 : break;
228 : case TYPE_INT_LIST:
229 2 : writeListValue< sal_Int32 >(handle, value);
230 2 : break;
231 : case TYPE_LONG_LIST:
232 0 : writeListValue< sal_Int64 >(handle, value);
233 0 : break;
234 : case TYPE_DOUBLE_LIST:
235 0 : writeListValue< double >(handle, value);
236 0 : break;
237 : case TYPE_STRING_LIST:
238 13238 : writeItemListValue< OUString >(handle, value);
239 13238 : break;
240 : case TYPE_HEXBINARY_LIST:
241 0 : writeItemListValue< css::uno::Sequence< sal_Int8 > >(handle, value);
242 0 : break;
243 : default: // TYPE_ERROR, TYPE_NIL, TYPE_ANY
244 : assert(false); // this cannot happen
245 : }
246 79770 : }
247 :
248 103544 : void writeNode(
249 : Components & components, oslFileHandle handle,
250 : rtl::Reference< Node > const & parent, OUString const & name,
251 : rtl::Reference< Node > const & node)
252 : {
253 : static xmlreader::Span const typeNames[] = {
254 : xmlreader::Span(), xmlreader::Span(), xmlreader::Span(),
255 : // TYPE_ERROR, TYPE_NIL, TYPE_ANY
256 : xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:boolean")),
257 : xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:short")),
258 : xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:int")),
259 : xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:long")),
260 : xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:double")),
261 : xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:string")),
262 : xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:hexBinary")),
263 : xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:boolean-list")),
264 : xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:short-list")),
265 : xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:int-list")),
266 : xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:long-list")),
267 : xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:double-list")),
268 : xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:string-list")),
269 103544 : xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:hexBinary-list")) };
270 103544 : switch (node->kind()) {
271 : case Node::KIND_PROPERTY:
272 : {
273 88655 : PropertyNode * prop = static_cast< PropertyNode * >(node.get());
274 88655 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<prop oor:name=\""));
275 88655 : writeAttributeValue(handle, name);
276 : writeData_(
277 88655 : handle, RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"fuse\""));
278 88655 : Type type = prop->getStaticType();
279 88655 : Type dynType = getDynamicType(prop->getValue(components));
280 : assert(dynType != TYPE_ERROR);
281 88655 : if (type == TYPE_ANY) {
282 20019 : type = dynType;
283 20019 : if (type != TYPE_NIL) {
284 : writeData_(
285 20019 : handle, RTL_CONSTASCII_STRINGPARAM(" oor:type=\""));
286 : writeData_(
287 20019 : handle, typeNames[type].begin, typeNames[type].length);
288 20019 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\""));
289 : }
290 : }
291 88655 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("><value"));
292 88655 : if (dynType == TYPE_NIL) {
293 : writeData_(
294 11053 : handle, RTL_CONSTASCII_STRINGPARAM(" xsi:nil=\"true\"/>"));
295 : } else {
296 77602 : writeValue(handle, type, prop->getValue(components));
297 : }
298 88655 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</prop>"));
299 : }
300 88655 : break;
301 : case Node::KIND_LOCALIZED_PROPERTY:
302 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<prop oor:name=\""));
303 0 : writeAttributeValue(handle, name);
304 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"fuse\">"));
305 0 : for (NodeMap::const_iterator i(node->getMembers().begin());
306 0 : i != node->getMembers().end(); ++i)
307 : {
308 0 : writeNode(components, handle, node, i->first, i->second);
309 : }
310 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</prop>"));
311 0 : break;
312 : case Node::KIND_LOCALIZED_VALUE:
313 : {
314 2168 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<value"));
315 2168 : if (!name.isEmpty()) {
316 2168 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM(" xml:lang=\""));
317 2168 : writeAttributeValue(handle, name);
318 2168 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\""));
319 : }
320 2168 : Type type = static_cast< LocalizedPropertyNode * >(parent.get())->
321 2168 : getStaticType();
322 : css::uno::Any value(
323 2168 : static_cast< LocalizedValueNode * >(node.get())->getValue());
324 2168 : Type dynType = getDynamicType(value);
325 : assert(dynType != TYPE_ERROR);
326 2168 : if (type == TYPE_ANY) {
327 0 : type = dynType;
328 0 : if (type != TYPE_NIL) {
329 : writeData_(
330 0 : handle, RTL_CONSTASCII_STRINGPARAM(" oor:type=\""));
331 : writeData_(
332 0 : handle, typeNames[type].begin, typeNames[type].length);
333 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\""));
334 : }
335 : }
336 2168 : if (dynType == TYPE_NIL) {
337 : writeData_(
338 0 : handle, RTL_CONSTASCII_STRINGPARAM(" xsi:nil=\"true\"/>"));
339 : } else {
340 2168 : writeValue(handle, type, value);
341 2168 : }
342 : }
343 2168 : break;
344 : case Node::KIND_GROUP:
345 : case Node::KIND_SET:
346 12721 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<node oor:name=\""));
347 12721 : writeAttributeValue(handle, name);
348 12721 : if (!node->getTemplateName().isEmpty()) { // set member
349 : writeData_(
350 6545 : handle, RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"replace"));
351 : }
352 12721 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\">"));
353 115287 : for (NodeMap::const_iterator i(node->getMembers().begin());
354 76858 : i != node->getMembers().end(); ++i)
355 : {
356 25708 : writeNode(components, handle, node, i->first, i->second);
357 : }
358 12721 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</node>"));
359 12721 : break;
360 : case Node::KIND_ROOT:
361 : assert(false); // this cannot happen
362 0 : break;
363 : }
364 103544 : }
365 :
366 107505 : void writeModifications(
367 : Components & components, oslFileHandle handle,
368 : OUString const & parentPathRepresentation,
369 : rtl::Reference< Node > const & parent, OUString const & nodeName,
370 : rtl::Reference< Node > const & node,
371 : Modifications::Node const & modifications)
372 : {
373 : // It is never necessary to write oor:finalized or oor:mandatory attributes,
374 : // as they cannot be set via the UNO API.
375 107505 : if (modifications.children.empty()) {
376 : assert(parent.is());
377 : // components themselves have no parent but must have children
378 78027 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<item oor:path=\""));
379 78027 : writeAttributeValue(handle, parentPathRepresentation);
380 78027 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\">"));
381 78027 : if (node.is()) {
382 77836 : writeNode(components, handle, parent, nodeName, node);
383 : } else {
384 191 : switch (parent->kind()) {
385 : case Node::KIND_LOCALIZED_PROPERTY:
386 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<value"));
387 0 : if (!nodeName.isEmpty()) {
388 : writeData_(
389 0 : handle, RTL_CONSTASCII_STRINGPARAM(" xml:lang=\""));
390 0 : writeAttributeValue(handle, nodeName);
391 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\""));
392 : }
393 : writeData_(
394 0 : handle, RTL_CONSTASCII_STRINGPARAM(" oor:op=\"remove\"/>"));
395 0 : break;
396 : case Node::KIND_GROUP:
397 : assert(
398 : static_cast< GroupNode * >(parent.get())->isExtensible());
399 : writeData_(
400 0 : handle, RTL_CONSTASCII_STRINGPARAM("<prop oor:name=\""));
401 0 : writeAttributeValue(handle, nodeName);
402 : writeData_(
403 : handle,
404 0 : RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"remove\"/>"));
405 0 : break;
406 : case Node::KIND_SET:
407 : writeData_(
408 191 : handle, RTL_CONSTASCII_STRINGPARAM("<node oor:name=\""));
409 191 : writeAttributeValue(handle, nodeName);
410 : writeData_(
411 : handle,
412 191 : RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"remove\"/>"));
413 191 : break;
414 : default:
415 : assert(false); // this cannot happen
416 0 : break;
417 : }
418 : }
419 78027 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</item>\n"));
420 : } else {
421 : assert(node.is());
422 : OUString pathRep(
423 58956 : parentPathRepresentation + "/" +
424 88434 : Data::createSegment(node->getTemplateName(), nodeName));
425 392148 : for (Modifications::Node::Children::const_iterator i(
426 29478 : modifications.children.begin());
427 261432 : i != modifications.children.end(); ++i)
428 : {
429 : writeModifications(
430 101238 : components, handle, pathRep, node, i->first,
431 202476 : node->getMember(i->first), i->second);
432 29478 : }
433 : }
434 107505 : }
435 :
436 : }
437 :
438 228418 : void writeData(oslFileHandle handle, OString const & text) {
439 228418 : writeData_(handle, text.getStr(), text.getLength());
440 228418 : }
441 :
442 181762 : void writeAttributeValue(oslFileHandle handle, OUString const & value) {
443 181762 : sal_Int32 i = 0;
444 181762 : sal_Int32 j = i;
445 8425787 : for (; j < value.getLength(); ++j) {
446 : assert(
447 : value[j] == 0x0009 || value[j] == 0x000A || value[j] == 0x000D ||
448 : (value[j] >= 0x0020 && value[j] != 0xFFFE && value[j] != 0xFFFF));
449 8244025 : switch(value[j]) {
450 : case '\x09':
451 0 : writeData(handle, convertToUtf8(value, i, j - i));
452 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("	"));
453 0 : i = j + 1;
454 0 : break;
455 : case '\x0A':
456 0 : writeData(handle, convertToUtf8(value, i, j - i));
457 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("
"));
458 0 : i = j + 1;
459 0 : break;
460 : case '\x0D':
461 0 : writeData(handle, convertToUtf8(value, i, j - i));
462 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("
"));
463 0 : i = j + 1;
464 0 : break;
465 : case '"':
466 0 : writeData(handle, convertToUtf8(value, i, j - i));
467 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("""));
468 0 : i = j + 1;
469 0 : break;
470 : case '&':
471 0 : writeData(handle, convertToUtf8(value, i, j - i));
472 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("&"));
473 0 : i = j + 1;
474 0 : break;
475 : case '<':
476 0 : writeData(handle, convertToUtf8(value, i, j - i));
477 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<"));
478 0 : i = j + 1;
479 0 : break;
480 : default:
481 8244025 : break;
482 : }
483 : }
484 181762 : writeData(handle, convertToUtf8(value, i, j - i));
485 181762 : }
486 :
487 38750 : void writeValueContent(oslFileHandle handle, OUString const & value) {
488 38750 : sal_Int32 i = 0;
489 38750 : sal_Int32 j = i;
490 890471 : for (; j < value.getLength(); ++j) {
491 851721 : sal_Unicode c = value[j];
492 851721 : if ((c < 0x0020 && c != 0x0009 && c != 0x000A && c != 0x000D) ||
493 851721 : c == 0xFFFE || c == 0xFFFF)
494 : {
495 0 : writeData(handle, convertToUtf8(value, i, j - i));
496 : writeData_(
497 0 : handle, RTL_CONSTASCII_STRINGPARAM("<unicode oor:scalar=\""));
498 : writeData(
499 0 : handle, OString::number(c));
500 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\"/>"));
501 0 : i = j + 1;
502 851721 : } else if (c == '\x0D') {
503 0 : writeData(handle, convertToUtf8(value, i, j - i));
504 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("
"));
505 0 : i = j + 1;
506 851721 : } else if (c == '&') {
507 0 : writeData(handle, convertToUtf8(value, i, j - i));
508 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("&"));
509 0 : i = j + 1;
510 851721 : } else if (c == '<') {
511 0 : writeData(handle, convertToUtf8(value, i, j - i));
512 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<"));
513 0 : i = j + 1;
514 851721 : } else if (c == '>') {
515 : // "MUST, for compatibility, be escaped [...] when it appears in the
516 : // string ']]>'":
517 0 : writeData(handle, convertToUtf8(value, i, j - i));
518 0 : writeData_(handle, RTL_CONSTASCII_STRINGPARAM(">"));
519 0 : i = j + 1;
520 : }
521 : }
522 38750 : writeData(handle, convertToUtf8(value, i, j - i));
523 38750 : }
524 :
525 1222 : void writeModFile(
526 : Components & components, OUString const & url, Data const & data)
527 : {
528 1222 : sal_Int32 i = url.lastIndexOf('/');
529 : assert(i != -1);
530 1222 : OUString dir(url.copy(0, i));
531 1222 : switch (osl::Directory::createPath(dir)) {
532 : case osl::FileBase::E_None:
533 : case osl::FileBase::E_EXIST:
534 1222 : break;
535 : case osl::FileBase::E_ACCES:
536 : SAL_INFO(
537 : "configmgr",
538 : ("cannot create registrymodifications.xcu path (E_ACCES); changes"
539 : " will be lost"));
540 0 : return;
541 : default:
542 : throw css::uno::RuntimeException(
543 0 : "cannot create directory " + dir);
544 : }
545 1222 : TempFile tmp;
546 1222 : switch (osl::FileBase::createTempFile(&dir, &tmp.handle, &tmp.url)) {
547 : case osl::FileBase::E_None:
548 1222 : break;
549 : case osl::FileBase::E_ACCES:
550 : SAL_INFO(
551 : "configmgr",
552 : ("cannot create temp registrymodifications.xcu (E_ACCES); changes"
553 : " will be lost"));
554 0 : return;
555 : default:
556 : throw css::uno::RuntimeException(
557 0 : "cannot create temporary file in " + dir);
558 : }
559 : writeData_(
560 : tmp.handle,
561 : RTL_CONSTASCII_STRINGPARAM(
562 : "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<oor:items"
563 : " xmlns:oor=\"http://openoffice.org/2001/registry\""
564 : " xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
565 1222 : " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"));
566 : //TODO: Do not write back information about those removed items that did not
567 : // come from the .xcs/.xcu files, anyway (but had been added dynamically
568 : // instead):
569 22467 : for (Modifications::Node::Children::const_iterator j(
570 1222 : data.modifications.getRoot().children.begin());
571 14978 : j != data.modifications.getRoot().children.end(); ++j)
572 : {
573 : writeModifications(
574 6267 : components, tmp.handle, "", rtl::Reference< Node >(), j->first,
575 12534 : data.getComponents().findNode(Data::NO_LAYER, j->first),
576 25068 : j->second);
577 : }
578 1222 : writeData_(tmp.handle, RTL_CONSTASCII_STRINGPARAM("</oor:items>\n"));
579 1222 : oslFileError e = osl_closeFile(tmp.handle);
580 1222 : tmp.closed = true;
581 1222 : if (e != osl_File_E_None) {
582 : throw css::uno::RuntimeException(
583 0 : "cannot close " + tmp.url);
584 : }
585 1222 : if (osl::File::move(tmp.url, url) != osl::FileBase::E_None) {
586 : throw css::uno::RuntimeException(
587 0 : "cannot move " + tmp.url);
588 : }
589 1222 : tmp.handle = 0;
590 : }
591 :
592 : }
593 :
594 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|