Update To 11.40.268.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 bool SerializationBuffer::GetUint8(uint8_t *value) {
174   if (bytes_unread() < sizeof *value) {
175     return false;
176   }
177   *value = static_cast<uint8_t>(buffer_[read_ix_]);
178   read_ix_ += sizeof *value;
179   return true;
180 }
181
182 bool SerializationBuffer::GetUint16(uint16_t *value) {
183   if (bytes_unread() < sizeof *value) {
184     return false;
185   }
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;
189   return true;
190 }
191
192 bool SerializationBuffer::GetUint32(uint32_t *value) {
193   if (bytes_unread() < sizeof *value) {
194     return false;
195   }
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;
201   return true;
202 }
203
204 bool SerializationBuffer::GetUint64(uint64_t *value) {
205   if (bytes_unread() < sizeof *value) {
206     return false;
207   }
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;
217   return true;
218 }
219
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)) {
225     return false;
226   }
227   v.ieee.negative = encoded >> 31;
228   v.ieee.exponent = encoded >> 23;
229   v.ieee.mantissa = encoded;
230   *value = v.f;
231   return true;
232 }
233
234 bool SerializationBuffer::GetDouble(double *value) {
235   union ieee754_double v;
236   uint64_t encoded;
237   if (!GetUint64(&encoded)) {
238     return false;
239   }
240   v.ieee.negative = encoded >> 63;
241   v.ieee.exponent = encoded >> 52;
242   v.ieee.mantissa0 = encoded >> 32;
243   v.ieee.mantissa1 = encoded;
244   *value = v.d;
245   return true;
246 }
247
248 bool SerializationBuffer::GetLongDouble(long double *value) {
249   union ieee854_long_double v;
250   uint16_t encoded1;
251   uint64_t encoded2;
252   if (in_use_ < read_ix_ + 10) {
253     return false;
254   }
255   if (!GetUint16(&encoded1) || !GetUint64(&encoded2)) {
256     return false;
257   }
258   v.ieee.negative = (encoded1 >> 15) & 1;
259   v.ieee.exponent = encoded1;
260   v.ieee.mantissa0 = encoded2 >> 32;
261   v.ieee.mantissa1 = encoded2;
262   *value = v.d;
263   return true;
264 }
265 #endif
266
267 void SerializationBuffer::EnsureTotalSize(size_t req_size) {
268   if (nbytes_ >= req_size) {
269     return;
270   }
271   size_t new_size = (0 == nbytes_) ? kInitialBufferSize : 2 * nbytes_;
272   CHECK(new_size > nbytes_);  // no arithmetic overflow
273   if (new_size < req_size) {
274     new_size = req_size;
275   }
276   buffer_.resize(new_size);
277   nbytes_ = new_size;
278 }
279
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);
285 }
286
287 }  // namespace nacl