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-12-17 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               1 : bool SerializationBuffer::GetUint8(uint8_t *value) {
     174               1 :   if (bytes_unread() < sizeof *value) {
     175               0 :     return false;
     176                 :   }
     177               1 :   *value = static_cast<uint8_t>(buffer_[read_ix_]);
     178               1 :   read_ix_ += sizeof *value;
     179               1 :   return true;
     180               1 : }
     181                 : 
     182               1 : bool SerializationBuffer::GetUint16(uint16_t *value) {
     183               1 :   if (bytes_unread() < sizeof *value) {
     184               0 :     return false;
     185                 :   }
     186                 :   *value = ((static_cast<uint16_t>(buffer_[read_ix_ + 0]) << 0) |
     187               1 :             (static_cast<uint16_t>(buffer_[read_ix_ + 1]) << 8));
     188               1 :   read_ix_ += sizeof *value;
     189               1 :   return true;
     190               1 : }
     191                 : 
     192               1 : bool SerializationBuffer::GetUint32(uint32_t *value) {
     193               1 :   if (bytes_unread() < sizeof *value) {
     194               0 :     return false;
     195                 :   }
     196                 :   *value = ((static_cast<uint32_t>(buffer_[read_ix_ + 0]) << 0) |
     197                 :             (static_cast<uint32_t>(buffer_[read_ix_ + 1]) << 8) |
     198                 :             (static_cast<uint32_t>(buffer_[read_ix_ + 2]) << 16) |
     199               1 :             (static_cast<uint32_t>(buffer_[read_ix_ + 3]) << 24));
     200               1 :   read_ix_ += sizeof *value;
     201               1 :   return true;
     202               1 : }
     203                 : 
     204               1 : bool SerializationBuffer::GetUint64(uint64_t *value) {
     205               1 :   if (bytes_unread() < sizeof *value) {
     206               0 :     return false;
     207                 :   }
     208                 :   *value = ((static_cast<uint64_t>(buffer_[read_ix_ + 0]) << 0) |
     209                 :             (static_cast<uint64_t>(buffer_[read_ix_ + 1]) << 8) |
     210                 :             (static_cast<uint64_t>(buffer_[read_ix_ + 2]) << 16) |
     211                 :             (static_cast<uint64_t>(buffer_[read_ix_ + 3]) << 24) |
     212                 :             (static_cast<uint64_t>(buffer_[read_ix_ + 4]) << 32) |
     213                 :             (static_cast<uint64_t>(buffer_[read_ix_ + 5]) << 40) |
     214                 :             (static_cast<uint64_t>(buffer_[read_ix_ + 6]) << 48) |
     215               1 :             (static_cast<uint64_t>(buffer_[read_ix_ + 7]) << 56));
     216               1 :   read_ix_ += sizeof *value;
     217               1 :   return true;
     218               1 : }
     219                 : 
     220                 : #if defined(NACL_HAS_IEEE_754)
     221                 : bool SerializationBuffer::GetFloat(float *value) {
     222                 :   union ieee754_float v;
     223                 :   uint32_t encoded = 0;
     224                 :   if (!GetUint32(&encoded)) {
     225                 :     return false;
     226                 :   }
     227                 :   v.ieee.negative = encoded >> 31;
     228                 :   v.ieee.exponent = encoded >> 23;
     229                 :   v.ieee.mantissa = encoded;
     230                 :   *value = v.f;
     231                 :   return true;
     232                 : }
     233                 : 
     234                 : bool SerializationBuffer::GetDouble(double *value) {
     235                 :   union ieee754_double v;
     236                 :   uint64_t encoded;
     237                 :   if (!GetUint64(&encoded)) {
     238                 :     return false;
     239                 :   }
     240                 :   v.ieee.negative = encoded >> 63;
     241                 :   v.ieee.exponent = encoded >> 52;
     242                 :   v.ieee.mantissa0 = encoded >> 32;
     243                 :   v.ieee.mantissa1 = encoded;
     244                 :   *value = v.d;
     245                 :   return true;
     246                 : }
     247                 : 
     248                 : bool SerializationBuffer::GetLongDouble(long double *value) {
     249                 :   union ieee854_long_double v;
     250                 :   uint16_t encoded1;
     251                 :   uint64_t encoded2;
     252                 :   if (in_use_ < read_ix_ + 10) {
     253                 :     return false;
     254                 :   }
     255                 :   if (!GetUint16(&encoded1) || !GetUint64(&encoded2)) {
     256                 :     return false;
     257                 :   }
     258                 :   v.ieee.negative = (encoded1 >> 15) & 1;
     259                 :   v.ieee.exponent = encoded1;
     260                 :   v.ieee.mantissa0 = encoded2 >> 32;
     261                 :   v.ieee.mantissa1 = encoded2;
     262                 :   *value = v.d;
     263                 :   return true;
     264                 : }
     265                 : #endif
     266                 : 
     267               1 : void SerializationBuffer::EnsureTotalSize(size_t req_size) {
     268               1 :   if (nbytes_ >= req_size) {
     269               1 :     return;
     270                 :   }
     271               1 :   size_t new_size = (0 == nbytes_) ? kInitialBufferSize : 2 * nbytes_;
     272               1 :   CHECK(new_size > nbytes_);  // no arithmetic overflow
     273               1 :   if (new_size < req_size) {
     274               1 :     new_size = req_size;
     275                 :   }
     276               1 :   buffer_.resize(new_size);
     277               1 :   nbytes_ = new_size;
     278               1 : }
     279                 : 
     280               1 : void SerializationBuffer::EnsureAvailableSpace(size_t req_space) {
     281               1 :   CHECK(nbytes_ >= in_use_);
     282               1 :   CHECK((~(size_t) 0) - in_use_ >= req_space);
     283               1 :   size_t new_size = in_use_ + req_space;
     284               1 :   EnsureTotalSize(new_size);
     285               1 : }
     286                 : 
     287                 : }  // namespace nacl

Generated by: LCOV version 1.7