byteOrder.h

Go to the documentation of this file.
00001 
00015 #ifndef _DLR_COMMON_BYTEORDER_H_
00016 #define _DLR_COMMON_BYTEORDER_H_
00017 
00018 #include <algorithm>
00019 #include <sstream>
00020 #include <dlrCommon/exception.h>
00021 #include <dlrCommon/types.h>
00022 
00023 namespace dlr {
00024 
00025   namespace common {
00026     
00031     enum ByteOrder {
00032       DLR_BIG_ENDIAN,
00033       DLR_LITTLE_ENDIAN,
00034     };
00035 
00036 
00045     inline ByteOrder
00046     getByteOrder();
00047 
00048 
00066     template <class Type>
00067     inline void
00068     switchByteOrder(Type* dataPtr,
00069                     size_t numberOfElements,
00070                     ByteOrder fromByteOrder,
00071                     ByteOrder toByteOrder);
00072 
00073     
00094     template <class Type>
00095     inline void
00096     switchByteOrder(const Type* fromDataPtr,
00097                     size_t numberOfElements,
00098                     Type* toDataPtr,
00099                     ByteOrder fromByteOrder,
00100                     ByteOrder toByteOrder);
00101 
00102 
00103   } // namespace common
00104   
00105 } // namespace dlr
00106 
00107 
00108 /* ======= Declarations to maintain compatibility with legacy code. ======= */
00109 
00110 namespace dlr {
00111 
00112   using common::ByteOrder;
00113   using common::DLR_BIG_ENDIAN;
00114   using common::DLR_LITTLE_ENDIAN;
00115   using common::getByteOrder;
00116   using common::switchByteOrder;
00117   
00118 } // namespace dlr
00119 
00120 
00121 /* ============ Implementation of template functions below ============ */
00122 
00123 #include <algorithm>
00124 
00125 namespace dlr {
00126 
00127   namespace common {
00128 
00130     namespace privateCode {
00131     
00140       template <int Size>
00141       inline void
00142       genericSwitchByteOrder(UnsignedInt8* dataPtr,
00143                              size_t numberOfElements,
00144                              ByteOrder fromByteOrder,
00145                              ByteOrder toByteOrder)
00146       {
00147         if(fromByteOrder == toByteOrder) {
00148           return;
00149         }
00150         std::ostringstream message;
00151         message << "This function is not implemented for types of size"
00152                 << Size << ".";
00153         DLR_THROW(NotImplementedException, "genericSwitchByteOrder()",
00154                   message.str().c_str());
00155       }
00156   
00157 
00158       template <>
00159       inline void
00160       genericSwitchByteOrder<2>(UnsignedInt8* dataPtr,
00161                                 size_t numberOfElements,
00162                                 ByteOrder fromByteOrder,
00163                                 ByteOrder toByteOrder)
00164       {
00165         if(fromByteOrder == toByteOrder) {
00166           return;
00167         }
00168         UnsignedInt8* endPtr = dataPtr + numberOfElements * 2;
00169         while(dataPtr < endPtr) {
00170           std::swap(*dataPtr, *(dataPtr + 1));
00171           dataPtr += 2;
00172         }
00173         return;
00174       }
00175 
00176 
00177       template <>
00178       inline void
00179       genericSwitchByteOrder<4>(UnsignedInt8* dataPtr,
00180                                 size_t numberOfElements,
00181                                 ByteOrder fromByteOrder,
00182                                 ByteOrder toByteOrder)
00183       {
00184         if(fromByteOrder == toByteOrder) {
00185           return;
00186         }
00187         UnsignedInt8* endPtr = dataPtr + numberOfElements * 4;
00188         while(dataPtr < endPtr) {
00189           std::swap(*dataPtr, *(dataPtr + 3));
00190           std::swap(*(dataPtr + 1), *(dataPtr + 2));
00191           dataPtr += 4;
00192         }
00193         return;
00194       }
00195 
00196 
00197       template <>
00198       inline void
00199       genericSwitchByteOrder<8>(UnsignedInt8* dataPtr,
00200                                 size_t numberOfElements,
00201                                 ByteOrder fromByteOrder,
00202                                 ByteOrder toByteOrder)
00203       {
00204         if(fromByteOrder == toByteOrder) {
00205           return;
00206         }
00207         UnsignedInt8* endPtr = dataPtr + numberOfElements * 8;
00208         while(dataPtr < endPtr) {
00209           std::swap(*dataPtr, *(dataPtr + 7));
00210           std::swap(*(dataPtr + 1), *(dataPtr + 6));
00211           std::swap(*(dataPtr + 2), *(dataPtr + 5));
00212           std::swap(*(dataPtr + 3), *(dataPtr + 4));
00213           dataPtr += 8;
00214         }
00215         return;
00216       }
00217 
00218 
00227       template <int Size>
00228       inline void
00229       genericSwitchByteOrder(const UnsignedInt8* fromDataPtr,
00230                              size_t numberOfElements,
00231                              UnsignedInt8* toDataPtr,
00232                              ByteOrder fromByteOrder,
00233                              ByteOrder toByteOrder)
00234       {
00235         if(fromByteOrder == toByteOrder) {
00236           std::copy(fromDataPtr, fromDataPtr + numberOfElements, toDataPtr);
00237           return;
00238         }
00239         std::ostringstream message;
00240         message << "This function is not implemented for types of size"
00241                 << Size << ".";
00242         DLR_THROW(NotImplementedException, "genericSwitchByteOrder()",
00243                   message.str().c_str());
00244       }
00245 
00246 
00247       template <>
00248       inline void
00249       genericSwitchByteOrder<2>(const UnsignedInt8* fromDataPtr,
00250                                 size_t numberOfElements,
00251                                 UnsignedInt8* toDataPtr,
00252                                 ByteOrder fromByteOrder,
00253                                 ByteOrder toByteOrder)
00254       {
00255         if(fromByteOrder == toByteOrder) {
00256           std::copy(fromDataPtr, fromDataPtr + numberOfElements, toDataPtr);
00257           return;
00258         }
00259         const UnsignedInt8* fromEndPtr =  fromDataPtr + numberOfElements * 2;
00260         while(fromDataPtr < fromEndPtr) {
00261           *toDataPtr = *(fromDataPtr + 1);
00262           *(toDataPtr + 1) = *(fromDataPtr);
00263           toDataPtr += 2;
00264           fromDataPtr += 2;
00265         }
00266         return;
00267       }
00268 
00269 
00270       template <>
00271       inline void
00272       genericSwitchByteOrder<4>(const UnsignedInt8* fromDataPtr,
00273                                 size_t numberOfElements,
00274                                 UnsignedInt8* toDataPtr,
00275                                 ByteOrder fromByteOrder,
00276                                 ByteOrder toByteOrder)
00277       {
00278         if(fromByteOrder == toByteOrder) {
00279           std::copy(fromDataPtr, fromDataPtr + numberOfElements, toDataPtr);
00280           return;
00281         }
00282         const UnsignedInt8* fromEndPtr = fromDataPtr + numberOfElements * 4;
00283         while(fromDataPtr < fromEndPtr) {
00284           *toDataPtr = *(fromDataPtr + 3);
00285           *(toDataPtr + 1) = *(fromDataPtr + 2);
00286           *(toDataPtr + 2) = *(fromDataPtr + 1);
00287           *(toDataPtr + 3) = *(fromDataPtr);
00288           toDataPtr += 4;
00289           fromDataPtr += 4;
00290         }
00291         return;
00292       }
00293 
00294 
00295       template <>
00296       inline void
00297       genericSwitchByteOrder<8>(const UnsignedInt8* fromDataPtr,
00298                                 size_t numberOfElements,
00299                                 UnsignedInt8* toDataPtr,
00300                                 ByteOrder fromByteOrder,
00301                                 ByteOrder toByteOrder)
00302       {
00303         if(fromByteOrder == toByteOrder) {
00304           std::copy(fromDataPtr, fromDataPtr + numberOfElements, toDataPtr);
00305           return;
00306         }
00307         const UnsignedInt8* fromEndPtr = fromDataPtr + numberOfElements * 8;
00308         while(fromDataPtr < fromEndPtr) {
00309           *toDataPtr = *(fromDataPtr + 7);
00310           *(toDataPtr + 1) = *(fromDataPtr + 6);
00311           *(toDataPtr + 2) = *(fromDataPtr + 5);
00312           *(toDataPtr + 3) = *(fromDataPtr + 4);
00313           *(toDataPtr + 4) = *(fromDataPtr + 3);
00314           *(toDataPtr + 5) = *(fromDataPtr + 2);
00315           *(toDataPtr + 6) = *(fromDataPtr + 1);
00316           *(toDataPtr + 7) = *(fromDataPtr);
00317           toDataPtr += 8;
00318           fromDataPtr += 8;
00319         }
00320         return;
00321       }
00322 
00323     } // namespace privateCode
00325 
00326   
00327     // This function returns the appropriate byte order for the platform
00328     // on which it is run.
00329     inline ByteOrder
00330     getByteOrder()
00331     {
00332       UnsignedInt16 byteOrderTester = 0x0102;
00333       if(*((UnsignedInt8*)(&byteOrderTester)) == 0x01) {
00334         return DLR_BIG_ENDIAN;
00335       }
00336       return DLR_LITTLE_ENDIAN;
00337     }
00338 
00339 
00340     // This function takes a pointer to a C-style array of values and
00341     // modifies the array in place so that it has a particular byte
00342     // order.
00343     template <class Type>
00344     void
00345     switchByteOrder(Type* dataPtr,
00346                     size_t numberOfElements,
00347                     ByteOrder fromByteOrder,
00348                     ByteOrder toByteOrder)
00349     {
00350       privateCode::genericSwitchByteOrder<sizeof(Type)>(
00351         reinterpret_cast<UnsignedInt8*>(dataPtr), numberOfElements,
00352         fromByteOrder, toByteOrder);
00353     }
00354 
00355     
00356     // This function takes a pointer to a C-style array of values and
00357     // copies it into another C-style array, swapping bytes if necessary
00358     // so that the output array has the specified byte order.
00359     template <class Type>
00360     void
00361     switchByteOrder(const Type* fromDataPtr,
00362                     size_t numberOfElements,
00363                     Type* toDataPtr,
00364                     ByteOrder fromByteOrder,
00365                     ByteOrder toByteOrder)
00366     {
00367       privateCode::genericSwitchByteOrder<sizeof(Type)>(
00368         reinterpret_cast<const UnsignedInt8*>(fromDataPtr), numberOfElements,
00369         reinterpret_cast<UnsignedInt8*>(toDataPtr), fromByteOrder, toByteOrder);
00370     }
00371 
00372     
00373   } // namespace common
00374   
00375 } // namespace dlr
00376     
00377 #endif // #ifndef _DLR_COMMON_BYTEORDER_H_

Generated on Mon Jul 9 20:34:02 2007 for dlrLibs Utility Libraries by  doxygen 1.5.2