LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/configmgr/source - writemodfile.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 182 298 61.1 %
Date: 2013-07-09 Functions: 20 31 64.5 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10