Wiselib
|
00001 /*************************************************************************** 00002 ** This file is part of the generic algorithm library Wiselib. ** 00003 ** Copyright (C) 2008,2009 by the Wisebed (www.wisebed.eu) project. ** 00004 ** ** 00005 ** The Wiselib is free software: you can redistribute it and/or modify ** 00006 ** it under the terms of the GNU Lesser General Public License as ** 00007 ** published by the Free Software Foundation, either version 3 of the ** 00008 ** License, or (at your option) any later version. ** 00009 ** ** 00010 ** The Wiselib is distributed in the hope that it will be useful, ** 00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** 00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** 00013 ** GNU Lesser General Public License for more details. ** 00014 ** ** 00015 ** You should have received a copy of the GNU Lesser General Public ** 00016 ** License along with the Wiselib. ** 00017 ** If not, see <http://www.gnu.org/licenses/>. ** 00018 ***************************************************************************/ 00019 #ifndef __WISELIB_UTIL_SERIALIZATION_FLOATING_POINT_H 00020 #define __WISELIB_UTIL_SERIALIZATION_FLOATING_POINT_H 00021 00022 #include <string.h> 00023 #include "util/serialization/endian.h" 00024 00025 namespace wiselib 00026 { 00027 00028 template <typename OsModel_P, 00029 Endianness, 00030 typename BlockData_P, 00031 typename Type_P, 00032 int Size_P> 00033 struct FpSerialization 00034 { 00035 typedef OsModel_P OsModel; 00036 typedef BlockData_P BlockData; 00037 typedef Type_P Type; 00038 static const int Size = Size_P; 00039 00040 typedef typename OsModel::size_t size_t; 00041 // -------------------------------------------------------------------- 00042 static inline size_t write( BlockData *target, Type& value ) 00043 { 00044 for ( unsigned int i = 0; i < sizeof(Type); i++ ) 00045 target[sizeof(Type) - 1 - i] = *((BlockData*)&value + i); 00046 return sizeof(Type); 00047 } 00048 // -------------------------------------------------------------------- 00049 static Type_P read( BlockData *target ) 00050 { 00051 Type value; 00052 for ( unsigned int i = 0; i < sizeof(Type); i++ ) 00053 *((BlockData*)&value + i) = target[sizeof(Type) - 1 - i]; 00054 return value; 00055 } 00056 00057 }; 00058 // ----------------------------------------------------------------------- 00059 // ----------------------------------------------------------------------- 00060 // ----------------------------------------------------------------------- 00061 template <typename OsModel_P, 00062 typename BlockData_P, 00063 typename Type_P, 00064 int Size_P> 00065 struct FpSerialization<OsModel_P, WISELIB_BIG_ENDIAN, BlockData_P, Type_P, Size_P> 00066 { 00067 typedef OsModel_P OsModel; 00068 typedef BlockData_P BlockData; 00069 typedef Type_P Type; 00070 static const int Size = Size_P; 00071 00072 typedef typename OsModel::size_t size_t; 00073 // -------------------------------------------------------------------- 00074 static inline size_t write( BlockData *target, Type& value ) 00075 { 00076 for ( unsigned int i = 0; i < sizeof(Type); i++ ) 00077 target[i] = *((BlockData*)&value + i); 00078 return sizeof(Type); 00079 } 00080 // -------------------------------------------------------------------- 00081 static Type_P read( BlockData *target ) 00082 { 00083 Type value; 00084 for ( unsigned int i = 0; i < sizeof(Type); i++ ) 00085 *((BlockData*)&value + i) = target[i]; 00086 return value; 00087 } 00088 00089 }; 00090 // ----------------------------------------------------------------------- 00091 // ----------------------------------------------------------------------- 00092 // ----------------------------------------------------------------------- 00093 template <typename OsModel_P, 00094 typename BlockData_P> 00095 struct FpSerialization<OsModel_P, WISELIB_LITTLE_ENDIAN, BlockData_P, double, 4> 00096 { 00097 typedef OsModel_P OsModel; 00098 typedef BlockData_P BlockData; 00099 typedef double Type; 00100 static const int Size = 4; 00101 00102 typedef typename OsModel::size_t size_t; 00103 // -------------------------------------------------------------------- 00138 static inline size_t write( BlockData *target, Type& value ) 00139 { 00140 // set target bytes initially to 0x00, because all further bit 00141 // operations use |= 00142 memset( target, 0x00, 8 ); 00143 BlockData *val = (BlockData *)&value; 00144 00145 // Sign bit and first bit of exponent; copy the following three bits 00146 // to bits 5..7 of first byte in target 00147 *target |= (*(val+3) & (0x80 | 0x40)) | ((*(val+3) >> 3) & 0x07); 00148 // Adding 111 to bits 2..4 of target, iff first bit source E is 0 00149 if ((*(val+3) & 0x40) == 0x00) 00150 *target |= 0x38; 00151 00152 // rest of exponent; to be put at first four bits of second byte 00153 // in single precision, they are located in last three bits of 00154 // first byte and first bit of second byte 00155 *(target+1) |= ((*(val+3) << 5) & 0xe0) | ((*(val+2) >> 3) & 0x10); 00156 00157 // Mantissa 00158 *(target+1) |= ((*(val+2) >> 3) & 0x0f); 00159 *(target+2) |= ((*(val+2) << 5) & 0xe0) | ((*(val+1) >> 3) & 0x1f); 00160 *(target+3) |= ((*(val+1) << 5) & 0xe0) | ((*(val+0) >> 3) & 0x1f); 00161 *(target+4) |= ((*(val+0) << 5) & 0xe0); 00162 00163 return sizeof(Type); 00164 } 00165 // -------------------------------------------------------------------- 00197 static Type read( BlockData *target ) 00198 { 00199 Type value; 00200 BlockData *val = (BlockData *)&value; 00201 memset( val, 0x00, sizeof(Type) ); 00202 00203 // copy sign bit and first one of E, and skip bits 1..3 of E 00204 *(val+3) |= (*(target+0) & 0xc0) | ((*(target+0) << 3) & 0x38) | 00205 ((*(target+1) >> 5) & 0x07); 00206 // copy last bit of E, and then the Mantisse F 00207 *(val+2) |= ((*(target+1) << 3) & 0xf8) | ((*(target+2) >> 5) & 0x07); 00208 *(val+1) |= ((*(target+2) << 3) & 0xf8) | ((*(target+3) >> 5) & 0x07); 00209 *(val+0) |= ((*(target+3) << 3) & 0xf8) | ((*(target+4) >> 5) & 0x07); 00210 00211 return value; 00212 } 00213 00214 }; 00215 // ----------------------------------------------------------------------- 00216 // ----------------------------------------------------------------------- 00217 // ----------------------------------------------------------------------- 00218 template <typename OsModel_P, 00219 typename BlockData_P> 00220 struct FpSerialization<OsModel_P, WISELIB_BIG_ENDIAN, BlockData_P, double, 4> 00221 { 00222 typedef OsModel_P OsModel; 00223 typedef BlockData_P BlockData; 00224 typedef double Type; 00225 static const int Size = 4; 00226 00227 typedef typename OsModel::size_t size_t; 00228 // -------------------------------------------------------------------- 00229 static inline size_t write( BlockData *target, Type& value ) 00230 { 00231 // set target bytes initially to 0x00, because all further bit 00232 // operations use |= 00233 memset( target, 0x00, 8 ); 00234 BlockData *val = (BlockData *)&value; 00235 00236 // Sign bit and first bit of exponent; copy the following three bits 00237 // to bits 5..7 of first byte in target 00238 *target |= (*(val+0) & (0x80 | 0x40)) | ((*(val+0) >> 3) & 0x07); 00239 // Adding 111 to bits 2..4 of target, iff first bit source E is 0 00240 if ((*(val+0) & 0x40) == 0x00) 00241 *target |= 0x38; 00242 00243 // rest of exponent; to be put at first four bits of second byte 00244 // in single precision, they are located in last three bits of 00245 // first byte and first bit of second byte 00246 *(target+1) |= ((*(val+0) << 5) & 0xe0) | ((*(val+1) >> 3) & 0x10); 00247 00248 // Mantissa 00249 *(target+1) |= ((*(val+1) >> 3) & 0x0f); 00250 *(target+2) |= ((*(val+1) << 5) & 0xe0) | ((*(val+2) >> 3) & 0x1f); 00251 *(target+3) |= ((*(val+2) << 5) & 0xe0) | ((*(val+3) >> 3) & 0x1f); 00252 *(target+4) |= ((*(val+3) << 5) & 0xe0); 00253 00254 return sizeof(Type); 00255 } 00256 // -------------------------------------------------------------------- 00257 static Type read( BlockData *target ) 00258 { 00259 Type value; 00260 BlockData *val = (BlockData *)&value; 00261 memset( val, 0x00, sizeof(Type) ); 00262 00263 // copy sign bit and first one of E, and skip bits 1..3 of E 00264 *(val+0) |= (*(target+0) & 0xc0) | ((*(target+0) << 3) & 0x38) | 00265 ((*(target+1) >> 5) & 0x07); 00266 // copy last bit of E, and then the Mantisse F 00267 *(val+1) |= ((*(target+1) << 3) & 0xf8) | ((*(target+2) >> 5) & 0x07); 00268 *(val+2) |= ((*(target+2) << 3) & 0xf8) | ((*(target+3) >> 5) & 0x07); 00269 *(val+3) |= ((*(target+3) << 3) & 0xf8) | ((*(target+4) >> 5) & 0x07); 00270 00271 return value; 00272 } 00273 00274 }; 00275 00276 } 00277 00278 #endif