LCOV - code coverage report
Current view: top level - configmgr/source - writemodfile.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 184 292 63.0 %
Date: 2014-11-03 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 <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      623458 : OString convertToUtf8(
      61             :     OUString const & text, sal_Int32 offset, sal_Int32 length)
      62             : {
      63             :     assert(offset <= text.getLength() && text.getLength() - offset >= length);
      64      623458 :     OString s;
      65      623458 :     if (!rtl_convertUStringToString(
      66      623458 :             &s.pData, text.pData->buffer + offset, length,
      67             :             RTL_TEXTENCODING_UTF8,
      68             :             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
      69      623458 :              RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
      70             :     {
      71             :         throw css::uno::RuntimeException(
      72           0 :             "cannot convert to UTF-8");
      73             :     }
      74      623458 :     return s;
      75             : }
      76             : 
      77             : struct TempFile: public boost::noncopyable {
      78             :     OUString url;
      79             :     oslFileHandle handle;
      80             :     bool closed;
      81             : 
      82        1354 :     TempFile(): handle(0), closed(false) {}
      83             : 
      84             :     ~TempFile();
      85             : };
      86             : 
      87        2708 : TempFile::~TempFile() {
      88        1354 :     if (handle != 0) {
      89           0 :         if (!closed) {
      90           0 :             oslFileError e = osl_closeFile(handle);
      91           0 :             if (e != osl_File_E_None) {
      92             :                 SAL_WARN("configmgr", "osl_closeFile failed with " << +e);
      93             :             }
      94             :         }
      95           0 :         osl::FileBase::RC e = osl::File::remove(url);
      96           0 :         if (e != osl::FileBase::E_None) {
      97             :             SAL_WARN(
      98             :                 "configmgr",
      99             :                 "osl::File::remove(" << url << ") failed with " << +e);
     100             :         }
     101             :     }
     102        1354 : }
     103             : 
     104     3428011 : void writeData_(oslFileHandle handle, char const * begin, sal_Int32 length) {
     105             :     assert(length >= 0);
     106             :     sal_uInt64 n;
     107     6856022 :     if ((osl_writeFile(handle, begin, static_cast< sal_uInt32 >(length), &n) !=
     108     6856022 :          osl_File_E_None) ||
     109     3428011 :         n != static_cast< sal_uInt32 >(length))
     110             :     {
     111             :         throw css::uno::RuntimeException(
     112           0 :             "write failure");
     113             :     }
     114     3428011 : }
     115             : 
     116             : void writeValueContent_(oslFileHandle, bool) SAL_DELETED_FUNCTION;
     117             :     // silence lopluign:salbool
     118       40849 : void writeValueContent_(oslFileHandle handle, sal_Bool value) {
     119       40849 :     if (value) {
     120       20331 :         writeData_(handle, RTL_CONSTASCII_STRINGPARAM("true"));
     121             :     } else {
     122       20518 :         writeData_(handle, RTL_CONSTASCII_STRINGPARAM("false"));
     123             :     }
     124       40849 : }
     125             : 
     126        2708 : void writeValueContent_(oslFileHandle handle, sal_Int16 value) {
     127        2708 :     writeData(handle, OString::number(value));
     128        2708 : }
     129             : 
     130        7675 : void writeValueContent_(oslFileHandle handle, sal_Int32 value) {
     131        7675 :     writeData(handle, OString::number(value));
     132        7675 : }
     133             : 
     134           0 : void writeValueContent_(oslFileHandle handle, sal_Int64 value) {
     135           0 :     writeData(handle, OString::number(value));
     136           0 : }
     137             : 
     138           0 : void writeValueContent_(oslFileHandle handle, double value) {
     139           0 :     writeData(handle, OString::number(value));
     140           0 : }
     141             : 
     142      165687 : void writeValueContent_(oslFileHandle handle, const OUString& value) {
     143      165687 :     writeValueContent(handle, value);
     144      165687 : }
     145             : 
     146           0 : void writeValueContent_(
     147             :     oslFileHandle handle, css::uno::Sequence< sal_Int8 > const & value)
     148             : {
     149           0 :     for (sal_Int32 i = 0; i < value.getLength(); ++i) {
     150             :         static char const hexDigit[16] = {
     151             :             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
     152             :             'D', 'E', 'F' };
     153           0 :         writeData_(handle, hexDigit + ((value[i] >> 4) & 0xF), 1);
     154           0 :         writeData_(handle, hexDigit + (value[i] & 0xF), 1);
     155             :     }
     156           0 : }
     157             : 
     158       82245 : template< typename T > void writeSingleValue(
     159             :     oslFileHandle handle, css::uno::Any const & value)
     160             : {
     161       82245 :     writeData_(handle, RTL_CONSTASCII_STRINGPARAM(">"));
     162       82245 :     T val = T();
     163       82245 :     value >>= val;
     164       82245 :     writeValueContent_(handle, val);
     165       82245 :     writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</value>"));
     166       82245 : }
     167             : 
     168           4 : template< typename T > void writeListValue(
     169             :     oslFileHandle handle, css::uno::Any const & value)
     170             : {
     171           4 :     writeData_(handle, RTL_CONSTASCII_STRINGPARAM(">"));
     172           4 :     css::uno::Sequence< T > val;
     173           4 :     value >>= val;
     174          24 :     for (sal_Int32 i = 0; i < val.getLength(); ++i) {
     175          20 :         if (i != 0) {
     176          16 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM(" "));
     177             :         }
     178          20 :         writeValueContent_(handle, val[i]);
     179             :     }
     180           4 :     writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</value>"));
     181           4 : }
     182             : 
     183      134570 : template< typename T > void writeItemListValue(
     184             :     oslFileHandle handle, css::uno::Any const & value)
     185             : {
     186      134570 :     writeData_(handle, RTL_CONSTASCII_STRINGPARAM(">"));
     187      134570 :     css::uno::Sequence< T > val;
     188      134570 :     value >>= val;
     189      269224 :     for (sal_Int32 i = 0; i < val.getLength(); ++i) {
     190      134654 :         writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<it>"));
     191      134654 :         writeValueContent_(handle, val[i]);
     192      134654 :         writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</it>"));
     193             :     }
     194      134570 :     writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</value>"));
     195      134570 : }
     196             : 
     197      216819 : void writeValue(oslFileHandle handle, Type type, css::uno::Any const & value) {
     198      216819 :     switch (type) {
     199             :     case TYPE_BOOLEAN:
     200       40849 :         writeSingleValue< sal_Bool >(handle, value);
     201       40849 :         break;
     202             :     case TYPE_SHORT:
     203        2708 :         writeSingleValue< sal_Int16 >(handle, value);
     204        2708 :         break;
     205             :     case TYPE_INT:
     206        7655 :         writeSingleValue< sal_Int32 >(handle, value);
     207        7655 :         break;
     208             :     case TYPE_LONG:
     209           0 :         writeSingleValue< sal_Int64 >(handle, value);
     210           0 :         break;
     211             :     case TYPE_DOUBLE:
     212           0 :         writeSingleValue< double >(handle, value);
     213           0 :         break;
     214             :     case TYPE_STRING:
     215       31033 :         writeSingleValue< OUString >(handle, value);
     216       31033 :         break;
     217             :     case TYPE_HEXBINARY:
     218           0 :         writeSingleValue< css::uno::Sequence< sal_Int8 > >(handle, value);
     219           0 :         break;
     220             :     case TYPE_BOOLEAN_LIST:
     221           0 :         writeListValue< sal_Bool >(handle, value);
     222           0 :         break;
     223             :     case TYPE_SHORT_LIST:
     224           0 :         writeListValue< sal_Int16 >(handle, value);
     225           0 :         break;
     226             :     case TYPE_INT_LIST:
     227           4 :         writeListValue< sal_Int32 >(handle, value);
     228           4 :         break;
     229             :     case TYPE_LONG_LIST:
     230           0 :         writeListValue< sal_Int64 >(handle, value);
     231           0 :         break;
     232             :     case TYPE_DOUBLE_LIST:
     233           0 :         writeListValue< double >(handle, value);
     234           0 :         break;
     235             :     case TYPE_STRING_LIST:
     236      134570 :         writeItemListValue< OUString >(handle, value);
     237      134570 :         break;
     238             :     case TYPE_HEXBINARY_LIST:
     239           0 :         writeItemListValue< css::uno::Sequence< sal_Int8 > >(handle, value);
     240           0 :         break;
     241             :     default: // TYPE_ERROR, TYPE_NIL, TYPE_ANY
     242             :         assert(false); // this cannot happen
     243             :     }
     244      216819 : }
     245             : 
     246      245968 : void writeNode(
     247             :     Components & components, oslFileHandle handle,
     248             :     rtl::Reference< Node > const & parent, OUString const & name,
     249             :     rtl::Reference< Node > const & node)
     250             : {
     251             :     static xmlreader::Span const typeNames[] = {
     252             :         xmlreader::Span(), xmlreader::Span(), xmlreader::Span(),
     253             :             // TYPE_ERROR, TYPE_NIL, TYPE_ANY
     254             :         xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:boolean")),
     255             :         xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:short")),
     256             :         xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:int")),
     257             :         xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:long")),
     258             :         xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:double")),
     259             :         xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:string")),
     260             :         xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:hexBinary")),
     261             :         xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:boolean-list")),
     262             :         xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:short-list")),
     263             :         xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:int-list")),
     264             :         xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:long-list")),
     265             :         xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:double-list")),
     266             :         xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:string-list")),
     267      245968 :         xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:hexBinary-list")) };
     268      245968 :     switch (node->kind()) {
     269             :     case Node::KIND_PROPERTY:
     270             :         {
     271      226404 :             PropertyNode * prop = static_cast< PropertyNode * >(node.get());
     272      226404 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<prop oor:name=\""));
     273      226404 :             writeAttributeValue(handle, name);
     274             :             writeData_(
     275      226404 :                 handle, RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"fuse\""));
     276      226404 :             Type type = prop->getStaticType();
     277      226404 :             Type dynType = getDynamicType(prop->getValue(components));
     278             :             assert(dynType != TYPE_ERROR);
     279      226404 :             if (type == TYPE_ANY) {
     280      142353 :                 type = dynType;
     281      142353 :                 if (type != TYPE_NIL) {
     282             :                     writeData_(
     283      142353 :                         handle, RTL_CONSTASCII_STRINGPARAM(" oor:type=\""));
     284             :                     writeData_(
     285      142353 :                         handle, typeNames[type].begin, typeNames[type].length);
     286      142353 :                     writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\""));
     287             :                 }
     288             :             }
     289      226404 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM("><value"));
     290      226404 :             if (dynType == TYPE_NIL) {
     291             :                 writeData_(
     292       12238 :                     handle, RTL_CONSTASCII_STRINGPARAM(" xsi:nil=\"true\"/>"));
     293             :             } else {
     294      214166 :                 writeValue(handle, type, prop->getValue(components));
     295             :             }
     296      226404 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</prop>"));
     297             :         }
     298      226404 :         break;
     299             :     case Node::KIND_LOCALIZED_PROPERTY:
     300           0 :         writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<prop oor:name=\""));
     301           0 :         writeAttributeValue(handle, name);
     302           0 :         writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"fuse\">"));
     303           0 :         for (NodeMap::const_iterator i(node->getMembers().begin());
     304           0 :              i != node->getMembers().end(); ++i)
     305             :         {
     306           0 :             writeNode(components, handle, node, i->first, i->second);
     307             :         }
     308           0 :         writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</prop>"));
     309           0 :         break;
     310             :     case Node::KIND_LOCALIZED_VALUE:
     311             :         {
     312        2653 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<value"));
     313        2653 :             if (!name.isEmpty()) {
     314        2653 :                 writeData_(handle, RTL_CONSTASCII_STRINGPARAM(" xml:lang=\""));
     315        2653 :                 writeAttributeValue(handle, name);
     316        2653 :                 writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\""));
     317             :             }
     318        2653 :             Type type = static_cast< LocalizedPropertyNode * >(parent.get())->
     319        2653 :                 getStaticType();
     320             :             css::uno::Any value(
     321        2653 :                 static_cast< LocalizedValueNode * >(node.get())->getValue());
     322        2653 :             Type dynType = getDynamicType(value);
     323             :             assert(dynType != TYPE_ERROR);
     324        2653 :             if (type == TYPE_ANY) {
     325           0 :                 type = dynType;
     326           0 :                 if (type != TYPE_NIL) {
     327             :                     writeData_(
     328           0 :                         handle, RTL_CONSTASCII_STRINGPARAM(" oor:type=\""));
     329             :                     writeData_(
     330           0 :                         handle, typeNames[type].begin, typeNames[type].length);
     331           0 :                     writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\""));
     332             :                 }
     333             :             }
     334        2653 :             if (dynType == TYPE_NIL) {
     335             :                 writeData_(
     336           0 :                     handle, RTL_CONSTASCII_STRINGPARAM(" xsi:nil=\"true\"/>"));
     337             :             } else {
     338        2653 :                 writeValue(handle, type, value);
     339        2653 :             }
     340             :         }
     341        2653 :         break;
     342             :     case Node::KIND_GROUP:
     343             :     case Node::KIND_SET:
     344       16911 :         writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<node oor:name=\""));
     345       16911 :         writeAttributeValue(handle, name);
     346       16911 :         if (!node->getTemplateName().isEmpty()) { // set member
     347             :             writeData_(
     348        8836 :                 handle, RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"replace"));
     349             :         }
     350       16911 :         writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\">"));
     351      154422 :         for (NodeMap::const_iterator i(node->getMembers().begin());
     352      102948 :              i != node->getMembers().end(); ++i)
     353             :         {
     354       34563 :             writeNode(components, handle, node, i->first, i->second);
     355             :         }
     356       16911 :         writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</node>"));
     357       16911 :         break;
     358             :     case Node::KIND_ROOT:
     359             :         assert(false); // this cannot happen
     360           0 :         break;
     361             :     }
     362      245968 : }
     363             : 
     364      248114 : void writeModifications(
     365             :     Components & components, oslFileHandle handle,
     366             :     OUString const & parentPathRepresentation,
     367             :     rtl::Reference< Node > const & parent, OUString const & nodeName,
     368             :     rtl::Reference< Node > const & node,
     369             :     Modifications::Node const & modifications)
     370             : {
     371             :     // It is never necessary to write oor:finalized or oor:mandatory attributes,
     372             :     // as they cannot be set via the UNO API.
     373      248114 :     if (modifications.children.empty()) {
     374             :         assert(parent.is());
     375             :             // components themselves have no parent but must have children
     376      211604 :         writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<item oor:path=\""));
     377      211604 :         writeAttributeValue(handle, parentPathRepresentation);
     378      211604 :         writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\">"));
     379      211604 :         if (node.is()) {
     380      211405 :             writeNode(components, handle, parent, nodeName, node);
     381             :         } else {
     382         199 :             switch (parent->kind()) {
     383             :             case Node::KIND_LOCALIZED_PROPERTY:
     384           0 :                 writeData_(handle, RTL_CONSTASCII_STRINGPARAM("<value"));
     385           0 :                 if (!nodeName.isEmpty()) {
     386             :                     writeData_(
     387           0 :                         handle, RTL_CONSTASCII_STRINGPARAM(" xml:lang=\""));
     388           0 :                     writeAttributeValue(handle, nodeName);
     389           0 :                     writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\""));
     390             :                 }
     391             :                 writeData_(
     392           0 :                     handle, RTL_CONSTASCII_STRINGPARAM(" oor:op=\"remove\"/>"));
     393           0 :                 break;
     394             :             case Node::KIND_GROUP:
     395             :                 assert(
     396             :                     static_cast< GroupNode * >(parent.get())->isExtensible());
     397             :                 writeData_(
     398           0 :                     handle, RTL_CONSTASCII_STRINGPARAM("<prop oor:name=\""));
     399           0 :                 writeAttributeValue(handle, nodeName);
     400             :                 writeData_(
     401             :                     handle,
     402           0 :                     RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"remove\"/>"));
     403           0 :                 break;
     404             :             case Node::KIND_SET:
     405             :                 writeData_(
     406         199 :                     handle, RTL_CONSTASCII_STRINGPARAM("<node oor:name=\""));
     407         199 :                 writeAttributeValue(handle, nodeName);
     408             :                 writeData_(
     409             :                     handle,
     410         199 :                     RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"remove\"/>"));
     411         199 :                 break;
     412             :             default:
     413             :                 assert(false); // this cannot happen
     414           0 :                 break;
     415             :             }
     416             :         }
     417      211604 :         writeData_(handle, RTL_CONSTASCII_STRINGPARAM("</item>\n"));
     418             :     } else {
     419             :         assert(node.is());
     420             :         OUString pathRep(
     421       73020 :             parentPathRepresentation + "/" +
     422      109530 :             Data::createSegment(node->getTemplateName(), nodeName));
     423      830973 :         for (Modifications::Node::Children::const_iterator i(
     424       36510 :                  modifications.children.begin());
     425      553982 :              i != modifications.children.end(); ++i)
     426             :         {
     427             :             writeModifications(
     428      240481 :                 components, handle, pathRep, node, i->first,
     429      480962 :                 node->getMember(i->first), i->second);
     430       36510 :         }
     431             :     }
     432      248114 : }
     433             : 
     434             : }
     435             : 
     436      633841 : void writeData(oslFileHandle handle, OString const & text) {
     437      633841 :     writeData_(handle, text.getStr(), text.getLength());
     438      633841 : }
     439             : 
     440      457771 : void writeAttributeValue(oslFileHandle handle, OUString const & value) {
     441      457771 :     sal_Int32 i = 0;
     442      457771 :     sal_Int32 j = i;
     443    18799152 :     for (; j < value.getLength(); ++j) {
     444             :         assert(
     445             :             value[j] == 0x0009 || value[j] == 0x000A || value[j] == 0x000D ||
     446             :             (value[j] >= 0x0020 && value[j] != 0xFFFE && value[j] != 0xFFFF));
     447    18341381 :         switch(value[j]) {
     448             :         case '\x09':
     449           0 :             writeData(handle, convertToUtf8(value, i, j - i));
     450           0 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM("&#9;"));
     451           0 :             i = j + 1;
     452           0 :             break;
     453             :         case '\x0A':
     454           0 :             writeData(handle, convertToUtf8(value, i, j - i));
     455           0 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM("&#xA;"));
     456           0 :             i = j + 1;
     457           0 :             break;
     458             :         case '\x0D':
     459           0 :             writeData(handle, convertToUtf8(value, i, j - i));
     460           0 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM("&#xD;"));
     461           0 :             i = j + 1;
     462           0 :             break;
     463             :         case '"':
     464           0 :             writeData(handle, convertToUtf8(value, i, j - i));
     465           0 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM("&quot;"));
     466           0 :             i = j + 1;
     467           0 :             break;
     468             :         case '&':
     469           0 :             writeData(handle, convertToUtf8(value, i, j - i));
     470           0 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM("&amp;"));
     471           0 :             i = j + 1;
     472           0 :             break;
     473             :         case '<':
     474           0 :             writeData(handle, convertToUtf8(value, i, j - i));
     475           0 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM("&lt;"));
     476           0 :             i = j + 1;
     477           0 :             break;
     478             :         default:
     479    18341381 :             break;
     480             :         }
     481             :     }
     482      457771 :     writeData(handle, convertToUtf8(value, i, j - i));
     483      457771 : }
     484             : 
     485      165687 : void writeValueContent(oslFileHandle handle, OUString const & value) {
     486      165687 :     sal_Int32 i = 0;
     487      165687 :     sal_Int32 j = i;
     488     5576396 :     for (; j < value.getLength(); ++j) {
     489     5410709 :         sal_Unicode c = value[j];
     490     5410709 :         if ((c < 0x0020 && c != 0x0009 && c != 0x000A && c != 0x000D) ||
     491     5410709 :             c == 0xFFFE || c == 0xFFFF)
     492             :         {
     493           0 :             writeData(handle, convertToUtf8(value, i, j - i));
     494             :             writeData_(
     495           0 :                 handle, RTL_CONSTASCII_STRINGPARAM("<unicode oor:scalar=\""));
     496             :             writeData(
     497           0 :                 handle, OString::number(c));
     498           0 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM("\"/>"));
     499           0 :             i = j + 1;
     500     5410709 :         } else if (c == '\x0D') {
     501           0 :             writeData(handle, convertToUtf8(value, i, j - i));
     502           0 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM("&#xD;"));
     503           0 :             i = j + 1;
     504     5410709 :         } else if (c == '&') {
     505           0 :             writeData(handle, convertToUtf8(value, i, j - i));
     506           0 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM("&amp;"));
     507           0 :             i = j + 1;
     508     5410709 :         } else if (c == '<') {
     509           0 :             writeData(handle, convertToUtf8(value, i, j - i));
     510           0 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM("&lt;"));
     511           0 :             i = j + 1;
     512     5410709 :         } else if (c == '>') {
     513             :             // "MUST, for compatibility, be escaped [...] when it appears in the
     514             :             // string ']]>'":
     515           0 :             writeData(handle, convertToUtf8(value, i, j - i));
     516           0 :             writeData_(handle, RTL_CONSTASCII_STRINGPARAM("&gt;"));
     517           0 :             i = j + 1;
     518             :         }
     519             :     }
     520      165687 :     writeData(handle, convertToUtf8(value, i, j - i));
     521      165687 : }
     522             : 
     523        1354 : void writeModFile(
     524             :     Components & components, OUString const & url, Data const & data)
     525             : {
     526        1354 :     sal_Int32 i = url.lastIndexOf('/');
     527             :     assert(i != -1);
     528        1354 :     OUString dir(url.copy(0, i));
     529        1354 :     switch (osl::Directory::createPath(dir)) {
     530             :     case osl::FileBase::E_None:
     531             :     case osl::FileBase::E_EXIST:
     532        1354 :         break;
     533             :     case osl::FileBase::E_ACCES:
     534             :         SAL_INFO(
     535             :             "configmgr",
     536             :             ("cannot create registrymodifications.xcu path (E_ACCES); changes"
     537             :              " will be lost"));
     538           0 :         return;
     539             :     default:
     540             :         throw css::uno::RuntimeException(
     541           0 :             "cannot create directory " + dir);
     542             :     }
     543        1354 :     TempFile tmp;
     544        1354 :     switch (osl::FileBase::createTempFile(&dir, &tmp.handle, &tmp.url)) {
     545             :     case osl::FileBase::E_None:
     546        1354 :         break;
     547             :     case osl::FileBase::E_ACCES:
     548             :         SAL_INFO(
     549             :             "configmgr",
     550             :             ("cannot create temp registrymodifications.xcu (E_ACCES); changes"
     551             :              " will be lost"));
     552           0 :         return;
     553             :     default:
     554             :         throw css::uno::RuntimeException(
     555           0 :             "cannot create temporary file in " + dir);
     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        1354 :             " 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       26961 :     for (Modifications::Node::Children::const_iterator j(
     568        1354 :              data.modifications.getRoot().children.begin());
     569       17974 :          j != data.modifications.getRoot().children.end(); ++j)
     570             :     {
     571             :         writeModifications(
     572        7633 :             components, tmp.handle, "", rtl::Reference< Node >(), j->first,
     573       15266 :             data.getComponents().findNode(Data::NO_LAYER, j->first),
     574       30532 :             j->second);
     575             :     }
     576        1354 :     writeData_(tmp.handle, RTL_CONSTASCII_STRINGPARAM("</oor:items>\n"));
     577        1354 :     oslFileError e = osl_closeFile(tmp.handle);
     578        1354 :     tmp.closed = true;
     579        1354 :     if (e != osl_File_E_None) {
     580             :         throw css::uno::RuntimeException(
     581           0 :             "cannot close " + tmp.url);
     582             :     }
     583        1354 :     if (osl::File::move(tmp.url, url) != osl::FileBase::E_None) {
     584             :         throw css::uno::RuntimeException(
     585           0 :             "cannot move " + tmp.url);
     586             :     }
     587        1354 :     tmp.handle = 0;
     588             : }
     589             : 
     590             : }
     591             : 
     592             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10