LCOV - code coverage report
Current view: top level - include/oox/helper - helper.hxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 38 42 90.5 %
Date: 2015-06-13 12:38:46 Functions: 136 146 93.2 %
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             : #ifndef INCLUDED_OOX_HELPER_HELPER_HXX
      21             : #define INCLUDED_OOX_HELPER_HELPER_HXX
      22             : 
      23             : #include <algorithm>
      24             : #include <limits>
      25             : #include <sal/macros.h>
      26             : #include <osl/endian.h>
      27             : #include <rtl/math.hxx>
      28             : #include <rtl/string.hxx>
      29             : #include <rtl/ustring.hxx>
      30             : #include <string.h>
      31             : 
      32             : namespace oox {
      33             : 
      34             : // Helper macros ==============================================================
      35             : 
      36             : /** Expands to a pointer behind the last element of a STATIC data array (like
      37             :     STL end()). */
      38             : #define STATIC_ARRAY_END( array ) \
      39             :     ((array)+SAL_N_ELEMENTS(array))
      40             : 
      41             : /** Expands to the 'index'-th element of a STATIC data array, or to 'def', if
      42             :     'index' is out of the array limits. */
      43             : #define STATIC_ARRAY_SELECT( array, index, def ) \
      44             :     ((static_cast<size_t>(index) < SAL_N_ELEMENTS(array)) ? ((array)[static_cast<size_t>(index)]) : (def))
      45             : 
      46             : /** Expands to a temporary OString, created from a literal(!) character
      47             :     array. */
      48             : #define CREATE_OSTRING( ascii ) \
      49             :     OString( RTL_CONSTASCII_STRINGPARAM( ascii ) )
      50             : 
      51             : /** Convert an OUString to an ASCII C string. Use for debug purposes only. */
      52             : #define OUSTRING_TO_CSTR( str ) \
      53             :     OUStringToOString( str, RTL_TEXTENCODING_ASCII_US ).getStr()
      54             : 
      55             : // Common constants ===========================================================
      56             : 
      57             : const sal_uInt8 WINDOWS_CHARSET_ANSI        = 0;
      58             : const sal_uInt8 WINDOWS_CHARSET_DEFAULT     = 1;
      59             : const sal_uInt8 WINDOWS_CHARSET_SYMBOL      = 2;
      60             : const sal_uInt8 WINDOWS_CHARSET_APPLE_ROMAN = 77;
      61             : const sal_uInt8 WINDOWS_CHARSET_SHIFTJIS    = 128;
      62             : const sal_uInt8 WINDOWS_CHARSET_HANGEUL     = 129;
      63             : const sal_uInt8 WINDOWS_CHARSET_JOHAB       = 130;
      64             : const sal_uInt8 WINDOWS_CHARSET_GB2312      = 134;
      65             : const sal_uInt8 WINDOWS_CHARSET_BIG5        = 136;
      66             : const sal_uInt8 WINDOWS_CHARSET_GREEK       = 161;
      67             : const sal_uInt8 WINDOWS_CHARSET_TURKISH     = 162;
      68             : const sal_uInt8 WINDOWS_CHARSET_VIETNAMESE  = 163;
      69             : const sal_uInt8 WINDOWS_CHARSET_HEBREW      = 177;
      70             : const sal_uInt8 WINDOWS_CHARSET_ARABIC      = 178;
      71             : const sal_uInt8 WINDOWS_CHARSET_BALTIC      = 186;
      72             : const sal_uInt8 WINDOWS_CHARSET_RUSSIAN     = 204;
      73             : const sal_uInt8 WINDOWS_CHARSET_THAI        = 222;
      74             : const sal_uInt8 WINDOWS_CHARSET_EASTERN     = 238;
      75             : const sal_uInt8 WINDOWS_CHARSET_OEM         = 255;
      76             : 
      77             : 
      78             : 
      79             : const sal_Int32 API_RGB_TRANSPARENT         = -1;       ///< Transparent color for API calls.
      80             : const sal_uInt32 UNSIGNED_RGB_TRANSPARENT         = static_cast<sal_uInt32>(-1);       ///< Transparent color for unsigned int32 places.
      81             : const sal_Int32 API_RGB_BLACK               = 0x000000;  ///< Black color for API calls.
      82             : const sal_Int32 API_RGB_GRAY                = 0x808080;  ///< Gray color for API calls.
      83             : const sal_Int32 API_RGB_WHITE               = 0xFFFFFF;  ///< White color for API calls.
      84             : 
      85             : const sal_Int16 API_LINE_SOLID              = 0;
      86             : const sal_Int16 API_LINE_DOTTED             = 1;
      87             : const sal_Int16 API_LINE_DASHED             = 2;
      88             : const sal_Int16 API_FINE_LINE_DASHED        = 14;
      89             : 
      90             : const sal_Int16 API_LINE_NONE               = 0;
      91             : const sal_Int16 API_LINE_HAIR               = 2;
      92             : const sal_Int16 API_LINE_THIN               = 35;
      93             : const sal_Int16 API_LINE_MEDIUM             = 88;
      94             : const sal_Int16 API_LINE_THICK              = 141;
      95             : 
      96             : const sal_Int16 API_ESCAPE_NONE             = 0;        ///< No escapement.
      97             : const sal_Int16 API_ESCAPE_SUPERSCRIPT      = 101;      ///< Superscript: raise characters automatically (magic value 101).
      98             : const sal_Int16 API_ESCAPE_SUBSCRIPT        = -101;     ///< Subscript: lower characters automatically (magic value -101).
      99             : 
     100             : const sal_Int8 API_ESCAPEHEIGHT_NONE        = 100;      ///< Relative character height if not escaped.
     101             : const sal_Int8 API_ESCAPEHEIGHT_DEFAULT     = 58;       ///< Relative character height if escaped.
     102             : 
     103             : 
     104             : 
     105             : // Limitate values ------------------------------------------------------------
     106             : 
     107             : template< typename ReturnType, typename Type >
     108      268894 : inline ReturnType getLimitedValue( Type nValue, Type nMin, Type nMax )
     109             : {
     110      268894 :     return static_cast< ReturnType >( ::std::min( ::std::max( nValue, nMin ), nMax ) );
     111             : }
     112             : 
     113             : template< typename ReturnType, typename Type >
     114          20 : inline ReturnType getIntervalValue( Type nValue, Type nBegin, Type nEnd )
     115             : {
     116             :     static_assert(::std::numeric_limits< Type >::is_integer, "is integer");
     117          20 :     Type nInterval = nEnd - nBegin;
     118          20 :     Type nCount = (nValue < nBegin) ? -((nBegin - nValue - 1) / nInterval + 1) : ((nValue - nBegin) / nInterval);
     119          20 :     return static_cast< ReturnType >( nValue - nCount * nInterval );
     120             : }
     121             : 
     122             : template< typename ReturnType >
     123         282 : inline ReturnType getDoubleIntervalValue( double fValue, double fBegin, double fEnd )
     124             : {
     125         282 :     double fInterval = fEnd - fBegin;
     126         282 :     double fCount = (fValue < fBegin) ? -(::rtl::math::approxFloor( (fBegin - fValue - 1.0) / fInterval ) + 1.0) : ::rtl::math::approxFloor( (fValue - fBegin) / fInterval );
     127         282 :     return static_cast< ReturnType >( fValue - fCount * fInterval );
     128             : }
     129             : 
     130             : // Read from bitfields --------------------------------------------------------
     131             : 
     132             : /** Returns true, if at least one of the bits set in nMask is set in nBitField. */
     133             : template< typename Type >
     134     2446199 : inline bool getFlag( Type nBitField, Type nMask )
     135             : {
     136     2446199 :     return (nBitField & nMask) != 0;
     137             : }
     138             : 
     139             : /** Returns nSet, if at least one bit of nMask is set in nBitField, otherwise nUnset. */
     140             : template< typename ReturnType, typename Type >
     141         175 : inline ReturnType getFlagValue( Type nBitField, Type nMask, ReturnType nSet, ReturnType nUnset )
     142             : {
     143         175 :     return getFlag( nBitField, nMask ) ? nSet : nUnset;
     144             : }
     145             : 
     146             : /** Extracts a value from a bit field.
     147             : 
     148             :     Returns the data fragment from nBitField, that starts at bit nStartBit
     149             :     (0-based, bit 0 is rightmost) with the width of nBitCount. The returned
     150             :     value will be right-aligned (normalized).
     151             :     For instance: extractValue<T>(0x4321,8,4) returns 3 (value in bits 8-11).
     152             :  */
     153             : template< typename ReturnType, typename Type >
     154      347995 : inline ReturnType extractValue( Type nBitField, sal_uInt8 nStartBit, sal_uInt8 nBitCount )
     155             : {
     156      347995 :     sal_uInt64 nMask = 1; nMask <<= nBitCount; --nMask;
     157      347995 :     return static_cast< ReturnType >( nMask & (nBitField >> nStartBit) );
     158             : }
     159             : 
     160             : // Write to bitfields ---------------------------------------------------------
     161             : 
     162             : /** Sets or clears (according to bSet) all set bits of nMask in ornBitField. */
     163             : template< typename Type >
     164      497183 : inline void setFlag( Type& ornBitField, Type nMask, bool bSet = true )
     165             : {
     166      497183 :     if( bSet ) ornBitField |= nMask; else ornBitField &= ~nMask;
     167      497183 : }
     168             : 
     169             : /** Inserts a value into a bitfield.
     170             : 
     171             :     Inserts the lower nBitCount bits of nValue into ornBitField, starting
     172             :     there at bit nStartBit. Other contents of ornBitField keep unchanged.
     173             :  */
     174             : template< typename Type, typename InsertType >
     175             : void insertValue( Type& ornBitField, InsertType nValue, sal_uInt8 nStartBit, sal_uInt8 nBitCount )
     176             : {
     177             :     sal_uInt64 nMask = 1; nMask <<= nBitCount; --nMask;
     178             :     Type nNewValue = static_cast< Type >( nValue & nMask );
     179             :     (ornBitField &= ~(nMask << nStartBit)) |= (nNewValue << nStartBit);
     180             : }
     181             : 
     182             : 
     183             : 
     184             : /** Optional value, similar to ::boost::optional<>, with convenience accessors.
     185             :  */
     186             : template< typename Type >
     187      603864 : class OptValue
     188             : {
     189             : public:
     190     9444974 :                  OptValue() : maValue(), mbHasValue( false ) {}
     191      133958 :     explicit     OptValue( const Type& rValue ) : maValue( rValue ), mbHasValue( true ) {}
     192      329206 :     explicit     OptValue( bool bHasValue, const Type& rValue ) : maValue( rValue ), mbHasValue( bHasValue ) {}
     193             : 
     194      180123 :     bool         has() const { return mbHasValue; }
     195         571 :     bool         operator!() const { return !mbHasValue; }
     196        3867 :     bool         differsFrom( const Type& rValue ) const { return mbHasValue && (maValue != rValue); }
     197             : 
     198      152354 :     const Type&  get() const { return maValue; }
     199      370143 :     const Type&  get( const Type& rDefValue ) const { return mbHasValue ? maValue : rDefValue; }
     200             : 
     201             :     void         reset() { mbHasValue = false; }
     202      100023 :     void         set( const Type& rValue ) { maValue = rValue; mbHasValue = true; }
     203       36259 :     Type&        use() { mbHasValue = true; return maValue; }
     204             : 
     205       61038 :     OptValue&    operator=( const Type& rValue ) { set( rValue ); return *this; }
     206        3242 :     bool         operator==( const OptValue& rValue ) const {
     207        3242 :                              return ( ( !mbHasValue && rValue.mbHasValue == false ) ||
     208        3242 :                                  ( mbHasValue == rValue.mbHasValue && maValue == rValue.maValue ) );
     209             :                  }
     210     1859546 :     void         assignIfUsed( const OptValue& rValue ) { if( rValue.mbHasValue ) set( rValue.maValue ); }
     211             : 
     212             : private:
     213             :     Type                maValue;
     214             :     bool                mbHasValue;
     215             : };
     216             : 
     217             : 
     218             : 
     219             : /** Provides platform independent functions to convert from or to little-endian
     220             :     byte order, e.g. for reading data from or writing data to memory or a
     221             :     binary stream.
     222             : 
     223             :     On big-endian platforms, the byte order in the passed values is swapped,
     224             :     this can be used for converting big-endian to and from little-endian data.
     225             : 
     226             :     On little-endian platforms, the conversion functions are implemented empty,
     227             :     thus compilers should completely optimize away the function call.
     228             :  */
     229             : class ByteOrderConverter
     230             : {
     231             : public:
     232             : #ifdef OSL_BIGENDIAN
     233             :     static void  convertLittleEndian( sal_Int8& ) {}     // present for usage in templates
     234             :     static void  convertLittleEndian( sal_uInt8& ) {}    // present for usage in templates
     235             :     static void  convertLittleEndian( sal_Int16& rnValue )  { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
     236             :     static void  convertLittleEndian( sal_uInt16& rnValue ) { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
     237             :     static void  convertLittleEndian( sal_Int32& rnValue )  { swap4( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
     238             :     static void  convertLittleEndian( sal_uInt32& rnValue ) { swap4( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
     239             :     static void  convertLittleEndian( sal_Int64& rnValue )  { swap8( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
     240             :     static void  convertLittleEndian( sal_uInt64& rnValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
     241             :     static void  convertLittleEndian( float& rfValue )      { swap4( reinterpret_cast< sal_uInt8* >( &rfValue ) ); }
     242             :     static void  convertLittleEndian( double& rfValue )     { swap8( reinterpret_cast< sal_uInt8* >( &rfValue ) ); }
     243             : 
     244             :     template< typename Type >
     245             :     inline static void  convertLittleEndianArray( Type* pnArray, size_t nElemCount );
     246             : 
     247             :     static void  convertLittleEndianArray( sal_Int8*, size_t ) {}
     248             :     static void  convertLittleEndianArray( sal_uInt8*, size_t ) {}
     249             : 
     250             : #else
     251             :     template< typename Type >
     252      106620 :     static void  convertLittleEndian( Type& ) {}
     253             : 
     254             :     template< typename Type >
     255         461 :     static void  convertLittleEndianArray( Type*, size_t ) {}
     256             : 
     257             : #endif
     258             : 
     259             :     /** Reads a value from memory, assuming memory buffer in little-endian.
     260             :         @param ornValue  (out-parameter) Contains the value read from memory.
     261             :         @param pSrcBuffer  The memory buffer to read the value from.
     262             :      */
     263             :     template< typename Type >
     264             :     inline static void  readLittleEndian( Type& ornValue, const void* pSrcBuffer );
     265             : 
     266             :     /** Writes a value to memory, while converting it to little-endian.
     267             :         @param pDstBuffer  The memory buffer to write the value to.
     268             :         @param nValue  The value to be written to memory in little-endian.
     269             :      */
     270             :     template< typename Type >
     271             :     inline static void  writeLittleEndian( void* pDstBuffer, Type nValue );
     272             : 
     273             : #ifdef OSL_BIGENDIAN
     274             : private:
     275             :     inline static void  swap2( sal_uInt8* pnData );
     276             :     inline static void  swap4( sal_uInt8* pnData );
     277             :     inline static void  swap8( sal_uInt8* pnData );
     278             : #endif
     279             : };
     280             : 
     281             : 
     282             : 
     283             : template< typename Type >
     284             : inline void ByteOrderConverter::readLittleEndian( Type& ornValue, const void* pSrcBuffer )
     285             : {
     286             :     memcpy( &ornValue, pSrcBuffer, sizeof( Type ) );
     287             :     convertLittleEndian( ornValue );
     288             : }
     289             : 
     290             : template< typename Type >
     291           0 : inline void ByteOrderConverter::writeLittleEndian( void* pDstBuffer, Type nValue )
     292             : {
     293           0 :     convertLittleEndian( nValue );
     294           0 :     memcpy( pDstBuffer, &nValue, sizeof( Type ) );
     295           0 : }
     296             : 
     297             : #ifdef OSL_BIGENDIAN
     298             : template< typename Type >
     299             : inline void ByteOrderConverter::convertLittleEndianArray( Type* pnArray, size_t nElemCount )
     300             : {
     301             :     for( Type* pnArrayEnd = pnArray + nElemCount; pnArray != pnArrayEnd; ++pnArray )
     302             :         convertLittleEndian( *pnArray );
     303             : }
     304             : 
     305             : inline void ByteOrderConverter::swap2( sal_uInt8* pnData )
     306             : {
     307             :     ::std::swap( pnData[ 0 ], pnData[ 1 ] );
     308             : }
     309             : 
     310             : inline void ByteOrderConverter::swap4( sal_uInt8* pnData )
     311             : {
     312             :     ::std::swap( pnData[ 0 ], pnData[ 3 ] );
     313             :     ::std::swap( pnData[ 1 ], pnData[ 2 ] );
     314             : }
     315             : 
     316             : inline void ByteOrderConverter::swap8( sal_uInt8* pnData )
     317             : {
     318             :     ::std::swap( pnData[ 0 ], pnData[ 7 ] );
     319             :     ::std::swap( pnData[ 1 ], pnData[ 6 ] );
     320             :     ::std::swap( pnData[ 2 ], pnData[ 5 ] );
     321             :     ::std::swap( pnData[ 3 ], pnData[ 4 ] );
     322             : }
     323             : #endif
     324             : 
     325             : 
     326             : 
     327             : } // namespace oox
     328             : 
     329             : #endif
     330             : 
     331             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11