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