LCOV - code coverage report
Current view: directory - src/shared/serialization - serialization.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 178 156 87.6 %
Date: 2014-06-18 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              51 :     , read_ix_(0) {}
      23                 : 
      24                 : 
      25               2 : SerializationBuffer::SerializationBuffer(uint8_t const *data_buffer,
      26               2 :                                          size_t nbytes)
      27                 :     : nbytes_(0)  // EnsureTotalSize will update
      28                 :     , in_use_(nbytes)
      29               2 :     , read_ix_(0) {
      30               1 :   EnsureTotalSize(nbytes);
      31               2 :   memcpy(&buffer_[0], data_buffer, nbytes);
      32               2 : }
      33                 : 
      34               2 : bool SerializationBuffer::Serialize(char const *cstr, size_t char_count) {
      35               2 :   if (char_count > ~(uint32_t) 0) {
      36               0 :     return false;
      37                 :   }
      38               2 :   AddTag<char *>();
      39               2 :   AddVal(static_cast<uint32_t>(char_count));
      40             842 :   for (size_t ix = 0; ix < char_count; ++ix) {
      41             419 :     AddVal<uint8_t>(cstr[ix]);
      42             419 :   }
      43               2 :   return true;
      44               2 : }
      45                 : 
      46               2 : bool SerializationBuffer::Serialize(char const *cstr) {
      47               2 :   size_t len = strlen(cstr) + 1;  // The ASCII character NUL is included
      48               2 :   return Serialize(cstr, len);
      49                 : }
      50                 : 
      51              31 : bool SerializationBuffer::Serialize(std::string str) {
      52              31 :   size_t bytes = str.size();
      53              31 :   if (bytes > ~(uint32_t) 0) {
      54               0 :     return false;
      55                 :   }
      56              31 :   AddTag<std::string>();
      57              31 :   AddVal(static_cast<uint32_t>(bytes));
      58            1788 :   for (size_t ix = 0; ix < bytes; ++ix) {
      59             863 :     AddVal<uint8_t>(str[ix]);
      60             863 :   }
      61              31 :   return true;
      62              31 : }
      63                 : 
      64               3 : bool SerializationBuffer::Deserialize(char *cstr, size_t *buffer_size) {
      65               3 :   size_t orig = cur_read_pos();
      66               3 :   if (bytes_unread() < kTagBytes + SerializationTraits<uint32_t>::kBytes) {
      67               0 :     return false;
      68                 :   }
      69               3 :   if (ReadTag() != SerializationTraits<char *>::kTag) {
      70               0 :     reset_read_pos(orig);
      71               0 :     return false;
      72                 :   }
      73               3 :   uint32_t char_count;
      74               3 :   if (!GetUint32(&char_count)) {
      75               0 :     reset_read_pos(orig);
      76               0 :     return false;
      77                 :   }
      78               3 :   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             842 :   for (size_t ix = 0; ix < char_count; ++ix) {
      84             419 :     uint8_t byte;
      85             419 :     if (!GetVal(&byte)) {
      86               0 :       reset_read_pos(orig);
      87               0 :       return false;  // encoded data is garbled!
      88                 :     }
      89             419 :     cstr[ix] = byte;
      90             419 :   }
      91               2 :   *buffer_size = char_count;
      92               2 :   return true;
      93               3 : }
      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               2 :     delete[] buffer;
     106               1 :     buffer = new char[used];
     107               3 :     CHECK(Deserialize(buffer, &used));
     108               1 :   }
     109               1 :   *cstr_out = buffer;
     110               1 :   return true;
     111               1 : }
     112                 : 
     113              15 : bool SerializationBuffer::Deserialize(std::string *str) {
     114              15 :   size_t orig = cur_read_pos();
     115              15 :   if (bytes_unread() < kTagBytes + SerializationTraits<uint32_t>::kBytes) {
     116               0 :     return false;
     117                 :   }
     118              15 :   if (ReadTag() != SerializationTraits<std::string>::kTag) {
     119               0 :     reset_read_pos(orig);
     120               0 :     return false;
     121                 :   }
     122              15 :   uint32_t bytes;
     123              15 :   if (!GetUint32(&bytes)) {
     124               0 :     reset_read_pos(orig);
     125               0 :     return false;
     126                 :   }
     127            1692 :   for (size_t ix = 0; ix < bytes; ++ix) {
     128             831 :     uint8_t b;
     129             831 :     if (!GetUint8(&b)) {
     130               0 :       reset_read_pos(orig);
     131               0 :       return false;
     132                 :     }
     133             831 :     str->push_back(b);
     134             831 :   }
     135              15 :   return true;
     136              15 : }
     137                 : 
     138            1396 : void SerializationBuffer::AddUint8(uint8_t value) {
     139            1396 :   EnsureAvailableSpace(sizeof value);
     140            1396 :   buffer_[in_use_] = value;
     141            1396 :   in_use_ += sizeof value;
     142            1396 : }
     143                 : 
     144               5 : void SerializationBuffer::AddUint16(uint16_t value) {
     145               5 :   EnsureAvailableSpace(sizeof value);
     146               5 :   buffer_[in_use_ + 0] = static_cast<uint8_t>(value >> 0);
     147               5 :   buffer_[in_use_ + 1] = static_cast<uint8_t>(value >> 8);
     148               5 :   in_use_ += sizeof value;
     149               5 : }
     150                 : 
     151             148 : void SerializationBuffer::AddUint32(uint32_t value) {
     152             148 :   EnsureAvailableSpace(sizeof value);
     153             148 :   buffer_[in_use_ + 0] = static_cast<uint8_t>(value >> 0);
     154             148 :   buffer_[in_use_ + 1] = static_cast<uint8_t>(value >> 8);
     155             148 :   buffer_[in_use_ + 2] = static_cast<uint8_t>(value >> 16);
     156             148 :   buffer_[in_use_ + 3] = static_cast<uint8_t>(value >> 24);
     157             148 :   in_use_ += sizeof value;
     158             148 : }
     159                 : 
     160               4 : void SerializationBuffer::AddUint64(uint64_t value) {
     161               4 :   EnsureAvailableSpace(sizeof value);
     162               4 :   buffer_[in_use_ + 0] = static_cast<uint8_t>(value >> 0);
     163               4 :   buffer_[in_use_ + 1] = static_cast<uint8_t>(value >> 8);
     164               4 :   buffer_[in_use_ + 2] = static_cast<uint8_t>(value >> 16);
     165               4 :   buffer_[in_use_ + 3] = static_cast<uint8_t>(value >> 24);
     166               4 :   buffer_[in_use_ + 4] = static_cast<uint8_t>(value >> 32);
     167               4 :   buffer_[in_use_ + 5] = static_cast<uint8_t>(value >> 40);
     168               4 :   buffer_[in_use_ + 6] = static_cast<uint8_t>(value >> 48);
     169               4 :   buffer_[in_use_ + 7] = static_cast<uint8_t>(value >> 56);
     170               4 :   in_use_ += sizeof value;
     171               4 : }
     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            1256 : bool SerializationBuffer::GetUint8(uint8_t *value) {
     202            1256 :   if (bytes_unread() < sizeof *value) {
     203               0 :     return false;
     204                 :   }
     205            1256 :   *value = static_cast<uint8_t>(buffer_[read_ix_]);
     206            1256 :   read_ix_ += sizeof *value;
     207            1256 :   return true;
     208            1256 : }
     209                 : 
     210               8 : bool SerializationBuffer::GetUint16(uint16_t *value) {
     211               8 :   if (bytes_unread() < sizeof *value) {
     212               0 :     return false;
     213                 :   }
     214               8 :   *value = ((static_cast<uint16_t>(buffer_[read_ix_ + 0]) << 0) |
     215               8 :             (static_cast<uint16_t>(buffer_[read_ix_ + 1]) << 8));
     216               8 :   read_ix_ += sizeof *value;
     217               8 :   return true;
     218               8 : }
     219                 : 
     220              34 : bool SerializationBuffer::GetUint32(uint32_t *value) {
     221              34 :   if (bytes_unread() < sizeof *value) {
     222               0 :     return false;
     223                 :   }
     224              34 :   *value = ((static_cast<uint32_t>(buffer_[read_ix_ + 0]) << 0) |
     225              34 :             (static_cast<uint32_t>(buffer_[read_ix_ + 1]) << 8) |
     226              34 :             (static_cast<uint32_t>(buffer_[read_ix_ + 2]) << 16) |
     227              34 :             (static_cast<uint32_t>(buffer_[read_ix_ + 3]) << 24));
     228              34 :   read_ix_ += sizeof *value;
     229              34 :   return true;
     230              34 : }
     231                 : 
     232               6 : bool SerializationBuffer::GetUint64(uint64_t *value) {
     233               6 :   if (bytes_unread() < sizeof *value) {
     234               0 :     return false;
     235                 :   }
     236               6 :   *value = ((static_cast<uint64_t>(buffer_[read_ix_ + 0]) << 0) |
     237               6 :             (static_cast<uint64_t>(buffer_[read_ix_ + 1]) << 8) |
     238               6 :             (static_cast<uint64_t>(buffer_[read_ix_ + 2]) << 16) |
     239               6 :             (static_cast<uint64_t>(buffer_[read_ix_ + 3]) << 24) |
     240               6 :             (static_cast<uint64_t>(buffer_[read_ix_ + 4]) << 32) |
     241               6 :             (static_cast<uint64_t>(buffer_[read_ix_ + 5]) << 40) |
     242               6 :             (static_cast<uint64_t>(buffer_[read_ix_ + 6]) << 48) |
     243               6 :             (static_cast<uint64_t>(buffer_[read_ix_ + 7]) << 56));
     244               6 :   read_ix_ += sizeof *value;
     245               6 :   return true;
     246               6 : }
     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            1554 : void SerializationBuffer::EnsureTotalSize(size_t req_size) {
     296            1554 :   if (nbytes_ >= req_size) {
     297            1528 :     return;
     298                 :   }
     299              78 :   size_t new_size = (0 == nbytes_) ? kInitialBufferSize : 2 * nbytes_;
     300              78 :   CHECK(new_size > nbytes_);  // no arithmetic overflow
     301              26 :   if (new_size < req_size) {
     302               1 :     new_size = req_size;
     303               1 :   }
     304              26 :   buffer_.resize(new_size);
     305              26 :   nbytes_ = new_size;
     306            1580 : }
     307                 : 
     308            1553 : void SerializationBuffer::EnsureAvailableSpace(size_t req_space) {
     309            4659 :   CHECK(nbytes_ >= in_use_);
     310            4659 :   CHECK((~(size_t) 0) - in_use_ >= req_space);
     311            1553 :   size_t new_size = in_use_ + req_space;
     312            1553 :   EnsureTotalSize(new_size);
     313            1553 : }
     314                 : 
     315                 : }  // namespace nacl

Generated by: LCOV version 1.7