casacore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LittleEndianConversion.h
Go to the documentation of this file.
1 //# LittleEndianConversion.h: A class with static functions to convert littleEndian format
2 //# Copyright (C) 1996,1997,1999,2001
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //# $Id$
27 
28 #ifndef CASA_LITTLEENDIANCONVERSION_H
29 #define CASA_LITTLEENDIANCONVERSION_H
30 
31 //# Includes
32 #include <casacore/casa/aips.h>
34 
35 
36 namespace casacore { //# NAMESPACE CASACORE - BEGIN
37 
38 // <summary>
39 // A class with static functions to convert littleEndian format
40 // </summary>
41 
42 // <use visibility=export>
43 
44 // <reviewed reviewer="Friso Olnon" date="1996/11/06" tests="tVAXConversion" demos="">
45 // </reviewed>
46 
47 // <synopsis>
48 // This class is intended to be used as a common class for all
49 // classes converting data to/from little-endian format.
50 // </synopsis>
51 
52 // <motivation>
53 // Sometimes data are stored in little-endian format (e.g. old VAX-data).
54 // Instead of putting all these conversion functions in all such classes,
55 // it is better to keep them separate to be able to use them elsewhere.
56 // However, note that this version handles a long as 4 bytes.
57 // On several little-endian machines (e.g. DEC-alpha) a long is 8 bytes,
58 // so a special function is needed for them.
59 // </motivation>
60 
61 // <todo asof="$DATE$">
62 // <li> Support data type long double.
63 // <li> Support a long as 4 or as 8 bytes.
64 // </todo>
65 
66 
68 {
69 public:
70  // Convert one value from littleEndian format to local format.
71  // The from and to buffer should not overlap.
72  // <group>
73  static void toLocal (char& to, const void* from);
74  static void toLocal (unsigned char& to, const void* from);
75  static void toLocal (short& to, const void* from);
76  static void toLocal (unsigned short& to, const void* from);
77  static void toLocal (int& to, const void* from);
78  static void toLocal (unsigned int& to, const void* from);
79  static void toLocal (Int64& to, const void* from);
80  static void toLocal (uInt64& to, const void* from);
81  static void toLocal (float& to, const void* from);
82  static void toLocal (double& to, const void* from);
83  // </group>
84 
85  // Convert nr values from littleEndian format to local format.
86  // The from and to buffer should not overlap.
87  // <group>
88  static void toLocal (char* to, const void* from,
89  size_t nr);
90  static void toLocal (unsigned char* to, const void* from,
91  size_t nr);
92  static void toLocal (short* to, const void* from,
93  size_t nr);
94  static void toLocal (unsigned short* to, const void* from,
95  size_t nr);
96  static void toLocal (int* to, const void* from,
97  size_t nr);
98  static void toLocal (unsigned int* to, const void* from,
99  size_t nr);
100  static void toLocal (Int64* to, const void* from,
101  size_t nr);
102  static void toLocal (uInt64* to, const void* from,
103  size_t nr);
104  static void toLocal (float* to, const void* from,
105  size_t nr);
106  static void toLocal (double* to, const void* from,
107  size_t nr);
108  // </group>
109 
110  // Convert one value from local format to littleEndian format.
111  // The from and to buffer should not overlap.
112  // <group>
113  static void fromLocal (void* to, char from);
114  static void fromLocal (void* to, unsigned char from);
115  static void fromLocal (void* to, short from);
116  static void fromLocal (void* to, unsigned short from);
117  static void fromLocal (void* to, int from);
118  static void fromLocal (void* to, unsigned int from);
119  static void fromLocal (void* to, Int64 from);
120  static void fromLocal (void* to, uInt64 from);
121  static void fromLocal (void* to, float from);
122  static void fromLocal (void* to, double from);
123  // </group>
124 
125  // Convert nr values from local format to littleEndian format.
126  // The from and to buffer should not overlap.
127  // <group>
128  static void fromLocal (void* to, const char* from,
129  size_t nr);
130  static void fromLocal (void* to, const unsigned char* from,
131  size_t nr);
132  static void fromLocal (void* to, const short* from,
133  size_t nr);
134  static void fromLocal (void* to, const unsigned short* from,
135  size_t nr);
136  static void fromLocal (void* to, const int* from,
137  size_t nr);
138  static void fromLocal (void* to, const unsigned int* from,
139  size_t nr);
140  static void fromLocal (void* to, const Int64* from,
141  size_t nr);
142  static void fromLocal (void* to, const uInt64* from,
143  size_t nr);
144  static void fromLocal (void* to, const float* from,
145  size_t nr);
146  static void fromLocal (void* to, const double* from,
147  size_t nr);
148  // </group>
149 
150 private:
151  // This class should not be constructed
152  // (so declare the constructor private).
154 };
155 
156 
157 
158 inline void LittleEndianConversion::toLocal (char& to, const void* from)
159 {
160  to = *(char*)from;
161 }
162 
163 inline void LittleEndianConversion::toLocal (unsigned char& to,
164  const void* from)
165 {
166  to = *(unsigned char*)from;
167 }
168 
169 inline void LittleEndianConversion::toLocal (short& to, const void* from)
170 {
171  if (sizeof(short) != 2) {
172  if (((signed char*)from)[2] < 0) {
173  to = -1;
174  }else{
175  to = 0;
176  }
177  }
178 #if !defined(AIPS_LITTLE_ENDIAN)
179  CanonicalConversion::reverse2 (((char*)&to)+sizeof(short)-2, from);
180 #else
181  CanonicalConversion::move2 (&to, from);
182 #endif
183 }
184 
185 inline void LittleEndianConversion::toLocal (unsigned short& to,
186  const void* from)
187 {
188  if (sizeof(unsigned short) != 2) {
189  to = 0;
190  }
191 #if !defined(AIPS_LITTLE_ENDIAN)
192  CanonicalConversion::reverse2 (((char*)&to)+sizeof(unsigned short)-2,from);
193 #else
194  CanonicalConversion::move2 (&to, from);
195 #endif
196 }
197 
198 inline void LittleEndianConversion::toLocal (int& to, const void* from)
199 {
200  if (sizeof(int) != 4) {
201  if (((signed char*)from)[3] < 0) {
202  to = -1;
203  }else{
204  to = 0;
205  }
206  }
207 #if !defined(AIPS_LITTLE_ENDIAN)
208  CanonicalConversion::reverse4 (((char*)&to)+sizeof(int)-4, from);
209 #else
210  CanonicalConversion::move4 (&to, from);
211 #endif
212 }
213 
214 inline void LittleEndianConversion::toLocal (unsigned int& to,
215  const void* from)
216 {
217  if (sizeof(unsigned int) != 4) {
218  to = 0;
219  }
220 #if !defined(AIPS_LITTLE_ENDIAN)
221  CanonicalConversion::reverse4 (((char*)&to)+sizeof(unsigned int)-4, from);
222 #else
223  CanonicalConversion::move4 (&to, from);
224 #endif
225 }
226 
227 inline void LittleEndianConversion::toLocal (Int64& to, const void* from)
228 {
229  int tmp;
231  to = tmp;
232 }
233 
235  const void* from)
236 {
237  unsigned int tmp;
239  to = tmp;
240 }
241 
242 inline void LittleEndianConversion::toLocal (float& to, const void* from)
243 {
244 #if !defined(AIPS_LITTLE_ENDIAN)
245  CanonicalConversion::reverse4 (&to, from);
246 #else
247  CanonicalConversion::move4 (&to, from);
248 #endif
249 }
250 
251 inline void LittleEndianConversion::toLocal (double& to, const void* from)
252 {
253 #if !defined(AIPS_LITTLE_ENDIAN)
254  CanonicalConversion::reverse8 (&to, from);
255 #else
256  CanonicalConversion::move8 (&to, from);
257 #endif
258 }
259 
260 
261 inline void LittleEndianConversion::fromLocal (void* to, char from)
262 {
263  *(char*)to = from;
264 }
265 inline void LittleEndianConversion::fromLocal (void* to, unsigned char from)
266 {
267  *(unsigned char*)to = from;
268 }
269 
270 inline void LittleEndianConversion::fromLocal (void* to, short from)
271 {
272 #if !defined(AIPS_LITTLE_ENDIAN)
273  CanonicalConversion::reverse2 (to, ((char*)&from)+sizeof(short)-2);
274 #else
275  CanonicalConversion::move2 (to, &from);
276 #endif
277 }
278 
279 inline void LittleEndianConversion::fromLocal (void* to, unsigned short from)
280 {
281 #if !defined(AIPS_LITTLE_ENDIAN)
282  CanonicalConversion::reverse2 (to,((char*)&from)+sizeof(unsigned short)-2);
283 #else
284  CanonicalConversion::move2 (to, &from);
285 #endif
286 }
287 
288 inline void LittleEndianConversion::fromLocal (void* to, int from)
289 {
290 #if !defined(AIPS_LITTLE_ENDIAN)
291  CanonicalConversion::reverse4 (to, ((char*)&from)+sizeof(int)-4);
292 #else
293  CanonicalConversion::move4 (to, &from);
294 #endif
295 }
296 
297 inline void LittleEndianConversion::fromLocal (void* to, unsigned int from)
298 {
299 #if !defined(AIPS_LITTLE_ENDIAN)
300  CanonicalConversion::reverse4 (to, ((char*)&from)+sizeof(unsigned int)-4);
301 #else
302  CanonicalConversion::move4 (to, &from);
303 #endif
304 }
305 
306 inline void LittleEndianConversion::fromLocal (void* to, Int64 from)
307 {
308 #if !defined(AIPS_LITTLE_ENDIAN)
309  CanonicalConversion::reverse4 (to, ((char*)&from)+sizeof(Int64)-4);
310 #else
311  CanonicalConversion::move4 (to, &from);
312 #endif
313 }
314 
315 inline void LittleEndianConversion::fromLocal (void* to, uInt64 from)
316 {
317 #if !defined(AIPS_LITTLE_ENDIAN)
318  CanonicalConversion::reverse4 (to, ((char*)&from)+sizeof(uInt64)-4);
319 #else
320  CanonicalConversion::move4 (to, &from);
321 #endif
322 }
323 
324 inline void LittleEndianConversion::fromLocal (void* to, float from)
325 {
326 #if !defined(AIPS_LITTLE_ENDIAN)
327  CanonicalConversion::reverse4 (to, ((char*)&from)+sizeof(float)-4);
328 #else
329  CanonicalConversion::move4 (to, &from);
330 #endif
331 }
332 
333 inline void LittleEndianConversion::fromLocal (void* to, double from)
334 {
335 #if !defined(AIPS_LITTLE_ENDIAN)
336  CanonicalConversion::reverse8 (to, ((char*)&from)+sizeof(double)-8);
337 #else
338  CanonicalConversion::move8 (to, &from);
339 #endif
340 }
341 
342 
343 
344 
345 } //# NAMESPACE CASACORE - END
346 
347 #endif
long long Int64
Define the extra non-standard types used by Casacore (like proposed uSize, Size)
Definition: aipsxtype.h:38
static void move2(void *to, const void *from)
Move 2 bytes.
LittleEndianConversion()
This class should not be constructed (so declare the constructor private).
static void reverse2(void *to, const void *from)
Reverse 2 bytes.
unsigned long long uInt64
Definition: aipsxtype.h:39
static void reverse8(void *to, const void *from)
Reverse 8 bytes.
static void toLocal(char &to, const void *from)
Convert one value from littleEndian format to local format.
static void fromLocal(void *to, char from)
Convert one value from local format to littleEndian format.
static void move4(void *to, const void *from)
Move 4 bytes.
A class with static functions to convert littleEndian format.
static void reverse4(void *to, const void *from)
Reverse 4 bytes.
static void move8(void *to, const void *from)
Move 8 bytes.