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