casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
LittleEndianConversion.h
Go to the documentation of this file.
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