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

Generated by: LCOV version 1.10