LCOV - code coverage report
Current view: top level - libreoffice/cosv/source/strings - streamstr.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 139 277 50.2 %
Date: 2012-12-27 Functions: 26 47 55.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #define CSV_USE_CSV_ASSERTIONS
      21             : #include <cosv/csv_env.hxx>
      22             : 
      23             : #include <cosv/comfunc.hxx>
      24             : #include <cosv/string.hxx>
      25             : #include <cosv/streamstr.hxx>
      26             : #include <cosv/std_outp.hxx>
      27             : #include <cosv/tpl/dyn.hxx>
      28             : 
      29             : // NOT FULLY DECLARED SERVICES
      30             : #include <string.h>
      31             : #include <stdio.h>
      32             : #include <stdarg.h> // both are needed to satisfy all compilers
      33             : #include <cstdarg>  // std::va_list and friends
      34             : 
      35             : #include <cosv/tpl/swelist.hxx>
      36             : 
      37             : 
      38             : 
      39             : namespace csv
      40             : {
      41             : 
      42             : 
      43             : // Maximal sizes of resulting integers in text form:
      44             : const uintt C_short_max_size    = sizeof(short) * 3;
      45             : const uintt C_int_max_size      = sizeof(int) * 3;
      46             : const uintt C_long_max_size     = sizeof(long) * 3;
      47             : 
      48             : 
      49             : inline void
      50    14561963 : StreamStr::Advance(size_type i_nAddedSize)
      51    14561963 : { pCur += i_nAddedSize; }
      52             : 
      53             : 
      54             : 
      55       12589 : StreamStr::StreamStr( size_type     i_nCapacity )
      56             :     :   bostream(),
      57             :         nCapacity1( i_nCapacity + 1 ),
      58       12589 :         dpData( new char [i_nCapacity + 1] ),
      59             :         pEnd(dpData),
      60             :         pCur(dpData),
      61       25178 :         eMode(str::overwrite)
      62             : {
      63       12589 :     *pEnd = '\0';
      64       12589 : }
      65             : 
      66           0 : StreamStr::StreamStr( const self & i_rOther )
      67             :     :   bostream(),
      68             :         nCapacity1( i_rOther.nCapacity1 ),
      69           0 :         dpData( new char [i_rOther.nCapacity1] ),
      70           0 :         pEnd( dpData + strlen(i_rOther.dpData) ),
      71           0 :         pCur( dpData + i_rOther.tellp() ),
      72           0 :         eMode(i_rOther.eMode)
      73             : {
      74           0 :     strcpy( dpData, i_rOther.dpData );      // SAFE STRCPY (#100211# - checked)
      75           0 : }
      76             : 
      77       25183 : StreamStr::~StreamStr()
      78             : {
      79       12589 :     delete [] dpData;
      80       12594 : }
      81             : 
      82             : 
      83             : StreamStr &
      84           0 : StreamStr::operator=( const self & i_rOther )
      85             : {
      86           0 :     delete [] dpData;
      87             : 
      88           0 :     nCapacity1 = i_rOther.nCapacity1;
      89           0 :     dpData = new char [i_rOther.nCapacity1];
      90           0 :     pEnd = dpData + strlen(i_rOther.dpData);
      91           0 :     strcpy( dpData, i_rOther.dpData );          // SAFE STRCPY (#100211# - checked)
      92           0 :     pCur = dpData + i_rOther.tellp();
      93           0 :     eMode = i_rOther.eMode;
      94             : 
      95           0 :     return *this;
      96             : }
      97             : 
      98             : StreamStr &
      99      393022 : StreamStr::operator<<( const char * i_s )
     100             : {
     101      393022 :     size_type nLength = strlen(i_s);
     102             : 
     103      393022 :     ProvideAddingSize( nLength );
     104      393022 :     memcpy( pCur, i_s, nLength );
     105      393022 :     Advance(nLength);
     106             : 
     107      393022 :     return *this;
     108             : }
     109             : 
     110             : StreamStr &
     111      640953 : StreamStr::operator<<( const String & i_s )
     112             : {
     113      640953 :     size_type nLength = i_s.length();
     114             : 
     115      640953 :     ProvideAddingSize( nLength );
     116      640953 :     memcpy( pCur, i_s.c_str(), nLength );
     117      640953 :     Advance(nLength);
     118             : 
     119      640953 :     return *this;
     120             : }
     121             : 
     122             : StreamStr &
     123      441324 : StreamStr::operator<<( char i_c )
     124             : {
     125      441324 :     ProvideAddingSize( 1 );
     126      441324 :     *pCur = i_c;
     127      441324 :     Advance(1);
     128             : 
     129      441324 :     return *this;
     130             : }
     131             : 
     132             : StreamStr &
     133           0 : StreamStr::operator<<( unsigned char i_c )
     134             : {
     135           0 :     return operator<<( char(i_c) );
     136             : }
     137             : 
     138             : StreamStr &
     139           0 : StreamStr::operator<<( signed char i_c )
     140             : {
     141           0 :     return operator<<( char(i_c) );
     142             : }
     143             : 
     144             : StreamStr &
     145           0 : StreamStr::operator<<( short i_n )
     146             : {
     147           0 :     char buf[C_short_max_size] = "";
     148           0 :     sprintf( buf, "%hi", i_n );         // SAFE SPRINTF (#100211# - checked)
     149             : 
     150           0 :     size_type nLength = strlen(buf);
     151           0 :     ProvideAddingSize( nLength );
     152           0 :     memcpy( pCur, buf, nLength );
     153           0 :     Advance( nLength );
     154             : 
     155           0 :     return *this;
     156             : }
     157             : 
     158             : StreamStr &
     159           0 : StreamStr::operator<<( unsigned short i_n )
     160             : {
     161           0 :     char buf[C_short_max_size] = "";
     162           0 :     sprintf( buf, "%hu", i_n );         // SAFE SPRINTF (#100211# - checked)
     163             : 
     164           0 :     size_type nLength = strlen(buf);
     165           0 :     ProvideAddingSize( nLength );
     166           0 :     memcpy( pCur, buf, nLength );
     167           0 :     Advance( nLength );
     168             : 
     169           0 :     return *this;
     170             : }
     171             : 
     172             : StreamStr &
     173        6083 : StreamStr::operator<<( int i_n )
     174             : {
     175        6083 :     char buf[C_int_max_size] = "";
     176        6083 :     sprintf( buf, "%i", i_n );          // SAFE SPRINTF (#100211# - checked)
     177             : 
     178        6083 :     size_type nLength = strlen(buf);
     179        6083 :     ProvideAddingSize( nLength );
     180        6083 :     memcpy( pCur, buf, nLength );
     181        6083 :     Advance( nLength );
     182             : 
     183        6083 :     return *this;
     184             : }
     185             : 
     186             : StreamStr &
     187           0 : StreamStr::operator<<( unsigned int i_n )
     188             : {
     189           0 :     char buf[C_int_max_size] = "";
     190           0 :     sprintf( buf, "%u", i_n );          // SAFE SPRINTF (#100211# - checked)
     191             : 
     192           0 :     size_type nLength = strlen(buf);
     193           0 :     ProvideAddingSize( nLength );
     194           0 :     memcpy( pCur, buf, nLength );
     195           0 :     Advance( nLength );
     196             : 
     197           0 :     return *this;
     198             : }
     199             : 
     200             : StreamStr &
     201           0 : StreamStr::operator<<( long i_n )
     202             : {
     203           0 :     char buf[C_long_max_size] = "";
     204           0 :     sprintf( buf, "%li", i_n );         // SAFE SPRINTF (#100211# - checked)
     205             : 
     206           0 :     size_type nLength = strlen(buf);
     207           0 :     ProvideAddingSize( nLength );
     208           0 :     memcpy( pCur, buf, nLength );
     209           0 :     Advance( nLength );
     210             : 
     211           0 :     return *this;
     212             : }
     213             : 
     214             : StreamStr &
     215        2858 : StreamStr::operator<<( unsigned long i_n )
     216             : {
     217        2858 :     char buf[C_long_max_size] = "";
     218        2858 :     sprintf( buf, "%lu", i_n );         // SAFE SPRINTF (#100211# - checked)
     219             : 
     220        2858 :     size_type nLength = strlen(buf);
     221        2858 :     ProvideAddingSize( nLength );
     222        2858 :     memcpy( pCur, buf, nLength );
     223        2858 :     Advance( nLength );
     224             : 
     225        2858 :     return *this;
     226             : }
     227             : 
     228             : StreamStr &
     229           0 : StreamStr::operator<<( float i_n )
     230             : {
     231           0 :     const int C_float_max_size = 20;
     232           0 :     char buf[C_float_max_size] = "";
     233           0 :     sprintf( buf, "%.*g", C_float_max_size-8, i_n );    // SAFE SPRINTF (#100211# - checked)
     234             : 
     235           0 :     size_type nLength = strlen(buf);
     236           0 :     ProvideAddingSize( nLength );
     237           0 :     memcpy( pCur, buf, nLength );
     238           0 :     Advance( nLength );
     239             : 
     240           0 :     return *this;
     241             : }
     242             : 
     243             : StreamStr &
     244           0 : StreamStr::operator<<( double i_n )
     245             : {
     246           0 :     const int C_double_max_size = 30;
     247           0 :     char buf[C_double_max_size] = "";
     248           0 :     sprintf( buf, "%.*lg", C_double_max_size-8, i_n );  // SAFE SPRINTF (#100211# - checked)
     249             : 
     250           0 :     size_type nLength = strlen(buf);
     251           0 :     ProvideAddingSize( nLength );
     252           0 :     memcpy( pCur, buf, nLength );
     253           0 :     Advance( nLength );
     254             : 
     255           0 :     return *this;
     256             : }
     257             : 
     258             : const char &
     259           0 : StreamStr::operator[]( position_type i_nPosition ) const
     260             : {
     261             :     static const char aNull_ = '\0';
     262             : 
     263           0 :     if ( position_type(pEnd - dpData) > i_nPosition )
     264           0 :         return dpData[i_nPosition];
     265           0 :     return aNull_;
     266             : }
     267             : 
     268             : char &
     269           0 : StreamStr::operator[]( position_type i_nPosition )
     270             : {
     271             :     static char aDummy_ = '\0';
     272             : 
     273           0 :     if ( position_type(pEnd - dpData) > i_nPosition )
     274           0 :         return dpData[i_nPosition];
     275           0 :     return aDummy_;
     276             : }
     277             : 
     278             : void
     279      208525 : StreamStr::resize( size_type i_nMinimumCapacity )
     280             : {
     281      208525 :     if ( i_nMinimumCapacity <= capacity() )
     282      417044 :         return;
     283             : 
     284           6 :     Resize(i_nMinimumCapacity);
     285             : }
     286             : 
     287             : StreamStr &
     288      538061 : StreamStr::seekp( seek_type           i_nCount,
     289             :                   seek_dir            i_eDirection )
     290             : {
     291      538061 :     seek_type nLength = seek_type( length() );
     292      538061 :     seek_type nNewPos = tellp();
     293             : 
     294      538061 :     switch ( i_eDirection )
     295             :     {
     296      538061 :          case ::csv::beg:  nNewPos = i_nCount;
     297      538061 :                           break;
     298           0 :         case ::csv::cur:  nNewPos += i_nCount;
     299           0 :                           break;
     300           0 :         case ::csv::end:  nNewPos = nLength + i_nCount;
     301           0 :                           break;
     302             :     }
     303             : 
     304      538061 :     if ( in_range<seek_type>(0, nNewPos, nLength + 1) )
     305             :     {
     306      538061 :         pCur = dpData + nNewPos;
     307      538061 :         if (eMode == str::overwrite)
     308             :         {
     309      538061 :              pEnd = pCur;
     310      538061 :             *pEnd = '\0';
     311             :         }
     312             :     }
     313             : 
     314      538061 :     return *this;
     315             : }
     316             : 
     317             : StreamStr &
     318      208525 : StreamStr::set_insert_mode( insert_mode i_eMode )
     319             : {
     320      208525 :     eMode = i_eMode;
     321      208525 :     return *this;
     322             : }
     323             : 
     324             : void
     325           0 : StreamStr::pop_front( size_type i_nCount )
     326             : {
     327           0 :     size_type nCount = min(i_nCount, length());
     328             : 
     329           0 :     MoveData( dpData + nCount, pEnd, -(seek_type(nCount)) );
     330             : 
     331           0 :     pCur -= nCount;
     332           0 :     pEnd -= nCount;
     333           0 :     *pEnd = '\0';
     334           0 : }
     335             : 
     336             : void
     337         250 : StreamStr::pop_back( size_type i_nCount )
     338             : {
     339         250 :     size_type nCount = min(i_nCount, length());
     340         250 :     pEnd -= nCount;
     341         250 :     if (pCur > pEnd)
     342         250 :         pCur = pEnd;
     343         250 :     *pEnd = '\0';
     344         250 : }
     345             : 
     346             : StreamStr &
     347         118 : StreamStr::operator_join( std::vector<String>::const_iterator i_rBegin,
     348             :                           std::vector<String>::const_iterator i_rEnd,
     349             :                           const char *                        i_sLink )
     350             : {
     351         118 :     std::vector<String>::const_iterator it = i_rBegin;
     352         118 :     if ( it != i_rEnd )
     353             :     {
     354         118 :         operator<<(*it);
     355         475 :         for ( ++it; it != i_rEnd; ++it )
     356             :         {
     357         357 :             operator<<(i_sLink);
     358         357 :             operator<<(*it);
     359             :         }
     360             :     }
     361         118 :     return *this;
     362             : }
     363             : 
     364             : StreamStr &
     365           0 : StreamStr::operator_add_substr( const char *        i_sText,
     366             :                                 size_type           i_nLength )
     367             : {
     368           0 :     size_type nLength = csv::min<size_type>(i_nLength, strlen(i_sText));
     369             : 
     370           0 :     ProvideAddingSize( nLength );
     371           0 :     memcpy( pCur, i_sText, nLength );
     372           0 :     Advance(nLength);
     373             : 
     374           0 :     return *this;
     375             : }
     376             : 
     377             : StreamStr &
     378           0 : StreamStr::operator_add_token( const char *        i_sText,
     379             :                                char                i_cDelimiter )
     380             : {
     381           0 :     const char * pTokenEnd = strchr(i_sText, i_cDelimiter);
     382           0 :     if (pTokenEnd == 0)
     383           0 :         operator<<(i_sText);
     384             :     else
     385           0 :         operator_add_substr(i_sText, pTokenEnd-i_sText);
     386           0 :     return *this;
     387             : }
     388             : 
     389             : StreamStr &
     390        7336 : StreamStr::operator_read_line( bstream & i_src )
     391             : {
     392        7336 :     char c = 0;
     393        7336 :     intt nCount = 0;
     394      218654 :     for ( nCount = i_src.read(&c, 1);
     395             :           nCount == 1 AND c != 13 AND c != 10;
     396      211318 :           nCount = i_src.read(&c, 1) )
     397             :     {
     398      211318 :         operator<<(c);
     399             :     }
     400             : 
     401             :     // Check for line-end:
     402        7336 :     if ( NOT (nCount == 0) AND c != 0 )
     403             :     {
     404        7336 :         char oldc = c;
     405        7336 :           if (i_src.read(&c, 1) == 1)
     406             :         {
     407        7335 :             if ( (c != 13 AND c != 10) OR c == oldc)
     408        7335 :                 i_src.seek(-1,::csv::cur);
     409             :         }
     410             :     }
     411        7336 :     return *this;
     412             : }
     413             : 
     414             : void
     415           0 : StreamStr::strip_front_whitespace()
     416             : {
     417           0 :     const_iterator it = begin();
     418           0 :     for ( ;
     419           0 :           it != end() ? *it < 33 : false;
     420             :           ++it ) ;
     421           0 :     pop_front(it - begin());
     422           0 : }
     423             : 
     424             : void
     425           0 : StreamStr::strip_back_whitespace()
     426             : {
     427           0 :     const_iterator it = end();
     428           0 :     for ( ;
     429           0 :           it != begin() ? *(it-1) < 33 : false;
     430             :           --it ) ;
     431           0 :     pop_back(end() - it);
     432           0 : }
     433             : 
     434             : void
     435           0 : StreamStr::strip_frontback_whitespace()
     436             : {
     437           0 :     strip_front_whitespace();
     438           0 :     strip_back_whitespace();
     439           0 : }
     440             : 
     441             : void
     442           0 : StreamStr::replace_all( char i_cCarToSearch,
     443             :                         char i_cReplacement )
     444             : {
     445           0 :    for ( char * p = dpData; p != pEnd; ++p )
     446             :    {
     447           0 :         if (*p == i_cCarToSearch)
     448           0 :             *p = i_cReplacement;
     449             :    }
     450           0 : }
     451             : 
     452             : class StreamStrPool
     453             : {
     454             :   public:
     455             :                         StreamStrPool();
     456             :                         ~StreamStrPool();
     457             :   private:
     458             :     // Non-copyable
     459             :     StreamStrPool(StreamStrPool &); // not defined
     460             :     void operator =(StreamStrPool &); // not defined
     461             : 
     462             :     // Interface to:
     463             :     friend class StreamStrLock;
     464             :     static StreamStr &  AcquireFromPool_(
     465             :                             uintt               i_nMinimalSize );
     466             :     static void         ReleaseToPool_(
     467             :                             DYN StreamStr *     let_dpUsedStr );
     468             : 
     469             :     // DATA
     470             :     SweList< DYN StreamStr* >
     471             :                         aPool;
     472             : };
     473             : 
     474           1 : StreamStrPool::StreamStrPool()
     475             : {
     476           1 : }
     477             : 
     478           2 : StreamStrPool::~StreamStrPool()
     479             : {
     480          18 :     for ( SweList< DYN StreamStr* >::iterator it = aPool.begin();
     481          12 :           it != aPool.end();
     482             :           ++it )
     483             :     {
     484           5 :          delete (*it);
     485             :     }
     486           1 : }
     487             : 
     488             : namespace
     489             : {
     490           1 :     static StreamStrPool aPool_;
     491             : }
     492             : 
     493             : 
     494             : StreamStr &
     495      208530 : StreamStrPool::AcquireFromPool_( uintt i_nMinimalSize )
     496             : {
     497      208530 :     if ( aPool_.aPool.empty() )
     498             :     {
     499           5 :         return *new StreamStr(i_nMinimalSize);
     500             :     }
     501             : 
     502      208525 :     StreamStr & ret = *aPool_.aPool.front();
     503      208525 :     aPool_.aPool.pop_front();
     504      208525 :     ret.resize(i_nMinimalSize);
     505      208525 :     ret.seekp(0);
     506      208525 :     ret.set_insert_mode(str::overwrite);
     507      208525 :     return ret;
     508             : }
     509             : 
     510             : void
     511      208530 : StreamStrPool::ReleaseToPool_( DYN StreamStr * let_dpUsedStr )
     512             : {
     513      208530 :     aPool_.aPool.push_back( let_dpUsedStr );
     514      208530 : }
     515             : 
     516      208530 : StreamStrLock::StreamStrLock( uintt i_nMinimalSize )
     517      208530 :     :   pStr( &StreamStrPool::AcquireFromPool_(i_nMinimalSize) )
     518             : {
     519      208530 : }
     520             : 
     521      208530 : StreamStrLock::~StreamStrLock()
     522             : {
     523      208530 :     StreamStrPool::ReleaseToPool_(pStr);
     524      208530 : }
     525             : 
     526             : 
     527             : UINT32
     528    13077723 : StreamStr::do_write( const void *    i_pSrc,
     529             :                      UINT32          i_nNrofBytes )
     530             : {
     531    13077723 :     ProvideAddingSize( i_nNrofBytes );
     532    13077723 :     memcpy( pCur, i_pSrc, i_nNrofBytes );
     533    13077723 :     Advance(i_nNrofBytes);
     534             : 
     535    13077723 :     return i_nNrofBytes;
     536             : }
     537             : 
     538             : void
     539    14561963 : StreamStr::ProvideAddingSize( size_type i_nSize2Add )
     540             : {
     541    14561963 :     size_type nLength = length();
     542    14561963 :     if ( capacity() - nLength < i_nSize2Add )
     543       24365 :         Resize( nLength + i_nSize2Add );
     544             : 
     545    14561963 :     pEnd += i_nSize2Add;
     546    14561963 :       *pEnd = '\0';
     547             : 
     548    14561963 :     if (eMode == str::insert AND pCur != pEnd)
     549             :     {
     550           0 :         MoveData( pCur, pCur + i_nSize2Add, seek_type(i_nSize2Add) );
     551             :     }
     552    14561963 : }
     553             : 
     554             : void
     555       24371 : StreamStr::Resize( size_type i_nMinimumCapacity )
     556             : {
     557             :     size_type nNewSize = nCapacity1 < 128
     558             :                             ?   nCapacity1 << 1
     559       24371 :                             :   (nCapacity1 << 1) - (nCapacity1 >> 1);
     560       24371 :     nCapacity1 = csv::max( nNewSize, size_type(i_nMinimumCapacity + 1) );
     561             : 
     562       24371 :     char * pNew = new char[nCapacity1];
     563       24371 :     strcpy ( pNew, dpData );            // SAFE STRCPY (#100211# - checked)
     564       24371 :     pEnd = pNew + (pEnd - dpData);
     565       24371 :     pCur = pNew + (pCur - dpData);
     566             : 
     567       24371 :     delete [] dpData;
     568       24371 :     dpData = pNew;
     569       24371 : }
     570             : 
     571             : void
     572           0 : StreamStr::MoveData( char *        i_pStart,
     573             :                      char *        i_pEnd,
     574             :                      seek_type     i_nDiff )
     575             : {
     576           0 :     if (i_nDiff > 0)
     577             :     {
     578           0 :         register const char * pSrc  = i_pEnd;
     579           0 :         register char * pDest = i_pEnd + i_nDiff;
     580           0 :         for ( ; pSrc != i_pStart; --pSrc, --pDest )
     581             :         {
     582           0 :             *pDest = *pSrc;
     583             :         }
     584           0 :         *pDest = *pSrc;
     585             :     }
     586           0 :     else if (i_nDiff < 0)
     587             :     {
     588           0 :         const char * pSrc  = i_pStart;
     589           0 :         char * pDest = i_pStart + i_nDiff;
     590           0 :         for ( ; pSrc != i_pEnd; ++pSrc, ++pDest )
     591             :         {
     592           0 :             *pDest = *pSrc;
     593             :         }
     594             :     }
     595           0 : }
     596             : 
     597             : // Does nothing, only the name of this function is needed.
     598             : void
     599           0 : c_str()
     600             : {
     601             :     // Does nothing.
     602           0 : }
     603             : 
     604           3 : }   // namespace csv
     605             : 
     606             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10