casa
$Rev:20696$
|
00001 //# LittleEndianConversion.h: A class with static functions to convert littleEndian format 00002 //# Copyright (C) 1996,1997,1999,2001 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# $Id: LittleEndianConversion.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $ 00027 00028 #ifndef CASA_LITTLEENDIANCONVERSION_H 00029 #define CASA_LITTLEENDIANCONVERSION_H 00030 00031 //# Includes 00032 #include <casa/aipsxtype.h> 00033 #include <casa/OS/CanonicalConversion.h> 00034 00035 00036 namespace casa { //# NAMESPACE CASA - BEGIN 00037 00038 // <summary> 00039 // A class with static functions to convert littleEndian format 00040 // </summary> 00041 00042 // <use visibility=export> 00043 00044 // <reviewed reviewer="Friso Olnon" date="1996/11/06" tests="tVAXConversion" demos=""> 00045 // </reviewed> 00046 00047 // <synopsis> 00048 // This class is intended to be used as a common class for all 00049 // classes converting data to/from little-endian format. 00050 // </synopsis> 00051 00052 // <motivation> 00053 // Sometimes data are stored in little-endian format (e.g. old VAX-data). 00054 // Instead of putting all these conversion functions in all such classes, 00055 // it is better to keep them separate to be able to use them elsewhere. 00056 // However, note that this version handles a long as 4 bytes. 00057 // On several little-endian machines (e.g. DEC-alpha) a long is 8 bytes, 00058 // so a special function is needed for them. 00059 // </motivation> 00060 00061 // <todo asof="$DATE$"> 00062 // <li> Support data type long double. 00063 // <li> Support a long as 4 or as 8 bytes. 00064 // </todo> 00065 00066 00067 class LittleEndianConversion 00068 { 00069 public: 00070 // Convert one value from littleEndian format to local format. 00071 // The from and to buffer should not overlap. 00072 // <group> 00073 static void toLocal (char& to, const void* from); 00074 static void toLocal (unsigned char& to, const void* from); 00075 static void toLocal (short& to, const void* from); 00076 static void toLocal (unsigned short& to, const void* from); 00077 static void toLocal (int& to, const void* from); 00078 static void toLocal (unsigned int& to, const void* from); 00079 static void toLocal (Int64& to, const void* from); 00080 static void toLocal (uInt64& to, const void* from); 00081 static void toLocal (float& to, const void* from); 00082 static void toLocal (double& to, const void* from); 00083 // </group> 00084 00085 // Convert nr values from littleEndian format to local format. 00086 // The from and to buffer should not overlap. 00087 // <group> 00088 static void toLocal (char* to, const void* from, 00089 unsigned int nr); 00090 static void toLocal (unsigned char* to, const void* from, 00091 unsigned int nr); 00092 static void toLocal (short* to, const void* from, 00093 unsigned int nr); 00094 static void toLocal (unsigned short* to, const void* from, 00095 unsigned int nr); 00096 static void toLocal (int* to, const void* from, 00097 unsigned int nr); 00098 static void toLocal (unsigned int* to, const void* from, 00099 unsigned int nr); 00100 static void toLocal (Int64* to, const void* from, 00101 unsigned int nr); 00102 static void toLocal (uInt64* to, const void* from, 00103 unsigned int nr); 00104 static void toLocal (float* to, const void* from, 00105 unsigned int nr); 00106 static void toLocal (double* to, const void* from, 00107 unsigned int nr); 00108 // </group> 00109 00110 // Convert one value from local format to littleEndian format. 00111 // The from and to buffer should not overlap. 00112 // <group> 00113 static void fromLocal (void* to, char from); 00114 static void fromLocal (void* to, unsigned char from); 00115 static void fromLocal (void* to, short from); 00116 static void fromLocal (void* to, unsigned short from); 00117 static void fromLocal (void* to, int from); 00118 static void fromLocal (void* to, unsigned int from); 00119 static void fromLocal (void* to, Int64 from); 00120 static void fromLocal (void* to, uInt64 from); 00121 static void fromLocal (void* to, float from); 00122 static void fromLocal (void* to, double from); 00123 // </group> 00124 00125 // Convert nr values from local format to littleEndian format. 00126 // The from and to buffer should not overlap. 00127 // <group> 00128 static void fromLocal (void* to, const char* from, 00129 unsigned int nr); 00130 static void fromLocal (void* to, const unsigned char* from, 00131 unsigned int nr); 00132 static void fromLocal (void* to, const short* from, 00133 unsigned int nr); 00134 static void fromLocal (void* to, const unsigned short* from, 00135 unsigned int nr); 00136 static void fromLocal (void* to, const int* from, 00137 unsigned int nr); 00138 static void fromLocal (void* to, const unsigned int* from, 00139 unsigned int nr); 00140 static void fromLocal (void* to, const Int64* from, 00141 unsigned int nr); 00142 static void fromLocal (void* to, const uInt64* from, 00143 unsigned int nr); 00144 static void fromLocal (void* to, const float* from, 00145 unsigned int nr); 00146 static void fromLocal (void* to, const double* from, 00147 unsigned int nr); 00148 // </group> 00149 00150 private: 00151 // This class should not be constructed 00152 // (so declare the constructor private). 00153 LittleEndianConversion(); 00154 }; 00155 00156 00157 00158 inline void LittleEndianConversion::toLocal (char& to, const void* from) 00159 { 00160 to = *(char*)from; 00161 } 00162 00163 inline void LittleEndianConversion::toLocal (unsigned char& to, 00164 const void* from) 00165 { 00166 to = *(unsigned char*)from; 00167 } 00168 00169 inline void LittleEndianConversion::toLocal (short& to, const void* from) 00170 { 00171 if (sizeof(short) != 2) { 00172 if (((signed char*)from)[2] < 0) { 00173 to = -1; 00174 }else{ 00175 to = 0; 00176 } 00177 } 00178 #if !defined(AIPS_LITTLE_ENDIAN) 00179 CanonicalConversion::reverse2 (((char*)&to)+sizeof(short)-2, from); 00180 #else 00181 CanonicalConversion::move2 (&to, from); 00182 #endif 00183 } 00184 00185 inline void LittleEndianConversion::toLocal (unsigned short& to, 00186 const void* from) 00187 { 00188 if (sizeof(unsigned short) != 2) { 00189 to = 0; 00190 } 00191 #if !defined(AIPS_LITTLE_ENDIAN) 00192 CanonicalConversion::reverse2 (((char*)&to)+sizeof(unsigned short)-2,from); 00193 #else 00194 CanonicalConversion::move2 (&to, from); 00195 #endif 00196 } 00197 00198 inline void LittleEndianConversion::toLocal (int& to, const void* from) 00199 { 00200 if (sizeof(int) != 4) { 00201 if (((signed char*)from)[3] < 0) { 00202 to = -1; 00203 }else{ 00204 to = 0; 00205 } 00206 } 00207 #if !defined(AIPS_LITTLE_ENDIAN) 00208 CanonicalConversion::reverse4 (((char*)&to)+sizeof(int)-4, from); 00209 #else 00210 CanonicalConversion::move4 (&to, from); 00211 #endif 00212 } 00213 00214 inline void LittleEndianConversion::toLocal (unsigned int& to, 00215 const void* from) 00216 { 00217 if (sizeof(unsigned int) != 4) { 00218 to = 0; 00219 } 00220 #if !defined(AIPS_LITTLE_ENDIAN) 00221 CanonicalConversion::reverse4 (((char*)&to)+sizeof(unsigned int)-4, from); 00222 #else 00223 CanonicalConversion::move4 (&to, from); 00224 #endif 00225 } 00226 00227 inline void LittleEndianConversion::toLocal (Int64& to, const void* from) 00228 { 00229 int tmp; 00230 LittleEndianConversion::toLocal (tmp, from); 00231 to = tmp; 00232 } 00233 00234 inline void LittleEndianConversion::toLocal (uInt64& to, 00235 const void* from) 00236 { 00237 unsigned int tmp; 00238 LittleEndianConversion::toLocal (tmp, from); 00239 to = tmp; 00240 } 00241 00242 inline void LittleEndianConversion::toLocal (float& to, const void* from) 00243 { 00244 #if !defined(AIPS_LITTLE_ENDIAN) 00245 CanonicalConversion::reverse4 (&to, from); 00246 #else 00247 CanonicalConversion::move4 (&to, from); 00248 #endif 00249 } 00250 00251 inline void LittleEndianConversion::toLocal (double& to, const void* from) 00252 { 00253 #if !defined(AIPS_LITTLE_ENDIAN) 00254 CanonicalConversion::reverse8 (&to, from); 00255 #else 00256 CanonicalConversion::move8 (&to, from); 00257 #endif 00258 } 00259 00260 00261 inline void LittleEndianConversion::fromLocal (void* to, char from) 00262 { 00263 *(char*)to = from; 00264 } 00265 inline void LittleEndianConversion::fromLocal (void* to, unsigned char from) 00266 { 00267 *(unsigned char*)to = from; 00268 } 00269 00270 inline void LittleEndianConversion::fromLocal (void* to, short from) 00271 { 00272 #if !defined(AIPS_LITTLE_ENDIAN) 00273 CanonicalConversion::reverse2 (to, ((char*)&from)+sizeof(short)-2); 00274 #else 00275 CanonicalConversion::move2 (to, &from); 00276 #endif 00277 } 00278 00279 inline void LittleEndianConversion::fromLocal (void* to, unsigned short from) 00280 { 00281 #if !defined(AIPS_LITTLE_ENDIAN) 00282 CanonicalConversion::reverse2 (to,((char*)&from)+sizeof(unsigned short)-2); 00283 #else 00284 CanonicalConversion::move2 (to, &from); 00285 #endif 00286 } 00287 00288 inline void LittleEndianConversion::fromLocal (void* to, int from) 00289 { 00290 #if !defined(AIPS_LITTLE_ENDIAN) 00291 CanonicalConversion::reverse4 (to, ((char*)&from)+sizeof(int)-4); 00292 #else 00293 CanonicalConversion::move4 (to, &from); 00294 #endif 00295 } 00296 00297 inline void LittleEndianConversion::fromLocal (void* to, unsigned int from) 00298 { 00299 #if !defined(AIPS_LITTLE_ENDIAN) 00300 CanonicalConversion::reverse4 (to, ((char*)&from)+sizeof(unsigned int)-4); 00301 #else 00302 CanonicalConversion::move4 (to, &from); 00303 #endif 00304 } 00305 00306 inline void LittleEndianConversion::fromLocal (void* to, Int64 from) 00307 { 00308 #if !defined(AIPS_LITTLE_ENDIAN) 00309 CanonicalConversion::reverse4 (to, ((char*)&from)+sizeof(Int64)-4); 00310 #else 00311 CanonicalConversion::move4 (to, &from); 00312 #endif 00313 } 00314 00315 inline void LittleEndianConversion::fromLocal (void* to, uInt64 from) 00316 { 00317 #if !defined(AIPS_LITTLE_ENDIAN) 00318 CanonicalConversion::reverse4 (to, ((char*)&from)+sizeof(uInt64)-4); 00319 #else 00320 CanonicalConversion::move4 (to, &from); 00321 #endif 00322 } 00323 00324 inline void LittleEndianConversion::fromLocal (void* to, float from) 00325 { 00326 #if !defined(AIPS_LITTLE_ENDIAN) 00327 CanonicalConversion::reverse4 (to, ((char*)&from)+sizeof(float)-4); 00328 #else 00329 CanonicalConversion::move4 (to, &from); 00330 #endif 00331 } 00332 00333 inline void LittleEndianConversion::fromLocal (void* to, double from) 00334 { 00335 #if !defined(AIPS_LITTLE_ENDIAN) 00336 CanonicalConversion::reverse8 (to, ((char*)&from)+sizeof(double)-8); 00337 #else 00338 CanonicalConversion::move8 (to, &from); 00339 #endif 00340 } 00341 00342 00343 00344 00345 } //# NAMESPACE CASA - END 00346 00347 #endif