Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: src/shared/serialization/serialization.cc

Issue 12316093: Serialization library. Useful for sending more complex data in RPCs. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: added missing NACL_WUR and CHECKs detected by clang Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/shared/serialization/serialization.h ('k') | src/shared/serialization/serialization.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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
OLDNEW
« no previous file with comments | « src/shared/serialization/serialization.h ('k') | src/shared/serialization/serialization.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698