LCOV - code coverage report
Current view: directory - src/shared/serialization - serialization.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 160 138 86.2 %
Date: 2014-09-25 Functions: 0 0 -

       1                 : /* -*- c++ -*- */
       2                 : /*
       3                 :  * Copyright (c) 2013 The Native Client Authors. All rights reserved.
       4                 :  * Use of this source code is governed by a BSD-style license that can be
       5                 :  * found in the LICENSE file.
       6                 :  */
       7                 : 
       8                 : #include "native_client/src/shared/serialization/serialization.h"
       9                 : 
      10                 : #include <stdio.h>
      11                 : #include <string.h>
      12                 : 
      13                 : #include "native_client/src/shared/platform/nacl_check.h"
      14                 : 
      15                 : namespace nacl {
      16                 : 
      17                 : int const kInitialBufferSize = 256;
      18                 : 
      19                 : SerializationBuffer::SerializationBuffer()
      20                 :     : nbytes_(0)
      21                 :     , in_use_(0)
      22               1 :     , read_ix_(0) {}
      23                 : 
      24                 : 
      25                 : SerializationBuffer::SerializationBuffer(uint8_t const *data_buffer,
      26                 :                                          size_t nbytes)
      27                 :     : nbytes_(0)  // EnsureTotalSize will update
      28                 :     , in_use_(nbytes)
      29               1 :     , read_ix_(0) {
      30               1 :   EnsureTotalSize(nbytes);
      31               1 :   memcpy(&buffer_[0], data_buffer, nbytes);
      32               1 : }
      33                 : 
      34               1 : bool SerializationBuffer::Serialize(char const *cstr, size_t char_count) {
      35               1 :   if (char_count > ~(uint32_t) 0) {
      36               0 :     return false;
      37                 :   }
      38               1 :   AddTag<char *>();
      39               1 :   AddVal(static_cast<uint32_t>(char_count));
      40               1 :   for (size_t ix = 0; ix < char_count; ++ix) {
      41               1 :     AddVal<uint8_t>(cstr[ix]);
      42               1 :   }
      43               1 :   return true;
      44               1 : }
      45                 : 
      46               1 : bool SerializationBuffer::Serialize(char const *cstr) {
      47               1 :   size_t len = strlen(cstr) + 1;  // The ASCII character NUL is included
      48               1 :   return Serialize(cstr, len);
      49               1 : }
      50                 : 
      51               1 : bool SerializationBuffer::Serialize(std::string str) {
      52               1 :   size_t bytes = str.size();
      53               1 :   if (bytes > ~(uint32_t) 0) {
      54               0 :     return false;
      55                 :   }
      56               1 :   AddTag<std::string>();
      57               1 :   AddVal(static_cast<uint32_t>(bytes));
      58               1 :   for (size_t ix = 0; ix < bytes; ++ix) {
      59               1 :     AddVal<uint8_t>(str[ix]);
      60               1 :   }
      61               1 :   return true;
      62               1 : }
      63                 : 
      64               1 : bool SerializationBuffer::Deserialize(char *cstr, size_t *buffer_size) {
      65               1 :   size_t orig = cur_read_pos();
      66               1 :   if (bytes_unread() < kTagBytes + SerializationTraits<uint32_t>::kBytes) {
      67               0 :     return false;
      68                 :   }
      69               1 :   if (ReadTag() != SerializationTraits<char *>::kTag) {
      70               0 :     reset_read_pos(orig);
      71               0 :     return false;
      72                 :   }
      73                 :   uint32_t char_count;
      74               1 :   if (!GetUint32(&char_count)) {
      75               0 :     reset_read_pos(orig);
      76               0 :     return false;
      77                 :   }
      78               1 :   if (char_count > *buffer_size) {
      79               1 :     *buffer_size = char_count;
      80               1 :     reset_read_pos(orig);
      81               1 :     return true;  // true means check buffer_size!
      82                 :   }
      83               1 :   for (size_t ix = 0; ix < char_count; ++ix) {
      84                 :     uint8_t byte;
      85               1 :     if (!GetVal(&byte)) {
      86               0 :       reset_read_pos(orig);
      87               0 :       return false;  // encoded data is garbled!
      88                 :     }
      89               1 :     cstr[ix] = byte;
      90               1 :   }
      91               1 :   *buffer_size = char_count;
      92               1 :   return true;
      93               1 : }
      94                 : 
      95               1 : bool SerializationBuffer::Deserialize(char **cstr_out) {
      96               1 :   size_t nbytes = 256;
      97               1 :   char *buffer = new char[nbytes];
      98                 : 
      99               1 :   size_t used = nbytes;
     100               1 :   if (!Deserialize(buffer, &used)) {
     101               0 :     delete[] buffer;
     102               0 :     return false;
     103                 :   }
     104               1 :   if (used > nbytes) {
     105               1 :     delete[] buffer;
     106               1 :     buffer = new char[used];
     107               1 :     CHECK(Deserialize(buffer, &used));
     108                 :   }
     109               1 :   *cstr_out = buffer;
     110               1 :   return true;
     111               1 : }
     112                 : 
     113               1 : bool SerializationBuffer::Deserialize(std::string *str) {
     114               1 :   size_t orig = cur_read_pos();
     115               1 :   if (bytes_unread() < kTagBytes + SerializationTraits<uint32_t>::kBytes) {
     116               0 :     return false;
     117                 :   }
     118               1 :   if (ReadTag() != SerializationTraits<std::string>::kTag) {
     119               0 :     reset_read_pos(orig);
     120               0 :     return false;
     121                 :   }
     122                 :   uint32_t bytes;
     123               1 :   if (!GetUint32(&bytes)) {
     124               0 :     reset_read_pos(orig);
     125               0 :     return false;
     126                 :   }
     127               1 :   for (size_t ix = 0; ix < bytes; ++ix) {
     128                 :     uint8_t b;
     129               1 :     if (!GetUint8(&b)) {
     130               0 :       reset_read_pos(orig);
     131               0 :       return false;
     132                 :     }
     133               1 :     str->push_back(b);
     134               1 :   }
     135               1 :   return true;
     136               1 : }
     137                 : 
     138               1 : void SerializationBuffer::AddUint8(uint8_t value) {
     139               1 :   EnsureAvailableSpace(sizeof value);
     140               1 :   buffer_[in_use_] = value;
     141               1 :   in_use_ += sizeof value;
     142               1 : }
     143                 : 
     144               1 : void SerializationBuffer::AddUint16(uint16_t value) {
     145               1 :   EnsureAvailableSpace(sizeof value);
     146               1 :   buffer_[in_use_ + 0] = static_cast<uint8_t>(value >> 0);
     147               1 :   buffer_[in_use_ + 1] = static_cast<uint8_t>(value >> 8);
     148               1 :   in_use_ += sizeof value;
     149               1 : }
     150                 : 
     151               1 : void SerializationBuffer::AddUint32(uint32_t value) {
     152               1 :   EnsureAvailableSpace(sizeof value);
     153               1 :   buffer_[in_use_ + 0] = static_cast<uint8_t>(value >> 0);
     154               1 :   buffer_[in_use_ + 1] = static_cast<uint8_t>(value >> 8);
     155               1 :   buffer_[in_use_ + 2] = static_cast<uint8_t>(value >> 16);
     156               1 :   buffer_[in_use_ + 3] = static_cast<uint8_t>(value >> 24);
     157               1 :   in_use_ += sizeof value;
     158               1 : }
     159                 : 
     160               1 : void SerializationBuffer::AddUint64(uint64_t value) {
     161               1 :   EnsureAvailableSpace(sizeof value);
     162               1 :   buffer_[in_use_ + 0] = static_cast<uint8_t>(value >> 0);
     163               1 :   buffer_[in_use_ + 1] = static_cast<uint8_t>(value >> 8);
     164               1 :   buffer_[in_use_ + 2] = static_cast<uint8_t>(value >> 16);
     165               1 :   buffer_[in_use_ + 3] = static_cast<uint8_t>(value >> 24);
     166               1 :   buffer_[in_use_ + 4] = static_cast<uint8_t>(value >> 32);
     167               1 :   buffer_[in_use_ + 5] = static_cast<uint8_t>(value >> 40);
     168               1 :   buffer_[in_use_ + 6] = static_cast<uint8_t>(value >> 48);
     169               1 :   buffer_[in_use_ + 7] = static_cast<uint8_t>(value >> 56);
     170               1 :   in_use_ += sizeof value;
     171               1 : }
     172                 : 
     173                 : #if defined(NACL_HAS_IEEE_754)
     174                 : void SerializationBuffer::AddFloat(float value) {
     175                 :   union ieee754_float v;
     176                 :   v.f = value;
     177                 :   AddUint32((static_cast<uint32_t>(v.ieee.negative) << 31) |
     178                 :             (static_cast<uint32_t>(v.ieee.exponent) << 23) |
     179                 :             (static_cast<uint32_t>(v.ieee.mantissa) << 0));
     180                 : }
     181                 : 
     182                 : void SerializationBuffer::AddDouble(double value) {
     183                 :   union ieee754_double v;
     184                 :   v.d = value;
     185                 :   AddUint64((static_cast<uint64_t>(v.ieee.negative) << 63) |
     186                 :             (static_cast<uint64_t>(v.ieee.exponent) << 52) |
     187                 :             (static_cast<uint64_t>(v.ieee.mantissa0) << 32) |
     188                 :             (static_cast<uint64_t>(v.ieee.mantissa1) << 0));
     189                 : }
     190                 : 
     191                 : void SerializationBuffer::AddLongDouble(long double value) {
     192                 :   union ieee854_long_double v;
     193                 :   v.d = value;
     194                 :   AddUint16((static_cast<uint16_t>(v.ieee.negative) << 15) |
     195                 :             (static_cast<uint16_t>(v.ieee.exponent) << 0));
     196                 :   AddUint64((static_cast<uint64_t>(v.ieee.mantissa0) << 32) |
     197                 :             (static_cast<uint64_t>(v.ieee.mantissa1) << 0));
     198                 : }
     199                 : #endif
     200                 : 
     201               1 : bool SerializationBuffer::GetUint8(uint8_t *value) {
     202               1 :   if (bytes_unread() < sizeof *value) {
     203               0 :     return false;
     204                 :   }
     205               1 :   *value = static_cast<uint8_t>(buffer_[read_ix_]);
     206               1 :   read_ix_ += sizeof *value;
     207               1 :   return true;
     208               1 : }
     209                 : 
     210               1 : bool SerializationBuffer::GetUint16(uint16_t *value) {
     211               1 :   if (bytes_unread() < sizeof *value) {
     212               0 :     return false;
     213                 :   }
     214                 :   *value = ((static_cast<uint16_t>(buffer_[read_ix_ + 0]) << 0) |
     215               1 :             (static_cast<uint16_t>(buffer_[read_ix_ + 1]) << 8));
     216               1 :   read_ix_ += sizeof *value;
     217               1 :   return true;
     218               1 : }
     219                 : 
     220               1 : bool SerializationBuffer::GetUint32(uint32_t *value) {
     221               1 :   if (bytes_unread() < sizeof *value) {
     222               0 :     return false;
     223                 :   }
     224                 :   *value = ((static_cast<uint32_t>(buffer_[read_ix_ + 0]) << 0) |
     225                 :             (static_cast<uint32_t>(buffer_[read_ix_ + 1]) << 8) |
     226                 :             (static_cast<uint32_t>(buffer_[read_ix_ + 2]) << 16) |
     227               1 :             (static_cast<uint32_t>(buffer_[read_ix_ + 3]) << 24));
     228               1 :   read_ix_ += sizeof *value;
     229               1 :   return true;
     230               1 : }
     231                 : 
     232               1 : bool SerializationBuffer::GetUint64(uint64_t *value) {
     233               1 :   if (bytes_unread() < sizeof *value) {
     234               0 :     return false;
     235                 :   }
     236                 :   *value = ((static_cast<uint64_t>(buffer_[read_ix_ + 0]) << 0) |
     237                 :             (static_cast<uint64_t>(buffer_[read_ix_ + 1]) << 8) |
     238                 :             (static_cast<uint64_t>(buffer_[read_ix_ + 2]) << 16) |
     239                 :             (static_cast<uint64_t>(buffer_[read_ix_ + 3]) << 24) |
     240                 :             (static_cast<uint64_t>(buffer_[read_ix_ + 4]) << 32) |
     241                 :             (static_cast<uint64_t>(buffer_[read_ix_ + 5]) << 40) |
     242                 :             (static_cast<uint64_t>(buffer_[read_ix_ + 6]) << 48) |
     243               1 :             (static_cast<uint64_t>(buffer_[read_ix_ + 7]) << 56));
     244               1 :   read_ix_ += sizeof *value;
     245               1 :   return true;
     246               1 : }
     247                 : 
     248                 : #if defined(NACL_HAS_IEEE_754)
     249                 : bool SerializationBuffer::GetFloat(float *value) {
     250                 :   union ieee754_float v;
     251                 :   uint32_t encoded = 0;
     252                 :   if (!GetUint32(&encoded)) {
     253                 :     return false;
     254                 :   }
     255                 :   v.ieee.negative = encoded >> 31;
     256                 :   v.ieee.exponent = encoded >> 23;
     257                 :   v.ieee.mantissa = encoded;
     258                 :   *value = v.f;
     259                 :   return true;
     260                 : }
     261                 : 
     262                 : bool SerializationBuffer::GetDouble(double *value) {
     263                 :   union ieee754_double v;
     264                 :   uint64_t encoded;
     265                 :   if (!GetUint64(&encoded)) {
     266                 :     return false;
     267                 :   }
     268                 :   v.ieee.negative = encoded >> 63;
     269                 :   v.ieee.exponent = encoded >> 52;
     270                 :   v.ieee.mantissa0 = encoded >> 32;
     271                 :   v.ieee.mantissa1 = encoded;
     272                 :   *value = v.d;
     273                 :   return true;
     274                 : }
     275                 : 
     276                 : bool SerializationBuffer::GetLongDouble(long double *value) {
     277                 :   union ieee854_long_double v;
     278                 :   uint16_t encoded1;
     279                 :   uint64_t encoded2;
     280                 :   if (in_use_ < read_ix_ + 10) {
     281                 :     return false;
     282                 :   }
     283                 :   if (!GetUint16(&encoded1) || !GetUint64(&encoded2)) {
     284                 :     return false;
     285                 :   }
     286                 :   v.ieee.negative = (encoded1 >> 15) & 1;
     287                 :   v.ieee.exponent = encoded1;
     288                 :   v.ieee.mantissa0 = encoded2 >> 32;
     289                 :   v.ieee.mantissa1 = encoded2;
     290                 :   *value = v.d;
     291                 :   return true;
     292                 : }
     293                 : #endif
     294                 : 
     295               1 : void SerializationBuffer::EnsureTotalSize(size_t req_size) {
     296               1 :   if (nbytes_ >= req_size) {
     297               1 :     return;
     298                 :   }
     299               1 :   size_t new_size = (0 == nbytes_) ? kInitialBufferSize : 2 * nbytes_;
     300               1 :   CHECK(new_size > nbytes_);  // no arithmetic overflow
     301               1 :   if (new_size < req_size) {
     302               1 :     new_size = req_size;
     303                 :   }
     304               1 :   buffer_.resize(new_size);
     305               1 :   nbytes_ = new_size;
     306               1 : }
     307                 : 
     308               1 : void SerializationBuffer::EnsureAvailableSpace(size_t req_space) {
     309               1 :   CHECK(nbytes_ >= in_use_);
     310               1 :   CHECK((~(size_t) 0) - in_use_ >= req_space);
     311               1 :   size_t new_size = in_use_ + req_space;
     312               1 :   EnsureTotalSize(new_size);
     313               1 : }
     314                 : 
     315                 : }  // namespace nacl

Generated by: LCOV version 1.7