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.
8 #include "native_client/src/shared/serialization/serialization.h"
13 #include "native_client/src/shared/platform/nacl_check.h"
17 int const kInitialBufferSize = 256;
19 SerializationBuffer::SerializationBuffer()
25 SerializationBuffer::SerializationBuffer(uint8_t const *data_buffer,
27 : nbytes_(0) // EnsureTotalSize will update
30 EnsureTotalSize(nbytes);
31 memcpy(&buffer_[0], data_buffer, nbytes);
34 bool SerializationBuffer::Serialize(char const *cstr, size_t char_count) {
35 if (char_count > ~(uint32_t) 0) {
39 AddVal(static_cast<uint32_t>(char_count));
40 for (size_t ix = 0; ix < char_count; ++ix) {
41 AddVal<uint8_t>(cstr[ix]);
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);
51 bool SerializationBuffer::Serialize(std::string str) {
52 size_t bytes = str.size();
53 if (bytes > ~(uint32_t) 0) {
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]);
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) {
69 if (ReadTag() != SerializationTraits<char *>::kTag) {
74 if (!GetUint32(&char_count)) {
78 if (char_count > *buffer_size) {
79 *buffer_size = char_count;
81 return true; // true means check buffer_size!
83 for (size_t ix = 0; ix < char_count; ++ix) {
87 return false; // encoded data is garbled!
91 *buffer_size = char_count;
95 bool SerializationBuffer::Deserialize(char **cstr_out) {
97 char *buffer = new char[nbytes];
100 if (!Deserialize(buffer, &used)) {
106 buffer = new char[used];
107 CHECK(Deserialize(buffer, &used));
113 bool SerializationBuffer::Deserialize(std::string *str) {
114 size_t orig = cur_read_pos();
115 if (bytes_unread() < kTagBytes + SerializationTraits<uint32_t>::kBytes) {
118 if (ReadTag() != SerializationTraits<std::string>::kTag) {
119 reset_read_pos(orig);
123 if (!GetUint32(&bytes)) {
124 reset_read_pos(orig);
127 for (size_t ix = 0; ix < bytes; ++ix) {
130 reset_read_pos(orig);
138 void SerializationBuffer::AddUint8(uint8_t value) {
139 EnsureAvailableSpace(sizeof value);
140 buffer_[in_use_] = value;
141 in_use_ += sizeof value;
144 void SerializationBuffer::AddUint16(uint16_t value) {
145 EnsureAvailableSpace(sizeof value);
146 buffer_[in_use_ + 0] = static_cast<uint8_t>(value >> 0);
147 buffer_[in_use_ + 1] = static_cast<uint8_t>(value >> 8);
148 in_use_ += sizeof value;
151 void SerializationBuffer::AddUint32(uint32_t value) {
152 EnsureAvailableSpace(sizeof value);
153 buffer_[in_use_ + 0] = static_cast<uint8_t>(value >> 0);
154 buffer_[in_use_ + 1] = static_cast<uint8_t>(value >> 8);
155 buffer_[in_use_ + 2] = static_cast<uint8_t>(value >> 16);
156 buffer_[in_use_ + 3] = static_cast<uint8_t>(value >> 24);
157 in_use_ += sizeof value;
160 void SerializationBuffer::AddUint64(uint64_t value) {
161 EnsureAvailableSpace(sizeof value);
162 buffer_[in_use_ + 0] = static_cast<uint8_t>(value >> 0);
163 buffer_[in_use_ + 1] = static_cast<uint8_t>(value >> 8);
164 buffer_[in_use_ + 2] = static_cast<uint8_t>(value >> 16);
165 buffer_[in_use_ + 3] = static_cast<uint8_t>(value >> 24);
166 buffer_[in_use_ + 4] = static_cast<uint8_t>(value >> 32);
167 buffer_[in_use_ + 5] = static_cast<uint8_t>(value >> 40);
168 buffer_[in_use_ + 6] = static_cast<uint8_t>(value >> 48);
169 buffer_[in_use_ + 7] = static_cast<uint8_t>(value >> 56);
170 in_use_ += sizeof value;
173 bool SerializationBuffer::GetUint8(uint8_t *value) {
174 if (bytes_unread() < sizeof *value) {
177 *value = static_cast<uint8_t>(buffer_[read_ix_]);
178 read_ix_ += sizeof *value;
182 bool SerializationBuffer::GetUint16(uint16_t *value) {
183 if (bytes_unread() < sizeof *value) {
186 *value = ((static_cast<uint16_t>(buffer_[read_ix_ + 0]) << 0) |
187 (static_cast<uint16_t>(buffer_[read_ix_ + 1]) << 8));
188 read_ix_ += sizeof *value;
192 bool SerializationBuffer::GetUint32(uint32_t *value) {
193 if (bytes_unread() < sizeof *value) {
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 (static_cast<uint32_t>(buffer_[read_ix_ + 3]) << 24));
200 read_ix_ += sizeof *value;
204 bool SerializationBuffer::GetUint64(uint64_t *value) {
205 if (bytes_unread() < sizeof *value) {
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 (static_cast<uint64_t>(buffer_[read_ix_ + 7]) << 56));
216 read_ix_ += sizeof *value;
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)) {
227 v.ieee.negative = encoded >> 31;
228 v.ieee.exponent = encoded >> 23;
229 v.ieee.mantissa = encoded;
234 bool SerializationBuffer::GetDouble(double *value) {
235 union ieee754_double v;
237 if (!GetUint64(&encoded)) {
240 v.ieee.negative = encoded >> 63;
241 v.ieee.exponent = encoded >> 52;
242 v.ieee.mantissa0 = encoded >> 32;
243 v.ieee.mantissa1 = encoded;
248 bool SerializationBuffer::GetLongDouble(long double *value) {
249 union ieee854_long_double v;
252 if (in_use_ < read_ix_ + 10) {
255 if (!GetUint16(&encoded1) || !GetUint64(&encoded2)) {
258 v.ieee.negative = (encoded1 >> 15) & 1;
259 v.ieee.exponent = encoded1;
260 v.ieee.mantissa0 = encoded2 >> 32;
261 v.ieee.mantissa1 = encoded2;
267 void SerializationBuffer::EnsureTotalSize(size_t req_size) {
268 if (nbytes_ >= req_size) {
271 size_t new_size = (0 == nbytes_) ? kInitialBufferSize : 2 * nbytes_;
272 CHECK(new_size > nbytes_); // no arithmetic overflow
273 if (new_size < req_size) {
276 buffer_.resize(new_size);
280 void SerializationBuffer::EnsureAvailableSpace(size_t req_space) {
281 CHECK(nbytes_ >= in_use_);
282 CHECK((~(size_t) 0) - in_use_ >= req_space);
283 size_t new_size = in_use_ + req_space;
284 EnsureTotalSize(new_size);