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 }
00104
00105 }
00106
00107
00108
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 }
00119
00120
00121
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 }
00325
00326
00327
00328
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
00341
00342
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
00357
00358
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 }
00374
00375 }
00376
00377 #endif // #ifndef _DLR_COMMON_BYTEORDER_H_