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

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: fixed conditional compilation control for fp support 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
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 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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698