• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  *
4  * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
5  *
6  */
7 
8 #ifndef __LESWAPS_H
9 #define __LESWAPS_H
10 
11 #include "LETypes.h"
12 
13 /**
14  * \file
15  * \brief C++ API: Endian independent access to data for LayoutEngine
16  */
17 
18 U_NAMESPACE_BEGIN
19 
20 /**
21  * A convenience macro which invokes the swapWord member function
22  * from a concise call.
23  *
24  * @stable ICU 2.8
25  */
26 #if defined(U_IS_BIG_ENDIAN)
27     #if U_IS_BIG_ENDIAN
28         #define SWAPW(value) (value)
29     #else
30         #define SWAPW(value) LESwaps::swapWord(value)
31     #endif
32 #else
33     #define SWAPW(value) (LESwaps::isBigEndian() ? (value) : LESwaps::swapWord(value))
34 #endif
35 
36 /**
37  * A convenience macro which invokes the swapLong member function
38  * from a concise call.
39  *
40  * @stable ICU 2.8
41  */
42 #if defined(U_IS_BIG_ENDIAN)
43     #if U_IS_BIG_ENDIAN
44         #define SWAPL(value) (value)
45     #else
46         #define SWAPL(value) LESwaps::swapLong(value)
47     #endif
48 #else
49     #define SWAPL(value) (LESwaps::isBigEndian() ? (value) : LESwaps::swapLong(value))
50 #endif
51 
52 /**
53  * This class is used to access data which stored in big endian order
54  * regardless of the conventions of the platform. It has been designed
55  * to automatically detect the endian-ness of the platform, so that a
56  * compilation flag is not needed.
57  *
58  * All methods are static and inline in an attempt to induce the compiler
59  * to do most of the calculations at compile time.
60  *
61  * @stable ICU 2.8
62  */
63 class U_LAYOUT_API LESwaps /* not : public UObject because all methods are static */ {
64 public:
65 
66 #if !defined(U_IS_BIG_ENDIAN)
67     /**
68      * This method detects the endian-ness of the platform by
69      * casting a pointer to a word to a pointer to a byte. On
70      * big endian platforms the FF will be in the byte with the
71      * lowest address. On little endian platforms, the FF will
72      * be in the byte with the highest address.
73      *
74      * @return TRUE if the platform is big endian
75      *
76      * @stable ICU 2.8
77      */
isBigEndian()78     static le_uint8 isBigEndian()
79     {
80         const le_uint16 word = 0xFF00;
81 
82         return *((le_uint8 *) &word);
83     };
84 #endif
85 
86     /**
87      * This method does the byte swap required on little endian platforms
88      * to correctly access a (16-bit) word.
89      *
90      * @param value - the word to be byte swapped
91      *
92      * @return the byte swapped word
93      *
94      * @stable ICU 2.8
95      */
swapWord(le_uint16 value)96     static le_uint16 swapWord(le_uint16 value)
97     {
98         return (((le_uint8) (value >> 8)) | (value << 8));
99     };
100 
101     /**
102      * This method does the byte swapping required on little endian platforms
103      * to correctly access a (32-bit) long.
104      *
105      * @param value - the long to be byte swapped
106      *
107      * @return the byte swapped long
108      *
109      * @stable ICU 2.8
110      */
swapLong(le_uint32 value)111     static le_uint32 swapLong(le_uint32 value)
112     {
113         return swapWord((le_uint16) (value >> 16)) | (swapWord((le_uint16) value) << 16);
114     };
115 
116 private:
LESwaps()117     LESwaps() {} // private - forbid instantiation
118 };
119 
120 U_NAMESPACE_END
121 #endif
122