LCOV - code coverage report
Current view: top level - sax/source/expatwrap - saxwriter.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 281 623 45.1 %
Date: 2012-08-25 Functions: 30 49 61.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 143 498 28.7 %

           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                 :            : #include <string.h>
      20                 :            : 
      21                 :            : #include <com/sun/star/lang/XServiceInfo.hpp>
      22                 :            : #include <com/sun/star/util/XCloneable.hpp>
      23                 :            : #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
      24                 :            : #include <com/sun/star/xml/sax/XParser.hpp>
      25                 :            : #include <com/sun/star/xml/sax/SAXParseException.hpp>
      26                 :            : #include <com/sun/star/xml/sax/SAXInvalidCharacterException.hpp>
      27                 :            : 
      28                 :            : #include <com/sun/star/io/XActiveDataSource.hpp>
      29                 :            : 
      30                 :            : #include <cppuhelper/factory.hxx>
      31                 :            : #include <cppuhelper/weak.hxx>
      32                 :            : #include <cppuhelper/implbase3.hxx>
      33                 :            : 
      34                 :            : #include <rtl/strbuf.hxx>
      35                 :            : #include <rtl/byteseq.hxx>
      36                 :            : #include <rtl/ustrbuf.hxx>
      37                 :            : 
      38                 :            : using namespace ::rtl;
      39                 :            : using namespace ::std;
      40                 :            : using namespace ::osl;
      41                 :            : using namespace ::cppu;
      42                 :            : using namespace ::com::sun::star::uno;
      43                 :            : using namespace ::com::sun::star::lang;
      44                 :            : using namespace ::com::sun::star::registry;
      45                 :            : using namespace ::com::sun::star::xml::sax;
      46                 :            : using namespace ::com::sun::star::util;
      47                 :            : using namespace ::com::sun::star::io;
      48                 :            : 
      49                 :            : #include "factory.hxx"
      50                 :            : #include "xml2utf.hxx"
      51                 :            : 
      52                 :            : #define LINEFEED 10
      53                 :            : #define SEQUENCESIZE 1024
      54                 :            : #define MAXCOLUMNCOUNT 72
      55                 :            : 
      56                 :            : /******
      57                 :            : *
      58                 :            : *
      59                 :            : * Character conversion functions
      60                 :            : *
      61                 :            : *
      62                 :            : *****/
      63                 :            : 
      64                 :            : namespace sax_expatwrap {
      65                 :            : 
      66                 :            : enum SaxInvalidCharacterError
      67                 :            : {
      68                 :            :     SAX_NONE,
      69                 :            :     SAX_WARNING,
      70                 :            :     SAX_ERROR
      71                 :            : };
      72                 :            : 
      73                 :            : class SaxWriterHelper
      74                 :            : {
      75                 :            :     Reference< XOutputStream >  m_out;
      76                 :            :     Sequence < sal_Int8 >       m_Sequence;
      77                 :            :     sal_Int8*                   mp_Sequence;
      78                 :            : 
      79                 :            :     sal_Int32                   nLastLineFeedPos; // is negative after writing a sequence
      80                 :            :     sal_uInt32                  nCurrentPos;
      81                 :            :     sal_Bool                    m_bStartElementFinished;
      82                 :            : 
      83                 :            : 
      84                 :            :     inline sal_uInt32 writeSequence() throw( SAXException );
      85                 :            : 
      86                 :            :     // use only if to insert the bytes more space in the sequence is needed and
      87                 :            :     // so the sequence has to write out and reset rPos to 0
      88                 :            :     // writes sequence only on overflow, sequence could be full on the end (rPos == SEQUENCESIZE)
      89                 :            :     inline void AddBytes(sal_Int8* pTarget, sal_uInt32& rPos,
      90                 :            :                 const sal_Int8* pBytes, sal_uInt32 nBytesCount) throw( SAXException );
      91                 :            :     inline sal_Bool convertToXML(const sal_Unicode * pStr,
      92                 :            :                         sal_Int32 nStrLen,
      93                 :            :                         sal_Bool bDoNormalization,
      94                 :            :                         sal_Bool bNormalizeWhitespace,
      95                 :            :                         sal_Int8 *pTarget,
      96                 :            :                         sal_uInt32& rPos) throw( SAXException );
      97                 :            :     inline void FinishStartElement() throw( SAXException );
      98                 :            : public:
      99                 :       2853 :     SaxWriterHelper(Reference< XOutputStream > m_TempOut) :
     100                 :            :         m_out(m_TempOut),
     101                 :            :         m_Sequence(SEQUENCESIZE),
     102                 :            :         mp_Sequence(NULL),
     103                 :            :         nLastLineFeedPos(0),
     104                 :            :         nCurrentPos(0),
     105         [ +  - ]:       2853 :         m_bStartElementFinished(sal_True)
     106                 :            :     {
     107                 :            :         OSL_ENSURE(SEQUENCESIZE > 50, "Sequence cache size to small");
     108         [ +  - ]:       2853 :         mp_Sequence = m_Sequence.getArray();
     109                 :       2853 :     }
     110                 :       2853 :     ~SaxWriterHelper()
     111         [ +  - ]:       2853 :     {
     112                 :            :         OSL_ENSURE(!nCurrentPos, "cached Sequence not written");
     113                 :            :         OSL_ENSURE(m_bStartElementFinished, "StartElement not complettly written");
     114                 :       2853 :     }
     115                 :            : 
     116                 :            :     inline void insertIndentation(sal_uInt32 m_nLevel)  throw( SAXException );
     117                 :            : 
     118                 :            : // returns whether it works correct or invalid characters were in the string
     119                 :            : // If there are invalid characters in the string it returns sal_False.
     120                 :            : // Than the calling method has to throw the needed Exception.
     121                 :            :     inline sal_Bool writeString(const rtl::OUString& rWriteOutString,
     122                 :            :                         sal_Bool bDoNormalization,
     123                 :            :                         sal_Bool bNormalizeWhitespace) throw( SAXException );
     124                 :            : 
     125                 :          0 :     sal_uInt32 GetLastColumnCount() const
     126                 :          0 :         { return (sal_uInt32)(nCurrentPos - nLastLineFeedPos); }
     127                 :            : 
     128                 :            :     inline void startDocument() throw( SAXException );
     129                 :            : 
     130                 :            : // returns whether it works correct or invalid characters were in the strings
     131                 :            : // If there are invalid characters in one of the strings it returns sal_False.
     132                 :            : // Than the calling method has to throw the needed Exception.
     133                 :            :     inline SaxInvalidCharacterError startElement(const rtl::OUString& rName, const Reference< XAttributeList >& xAttribs) throw( SAXException );
     134                 :            :     inline sal_Bool FinishEmptyElement() throw( SAXException );
     135                 :            : 
     136                 :            : // returns whether it works correct or invalid characters were in the string
     137                 :            : // If there are invalid characters in the string it returns sal_False.
     138                 :            : // Than the calling method has to throw the needed Exception.
     139                 :            :     inline sal_Bool endElement(const rtl::OUString& rName) throw( SAXException );
     140                 :            :     inline void endDocument() throw( SAXException );
     141                 :            : 
     142                 :            : // returns whether it works correct or invalid characters were in the strings
     143                 :            : // If there are invalid characters in the string it returns sal_False.
     144                 :            : // Than the calling method has to throw the needed Exception.
     145                 :            :     inline sal_Bool processingInstruction(const rtl::OUString& rTarget, const rtl::OUString& rData) throw( SAXException );
     146                 :            :     inline void startCDATA() throw( SAXException );
     147                 :            :     inline void endCDATA() throw( SAXException );
     148                 :            : 
     149                 :            : // returns whether it works correct or invalid characters were in the strings
     150                 :            : // If there are invalid characters in the string it returns sal_False.
     151                 :            : // Than the calling method has to throw the needed Exception.
     152                 :            :     inline sal_Bool comment(const rtl::OUString& rComment) throw( SAXException );
     153                 :            : 
     154                 :            :     inline void clearBuffer() throw( SAXException );
     155                 :            : };
     156                 :            : 
     157                 :            : const sal_Bool g_bValidCharsBelow32[32] =
     158                 :            : {
     159                 :            : //  0 1 2 3 4 5 6 7
     160                 :            :     0,0,0,0,0,0,0,0,  //0
     161                 :            :     0,1,1,0,0,1,0,0,  //8
     162                 :            :     0,0,0,0,0,0,0,0,  //16
     163                 :            :     0,0,0,0,0,0,0,0
     164                 :            : };
     165                 :            : 
     166                 :    7109688 : inline sal_Bool IsInvalidChar(const sal_Unicode aChar)
     167                 :            : {
     168                 :    7109688 :     sal_Bool bRet(sal_False);
     169                 :            :     // check first for the most common characters
     170 [ +  + ][ -  + ]:    7109688 :     if( aChar < 32 || aChar >= 0xd800 )
     171                 :         18 :         bRet = ( (aChar < 32 && ! g_bValidCharsBelow32[aChar]) ||
     172                 :            :             aChar == 0xffff ||
     173 [ +  - ][ +  - ]:         18 :             aChar == 0xfffe );
         [ +  - ][ -  + ]
     174                 :    7109688 :     return bRet;
     175                 :            : }
     176                 :            : 
     177                 :            : /********
     178                 :            : * write through to the output stream
     179                 :            : *
     180                 :            : *****/
     181                 :       9636 : inline sal_uInt32 SaxWriterHelper::writeSequence() throw( SAXException )
     182                 :            : {
     183                 :            :     try
     184                 :            :     {
     185 [ +  - ][ +  - ]:       9636 :         m_out->writeBytes( m_Sequence );
     186                 :            :     }
     187         [ #  # ]:          0 :     catch (const IOException & e)
     188                 :            :     {
     189                 :          0 :         Any a;
     190         [ #  # ]:          0 :         a <<= e;
     191                 :            :         throw SAXException(
     192                 :            :             OUString("io exception during writing"),
     193                 :            :             Reference< XInterface > (),
     194         [ #  # ]:          0 :             a );
     195                 :            :     }
     196                 :       9636 :     nLastLineFeedPos -= SEQUENCESIZE;
     197                 :       9636 :     return 0;
     198                 :            : }
     199                 :            : 
     200                 :          6 : inline void SaxWriterHelper::AddBytes(sal_Int8* pTarget, sal_uInt32& rPos,
     201                 :            :                 const sal_Int8* pBytes, sal_uInt32 nBytesCount) throw( SAXException )
     202                 :            : {
     203                 :            :     OSL_ENSURE((rPos + nBytesCount) > SEQUENCESIZE, "wrong use of AddBytesMethod");
     204                 :          6 :     sal_uInt32 nCount(SEQUENCESIZE - rPos);
     205                 :          6 :     memcpy( &(pTarget[rPos]) , pBytes,  nCount);
     206                 :            : 
     207                 :            :     OSL_ENSURE(rPos + nCount == SEQUENCESIZE, "the position should be the at the end");
     208                 :            : 
     209                 :          6 :     rPos = writeSequence();
     210                 :          6 :     sal_uInt32 nRestCount(nBytesCount - nCount);
     211         [ +  - ]:          6 :     if ((rPos + nRestCount) <= SEQUENCESIZE)
     212                 :            :     {
     213                 :          6 :         memcpy( &(pTarget[rPos]), &pBytes[nCount], nRestCount);
     214                 :          6 :         rPos += nRestCount;
     215                 :            :     }
     216                 :            :     else
     217                 :          0 :         AddBytes(pTarget, rPos, &pBytes[nCount], nRestCount);
     218                 :          6 : }
     219                 :            : 
     220                 :            : /** Converts an UTF16 string to UTF8 and does XML normalization
     221                 :            : 
     222                 :            :     @param pTarget
     223                 :            :            Pointer to a piece of memory, to where the output should be written. The caller
     224                 :            :            must call calcXMLByteLength on the same string, to ensure,
     225                 :            :            that there is enough memory for converting.
     226                 :            :  */
     227                 :     559390 : inline sal_Bool SaxWriterHelper::convertToXML( const sal_Unicode * pStr,
     228                 :            :                         sal_Int32 nStrLen,
     229                 :            :                         sal_Bool bDoNormalization,
     230                 :            :                         sal_Bool bNormalizeWhitespace,
     231                 :            :                         sal_Int8 *pTarget,
     232                 :            :                         sal_uInt32& rPos ) throw( SAXException )
     233                 :            : {
     234                 :     559390 :     sal_Bool bRet(sal_True);
     235                 :     559390 :     sal_uInt32 nSurrogate = 0;
     236                 :            : 
     237         [ +  + ]:    7669078 :     for( sal_Int32 i = 0 ; i < nStrLen ; i ++ )
     238                 :            :     {
     239                 :    7109688 :         sal_uInt16 c = pStr[i];
     240         [ -  + ]:    7109688 :         if (IsInvalidChar(c))
     241                 :          0 :             bRet = sal_False;
     242 [ +  - ][ +  + ]:    7109688 :         else if( (c >= 0x0001) && (c <= 0x007F) )
     243                 :            :         {
     244         [ +  + ]:   14214012 :             if( bDoNormalization )
     245                 :            :             {
     246   [ -  +  +  +  :    2600491 :                 switch( c )
             -  -  +  -  
                      + ]
     247                 :            :                 {
     248                 :            :                     case '&':  // resemble to &amp;
     249                 :            :                     {
     250         [ #  # ]:          0 :                         if ((rPos + 5) > SEQUENCESIZE)
     251                 :          0 :                             AddBytes(pTarget, rPos, (sal_Int8*)"&amp;", 5);
     252                 :            :                         else
     253                 :            :                         {
     254                 :          0 :                             memcpy( &(pTarget[rPos]) , "&amp;", 5 );
     255                 :          0 :                             rPos += 5;
     256                 :            :                         }
     257                 :            :                     }
     258                 :          0 :                     break;
     259                 :            :                     case '<':
     260                 :            :                     {
     261         [ -  + ]:        246 :                         if ((rPos + 4) > SEQUENCESIZE)
     262                 :          0 :                             AddBytes(pTarget, rPos, (sal_Int8*)"&lt;", 4);
     263                 :            :                         else
     264                 :            :                         {
     265                 :        246 :                             memcpy( &(pTarget[rPos]) , "&lt;" , 4 );
     266                 :        246 :                             rPos += 4;        // &lt;
     267                 :            :                         }
     268                 :            :                     }
     269                 :        246 :                     break;
     270                 :            :                     case '>':
     271                 :            :                     {
     272         [ -  + ]:        106 :                         if ((rPos + 4) > SEQUENCESIZE)
     273                 :          0 :                             AddBytes(pTarget, rPos, (sal_Int8*)"&gt;", 4);
     274                 :            :                         else
     275                 :            :                         {
     276                 :        106 :                             memcpy( &(pTarget[rPos]) , "&gt;" , 4 );
     277                 :        106 :                             rPos += 4;        // &gt;
     278                 :            :                         }
     279                 :            :                     }
     280                 :        106 :                     break;
     281                 :            :                     case 39:                 // 39 == '''
     282                 :            :                     {
     283         [ +  + ]:        664 :                         if ((rPos + 6) > SEQUENCESIZE)
     284                 :          6 :                             AddBytes(pTarget, rPos, (sal_Int8*)"&apos;", 6);
     285                 :            :                         else
     286                 :            :                         {
     287                 :        658 :                             memcpy( &(pTarget[rPos]) , "&apos;" , 6 );
     288                 :        658 :                             rPos += 6;        // &apos;
     289                 :            :                         }
     290                 :            :                     }
     291                 :        664 :                     break;
     292                 :            :                     case '"':
     293                 :            :                     {
     294         [ #  # ]:          0 :                         if ((rPos + 6) > SEQUENCESIZE)
     295                 :          0 :                             AddBytes(pTarget, rPos, (sal_Int8*)"&quot;", 6);
     296                 :            :                         else
     297                 :            :                         {
     298                 :          0 :                             memcpy( &(pTarget[rPos]) , "&quot;" , 6 );
     299                 :          0 :                             rPos += 6;        // &quot;
     300                 :            :                         }
     301                 :            :                     }
     302                 :          0 :                     break;
     303                 :            :                     case 13:
     304                 :            :                     {
     305         [ #  # ]:          0 :                         if ((rPos + 6) > SEQUENCESIZE)
     306                 :          0 :                             AddBytes(pTarget, rPos, (sal_Int8*)"&#x0d;", 6);
     307                 :            :                         else
     308                 :            :                         {
     309                 :          0 :                             memcpy( &(pTarget[rPos]) , "&#x0d;" , 6 );
     310                 :          0 :                             rPos += 6;
     311                 :            :                         }
     312                 :            :                     }
     313                 :          0 :                     break;
     314                 :            :                     case LINEFEED:
     315                 :            :                     {
     316         [ -  + ]:         18 :                         if( bNormalizeWhitespace )
     317                 :            :                         {
     318         [ #  # ]:          0 :                             if ((rPos + 6) > SEQUENCESIZE)
     319                 :          0 :                                 AddBytes(pTarget, rPos, (sal_Int8*)"&#x0a;" , 6);
     320                 :            :                             else
     321                 :            :                             {
     322                 :          0 :                                 memcpy( &(pTarget[rPos]) , "&#x0a;" , 6 );
     323                 :          0 :                                 rPos += 6;
     324                 :            :                             }
     325                 :            :                         }
     326                 :            :                         else
     327                 :            :                         {
     328                 :         18 :                             pTarget[rPos] = LINEFEED;
     329                 :         18 :                             nLastLineFeedPos = rPos;
     330                 :         18 :                             rPos ++;
     331                 :            :                         }
     332                 :            :                     }
     333                 :         18 :                     break;
     334                 :            :                     case 9:
     335                 :            :                     {
     336         [ #  # ]:          0 :                         if( bNormalizeWhitespace )
     337                 :            :                         {
     338         [ #  # ]:          0 :                             if ((rPos + 6) > SEQUENCESIZE)
     339                 :          0 :                                 AddBytes(pTarget, rPos, (sal_Int8*)"&#x09;" , 6);
     340                 :            :                             else
     341                 :            :                             {
     342                 :          0 :                                 memcpy( &(pTarget[rPos]) , "&#x09;" , 6 );
     343                 :          0 :                                 rPos += 6;
     344                 :            :                             }
     345                 :            :                         }
     346                 :            :                         else
     347                 :            :                         {
     348                 :          0 :                             pTarget[rPos] = 9;
     349                 :          0 :                             rPos ++;
     350                 :            :                         }
     351                 :            :                     }
     352                 :          0 :                     break;
     353                 :            :                     default:
     354                 :            :                     {
     355                 :    2599457 :                         pTarget[rPos] = (sal_Int8)c;
     356                 :    2599457 :                         rPos ++;
     357                 :            :                     }
     358                 :    2600491 :                     break;
     359                 :            :                 }
     360                 :            :             }
     361                 :            :             else
     362                 :            :             {
     363                 :    4506515 :                 pTarget[rPos] = (sal_Int8)c;
     364         [ -  + ]:    4506515 :                 if ((sal_Int8)c == LINEFEED)
     365                 :          0 :                     nLastLineFeedPos = rPos;
     366                 :    4506515 :                 rPos ++;
     367                 :            :             }
     368                 :            :         }
     369 [ -  + ][ #  # ]:       2682 :         else if( c >= 0xd800 && c < 0xdc00  )
     370                 :            :         {
     371                 :            :             // 1. surrogate: save (until 2. surrogate)
     372                 :            :             OSL_ENSURE( nSurrogate == 0, "left-over Unicode surrogate" );
     373                 :          0 :             nSurrogate = ( ( c & 0x03ff ) + 0x0040 );
     374                 :            :         }
     375 [ -  + ][ #  # ]:       2682 :         else if( c >= 0xdc00 && c < 0xe000 )
     376                 :            :         {
     377                 :            :             // 2. surrogate: write as UTF-8
     378                 :            :             OSL_ENSURE( nSurrogate != 0, "lone 2nd Unicode surrogate" );
     379                 :            : 
     380                 :          0 :             nSurrogate = ( nSurrogate << 10 ) | ( c & 0x03ff );
     381 [ #  # ][ #  # ]:          0 :             if( nSurrogate >= 0x00010000  &&  nSurrogate <= 0x0010FFFF )
     382                 :            :             {
     383                 :            :                 sal_Int8 aBytes[] = { sal_Int8(0xF0 | ((nSurrogate >> 18) & 0x0F)),
     384                 :            :                                       sal_Int8(0x80 | ((nSurrogate >> 12) & 0x3F)),
     385                 :            :                                       sal_Int8(0x80 | ((nSurrogate >>  6) & 0x3F)),
     386                 :          0 :                                       sal_Int8(0x80 | ((nSurrogate >>  0) & 0x3F)) };
     387         [ #  # ]:          0 :                 if ((rPos + 4) > SEQUENCESIZE)
     388         [ #  # ]:          0 :                     AddBytes(pTarget, rPos, aBytes, 4);
     389                 :            :                 else
     390                 :            :                 {
     391                 :          0 :                     pTarget[rPos] = aBytes[0];
     392                 :          0 :                     rPos ++;
     393                 :          0 :                     pTarget[rPos] = aBytes[1];
     394                 :          0 :                     rPos ++;
     395                 :          0 :                     pTarget[rPos] = aBytes[2];
     396                 :          0 :                     rPos ++;
     397                 :          0 :                     pTarget[rPos] = aBytes[3];
     398                 :          0 :                     rPos ++;
     399                 :          0 :                 }
     400                 :            :             }
     401                 :            :             else
     402                 :            :             {
     403                 :            :                 OSL_FAIL( "illegal Unicode character" );
     404                 :          0 :                 bRet = sal_False;
     405                 :            :             }
     406                 :            : 
     407                 :            :             // reset surrogate
     408                 :          0 :             nSurrogate = 0;
     409                 :            :         }
     410         [ +  + ]:       2682 :         else if( c > 0x07FF )
     411                 :            :         {
     412                 :            :             sal_Int8 aBytes[] = { sal_Int8(0xE0 | ((c >> 12) & 0x0F)),
     413                 :            :                                   sal_Int8(0x80 | ((c >>  6) & 0x3F)),
     414                 :       1552 :                                   sal_Int8(0x80 | ((c >>  0) & 0x3F)) };
     415         [ -  + ]:       1552 :             if ((rPos + 3) > SEQUENCESIZE)
     416         [ #  # ]:          0 :                 AddBytes(pTarget, rPos, aBytes, 3);
     417                 :            :             else
     418                 :            :             {
     419                 :       1552 :                 pTarget[rPos] = aBytes[0];
     420                 :       1552 :                 rPos ++;
     421                 :       1552 :                 pTarget[rPos] = aBytes[1];
     422                 :       1552 :                 rPos ++;
     423                 :       1552 :                 pTarget[rPos] = aBytes[2];
     424                 :       1552 :                 rPos ++;
     425                 :            :             }
     426                 :            :         }
     427                 :            :         else
     428                 :            :         {
     429                 :            :             sal_Int8 aBytes[] = { sal_Int8(0xC0 | ((c >>  6) & 0x1F)),
     430                 :       1130 :                                 sal_Int8(0x80 | ((c >>  0) & 0x3F)) };
     431         [ -  + ]:       1130 :             if ((rPos + 2) > SEQUENCESIZE)
     432         [ #  # ]:          0 :                 AddBytes(pTarget, rPos, aBytes, 2);
     433                 :            :             else
     434                 :            :             {
     435                 :       1130 :                 pTarget[rPos] = aBytes[0];
     436                 :       1130 :                 rPos ++;
     437                 :       1130 :                 pTarget[rPos] = aBytes[1];
     438                 :       1130 :                 rPos ++;
     439                 :            :             }
     440                 :            :         }
     441                 :            :         OSL_ENSURE(rPos <= SEQUENCESIZE, "not reset current position");
     442         [ +  + ]:    7109688 :         if (rPos == SEQUENCESIZE)
     443                 :       6630 :             rPos = writeSequence();
     444                 :            : 
     445                 :            :         // reset left-over surrogate
     446 [ -  + ][ #  # ]:    7109688 :         if( ( nSurrogate != 0 ) && !( c >= 0xd800 && c < 0xdc00 ) )
                 [ #  # ]
     447                 :            :         {
     448                 :            :             OSL_ENSURE( nSurrogate != 0, "left-over Unicode surrogate" );
     449                 :          0 :             nSurrogate = 0;
     450                 :          0 :             bRet = sal_False;
     451                 :            :         }
     452                 :            :     }
     453                 :     559390 :     return bRet;
     454                 :            : }
     455                 :            : 
     456                 :     736290 : inline void SaxWriterHelper::FinishStartElement() throw( SAXException )
     457                 :            : {
     458         [ +  + ]:     736290 :     if (!m_bStartElementFinished)
     459                 :            :     {
     460                 :      81896 :         mp_Sequence[nCurrentPos] = '>';
     461                 :      81896 :         nCurrentPos++;
     462         [ -  + ]:      81896 :         if (nCurrentPos == SEQUENCESIZE)
     463                 :          0 :             nCurrentPos = writeSequence();
     464                 :      81896 :         m_bStartElementFinished = sal_True;
     465                 :            :     }
     466                 :     736290 : }
     467                 :            : 
     468                 :       1910 : inline void SaxWriterHelper::insertIndentation(sal_uInt32 m_nLevel) throw( SAXException )
     469                 :            : {
     470                 :       1910 :     FinishStartElement();
     471         [ +  + ]:       1910 :     if (m_nLevel > 0)
     472                 :            :     {
     473         [ +  - ]:       1200 :         if ((nCurrentPos + m_nLevel + 1) <= SEQUENCESIZE)
     474                 :            :         {
     475                 :       1200 :             mp_Sequence[nCurrentPos] = LINEFEED;
     476                 :       1200 :             nLastLineFeedPos = nCurrentPos;
     477                 :       1200 :             nCurrentPos++;
     478                 :       1200 :             memset( &(mp_Sequence[nCurrentPos]) , 32 , m_nLevel );
     479                 :       1200 :             nCurrentPos += m_nLevel;
     480         [ -  + ]:       1200 :             if (nCurrentPos == SEQUENCESIZE)
     481                 :          0 :                 nCurrentPos = writeSequence();
     482                 :            :         }
     483                 :            :         else
     484                 :            :         {
     485                 :          0 :             sal_uInt32 nCount(m_nLevel + 1);
     486                 :          0 :             sal_Int8* pBytes = new sal_Int8[nCount];
     487                 :          0 :             pBytes[0] = LINEFEED;
     488                 :          0 :             memset( &(pBytes[1]), 32, m_nLevel );
     489                 :          0 :             AddBytes(mp_Sequence, nCurrentPos, pBytes, nCount);
     490         [ #  # ]:          0 :             delete[] pBytes;
     491                 :          0 :             nLastLineFeedPos = nCurrentPos - nCount;
     492         [ #  # ]:          0 :             if (nCurrentPos == SEQUENCESIZE)
     493                 :          0 :                 nCurrentPos = writeSequence();
     494                 :            :         }
     495                 :            :     }
     496                 :            :     else
     497                 :            :     {
     498                 :        710 :         mp_Sequence[nCurrentPos] = LINEFEED;
     499                 :        710 :         nLastLineFeedPos = nCurrentPos;
     500                 :        710 :         nCurrentPos++;
     501         [ -  + ]:        710 :         if (nCurrentPos == SEQUENCESIZE)
     502                 :          0 :             nCurrentPos = writeSequence();
     503                 :            :     }
     504                 :       1910 : }
     505                 :            : 
     506                 :     559390 : inline sal_Bool SaxWriterHelper::writeString( const rtl::OUString& rWriteOutString,
     507                 :            :                         sal_Bool bDoNormalization,
     508                 :            :                         sal_Bool bNormalizeWhitespace ) throw( SAXException )
     509                 :            : {
     510                 :     559390 :     FinishStartElement();
     511                 :            :     return convertToXML(rWriteOutString.getStr(),
     512                 :            :                     rWriteOutString.getLength(),
     513                 :            :                     bDoNormalization,
     514                 :            :                     bNormalizeWhitespace,
     515                 :            :                     mp_Sequence,
     516                 :     559390 :                     nCurrentPos);
     517                 :            : }
     518                 :            : 
     519                 :       2835 : inline void SaxWriterHelper::startDocument() throw( SAXException )
     520                 :            : {
     521                 :       2835 :     const char pc[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
     522                 :       2835 :     const int nLen = strlen( pc );
     523         [ +  - ]:       2835 :     if ((nCurrentPos + nLen) <= SEQUENCESIZE)
     524                 :            :     {
     525                 :       2835 :         memcpy( mp_Sequence, pc , nLen );
     526                 :       2835 :         nCurrentPos += nLen;
     527                 :            :     }
     528                 :            :     else
     529                 :            :     {
     530         [ #  # ]:          0 :         AddBytes(mp_Sequence, nCurrentPos, (sal_Int8*)pc, nLen);
     531                 :            :     }
     532                 :            :     OSL_ENSURE(nCurrentPos <= SEQUENCESIZE, "not reset current position");
     533         [ -  + ]:       2835 :     if (nCurrentPos == SEQUENCESIZE)
     534         [ #  # ]:          0 :         nCurrentPos = writeSequence();
     535                 :       2835 :     mp_Sequence[nCurrentPos] = LINEFEED;
     536                 :       2835 :     nCurrentPos++;
     537         [ -  + ]:       2835 :     if (nCurrentPos == SEQUENCESIZE)
     538         [ #  # ]:          0 :         nCurrentPos = writeSequence();
     539                 :       2835 : }
     540                 :            : 
     541                 :      93094 : inline SaxInvalidCharacterError SaxWriterHelper::startElement(const rtl::OUString& rName, const Reference< XAttributeList >& xAttribs) throw( SAXException )
     542                 :            : {
     543                 :      93094 :     FinishStartElement();
     544                 :      93094 :     mp_Sequence[nCurrentPos] = '<';
     545                 :      93094 :     nCurrentPos++;
     546         [ +  + ]:      93094 :     if (nCurrentPos == SEQUENCESIZE)
     547                 :         32 :         nCurrentPos = writeSequence();
     548                 :            : 
     549                 :      93094 :     SaxInvalidCharacterError eRet(SAX_NONE);
     550         [ -  + ]:      93094 :     if (!writeString(rName, sal_False, sal_False))
     551                 :          0 :         eRet = SAX_ERROR;
     552                 :            : 
     553         [ +  - ]:      93094 :     sal_Int16 nAttribCount = xAttribs.is() ? static_cast<sal_Int16>(xAttribs->getLength()) : 0;
     554         [ +  + ]:     251952 :     for(sal_Int16 i = 0 ; i < nAttribCount ; i++ )
     555                 :            :     {
     556                 :     158858 :         mp_Sequence[nCurrentPos] = ' ';
     557                 :     158858 :         nCurrentPos++;
     558         [ +  + ]:     158858 :         if (nCurrentPos == SEQUENCESIZE)
     559                 :         28 :             nCurrentPos = writeSequence();
     560                 :            : 
     561 [ +  - ][ -  + ]:     158858 :         if (!writeString(xAttribs->getNameByIndex( i ), sal_False, sal_False))
     562                 :          0 :             eRet = SAX_ERROR;
     563                 :            : 
     564                 :     158858 :         mp_Sequence[nCurrentPos] = '=';
     565                 :     158858 :         nCurrentPos++;
     566         [ +  + ]:     158858 :         if (nCurrentPos == SEQUENCESIZE)
     567                 :         32 :             nCurrentPos = writeSequence();
     568                 :     158858 :         mp_Sequence[nCurrentPos] = '"';
     569                 :     158858 :         nCurrentPos++;
     570         [ +  + ]:     158858 :         if (nCurrentPos == SEQUENCESIZE)
     571                 :         14 :             nCurrentPos = writeSequence();
     572                 :            : 
     573 [ +  - ][ +  - ]:     158858 :         if (!writeString(xAttribs->getValueByIndex( i ), sal_True, sal_True) &&
         [ +  - ][ -  + ]
         [ #  # ][ +  - ]
           [ -  +  #  # ]
     574                 :            :             !(eRet == SAX_ERROR))
     575                 :          0 :             eRet = SAX_WARNING;
     576                 :            : 
     577                 :     158858 :         mp_Sequence[nCurrentPos] = '"';
     578                 :     158858 :         nCurrentPos++;
     579         [ +  + ]:     158858 :         if (nCurrentPos == SEQUENCESIZE)
     580                 :         24 :             nCurrentPos = writeSequence();
     581                 :            :     }
     582                 :            : 
     583                 :      93094 :     m_bStartElementFinished = sal_False;    // because the '>' character is not added,
     584                 :            :                                             // because it is possible, that the "/>"
     585                 :            :                                             // characters have to add
     586                 :      93094 :     return eRet;
     587                 :            : }
     588                 :            : 
     589                 :      93094 : inline sal_Bool SaxWriterHelper::FinishEmptyElement() throw( SAXException )
     590                 :            : {
     591         [ +  + ]:      93094 :     if (m_bStartElementFinished)
     592                 :      81896 :         return sal_False;
     593                 :            : 
     594                 :      11198 :     mp_Sequence[nCurrentPos] = '/';
     595                 :      11198 :     nCurrentPos++;
     596         [ +  + ]:      11198 :     if (nCurrentPos == SEQUENCESIZE)
     597                 :         14 :         nCurrentPos = writeSequence();
     598                 :      11198 :     mp_Sequence[nCurrentPos] = '>';
     599                 :      11198 :     nCurrentPos++;
     600         [ +  + ]:      11198 :     if (nCurrentPos == SEQUENCESIZE)
     601                 :          6 :         nCurrentPos = writeSequence();
     602                 :            : 
     603                 :      11198 :     m_bStartElementFinished = sal_True;
     604                 :            : 
     605                 :      93094 :     return sal_True;
     606                 :            : }
     607                 :            : 
     608                 :      81896 : inline sal_Bool SaxWriterHelper::endElement(const rtl::OUString& rName) throw( SAXException )
     609                 :            : {
     610                 :      81896 :     FinishStartElement();
     611                 :      81896 :     mp_Sequence[nCurrentPos] = '<';
     612                 :      81896 :     nCurrentPos++;
     613         [ +  + ]:      81896 :     if (nCurrentPos == SEQUENCESIZE)
     614                 :          5 :         nCurrentPos = writeSequence();
     615                 :      81896 :     mp_Sequence[nCurrentPos] = '/';
     616                 :      81896 :     nCurrentPos++;
     617         [ +  + ]:      81896 :     if (nCurrentPos == SEQUENCESIZE)
     618                 :          4 :         nCurrentPos = writeSequence();
     619                 :            : 
     620                 :      81896 :     sal_Bool bRet(writeString( rName, sal_False, sal_False));
     621                 :            : 
     622                 :      81896 :     mp_Sequence[nCurrentPos] = '>';
     623                 :      81896 :     nCurrentPos++;
     624         [ +  + ]:      81896 :     if (nCurrentPos == SEQUENCESIZE)
     625                 :          6 :         nCurrentPos = writeSequence();
     626                 :            : 
     627                 :      81896 :     return bRet;
     628                 :            : }
     629                 :            : 
     630                 :       2835 : inline void SaxWriterHelper::endDocument() throw( SAXException )
     631                 :            : {
     632         [ +  - ]:       2835 :     if (nCurrentPos > 0)
     633                 :            :     {
     634                 :       2835 :         m_Sequence.realloc(nCurrentPos);
     635                 :       2835 :         nCurrentPos = writeSequence();
     636                 :            :         //m_Sequence.realloc(SEQUENCESIZE);
     637                 :            :     }
     638                 :       2835 : }
     639                 :            : 
     640                 :          0 : inline void SaxWriterHelper::clearBuffer() throw( SAXException )
     641                 :            : {
     642                 :          0 :     FinishStartElement();
     643         [ #  # ]:          0 :     if (nCurrentPos > 0)
     644                 :            :     {
     645                 :          0 :         m_Sequence.realloc(nCurrentPos);
     646                 :          0 :         nCurrentPos = writeSequence();
     647                 :          0 :         m_Sequence.realloc(SEQUENCESIZE);
     648                 :            :         // Be sure to update the array pointer after the reallocation.
     649                 :          0 :         mp_Sequence = m_Sequence.getArray();
     650                 :            :     }
     651                 :          0 : }
     652                 :            : 
     653                 :          0 : inline sal_Bool SaxWriterHelper::processingInstruction(const rtl::OUString& rTarget, const rtl::OUString& rData) throw( SAXException )
     654                 :            : {
     655                 :          0 :     FinishStartElement();
     656                 :          0 :     mp_Sequence[nCurrentPos] = '<';
     657                 :          0 :     nCurrentPos++;
     658         [ #  # ]:          0 :     if (nCurrentPos == SEQUENCESIZE)
     659                 :          0 :         nCurrentPos = writeSequence();
     660                 :          0 :     mp_Sequence[nCurrentPos] = '?';
     661                 :          0 :     nCurrentPos++;
     662         [ #  # ]:          0 :     if (nCurrentPos == SEQUENCESIZE)
     663                 :          0 :         nCurrentPos = writeSequence();
     664                 :            : 
     665                 :          0 :     sal_Bool bRet(writeString( rTarget, sal_False, sal_False ));
     666                 :            : 
     667                 :          0 :     mp_Sequence[nCurrentPos] = ' ';
     668                 :          0 :     nCurrentPos++;
     669         [ #  # ]:          0 :     if (nCurrentPos == SEQUENCESIZE)
     670                 :          0 :         nCurrentPos = writeSequence();
     671                 :            : 
     672         [ #  # ]:          0 :     if (!writeString( rData, sal_False, sal_False ))
     673                 :          0 :         bRet = sal_False;
     674                 :            : 
     675                 :          0 :     mp_Sequence[nCurrentPos] = '?';
     676                 :          0 :     nCurrentPos++;
     677         [ #  # ]:          0 :     if (nCurrentPos == SEQUENCESIZE)
     678                 :          0 :         nCurrentPos = writeSequence();
     679                 :          0 :     mp_Sequence[nCurrentPos] = '>';
     680                 :          0 :     nCurrentPos++;
     681         [ #  # ]:          0 :     if (nCurrentPos == SEQUENCESIZE)
     682                 :          0 :         nCurrentPos = writeSequence();
     683                 :            : 
     684                 :          0 :     return bRet;
     685                 :            : }
     686                 :            : 
     687                 :          0 : inline void SaxWriterHelper::startCDATA() throw( SAXException )
     688                 :            : {
     689                 :          0 :     FinishStartElement();
     690         [ #  # ]:          0 :     if ((nCurrentPos + 9) <= SEQUENCESIZE)
     691                 :            :     {
     692                 :          0 :         memcpy( &(mp_Sequence[nCurrentPos]), "<![CDATA[" , 9 );
     693                 :          0 :         nCurrentPos += 9;
     694                 :            :     }
     695                 :            :     else
     696                 :          0 :         AddBytes(mp_Sequence, nCurrentPos, (sal_Int8*)"<![CDATA[" , 9);
     697         [ #  # ]:          0 :     if (nCurrentPos == SEQUENCESIZE)
     698                 :          0 :         nCurrentPos = writeSequence();
     699                 :          0 : }
     700                 :            : 
     701                 :          0 : inline void SaxWriterHelper::endCDATA() throw( SAXException )
     702                 :            : {
     703                 :          0 :     FinishStartElement();
     704         [ #  # ]:          0 :     if ((nCurrentPos + 3) <= SEQUENCESIZE)
     705                 :            :     {
     706                 :          0 :         memcpy( &(mp_Sequence[nCurrentPos]), "]]>" , 3 );
     707                 :          0 :         nCurrentPos += 3;
     708                 :            :     }
     709                 :            :     else
     710                 :          0 :         AddBytes(mp_Sequence, nCurrentPos, (sal_Int8*)"]]>" , 3);
     711         [ #  # ]:          0 :     if (nCurrentPos == SEQUENCESIZE)
     712                 :          0 :         nCurrentPos = writeSequence();
     713                 :          0 : }
     714                 :            : 
     715                 :          0 : inline sal_Bool SaxWriterHelper::comment(const rtl::OUString& rComment) throw( SAXException )
     716                 :            : {
     717                 :          0 :     FinishStartElement();
     718                 :          0 :     mp_Sequence[nCurrentPos] = '<';
     719                 :          0 :     nCurrentPos++;
     720         [ #  # ]:          0 :     if (nCurrentPos == SEQUENCESIZE)
     721                 :          0 :         nCurrentPos = writeSequence();
     722                 :          0 :     mp_Sequence[nCurrentPos] = '!';
     723                 :          0 :     nCurrentPos++;
     724         [ #  # ]:          0 :     if (nCurrentPos == SEQUENCESIZE)
     725                 :          0 :         nCurrentPos = writeSequence();
     726                 :          0 :     mp_Sequence[nCurrentPos] = '-';
     727                 :          0 :     nCurrentPos++;
     728         [ #  # ]:          0 :     if (nCurrentPos == SEQUENCESIZE)
     729                 :          0 :         nCurrentPos = writeSequence();
     730                 :          0 :     mp_Sequence[nCurrentPos] = '-';
     731                 :          0 :     nCurrentPos++;
     732         [ #  # ]:          0 :     if (nCurrentPos == SEQUENCESIZE)
     733                 :          0 :         nCurrentPos = writeSequence();
     734                 :            : 
     735                 :          0 :     sal_Bool bRet(writeString( rComment, sal_False, sal_False));
     736                 :            : 
     737                 :          0 :     mp_Sequence[nCurrentPos] = '-';
     738                 :          0 :     nCurrentPos++;
     739         [ #  # ]:          0 :     if (nCurrentPos == SEQUENCESIZE)
     740                 :          0 :         nCurrentPos = writeSequence();
     741                 :          0 :     mp_Sequence[nCurrentPos] = '-';
     742                 :          0 :     nCurrentPos++;
     743         [ #  # ]:          0 :     if (nCurrentPos == SEQUENCESIZE)
     744                 :          0 :         nCurrentPos = writeSequence();
     745                 :          0 :     mp_Sequence[nCurrentPos] = '>';
     746                 :          0 :     nCurrentPos++;
     747         [ #  # ]:          0 :     if (nCurrentPos == SEQUENCESIZE)
     748                 :          0 :         nCurrentPos = writeSequence();
     749                 :            : 
     750                 :          0 :     return bRet;
     751                 :            : }
     752                 :            : 
     753                 :          0 : inline sal_Int32 calcXMLByteLength( const sal_Unicode *pStr, sal_Int32 nStrLen,
     754                 :            :                                     sal_Bool bDoNormalization,
     755                 :            :                                     sal_Bool bNormalizeWhitespace )
     756                 :            : {
     757                 :          0 :     sal_Int32 nOutputLength = 0;
     758                 :          0 :     sal_uInt32 nSurrogate = 0;
     759                 :            : 
     760         [ #  # ]:          0 :     for( sal_Int32 i = 0 ; i < nStrLen ; i++ )
     761                 :            :     {
     762                 :          0 :         sal_uInt16 c = pStr[i];
     763 [ #  # ][ #  # ]:          0 :         if( !IsInvalidChar(c) && (c >= 0x0001) && (c <= 0x007F) )
         [ #  # ][ #  # ]
     764                 :            :         {
     765         [ #  # ]:          0 :             if( bDoNormalization )
     766                 :            :             {
     767   [ #  #  #  #  :          0 :                 switch( c )
                      # ]
     768                 :            :                 {
     769                 :            :                 case '&':       // resemble to &amp;
     770                 :          0 :                     nOutputLength +=5;
     771                 :          0 :                     break;
     772                 :            :                 case '<':       // &lt;
     773                 :            :                 case '>':       // &gt;
     774                 :          0 :                     nOutputLength +=4;
     775                 :          0 :                     break;
     776                 :            :                 case 39:        // 39 == ''', &apos;
     777                 :            :                 case '"':       // &quot;
     778                 :            :                 case 13:        // &#x0d;
     779                 :          0 :                     nOutputLength += 6;
     780                 :          0 :                     break;
     781                 :            : 
     782                 :            :                 case 10:        // &#x0a;
     783                 :            :                 case 9:         // &#x09;
     784         [ #  # ]:          0 :                     if( bNormalizeWhitespace )
     785                 :            :                     {
     786                 :          0 :                         nOutputLength += 6;       //
     787                 :            :                     }
     788                 :            :                     else
     789                 :            :                     {
     790                 :          0 :                         nOutputLength ++;
     791                 :            :                     }
     792                 :          0 :                     break;
     793                 :            :                 default:
     794                 :          0 :                     nOutputLength ++;
     795                 :            :                 }
     796                 :            :             }
     797                 :            :             else
     798                 :            :             {
     799                 :          0 :                 nOutputLength ++;
     800                 :            :             }
     801                 :            :         }
     802 [ #  # ][ #  # ]:          0 :         else if( c >= 0xd800 && c < 0xdc00  )
     803                 :            :         {
     804                 :            :             // save surrogate
     805                 :          0 :             nSurrogate = ( ( c & 0x03ff ) + 0x0040 );
     806                 :            :         }
     807 [ #  # ][ #  # ]:          0 :         else if( c >= 0xdc00 && c < 0xe000 )
     808                 :            :         {
     809                 :            :             // 2. surrogate: write as UTF-8 (if range is OK
     810                 :          0 :             nSurrogate = ( nSurrogate << 10 ) | ( c & 0x03ff );
     811 [ #  # ][ #  # ]:          0 :             if( nSurrogate >= 0x00010000  &&  nSurrogate <= 0x0010FFFF )
     812                 :          0 :                 nOutputLength += 4;
     813                 :          0 :             nSurrogate = 0;
     814                 :            :         }
     815         [ #  # ]:          0 :         else if( c > 0x07FF )
     816                 :            :         {
     817                 :          0 :             nOutputLength += 3;
     818                 :            :         }
     819                 :            :         else
     820                 :            :         {
     821                 :          0 :             nOutputLength += 2;
     822                 :            :         }
     823                 :            : 
     824                 :            :         // surrogate processing
     825 [ #  # ][ #  # ]:          0 :         if( ( nSurrogate != 0 ) && !( c >= 0xd800 && c < 0xdc00 ) )
                 [ #  # ]
     826                 :          0 :             nSurrogate = 0;
     827                 :            :     }
     828                 :            : 
     829                 :          0 :     return nOutputLength;
     830                 :            : }
     831                 :            : 
     832                 :            : /** returns position of first ascii 10 within the string, -1 when no 10 in string.
     833                 :            :  */
     834                 :          0 : static inline sal_Int32 getFirstLineBreak( const OUString & str ) throw ()
     835                 :            : {
     836                 :          0 :     const sal_Unicode *pSource = str.getStr();
     837                 :          0 :     sal_Int32 nLen  = str.getLength();
     838                 :            : 
     839         [ #  # ]:          0 :     for( int n = 0; n < nLen ; n ++ )
     840                 :            :     {
     841         [ #  # ]:          0 :         if( LINEFEED == pSource[n] ) {
     842                 :          0 :             return n;
     843                 :            :         }
     844                 :            :     }
     845                 :          0 :     return -1;
     846                 :            : }
     847                 :            : 
     848                 :            : /** returns position of last ascii 10 within sequence, -1 when no 10 in string.
     849                 :            :  */
     850                 :            : static inline sal_Int32 getLastLineBreak( const Sequence<sal_Int8>  & seq) throw ()
     851                 :            : {
     852                 :            :     const sal_Int8 *pSource = seq.getConstArray();
     853                 :            :     sal_Int32 nLen  = seq.getLength();
     854                 :            : 
     855                 :            :     for( int n = nLen-1; n >= 0 ; n -- )
     856                 :            :     {
     857                 :            :         if( LINEFEED == pSource[n] ) {
     858                 :            :             return n;
     859                 :            :         }
     860                 :            :     }
     861                 :            :     return -1;
     862                 :            : }
     863                 :            : 
     864                 :            : 
     865                 :            : class SAXWriter :
     866                 :            :     public WeakImplHelper3<
     867                 :            :             XActiveDataSource,
     868                 :            :             XExtendedDocumentHandler,
     869                 :            :               XServiceInfo >
     870                 :            : {
     871                 :            : public:
     872                 :       2787 :     SAXWriter( ) :
     873                 :            :         m_seqStartElement(),
     874                 :            :         mp_SaxWriterHelper( NULL ),
     875                 :            :         m_bForceLineBreak(sal_False),
     876         [ +  - ]:       2787 :         m_bAllowLineBreak(sal_False)
     877                 :       2787 :         {}
     878                 :       5574 :     ~SAXWriter()
     879         [ +  - ]:       2787 :     {
     880 [ +  - ][ +  - ]:       2787 :         delete mp_SaxWriterHelper;
     881         [ -  + ]:       5574 :     }
     882                 :            : 
     883                 :            : public: // XActiveDataSource
     884                 :       2853 :     virtual void SAL_CALL setOutputStream(const Reference< XOutputStream > & aStream)
     885                 :            :         throw (RuntimeException)
     886                 :            :             {
     887                 :            :                 // temporary: set same stream again to clear buffer
     888 [ -  + ][ #  # ]:       2853 :                 if ( m_out == aStream && mp_SaxWriterHelper && m_bDocStarted )
         [ #  # ][ -  + ]
     889                 :          0 :                     mp_SaxWriterHelper->clearBuffer();
     890                 :            :                 else
     891                 :            :                 {
     892                 :            : 
     893                 :       2853 :                 m_out = aStream;
     894         [ +  + ]:       2853 :                 delete mp_SaxWriterHelper;
     895 [ +  - ][ +  - ]:       2853 :                 mp_SaxWriterHelper = new SaxWriterHelper(m_out);
     896                 :       2853 :                 m_bDocStarted = sal_False;
     897                 :       2853 :                 m_nLevel = 0;
     898                 :       2853 :                 m_bIsCDATA = sal_False;
     899                 :            : 
     900                 :            :                 }
     901                 :       2853 :             }
     902                 :          0 :     virtual Reference< XOutputStream >  SAL_CALL getOutputStream(void)
     903                 :            :         throw(RuntimeException)
     904                 :          0 :             { return m_out; }
     905                 :            : 
     906                 :            : public: // XDocumentHandler
     907                 :            :     virtual void SAL_CALL startDocument(void)
     908                 :            :         throw(SAXException, RuntimeException);
     909                 :            : 
     910                 :            :     virtual void SAL_CALL endDocument(void)
     911                 :            :         throw(SAXException, RuntimeException);
     912                 :            : 
     913                 :            :     virtual void SAL_CALL startElement(const OUString& aName,
     914                 :            :                                        const Reference< XAttributeList > & xAttribs)
     915                 :            :         throw (SAXException, RuntimeException);
     916                 :            : 
     917                 :            :     virtual void SAL_CALL endElement(const OUString& aName)
     918                 :            :         throw(SAXException, RuntimeException);
     919                 :            : 
     920                 :            :     virtual void SAL_CALL characters(const OUString& aChars)
     921                 :            :         throw(SAXException, RuntimeException);
     922                 :            : 
     923                 :            :     virtual void SAL_CALL ignorableWhitespace(const OUString& aWhitespaces)
     924                 :            :         throw(SAXException, RuntimeException);
     925                 :            :     virtual void SAL_CALL processingInstruction(const OUString& aTarget,
     926                 :            :                                                 const OUString& aData)
     927                 :            :         throw(SAXException, RuntimeException);
     928                 :            :     virtual void SAL_CALL setDocumentLocator(const Reference< XLocator > & xLocator)
     929                 :            :         throw(SAXException, RuntimeException);
     930                 :            : 
     931                 :            : public: // XExtendedDocumentHandler
     932                 :            :     virtual void SAL_CALL startCDATA(void) throw(SAXException, RuntimeException);
     933                 :            :     virtual void SAL_CALL endCDATA(void) throw(RuntimeException);
     934                 :            :     virtual void SAL_CALL comment(const OUString& sComment)
     935                 :            :         throw(SAXException, RuntimeException);
     936                 :            :     virtual void SAL_CALL unknown(const OUString& sString)
     937                 :            :         throw(SAXException, RuntimeException);
     938                 :            :     virtual void SAL_CALL allowLineBreak(void)
     939                 :            :         throw(SAXException,RuntimeException);
     940                 :            : 
     941                 :            : public: // XServiceInfo
     942                 :            :     OUString                     SAL_CALL getImplementationName() throw();
     943                 :            :     Sequence< OUString >         SAL_CALL getSupportedServiceNames(void) throw();
     944                 :            :     sal_Bool                    SAL_CALL supportsService(const OUString& ServiceName) throw();
     945                 :            : 
     946                 :            : private:
     947                 :            : 
     948                 :            :     void writeSequence( const Sequence<sal_Int8> & seq );
     949                 :            :     sal_Int32 getIndentPrefixLength( sal_Int32 nFirstLineBreakOccurrence ) throw();
     950                 :            : 
     951                 :            :     Reference< XOutputStream >  m_out;
     952                 :            :     Sequence < sal_Int8 >       m_seqStartElement;
     953                 :            :     SaxWriterHelper*            mp_SaxWriterHelper;
     954                 :            : 
     955                 :            :     // Status information
     956                 :            :     sal_Bool m_bDocStarted : 1;
     957                 :            :     sal_Bool m_bIsCDATA : 1;
     958                 :            :     sal_Bool m_bForceLineBreak : 1;
     959                 :            :     sal_Bool m_bAllowLineBreak : 1;
     960                 :            :     sal_Int32 m_nLevel;
     961                 :            : };
     962                 :            : 
     963                 :            : 
     964                 :            : //--------------------------------------
     965                 :            : // the extern interface
     966                 :            : //---------------------------------------
     967                 :       2787 : Reference < XInterface > SAL_CALL SaxWriter_CreateInstance(
     968                 :            :     SAL_UNUSED_PARAMETER const Reference < XMultiServiceFactory > & )
     969                 :            :     throw (Exception)
     970                 :            : {
     971         [ +  - ]:       2787 :     SAXWriter *p = new SAXWriter;
     972                 :       2787 :     return Reference< XInterface > ( (static_cast< OWeakObject * >(p)) );
     973                 :            : }
     974                 :            : 
     975                 :         83 : OUString SaxWriter_getServiceName() throw()
     976                 :            : {
     977                 :         83 :     return OUString("com.sun.star.xml.sax.Writer");
     978                 :            : }
     979                 :            : 
     980                 :         83 : OUString SaxWriter_getImplementationName() throw()
     981                 :            : {
     982                 :         83 :     return OUString("com.sun.star.extensions.xml.sax.Writer");
     983                 :            : }
     984                 :            : 
     985                 :         83 : Sequence< OUString >    SaxWriter_getSupportedServiceNames(void) throw()
     986                 :            : {
     987                 :         83 :     Sequence<OUString> aRet(1);
     988         [ +  - ]:         83 :     aRet.getArray()[0] = SaxWriter_getServiceName();
     989                 :         83 :     return aRet;
     990                 :            : }
     991                 :            : 
     992                 :            : 
     993                 :     241674 : sal_Int32 SAXWriter::getIndentPrefixLength( sal_Int32 nFirstLineBreakOccurrence ) throw()
     994                 :            : {
     995                 :     241674 :     sal_Int32 nLength =-1;
     996         [ +  - ]:     241674 :     if (mp_SaxWriterHelper)
     997                 :            :     {
     998         [ +  + ]:     241674 :         if ( m_bForceLineBreak ||
           [ -  +  #  # ]
                 [ +  + ]
     999                 :            :             (m_bAllowLineBreak &&
    1000                 :          0 :             ((nFirstLineBreakOccurrence + mp_SaxWriterHelper->GetLastColumnCount()) > MAXCOLUMNCOUNT)) )
    1001                 :       1910 :             nLength = m_nLevel;
    1002                 :            :     }
    1003                 :     241674 :     m_bForceLineBreak = sal_False;
    1004                 :     241674 :     m_bAllowLineBreak = sal_False;
    1005                 :     241674 :     return nLength;
    1006                 :            : }
    1007                 :            : 
    1008                 :          0 : static inline sal_Bool isFirstCharWhitespace( const sal_Unicode *p ) throw()
    1009                 :            : {
    1010                 :          0 :     return *p == ' ';
    1011                 :            : }
    1012                 :            : 
    1013                 :            : 
    1014                 :            : // XServiceInfo
    1015                 :          0 : OUString SAXWriter::getImplementationName() throw()
    1016                 :            : {
    1017                 :          0 :     return SaxWriter_getImplementationName();
    1018                 :            : }
    1019                 :            : 
    1020                 :            : // XServiceInfo
    1021                 :          0 : sal_Bool SAXWriter::supportsService(const OUString& ServiceName) throw()
    1022                 :            : {
    1023                 :          0 :     Sequence< OUString > aSNL = getSupportedServiceNames();
    1024                 :          0 :     const OUString * pArray = aSNL.getConstArray();
    1025                 :            : 
    1026         [ #  # ]:          0 :     for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
    1027         [ #  # ]:          0 :         if( pArray[i] == ServiceName )
    1028                 :          0 :             return sal_True;
    1029                 :            : 
    1030         [ #  # ]:          0 :     return sal_False;
    1031                 :            : }
    1032                 :            : 
    1033                 :            : // XServiceInfo
    1034                 :          0 : Sequence< OUString > SAXWriter::getSupportedServiceNames(void) throw ()
    1035                 :            : {
    1036                 :          0 :     Sequence<OUString> seq(1);
    1037         [ #  # ]:          0 :     seq.getArray()[0] = SaxWriter_getServiceName();
    1038                 :          0 :     return seq;
    1039                 :            : }
    1040                 :            : 
    1041                 :            : 
    1042                 :            : 
    1043                 :       2835 : void SAXWriter::startDocument()                     throw(SAXException, RuntimeException )
    1044                 :            : {
    1045 [ +  - ][ +  - ]:       2835 :     if( m_bDocStarted || ! m_out.is() || !mp_SaxWriterHelper ) {
         [ -  + ][ -  + ]
    1046         [ #  # ]:          0 :         throw SAXException();
    1047                 :            :     }
    1048                 :       2835 :     m_bDocStarted = sal_True;
    1049                 :       2835 :     mp_SaxWriterHelper->startDocument();
    1050                 :       2835 : }
    1051                 :            : 
    1052                 :            : 
    1053                 :       2835 : void SAXWriter::endDocument(void)                   throw(SAXException, RuntimeException)
    1054                 :            : {
    1055         [ -  + ]:       2835 :     if( ! m_bDocStarted )
    1056                 :            :     {
    1057                 :            :         throw SAXException(
    1058                 :            :             OUString("endDocument called before startDocument"),
    1059         [ #  # ]:          0 :             Reference< XInterface >() , Any() );
    1060                 :            :     }
    1061         [ -  + ]:       2835 :     if( m_nLevel ) {
    1062                 :            :         throw SAXException(
    1063                 :            :             OUString("unexpected end of document"),
    1064         [ #  # ]:          0 :             Reference< XInterface >() , Any() );
    1065                 :            :     }
    1066                 :       2835 :     mp_SaxWriterHelper->endDocument();
    1067                 :            :     try
    1068                 :            :     {
    1069 [ +  - ][ +  - ]:       2835 :         m_out->closeOutput();
    1070                 :            :     }
    1071         [ #  # ]:          0 :     catch (const IOException & e)
    1072                 :            :     {
    1073                 :          0 :         Any a;
    1074         [ #  # ]:          0 :         a <<= e;
    1075                 :            :         throw SAXException(
    1076                 :            :             OUString("IO exception during closing the IO Stream"),
    1077                 :            :             Reference< XInterface > (),
    1078         [ #  # ]:          0 :             a );
    1079                 :            :     }
    1080                 :       2835 : }
    1081                 :            : 
    1082                 :            : 
    1083                 :      93094 : void SAXWriter::startElement(const OUString& aName, const Reference< XAttributeList >& xAttribs)
    1084                 :            :     throw(SAXException, RuntimeException)
    1085                 :            : {
    1086         [ -  + ]:      93094 :     if( ! m_bDocStarted )
    1087                 :            :     {
    1088         [ #  # ]:          0 :         SAXException except;
    1089                 :          0 :         except.Message = OUString(  "startElement called before startDocument" );
    1090         [ #  # ]:          0 :         throw except;
    1091                 :            :     }
    1092         [ -  + ]:      93094 :     if( m_bIsCDATA )
    1093                 :            :     {
    1094         [ #  # ]:          0 :         SAXException except;
    1095                 :          0 :         except.Message = OUString(  "startElement call not allowed with CDATA sections" );
    1096         [ #  # ]:          0 :         throw except;
    1097                 :            :     }
    1098                 :            : 
    1099                 :      93094 :     sal_Int32 nLength(0);
    1100         [ -  + ]:      93094 :     if (m_bAllowLineBreak)
    1101                 :            :     {
    1102         [ #  # ]:          0 :         sal_Int32 nAttribCount = xAttribs.is() ? xAttribs->getLength() : 0;
    1103                 :            : 
    1104                 :          0 :         nLength ++; // "<"
    1105                 :            :         nLength += calcXMLByteLength( aName.getStr() , aName.getLength(),
    1106                 :          0 :                                   sal_False, sal_False ); // the tag name
    1107                 :            : 
    1108                 :            :         sal_Int16 n;
    1109         [ #  # ]:          0 :         for( n = 0 ; n < static_cast<sal_Int16>(nAttribCount) ; n ++ ) {
    1110                 :          0 :             nLength ++; // " "
    1111 [ #  # ][ #  # ]:          0 :             OUString tmp =  xAttribs->getNameByIndex( n );
    1112                 :            : 
    1113                 :          0 :             nLength += calcXMLByteLength( tmp.getStr() , tmp.getLength() , sal_False, sal_False );
    1114                 :            : 
    1115                 :          0 :             nLength += 2; // ="
    1116                 :            : 
    1117 [ #  # ][ #  # ]:          0 :             tmp = xAttribs->getValueByIndex( n );
    1118                 :            : 
    1119                 :          0 :             nLength += calcXMLByteLength( tmp.getStr(), tmp.getLength(), sal_True, sal_True );
    1120                 :            : 
    1121                 :          0 :             nLength += 1; // "
    1122                 :          0 :         }
    1123                 :            : 
    1124                 :          0 :         nLength ++;  // '>'
    1125                 :            :     }
    1126                 :            : 
    1127                 :            :     // Is there a new indentation necesarry ?
    1128                 :      93094 :     sal_Int32 nPrefix(getIndentPrefixLength( nLength ));
    1129                 :            : 
    1130                 :            :     // write into sequence
    1131         [ +  + ]:      93094 :     if( nPrefix >= 0 )
    1132                 :       1334 :         mp_SaxWriterHelper->insertIndentation( nPrefix );
    1133                 :            : 
    1134                 :      93094 :     SaxInvalidCharacterError eRet(mp_SaxWriterHelper->startElement(aName, xAttribs));
    1135                 :            : 
    1136                 :      93094 :     m_nLevel++;
    1137                 :            : 
    1138         [ -  + ]:      93094 :     if (eRet == SAX_WARNING)
    1139                 :            :     {
    1140         [ #  # ]:          0 :         SAXInvalidCharacterException except;
    1141                 :          0 :         except.Message = OUString(  "Invalid charcter during XML-Export in a attribute value"  );
    1142         [ #  # ]:          0 :         throw except;
    1143                 :            :     }
    1144         [ -  + ]:      93094 :     else if (eRet == SAX_ERROR)
    1145                 :            :     {
    1146         [ #  # ]:          0 :         SAXException except;
    1147                 :          0 :         except.Message = OUString(  "Invalid charcter during XML-Export"  );
    1148         [ #  # ]:          0 :         throw except;
    1149                 :            :     }
    1150                 :      93094 : }
    1151                 :            : 
    1152                 :      93094 : void SAXWriter::endElement(const OUString& aName)   throw (SAXException, RuntimeException)
    1153                 :            : {
    1154         [ -  + ]:      93094 :     if( ! m_bDocStarted ) {
    1155         [ #  # ]:          0 :         throw SAXException ();
    1156                 :            :     }
    1157                 :      93094 :     m_nLevel --;
    1158                 :            : 
    1159         [ -  + ]:      93094 :     if( m_nLevel < 0 ) {
    1160         [ #  # ]:          0 :         throw SAXException();
    1161                 :            :     }
    1162                 :      93094 :     sal_Bool bRet(sal_True);
    1163                 :            : 
    1164         [ +  + ]:      93094 :     if( mp_SaxWriterHelper->FinishEmptyElement() )
    1165                 :      11198 :         m_bForceLineBreak = sal_False;
    1166                 :            :     else
    1167                 :            :     {
    1168                 :            :         // only ascii chars allowed
    1169                 :      81896 :         sal_Int32 nLength(0);
    1170         [ -  + ]:      81896 :         if (m_bAllowLineBreak)
    1171                 :          0 :             nLength = 3 + calcXMLByteLength( aName.getStr(), aName.getLength(), sal_False, sal_False );
    1172                 :      81896 :         sal_Int32 nPrefix = getIndentPrefixLength( nLength );
    1173                 :            : 
    1174         [ +  + ]:      81896 :         if( nPrefix >= 0 )
    1175                 :        576 :             mp_SaxWriterHelper->insertIndentation( nPrefix );
    1176                 :            : 
    1177                 :      81896 :         bRet = mp_SaxWriterHelper->endElement(aName);
    1178                 :            :     }
    1179                 :            : 
    1180         [ -  + ]:      93094 :     if (!bRet)
    1181                 :            :     {
    1182         [ #  # ]:          0 :         SAXException except;
    1183                 :          0 :         except.Message = OUString(  "Invalid charcter during XML-Export"  );
    1184         [ #  # ]:          0 :         throw except;
    1185                 :            :     }
    1186                 :      93094 : }
    1187                 :            : 
    1188                 :      66572 : void SAXWriter::characters(const OUString& aChars)  throw(SAXException, RuntimeException)
    1189                 :            : {
    1190         [ -  + ]:      66572 :     if( ! m_bDocStarted )
    1191                 :            :     {
    1192         [ #  # ]:          0 :         SAXException except;
    1193                 :          0 :         except.Message = OUString(  "characters method called before startDocument"  );
    1194         [ #  # ]:          0 :         throw except;
    1195                 :            :     }
    1196                 :            : 
    1197                 :      66572 :     sal_Bool bThrowException(sal_False);
    1198         [ +  + ]:      66572 :     if( !aChars.isEmpty() )
    1199                 :            :     {
    1200         [ -  + ]:      66550 :         if( m_bIsCDATA )
    1201                 :          0 :             bThrowException = !mp_SaxWriterHelper->writeString( aChars, sal_False, sal_False );
    1202                 :            :         else
    1203                 :            :         {
    1204                 :            :             // Note : nFirstLineBreakOccurrence is not exact, because we don't know, how
    1205                 :            :             //        many 2 and 3 byte chars are inbetween. However this whole stuff
    1206                 :            :             //        is eitherway for pretty printing only, so it does not need to be exact.
    1207                 :      66550 :             sal_Int32 nLength(0);
    1208                 :      66550 :             sal_Int32 nIndentPrefix(-1);
    1209         [ -  + ]:      66550 :             if (m_bAllowLineBreak)
    1210                 :            :             {
    1211                 :          0 :                 sal_Int32 nFirstLineBreakOccurrence = getFirstLineBreak( aChars );
    1212                 :            : 
    1213                 :            :                 nLength = calcXMLByteLength( aChars.getStr(), aChars.getLength(),
    1214                 :          0 :                                                ! m_bIsCDATA , sal_False );
    1215                 :            :                 nIndentPrefix = getIndentPrefixLength(
    1216         [ #  # ]:          0 :                     nFirstLineBreakOccurrence >= 0 ? nFirstLineBreakOccurrence : nLength );
    1217                 :            :             }
    1218                 :            :             else
    1219                 :      66550 :                 nIndentPrefix = getIndentPrefixLength(nLength);
    1220                 :            : 
    1221                 :            :             // insert indentation
    1222         [ -  + ]:      66550 :             if( nIndentPrefix >= 0 )
    1223                 :            :             {
    1224         [ #  # ]:          0 :                 if( isFirstCharWhitespace( aChars.getStr() ) )
    1225                 :          0 :                     mp_SaxWriterHelper->insertIndentation( nIndentPrefix - 1 );
    1226                 :            :                 else
    1227                 :          0 :                     mp_SaxWriterHelper->insertIndentation( nIndentPrefix );
    1228                 :            :             }
    1229                 :      66550 :             bThrowException = !mp_SaxWriterHelper->writeString(aChars, sal_True , sal_False);
    1230                 :            :         }
    1231                 :            :     }
    1232         [ -  + ]:      66572 :     if (bThrowException)
    1233                 :            :     {
    1234         [ #  # ]:          0 :         SAXInvalidCharacterException except;
    1235                 :          0 :         except.Message = OUString(  "Invalid charcter during XML-Export"  );
    1236         [ #  # ]:          0 :         throw except;
    1237                 :            :     }
    1238                 :      66572 : }
    1239                 :            : 
    1240                 :            : 
    1241                 :       4038 : void SAXWriter::ignorableWhitespace(const OUString&) throw(SAXException, RuntimeException)
    1242                 :            : {
    1243         [ -  + ]:       4038 :     if( ! m_bDocStarted )
    1244                 :            :     {
    1245         [ #  # ]:          0 :         throw SAXException ();
    1246                 :            :     }
    1247                 :            : 
    1248                 :       4038 :     m_bForceLineBreak = sal_True;
    1249                 :       4038 : }
    1250                 :            : 
    1251                 :          0 : void SAXWriter::processingInstruction(const OUString& aTarget, const OUString& aData)
    1252                 :            :     throw (SAXException, RuntimeException)
    1253                 :            : {
    1254 [ #  # ][ #  # ]:          0 :     if( ! m_bDocStarted || m_bIsCDATA )
    1255                 :            :     {
    1256         [ #  # ]:          0 :         throw SAXException();
    1257                 :            :     }
    1258                 :            : 
    1259                 :          0 :     sal_Int32 nLength(0);
    1260         [ #  # ]:          0 :     if (m_bAllowLineBreak)
    1261                 :            :     {
    1262                 :          0 :         nLength = 2;  // "<?"
    1263                 :          0 :         nLength += calcXMLByteLength( aTarget.getStr(), aTarget.getLength(), sal_False, sal_False );
    1264                 :            : 
    1265                 :          0 :         nLength += 1;  // " "
    1266                 :            : 
    1267                 :          0 :         nLength += calcXMLByteLength( aData.getStr(), aData.getLength(), sal_False, sal_False );
    1268                 :            : 
    1269                 :          0 :         nLength += 2; // "?>"
    1270                 :            :     }
    1271                 :            : 
    1272                 :          0 :     sal_Int32 nPrefix = getIndentPrefixLength( nLength );
    1273                 :            : 
    1274         [ #  # ]:          0 :     if( nPrefix >= 0 )
    1275                 :          0 :         mp_SaxWriterHelper->insertIndentation( nPrefix );
    1276                 :            : 
    1277         [ #  # ]:          0 :     if (!mp_SaxWriterHelper->processingInstruction(aTarget, aData))
    1278                 :            :     {
    1279         [ #  # ]:          0 :         SAXException except;
    1280                 :          0 :         except.Message = OUString(  "Invalid charcter during XML-Export"  );
    1281         [ #  # ]:          0 :         throw except;
    1282                 :            :     }
    1283                 :          0 : }
    1284                 :            : 
    1285                 :            : 
    1286                 :          0 : void SAXWriter::setDocumentLocator(const Reference< XLocator >&)
    1287                 :            :         throw (SAXException, RuntimeException)
    1288                 :            : {
    1289                 :            : 
    1290                 :          0 : }
    1291                 :            : 
    1292                 :          0 : void SAXWriter::startCDATA(void) throw(SAXException, RuntimeException)
    1293                 :            : {
    1294 [ #  # ][ #  # ]:          0 :     if( ! m_bDocStarted || m_bIsCDATA)
    1295                 :            :     {
    1296         [ #  # ]:          0 :         throw SAXException ();
    1297                 :            :     }
    1298                 :            : 
    1299                 :          0 :     sal_Int32 nLength = 9;
    1300                 :          0 :     sal_Int32 nPrefix = getIndentPrefixLength( nLength );
    1301         [ #  # ]:          0 :     if( nPrefix >= 0 )
    1302                 :          0 :         mp_SaxWriterHelper->insertIndentation( nPrefix );
    1303                 :            : 
    1304                 :          0 :     mp_SaxWriterHelper->startCDATA();
    1305                 :            : 
    1306                 :          0 :     m_bIsCDATA = sal_True;
    1307                 :          0 : }
    1308                 :            : 
    1309                 :          0 : void SAXWriter::endCDATA(void) throw (RuntimeException)
    1310                 :            : {
    1311         [ #  # ]:          0 :     if( ! m_bDocStarted | ! m_bIsCDATA)
    1312                 :            :     {
    1313         [ #  # ]:          0 :         SAXException except;
    1314                 :          0 :         except.Message = OUString(  "endCDATA was called without startCDATA"  );
    1315         [ #  # ]:          0 :         throw except;
    1316                 :            :     }
    1317                 :            : 
    1318                 :          0 :     sal_Int32 nLength = 3;
    1319                 :          0 :     sal_Int32 nPrefix = getIndentPrefixLength( nLength );
    1320         [ #  # ]:          0 :     if( nPrefix >= 0 )
    1321                 :          0 :         mp_SaxWriterHelper->insertIndentation( nPrefix );
    1322                 :            : 
    1323                 :          0 :     mp_SaxWriterHelper->endCDATA();
    1324                 :            : 
    1325                 :          0 :     m_bIsCDATA = sal_False;
    1326                 :          0 : }
    1327                 :            : 
    1328                 :            : 
    1329                 :          0 : void SAXWriter::comment(const OUString& sComment) throw(SAXException, RuntimeException)
    1330                 :            : {
    1331 [ #  # ][ #  # ]:          0 :     if( ! m_bDocStarted || m_bIsCDATA )
    1332                 :            :     {
    1333         [ #  # ]:          0 :         throw SAXException();
    1334                 :            :     }
    1335                 :            : 
    1336                 :          0 :     sal_Int32 nLength(0);
    1337         [ #  # ]:          0 :     if (m_bAllowLineBreak)
    1338                 :            :     {
    1339                 :          0 :         nLength = 4; // "<!--"
    1340                 :          0 :         nLength += calcXMLByteLength( sComment.getStr(), sComment.getLength(), sal_False, sal_False);
    1341                 :            : 
    1342                 :          0 :         nLength += 3;
    1343                 :            :     }
    1344                 :            : 
    1345                 :          0 :     sal_Int32 nPrefix = getIndentPrefixLength( nLength );
    1346         [ #  # ]:          0 :     if( nPrefix >= 0 )
    1347                 :          0 :         mp_SaxWriterHelper->insertIndentation( nPrefix );
    1348                 :            : 
    1349         [ #  # ]:          0 :     if (!mp_SaxWriterHelper->comment(sComment))
    1350                 :            :     {
    1351         [ #  # ]:          0 :         SAXException except;
    1352                 :          0 :         except.Message = OUString(  "Invalid charcter during XML-Export"  );
    1353         [ #  # ]:          0 :         throw except;
    1354                 :            :     }
    1355                 :          0 : }
    1356                 :            : 
    1357                 :            : 
    1358                 :          0 : void SAXWriter::allowLineBreak( )   throw ( SAXException , RuntimeException)
    1359                 :            : {
    1360 [ #  # ][ #  # ]:          0 :     if( ! m_bDocStarted || m_bAllowLineBreak ) {
    1361         [ #  # ]:          0 :         throw SAXException();
    1362                 :            :     }
    1363                 :            : 
    1364                 :          0 :      m_bAllowLineBreak = sal_True;
    1365                 :          0 : }
    1366                 :            : 
    1367                 :        134 : void SAXWriter::unknown(const OUString& sString) throw (SAXException, RuntimeException)
    1368                 :            : {
    1369                 :            : 
    1370         [ -  + ]:        134 :     if( ! m_bDocStarted )
    1371                 :            :     {
    1372         [ #  # ]:          0 :         throw SAXException ();
    1373                 :            :     }
    1374         [ -  + ]:        134 :     if( m_bIsCDATA )
    1375                 :            :     {
    1376         [ #  # ]:          0 :         throw SAXException();
    1377                 :            :     }
    1378                 :            : 
    1379         [ -  + ]:        134 :     if( sString.matchAsciiL( "<?xml", 5 ) )
    1380                 :        134 :         return;
    1381                 :            : 
    1382                 :        134 :     sal_Int32 nLength(0);
    1383         [ -  + ]:        134 :     if (m_bAllowLineBreak)
    1384                 :          0 :         nLength = calcXMLByteLength( sString.getStr(), sString.getLength(), sal_False, sal_False );
    1385                 :            : 
    1386                 :        134 :     sal_Int32 nPrefix = getIndentPrefixLength( nLength );
    1387         [ -  + ]:        134 :     if( nPrefix >= 0 )
    1388                 :          0 :         mp_SaxWriterHelper->insertIndentation( nPrefix );
    1389                 :            : 
    1390         [ -  + ]:        134 :     if (!mp_SaxWriterHelper->writeString( sString, sal_False, sal_False))
    1391                 :            :     {
    1392         [ #  # ]:          0 :         SAXException except;
    1393                 :          0 :         except.Message = OUString(  "Invalid charcter during XML-Export"  );
    1394         [ #  # ]:          0 :         throw except;
    1395                 :            :     }
    1396                 :            : }
    1397                 :            : 
    1398                 :            : }
    1399                 :            : 
    1400                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10