1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef OOX_HELPER_HELPER_HXX
21 #define OOX_HELPER_HELPER_HXX
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>
34 // Helper macros ==============================================================
36 /** Expands to the number of elements in a STATIC data array. */
37 #define STATIC_ARRAY_SIZE( array ) \
38 (sizeof(array)/sizeof(*(array)))
40 /** Expands to a pointer behind the last element of a STATIC data array (like
42 #define STATIC_ARRAY_END( array ) \
43 ((array)+STATIC_ARRAY_SIZE(array))
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))
50 /** Expands to a temporary OString, created from a literal(!) character
52 #define CREATE_OSTRING( ascii ) \
53 OString( RTL_CONSTASCII_STRINGPARAM( ascii ) )
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()
59 // Common constants ===========================================================
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;
81 // ----------------------------------------------------------------------------
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.
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;
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;
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).
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.
106 // ============================================================================
108 // Limitate values ------------------------------------------------------------
110 template< typename ReturnType
, typename Type
>
111 inline ReturnType
getLimitedValue( Type nValue
, Type nMin
, Type nMax
)
113 return static_cast< ReturnType
>( ::std::min( ::std::max( nValue
, nMin
), nMax
) );
116 template< typename ReturnType
, typename Type
>
117 inline ReturnType
getIntervalValue( Type nValue
, Type nBegin
, Type nEnd
)
119 // this BOOST_STATIC_ASSERT fails with suncc
120 // BOOST_STATIC_ASSERT( ::std::numeric_limits< Type >::is_integer );
121 Type nInterval
= nEnd
- nBegin
;
122 Type nCount
= (nValue
< nBegin
) ? -((nBegin
- nValue
- 1) / nInterval
+ 1) : ((nValue
- nBegin
) / nInterval
);
123 return static_cast< ReturnType
>( nValue
- nCount
* nInterval
);
126 template< typename ReturnType
>
127 inline ReturnType
getDoubleIntervalValue( double fValue
, double fBegin
, double fEnd
)
129 double fInterval
= fEnd
- fBegin
;
130 double fCount
= (fValue
< fBegin
) ? -(::rtl::math::approxFloor( (fBegin
- fValue
- 1.0) / fInterval
) + 1.0) : ::rtl::math::approxFloor( (fValue
- fBegin
) / fInterval
);
131 return static_cast< ReturnType
>( fValue
- fCount
* fInterval
);
134 // Read from bitfields --------------------------------------------------------
136 /** Returns true, if at least one of the bits set in nMask is set in nBitField. */
137 template< typename Type
>
138 inline bool getFlag( Type nBitField
, Type nMask
)
140 return (nBitField
& nMask
) != 0;
143 /** Returns nSet, if at least one bit of nMask is set in nBitField, otherwise nUnset. */
144 template< typename ReturnType
, typename Type
>
145 inline ReturnType
getFlagValue( Type nBitField
, Type nMask
, ReturnType nSet
, ReturnType nUnset
)
147 return getFlag( nBitField
, nMask
) ? nSet
: nUnset
;
150 /** Extracts a value from a bit field.
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).
157 template< typename ReturnType
, typename Type
>
158 inline ReturnType
extractValue( Type nBitField
, sal_uInt8 nStartBit
, sal_uInt8 nBitCount
)
160 sal_uInt64 nMask
= 1; nMask
<<= nBitCount
; --nMask
;
161 return static_cast< ReturnType
>( nMask
& (nBitField
>> nStartBit
) );
164 // Write to bitfields ---------------------------------------------------------
166 /** Sets or clears (according to bSet) all set bits of nMask in ornBitField. */
167 template< typename Type
>
168 inline void setFlag( Type
& ornBitField
, Type nMask
, bool bSet
= true )
170 if( bSet
) ornBitField
|= nMask
; else ornBitField
&= ~nMask
;
173 /** Inserts a value into a bitfield.
175 Inserts the lower nBitCount bits of nValue into ornBitField, starting
176 there at bit nStartBit. Other contents of ornBitField keep unchanged.
178 template< typename Type
, typename InsertType
>
179 void insertValue( Type
& ornBitField
, InsertType nValue
, sal_uInt8 nStartBit
, sal_uInt8 nBitCount
)
181 sal_uInt64 nMask
= 1; nMask
<<= nBitCount
; --nMask
;
182 Type nNewValue
= static_cast< Type
>( nValue
& nMask
);
183 (ornBitField
&= ~(nMask
<< nStartBit
)) |= (nNewValue
<< nStartBit
);
186 // ============================================================================
188 /** Optional value, similar to ::boost::optional<>, with convenience accessors.
190 template< typename Type
>
194 inline explicit OptValue() : maValue(), mbHasValue( false ) {}
195 inline explicit OptValue( const Type
& rValue
) : maValue( rValue
), mbHasValue( true ) {}
196 inline explicit OptValue( bool bHasValue
, const Type
& rValue
) : maValue( rValue
), mbHasValue( bHasValue
) {}
198 inline bool has() const { return mbHasValue
; }
199 inline bool operator!() const { return !mbHasValue
; }
200 inline bool differsFrom( const Type
& rValue
) const { return mbHasValue
&& (maValue
!= rValue
); }
202 inline const Type
& get() const { return maValue
; }
203 inline const Type
& get( const Type
& rDefValue
) const { return mbHasValue
? maValue
: rDefValue
; }
205 inline void reset() { mbHasValue
= false; }
206 inline void set( const Type
& rValue
) { maValue
= rValue
; mbHasValue
= true; }
207 inline Type
& use() { mbHasValue
= true; return maValue
; }
209 inline OptValue
& operator=( const Type
& rValue
) { set( rValue
); return *this; }
210 inline bool operator==( const OptValue
& rValue
) const {
211 return ( ( mbHasValue
== false && rValue
.mbHasValue
== false ) ||
212 ( mbHasValue
== rValue
.mbHasValue
&& maValue
== rValue
.maValue
) );
214 inline void assignIfUsed( const OptValue
& rValue
) { if( rValue
.mbHasValue
) set( rValue
.maValue
); }
221 // ============================================================================
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
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.
230 On little-endian platforms, the conversion functions are implemented empty,
231 thus compilers should completely optimize away the function call.
233 class ByteOrderConverter
237 inline static void convertLittleEndian( sal_Int8
& ) {} // present for usage in templates
238 inline static void convertLittleEndian( sal_uInt8
& ) {} // present for usage in templates
239 inline static void convertLittleEndian( sal_Int16
& rnValue
) { swap2( reinterpret_cast< sal_uInt8
* >( &rnValue
) ); }
240 inline static void convertLittleEndian( sal_uInt16
& rnValue
) { swap2( reinterpret_cast< sal_uInt8
* >( &rnValue
) ); }
241 inline static void convertLittleEndian( sal_Int32
& rnValue
) { swap4( reinterpret_cast< sal_uInt8
* >( &rnValue
) ); }
242 inline static void convertLittleEndian( sal_uInt32
& rnValue
) { swap4( reinterpret_cast< sal_uInt8
* >( &rnValue
) ); }
243 inline static void convertLittleEndian( sal_Int64
& rnValue
) { swap8( reinterpret_cast< sal_uInt8
* >( &rnValue
) ); }
244 inline static void convertLittleEndian( sal_uInt64
& rnValue
) { swap8( reinterpret_cast< sal_uInt8
* >( &rnValue
) ); }
245 inline static void convertLittleEndian( float& rfValue
) { swap4( reinterpret_cast< sal_uInt8
* >( &rfValue
) ); }
246 inline static void convertLittleEndian( double& rfValue
) { swap8( reinterpret_cast< sal_uInt8
* >( &rfValue
) ); }
248 template< typename Type
>
249 inline static void convertLittleEndianArray( Type
* pnArray
, size_t nElemCount
);
251 inline static void convertLittleEndianArray( sal_Int8
*, size_t ) {}
252 inline static void convertLittleEndianArray( sal_uInt8
*, size_t ) {}
255 template< typename Type
>
256 inline static void convertLittleEndian( Type
& ) {}
258 template< typename Type
>
259 inline static void convertLittleEndianArray( Type
*, size_t ) {}
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.
267 template< typename Type
>
268 inline static void readLittleEndian( Type
& ornValue
, const void* pSrcBuffer
);
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.
274 template< typename Type
>
275 inline static void writeLittleEndian( void* pDstBuffer
, Type nValue
);
279 inline static void swap2( sal_uInt8
* pnData
);
280 inline static void swap4( sal_uInt8
* pnData
);
281 inline static void swap8( sal_uInt8
* pnData
);
285 // ----------------------------------------------------------------------------
287 template< typename Type
>
288 inline void ByteOrderConverter::readLittleEndian( Type
& ornValue
, const void* pSrcBuffer
)
290 memcpy( &ornValue
, pSrcBuffer
, sizeof( Type
) );
291 convertLittleEndian( ornValue
);
294 template< typename Type
>
295 inline void ByteOrderConverter::writeLittleEndian( void* pDstBuffer
, Type nValue
)
297 convertLittleEndian( nValue
);
298 memcpy( pDstBuffer
, &nValue
, sizeof( Type
) );
302 template< typename Type
>
303 inline void ByteOrderConverter::convertLittleEndianArray( Type
* pnArray
, size_t nElemCount
)
305 for( Type
* pnArrayEnd
= pnArray
+ nElemCount
; pnArray
!= pnArrayEnd
; ++pnArray
)
306 convertLittleEndian( *pnArray
);
309 inline void ByteOrderConverter::swap2( sal_uInt8
* pnData
)
311 ::std::swap( pnData
[ 0 ], pnData
[ 1 ] );
314 inline void ByteOrderConverter::swap4( sal_uInt8
* pnData
)
316 ::std::swap( pnData
[ 0 ], pnData
[ 3 ] );
317 ::std::swap( pnData
[ 1 ], pnData
[ 2 ] );
320 inline void ByteOrderConverter::swap8( sal_uInt8
* pnData
)
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 ] );
329 // ============================================================================
335 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */