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

Side by Side Diff: base/serializable_object.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 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
« no previous file with comments | « base/serializable_object.h ('k') | base/serializable_object_unittest.cc » ('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 // Copyright 2005-2009 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15 //
16 // Provides the base class framework for those objects to be serialized
17 //
18 // HACK:
19 //
20 // During the serialization/deserialization of vector<T> members, we
21 // coerce the type from vector<T> to vector<byte> since we are unable to
22 // get the real type vector<T> at later time. This is feasible because
23 // vector<T> in the vector library we are linking now keeps track of
24 // only front() and end() pointers and use them to calculate size().
25 // We need to check whether this approach is still OK if we upgrade the
26 // standard libraries.
27
28 #include "omaha/base/serializable_object.h"
29 #include "omaha/base/debug.h"
30 #include "omaha/base/logging.h"
31
32 namespace omaha {
33
34 // Serialize
35 bool SerializableObject::Serialize(std::vector<byte>* data) const {
36 ASSERT(data, (_T("")));
37
38 // Estimate how much memory we need
39 int size = data->size();
40 for (size_t i = 0; i < members_.size(); ++i)
41 size += (members_[i].size > 0) ? members_[i].size : sizeof(int);
42
43 // Reserve the estimated size fo vector memory
44 data->reserve(size);
45
46 // Copy over the data
47 for (size_t i = 0; i < members_.size(); ++i) {
48 switch (members_[i].type) {
49 case SERIALIZABLE_VALUE_TYPE: {
50 int pos = data->size();
51 data->resize(data->size() + members_[i].size);
52 memcpy(&(*data)[pos], members_[i].ptr, members_[i].size);
53 break;
54 }
55
56 case SERIALIZABLE_CSTRING: {
57 CString* s = reinterpret_cast<CString*>(members_[i].ptr);
58 SerializeValueList(data,
59 reinterpret_cast<const byte*>(s->GetString()),
60 sizeof(TCHAR),
61 s->GetLength());
62 break;
63 }
64
65 case SERIALIZABLE_NESTED_OBJECT: {
66 SerializableObject* nested_obj =
67 reinterpret_cast<SerializableObject*>(members_[i].ptr);
68 if (!nested_obj->Serialize(data))
69 return false;
70 break;
71 }
72
73 case SERIALIZABLE_VECTOR | SERIALIZABLE_VALUE_TYPE: {
74 // Hack: coerce vector<T> to vector<byte>
75 std::vector<byte>* v =
76 reinterpret_cast<std::vector<byte>*>(members_[i].ptr);
77 if (v->size() != 0) {
78 SerializeValueList(data,
79 &v->front(),
80 members_[i].size,
81 v->size() / members_[i].size);
82 } else {
83 SerializeValueList(data,
84 NULL,
85 members_[i].size,
86 v->size() / members_[i].size);
87 }
88 break;
89 }
90
91 case SERIALIZABLE_VECTOR | SERIALIZABLE_CSTRING: {
92 std::vector<CString>* v =
93 reinterpret_cast<std::vector<CString>*>(members_[i].ptr);
94 SerializeSizeAndCount(data, 1, v->size());
95 if (!v->empty()) {
96 for (std::vector<CString>::const_iterator it = v->begin();
97 it != v->end();
98 ++it) {
99 SerializeValueList(data,
100 reinterpret_cast<const byte*>(it->GetString()),
101 sizeof(TCHAR),
102 it->GetLength());
103 }
104 }
105 break;
106 }
107
108 case SERIALIZABLE_VECTOR | SERIALIZABLE_NESTED_OBJECT: {
109 if (!SerializeVectorNestedObject(data, members_[i].ptr))
110 return false;
111 break;
112 }
113
114 default:
115 ASSERT(false, (_T("")));
116 return false;
117 }
118 }
119
120 return true;
121 }
122
123 // Serialize the size and count values
124 void SerializableObject::SerializeSizeAndCount(std::vector<byte>* data,
125 int size,
126 int count) const {
127 ASSERT(data, (_T("")));
128 ASSERT(size >= 0, (_T("")));
129
130 // Get current size
131 int pos = data->size();
132
133 // Adjust the size of the data buffer
134 data->resize(data->size() + 2 * sizeof(int));
135
136 // Get pointer to the position of data buffer we start to write
137 byte* ptr = &((*data)[pos]);
138
139 // Push size
140 memcpy(ptr, &size, sizeof(int));
141 ptr += sizeof(int);
142
143 // Push count
144 memcpy(ptr, &count, sizeof(int));
145 ptr += sizeof(int);
146 }
147
148 // Serialize a list of value-typed elements
149 //
150 // Args:
151 // ser_data: pointer to the vector for the serialized data
152 // raw_data: pointer to the raw data to be serialized
153 // size: the size of the element in the list
154 // count: the number of the elements in the list
155 void SerializableObject::SerializeValueList(std::vector<byte>* ser_data,
156 const byte* raw_data,
157 int size,
158 int count) const {
159 ASSERT(ser_data, (_T("")));
160 ASSERT(size > 0, (_T("")));
161
162 // Serialize the size and count values
163 SerializeSizeAndCount(ser_data, size, count);
164
165 // Push data
166 if (count > 0) {
167 // Get current size
168 int pos = ser_data->size();
169
170 // Adjust the size of the data buffer
171 ser_data->resize(ser_data->size() + count * size);
172
173 // Get pointer to the position of data buffer we start to write
174 byte* ptr = &((*ser_data)[pos]);
175
176 // Copy data
177 memcpy(ptr, raw_data, count * size);
178 }
179 }
180
181 // Deserialize
182 bool SerializableObject::Deserialize(byte* data, int size, uint32 version) {
183 ASSERT(data, (_T("")));
184 ASSERT(size > 0, (_T("")));
185
186 byte* tail = data + size;
187 byte** data_ptr = &data;
188 if (!DeserializeHelper(data_ptr, size, version))
189 return false;
190
191 if (*data_ptr != tail) {
192 UTIL_LOG(LE, (_T("[SerializableObject::Deserialize]")
193 _T("[failed to deserialize all data]")));
194 return false;
195 }
196
197 return true;
198 }
199
200 // Deserialize helper
201 bool SerializableObject::DeserializeHelper(byte** data,
202 int size,
203 uint32 version) {
204 ASSERT(data, (_T("")));
205 ASSERT(size > 0, (_T("")));
206
207 byte* tail = *data + size;
208
209 for (size_t i = 0; i < members_.size(); ++i) {
210 // Ignore those members which are persisted in newer versions
211 if (version != kLatestSerializableVersion &&
212 members_[i].version > version) {
213 continue;
214 }
215
216 switch (members_[i].type) {
217 case SERIALIZABLE_VALUE_TYPE:
218 if (*data + members_[i].size > tail) {
219 UTIL_LOG(L6, (_T("[SerializableObject::DeserializeHelper]")
220 _T("[overflow when deserializing value type]")));
221 return false;
222 }
223 memcpy(members_[i].ptr, *data, members_[i].size);
224 *data += members_[i].size;
225 break;
226
227 case SERIALIZABLE_CSTRING: {
228 std::vector<byte> deser_data;
229 if (!DeserializeValueList(&deser_data,
230 members_[i].size,
231 data,
232 tail - *data))
233 return false;
234 CString* s = reinterpret_cast<CString*>(members_[i].ptr);
235 if (deser_data.size() != 0) {
236 s->SetString(reinterpret_cast<const TCHAR*>(&deser_data.front()),
237 deser_data.size() / members_[i].size);
238 } else {
239 s->SetString(_T(""));
240 }
241 break;
242 }
243
244 case SERIALIZABLE_NESTED_OBJECT: {
245 SerializableObject* nested_obj =
246 reinterpret_cast<SerializableObject*>(members_[i].ptr);
247 if (!nested_obj->DeserializeHelper(data, size, version))
248 return false;
249 break;
250 }
251
252 case SERIALIZABLE_VECTOR | SERIALIZABLE_VALUE_TYPE: {
253 // Hack: coerce vector<T> to vector<byte>
254 std::vector<byte>* v =
255 reinterpret_cast<std::vector<byte>*>(members_[i].ptr);
256 if (!DeserializeValueList(v, members_[i].size, data, tail - *data))
257 return false;
258 break;
259 }
260
261 case SERIALIZABLE_VECTOR | SERIALIZABLE_CSTRING: {
262 std::vector<CString>* v =
263 reinterpret_cast<std::vector<CString>*>(members_[i].ptr);
264 int count = 0;
265 if (!DeserializeSizeAndCount(&count, 1, data, tail - *data))
266 return false;
267 for (int j = 0; j < count; ++j) {
268 std::vector<byte> deser_data;
269 if (!DeserializeValueList(&deser_data,
270 members_[i].size,
271 data,
272 tail - *data))
273 return false;
274
275 CString s;
276 if (deser_data.size() != 0) {
277 s = CString(reinterpret_cast<const TCHAR*>(&deser_data.front()),
278 deser_data.size() / members_[i].size);
279 }
280 v->push_back(s);
281 }
282 break;
283 }
284
285 case SERIALIZABLE_VECTOR | SERIALIZABLE_NESTED_OBJECT: {
286 if (!DeserializeVectorNestedObject(data,
287 tail - *data,
288 members_[i].ptr,
289 version))
290 return false;
291 break;
292 }
293
294 default:
295 ASSERT(false, (_T("")));
296 break;
297 }
298 }
299
300 return true;
301 }
302
303 // Serialize the size and count values
304 bool SerializableObject::DeserializeSizeAndCount(int* count,
305 int size,
306 byte** ser_data,
307 int ser_size) const {
308 ASSERT(ser_data, (_T("")));
309 ASSERT(count, (_T("")));
310
311 byte* ser_tail = *ser_data + ser_size;
312
313 // Check to make sure that the serialization data should at least contain
314 // 'size' and 'count'
315 if (*ser_data + 2 * sizeof(int) > ser_tail) {
316 UTIL_LOG(L6, (_T("[SerializableObject::DeserializeSizeAndCount]")
317 _T("[overflow when deserializing size and count]")));
318 return false;
319 }
320
321 // Get size
322 // If the passing size is 0, skip the size check
323 int size2 = *(reinterpret_cast<const int*>(*ser_data));
324 *ser_data += sizeof(int);
325 if (size && size != size2)
326 return false;
327
328 // Get count
329 *count = *(reinterpret_cast<const int*>(*ser_data));
330 *ser_data += sizeof(int);
331
332 return true;
333 }
334
335 // Deserialize a list of value-typed elements
336 //
337 // Args:
338 // ser_data: pointer to the vector for the serialized data
339 // size: the size of the element in the list
340 // raw_data: pointer to the raw data to be serialized
341 // ser_size: size of the serization data
342 bool SerializableObject::DeserializeValueList(std::vector<byte>* raw_data,
343 int size,
344 byte** ser_data,
345 int ser_size) {
346 ASSERT(raw_data, (_T("")));
347 ASSERT(ser_data, (_T("")));
348
349 byte* ser_tail = *ser_data + ser_size;
350
351 // Deserialize the size and count values
352 int count = 0;
353 bool ret = DeserializeSizeAndCount(&count, size, ser_data, ser_size);
354 if (!ret)
355 return false;
356
357 // Check to make sure that the serialization data is in the right size
358 if (*ser_data + count * size > ser_tail) {
359 UTIL_LOG(L6, (_T("[SerializableObject::DeserializeValueList]")
360 _T("[overflow when deserializing value list]")));
361 return false;
362 }
363
364 // Get data
365 raw_data->resize(size * count);
366 if (count > 0) {
367 memcpy(&raw_data->front(), *ser_data, count * size);
368 *ser_data += count * size;
369 }
370
371 return true;
372 }
373
374 } // namespace omaha
375
OLDNEW
« no previous file with comments | « base/serializable_object.h ('k') | base/serializable_object_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698