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

Generated by: LCOV version 1.10