LCOV - code coverage report
Current view: top level - configmgr/source - writemodfile.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 184 292 63.0 %
Date: 2015-06-13 12:38:46 Functions: 21 32 65.6 %
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 <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("&#9;"));
     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("&#xA;"));
     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("&#xD;"));
     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("&quot;"));
     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("&amp;"));
     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("&lt;"));
     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("&#xD;"));
     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("&amp;"));
     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("&lt;"));
     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("&gt;"));
     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: */

Generated by: LCOV version 1.11