Wiselib
wiselib.stable/util/serialization/floating_point.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines