Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / native_client / src / shared / serialization / serialization.cc
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     delete[] buffer;
102     return false;
103   }
104   if (used > nbytes) {
105     delete[] buffer;
106     buffer = new char[used];
107     CHECK(Deserialize(buffer, &used));
108   }
109   *cstr_out = buffer;
110   return true;
111 }
112
113 bool SerializationBuffer::Deserialize(std::string *str) {
114   size_t orig = cur_read_pos();
115   if (bytes_unread() < kTagBytes + SerializationTraits<uint32_t>::kBytes) {
116     return false;
117   }
118   if (ReadTag() != SerializationTraits<std::string>::kTag) {
119     reset_read_pos(orig);
120     return false;
121   }
122   uint32_t bytes;
123   if (!GetUint32(&bytes)) {
124     reset_read_pos(orig);
125     return false;
126   }
127   for (size_t ix = 0; ix < bytes; ++ix) {
128     uint8_t b;
129     if (!GetUint8(&b)) {
130       reset_read_pos(orig);
131       return false;
132     }
133     str->push_back(b);
134   }
135   return true;
136 }
137
138 void SerializationBuffer::AddUint8(uint8_t value) {
139   EnsureAvailableSpace(sizeof value);
140   buffer_[in_use_] = value;
141   in_use_ += sizeof value;
142 }
143
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;
149 }
150
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;
158 }
159
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;
171 }
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 bool SerializationBuffer::GetUint8(uint8_t *value) {
202   if (bytes_unread() < sizeof *value) {
203     return false;
204   }
205   *value = static_cast<uint8_t>(buffer_[read_ix_]);
206   read_ix_ += sizeof *value;
207   return true;
208 }
209
210 bool SerializationBuffer::GetUint16(uint16_t *value) {
211   if (bytes_unread() < sizeof *value) {
212     return false;
213   }
214   *value = ((static_cast<uint16_t>(buffer_[read_ix_ + 0]) << 0) |
215             (static_cast<uint16_t>(buffer_[read_ix_ + 1]) << 8));
216   read_ix_ += sizeof *value;
217   return true;
218 }
219
220 bool SerializationBuffer::GetUint32(uint32_t *value) {
221   if (bytes_unread() < sizeof *value) {
222     return false;
223   }
224   *value = ((static_cast<uint32_t>(buffer_[read_ix_ + 0]) << 0) |
225             (static_cast<uint32_t>(buffer_[read_ix_ + 1]) << 8) |
226             (static_cast<uint32_t>(buffer_[read_ix_ + 2]) << 16) |
227             (static_cast<uint32_t>(buffer_[read_ix_ + 3]) << 24));
228   read_ix_ += sizeof *value;
229   return true;
230 }
231
232 bool SerializationBuffer::GetUint64(uint64_t *value) {
233   if (bytes_unread() < sizeof *value) {
234     return false;
235   }
236   *value = ((static_cast<uint64_t>(buffer_[read_ix_ + 0]) << 0) |
237             (static_cast<uint64_t>(buffer_[read_ix_ + 1]) << 8) |
238             (static_cast<uint64_t>(buffer_[read_ix_ + 2]) << 16) |
239             (static_cast<uint64_t>(buffer_[read_ix_ + 3]) << 24) |
240             (static_cast<uint64_t>(buffer_[read_ix_ + 4]) << 32) |
241             (static_cast<uint64_t>(buffer_[read_ix_ + 5]) << 40) |
242             (static_cast<uint64_t>(buffer_[read_ix_ + 6]) << 48) |
243             (static_cast<uint64_t>(buffer_[read_ix_ + 7]) << 56));
244   read_ix_ += sizeof *value;
245   return true;
246 }
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 void SerializationBuffer::EnsureTotalSize(size_t req_size) {
296   if (nbytes_ >= req_size) {
297     return;
298   }
299   size_t new_size = (0 == nbytes_) ? kInitialBufferSize : 2 * nbytes_;
300   CHECK(new_size > nbytes_);  // no arithmetic overflow
301   if (new_size < req_size) {
302     new_size = req_size;
303   }
304   buffer_.resize(new_size);
305   nbytes_ = new_size;
306 }
307
308 void SerializationBuffer::EnsureAvailableSpace(size_t req_space) {
309   CHECK(nbytes_ >= in_use_);
310   CHECK((~(size_t) 0) - in_use_ >= req_space);
311   size_t new_size = in_use_ + req_space;
312   EnsureTotalSize(new_size);
313 }
314
315 }  // namespace nacl