Changeset 187:108677185b5f in rrlib_serialization


Ignore:
Timestamp:
15.04.2019 18:30:12 (2 months ago)
Author:
Max Reichardt <max.reichardt@…>
Branch:
17.03
Phase:
public
Message:

Reworks endianness handling - and fixes issues on big endian platforms in this regard

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • definitions.h

    r174 r187  
    101101#ifndef __BYTE_ORDER__ 
    102102#warning __BYTE_ORDER__ not defined 
     103#else 
     104#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 
     105#define RRLIB_SERIALIZATION_BIG_ENDIAN_PLATFORM 
     106#endif 
    103107#endif 
    104108 
     
    106110// Function declarations 
    107111//---------------------------------------------------------------------- 
     112 
     113/*! 
     114 * Converts integer value in platform native byte order to serialization byte order (which is little endian) 
     115 * 
     116 * \param value Value to convert 
     117 * \return Converted value 
     118 */ 
     119template <typename T, int cSIZE = sizeof(T)> 
     120inline T NativeToSerializationByteOrder(typename std::enable_if < cSIZE == 1 && std::is_integral<T>::value, T >::type value) 
     121{ 
     122  return value; 
     123} 
     124template <typename T, int cSIZE = sizeof(T)> 
     125inline T NativeToSerializationByteOrder(typename std::enable_if < cSIZE == 2 && std::is_integral<T>::value, T >::type value) 
     126{ 
     127#ifdef RRLIB_SERIALIZATION_BIG_ENDIAN_PLATFORM 
     128  union 
     129  { 
     130    uint16_t temp_int; 
     131    T temp_value; 
     132  }; 
     133  temp_value = value; 
     134  temp_int = __builtin_bswap16(temp_int); 
     135  return temp_value; 
     136#else 
     137  return value; 
     138#endif 
     139} 
     140template <typename T, int cSIZE = sizeof(T)> 
     141inline T NativeToSerializationByteOrder(typename std::enable_if < cSIZE == 4 && (std::is_integral<T>::value || std::is_floating_point<T>::value), T >::type value) 
     142{ 
     143#ifdef RRLIB_SERIALIZATION_BIG_ENDIAN_PLATFORM 
     144  union 
     145  { 
     146    uint32_t temp_int; 
     147    T temp_value; 
     148  }; 
     149  temp_value = value; 
     150  temp_int = __builtin_bswap32(temp_int); 
     151  return temp_value; 
     152#else 
     153  return value; 
     154#endif 
     155} 
     156template <typename T, int cSIZE = sizeof(T)> 
     157inline T NativeToSerializationByteOrder(typename std::enable_if < cSIZE == 8 && (std::is_integral<T>::value || std::is_floating_point<T>::value), T >::type value) 
     158{ 
     159#ifdef RRLIB_SERIALIZATION_BIG_ENDIAN_PLATFORM 
     160  union 
     161  { 
     162    uint64_t temp_int; 
     163    T temp_value; 
     164  }; 
     165  temp_value = value; 
     166  temp_int = __builtin_bswap64(temp_int); 
     167  return temp_value; 
     168#else 
     169  return value; 
     170#endif 
     171} 
     172 
     173 
     174/*! 
     175 * Converts integer value in serialization byte order (little endian) to platform native byte order 
     176 * 
     177 * \param value Value to convert 
     178 * \return Converted value 
     179 */ 
     180template <typename T> 
     181inline T SerializationToNativeByteOrder(T value) 
     182{ 
     183#ifdef RRLIB_SERIALIZATION_BIG_ENDIAN_PLATFORM 
     184  return NativeToSerializationByteOrder<T>(value); 
     185#else 
     186  return value; 
     187#endif 
     188} 
    108189 
    109190//---------------------------------------------------------------------- 
  • tInputStream.cpp

    r164 r187  
    191191} 
    192192 
    193 int8_t tInputStream::ReadByte() 
    194 { 
    195   EnsureAvailable(1u); 
    196   int8_t b = cur_buffer->buffer->GetByte(cur_buffer->position); 
    197   cur_buffer->position++; 
    198   return b; 
    199 } 
    200  
    201 double tInputStream::ReadDouble() 
    202 { 
    203   EnsureAvailable(8u); 
    204   double d = cur_buffer->buffer->GetDouble(cur_buffer->position); 
    205   cur_buffer->position += 8u; 
    206   return d; 
    207 } 
    208  
    209 float tInputStream::ReadFloat() 
    210 { 
    211   EnsureAvailable(4u); 
    212   float f = cur_buffer->buffer->GetFloat(cur_buffer->position); 
    213   cur_buffer->position += 4u; 
    214   return f; 
    215 } 
    216  
    217193void tInputStream::ReadFully(tFixedBuffer& bb, size_t off, size_t len) 
    218194{ 
  • tInputStream.h

    r172 r187  
    204204   * \return 8 bit integer 
    205205   */ 
    206   int8_t ReadByte(); 
     206  int8_t ReadByte() 
     207  { 
     208    return ReadNumber<int8_t>(); 
     209  } 
    207210 
    208211  /*! 
    209212   * \return 64 bit floating point 
    210213   */ 
    211   double ReadDouble(); 
     214  double ReadDouble() 
     215  { 
     216    return ReadNumber<double>(); 
     217  } 
    212218 
    213219  /*! 
     
    260266   * \return 32 bit floating point 
    261267   */ 
    262   float ReadFloat(); 
     268  float ReadFloat() 
     269  { 
     270    return ReadNumber<float>(); 
     271  } 
    263272 
    264273  /*! 
     
    321330    T t = cur_buffer->buffer->GetGeneric<T>(cur_buffer->position); 
    322331    cur_buffer->position += sizeof(T); 
    323  
    324 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 
    325     T tmp = t; 
    326     char* dest = reinterpret_cast<char*>(&t); 
    327     char* src = reinterpret_cast<char*>(&tmp); 
    328     src += sizeof(T); 
    329     for (size_t i = 0; i < sizeof(T); i++) 
    330     { 
    331       src--; 
    332       *dest = *src; 
    333       dest++; 
    334     } 
    335 #endif 
    336  
    337     return t; 
     332    return SerializationToNativeByteOrder<T>(t); 
    338333  } 
    339334 
  • tOutputStream.cpp

    r163 r187  
    171171  else 
    172172  { 
    173     buffer.buffer->PutInt(cur_skip_offset_placeholder, buffer.position - cur_skip_offset_placeholder - 4); 
     173    buffer.buffer->PutInt(cur_skip_offset_placeholder, NativeToSerializationByteOrder<uint>(buffer.position - cur_skip_offset_placeholder - 4)); 
    174174  } 
    175175  cur_skip_offset_placeholder = -1; 
  • tOutputStream.h

    r172 r187  
    359359  inline void WriteDouble(double v) 
    360360  { 
    361     EnsureAdditionalCapacity(8u); 
    362     buffer.buffer->PutDouble(buffer.position, v); 
    363     buffer.position += 8u; 
     361    WriteNumber<double>(v); 
    364362  } 
    365363 
     
    424422  inline void WriteFloat(float v) 
    425423  { 
    426     EnsureAdditionalCapacity(4u); 
    427     buffer.buffer->PutFloat(buffer.position, v); 
    428     buffer.position += 4u; 
     424    WriteNumber<float>(v); 
    429425  } 
    430426 
     
    454450  { 
    455451    EnsureAdditionalCapacity(sizeof(T)); 
    456  
    457 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 
    458     T tmp = t; 
    459     char* dest = reinterpret_cast<char*>(&t); 
    460     char* src = reinterpret_cast<char*>(&tmp); 
    461     src += sizeof(T); 
    462     for (size_t i = 0; i < sizeof(T); i++) 
    463     { 
    464       src--; 
    465       *dest = *src; 
    466       dest++; 
    467     } 
    468 #endif 
    469  
    470     buffer.buffer->PutGeneric<T>(buffer.position, t); 
     452    buffer.buffer->PutGeneric<T>(buffer.position, NativeToSerializationByteOrder<T>(t)); 
    471453    buffer.position += sizeof(T); 
    472454  } 
Note: See TracChangeset for help on using the changeset viewer.