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

Generated by: LCOV version 1.10