LCOV - code coverage report
Current view: top level - configmgr/source - writemodfile.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 177 281 63.0 %
Date: 2012-08-25 Functions: 20 31 64.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 136 464 29.3 %

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

Generated by: LCOV version 1.10