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

Side by Side Diff: mojo/public/cpp/bindings/lib/array_serialization.h

Issue 1358353002: * Change C++ serialization/deserialization to not be move-only operations (with the except of |Ha… (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: simplify array_serialization.h (ArraySerializer::SerializeElements and [De]SerializeCaller) Created 5 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
7 7
8 #include <string.h> // For |memcpy()|. 8 #include <string.h> // For |memcpy()|.
9
10 #include <vector> 9 #include <vector>
11 10
12 #include "mojo/public/c/system/macros.h" 11 #include "mojo/public/c/system/macros.h"
13 #include "mojo/public/cpp/bindings/lib/array_internal.h" 12 #include "mojo/public/cpp/bindings/lib/array_internal.h"
14 #include "mojo/public/cpp/bindings/lib/map_serialization.h" 13 #include "mojo/public/cpp/bindings/lib/bindings_internal.h"
14 #include "mojo/public/cpp/bindings/lib/iterator_util.h"
15 #include "mojo/public/cpp/bindings/lib/map_data_internal.h"
16 #include "mojo/public/cpp/bindings/lib/map_serialization_forward.h"
15 #include "mojo/public/cpp/bindings/lib/string_serialization.h" 17 #include "mojo/public/cpp/bindings/lib/string_serialization.h"
16 #include "mojo/public/cpp/bindings/lib/template_util.h" 18 #include "mojo/public/cpp/bindings/lib/template_util.h"
17 #include "mojo/public/cpp/bindings/lib/validation_errors.h" 19 #include "mojo/public/cpp/bindings/lib/validation_errors.h"
18 20
19 namespace mojo { 21 namespace mojo {
20
21 template <typename E>
22 inline size_t GetSerializedSize_(const Array<E>& input);
23
24 template <typename E, typename F>
25 inline void SerializeArray_(
26 Array<E> input,
27 internal::Buffer* buf,
28 internal::Array_Data<F>** output,
29 const internal::ArrayValidateParams* validate_params);
30
31 template <typename E, typename F>
32 inline void Deserialize_(internal::Array_Data<F>* data, Array<E>* output);
33
34 namespace internal { 22 namespace internal {
35 23
24 // The ArraySerializer template contains static methods for serializing |Array|s
25 // of various types. These methods include:
26 // * size_t GetSerializedSize(..)
27 // Computes the size of the serialized version of the |Array|.
28 // * void SerializeElements(..)
29 // Takes an |Iterator| and a size and serializes it.
30 // * void DeserializeElements(..)
31 // Takes a pointer to an |Array_Data| and deserializes it into a given
32 // |Array|.
36 template <typename E, 33 template <typename E,
37 typename F, 34 typename F,
38 bool is_union = 35 bool is_union =
39 IsUnionDataType<typename RemovePointer<F>::type>::value> 36 IsUnionDataType<typename RemovePointer<F>::type>::value>
40 struct ArraySerializer; 37 struct ArraySerializer;
41 38
42 // Handles serialization and deserialization of arrays of pod types. 39 // Handles serialization and deserialization of arrays of pod types.
43 template <typename E, typename F> 40 template <typename E, typename F>
44 struct ArraySerializer<E, F, false> { 41 struct ArraySerializer<E, F, false> {
45 static_assert(sizeof(E) == sizeof(F), "Incorrect array serializer"); 42 static_assert(sizeof(E) == sizeof(F), "Incorrect array serializer");
46 static size_t GetSerializedSize(const Array<E>& input) { 43 static size_t GetSerializedSize(const Array<E>& input) {
47 return sizeof(Array_Data<F>) + Align(input.size() * sizeof(E)); 44 return sizeof(Array_Data<F>) + Align(input.size() * sizeof(E));
48 } 45 }
49 46
50 static void SerializeElements(Array<E> input, 47 template <typename Iterator>
48 static void SerializeElements(Iterator it,
49 size_t num_elements,
51 Buffer* buf, 50 Buffer* buf,
52 Array_Data<F>* output, 51 Array_Data<F>* output,
53 const ArrayValidateParams* validate_params) { 52 const ArrayValidateParams* validate_params) {
54 MOJO_DCHECK(!validate_params->element_is_nullable) 53 MOJO_DCHECK(!validate_params->element_is_nullable)
55 << "Primitive type should be non-nullable"; 54 << "Primitive type should be non-nullable";
56 MOJO_DCHECK(!validate_params->element_validate_params) 55 MOJO_DCHECK(!validate_params->element_validate_params)
57 << "Primitive type should not have array validate params"; 56 << "Primitive type should not have array validate params";
57 for (size_t i = 0; i < num_elements; ++i, ++it)
58 output->at(i) = *it;
59 }
58 60
59 if (input.size()) 61 // We can optimize serializing PODs by |memcpy|ing directly.
60 memcpy(output->storage(), &input.storage()[0], input.size() * sizeof(E)); 62 // Note that this has precedence over its templated sibling defined above.
63 static void SerializeElements(typename Array<E>::Iterator it,
64 size_t num_elements,
65 Buffer* buf,
66 Array_Data<F>* output,
67 const ArrayValidateParams* validate_params) {
68 MOJO_DCHECK(!validate_params->element_is_nullable)
69 << "Primitive type should be non-nullable";
70 MOJO_DCHECK(!validate_params->element_validate_params)
71 << "Primitive type should not have array validate params";
72 if (num_elements) {
viettrungluu 2015/09/25 20:08:08 nit: omit {}
vardhan 2015/09/28 21:55:44 Done.
73 memcpy(output->storage(), &(*it), num_elements * sizeof(E));
74 }
61 } 75 }
76
62 static void DeserializeElements(Array_Data<F>* input, Array<E>* output) { 77 static void DeserializeElements(Array_Data<F>* input, Array<E>* output) {
63 std::vector<E> result(input->size()); 78 std::vector<E> result(input->size());
64 if (input->size()) 79 if (input->size())
65 memcpy(&result[0], input->storage(), input->size() * sizeof(E)); 80 memcpy(&result[0], input->storage(), input->size() * sizeof(E));
66 output->Swap(&result); 81 output->Swap(&result);
67 } 82 }
68 }; 83 };
69 84
70 // Serializes and deserializes arrays of bools. 85 // Serializes and deserializes arrays of bools.
71 template <> 86 template <>
72 struct ArraySerializer<bool, bool, false> { 87 struct ArraySerializer<bool, bool, false> {
73 static size_t GetSerializedSize(const Array<bool>& input) { 88 static size_t GetSerializedSize(const Array<bool>& input) {
74 return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8); 89 return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8);
75 } 90 }
76 91
77 static void SerializeElements(Array<bool> input, 92 template <typename Iterator>
93 static void SerializeElements(Iterator it,
94 size_t num_elements,
78 Buffer* buf, 95 Buffer* buf,
79 Array_Data<bool>* output, 96 Array_Data<bool>* output,
80 const ArrayValidateParams* validate_params) { 97 const ArrayValidateParams* validate_params) {
81 MOJO_DCHECK(!validate_params->element_is_nullable) 98 MOJO_DCHECK(!validate_params->element_is_nullable)
82 << "Primitive type should be non-nullable"; 99 << "Primitive type should be non-nullable";
83 MOJO_DCHECK(!validate_params->element_validate_params) 100 MOJO_DCHECK(!validate_params->element_validate_params)
84 << "Primitive type should not have array validate params"; 101 << "Primitive type should not have array validate params";
85 102
86 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? 103 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
87 for (size_t i = 0; i < input.size(); ++i) 104 for (size_t i = 0; i < num_elements; ++i, ++it)
88 output->at(i) = input[i]; 105 output->at(i) = *it;
89 } 106 }
107
90 static void DeserializeElements(Array_Data<bool>* input, 108 static void DeserializeElements(Array_Data<bool>* input,
91 Array<bool>* output) { 109 Array<bool>* output) {
92 Array<bool> result(input->size()); 110 Array<bool> result(input->size());
93 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy? 111 // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
94 for (size_t i = 0; i < input->size(); ++i) 112 for (size_t i = 0; i < input->size(); ++i)
95 result.at(i) = input->at(i); 113 result.at(i) = input->at(i);
96 output->Swap(&result); 114 output->Swap(&result);
97 } 115 }
98 }; 116 };
99 117
100 // Serializes and deserializes arrays of handles. 118 // Serializes and deserializes arrays of handles.
101 template <typename H> 119 template <typename H>
102 struct ArraySerializer<ScopedHandleBase<H>, H, false> { 120 struct ArraySerializer<ScopedHandleBase<H>, H, false> {
103 static size_t GetSerializedSize(const Array<ScopedHandleBase<H>>& input) { 121 static size_t GetSerializedSize(const Array<ScopedHandleBase<H>>& input) {
104 return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H)); 122 return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H));
105 } 123 }
106 124
107 static void SerializeElements(Array<ScopedHandleBase<H>> input, 125 template <typename Iterator>
126 static void SerializeElements(Iterator it,
127 size_t num_elements,
108 Buffer* buf, 128 Buffer* buf,
109 Array_Data<H>* output, 129 Array_Data<H>* output,
110 const ArrayValidateParams* validate_params) { 130 const ArrayValidateParams* validate_params) {
111 MOJO_DCHECK(!validate_params->element_validate_params) 131 MOJO_DCHECK(!validate_params->element_validate_params)
112 << "Handle type should not have array validate params"; 132 << "Handle type should not have array validate params";
113 133
114 for (size_t i = 0; i < input.size(); ++i) { 134 for (size_t i = 0; i < num_elements; ++i, ++it) {
115 output->at(i) = input[i].release(); // Transfer ownership of the handle. 135 // Transfer ownership of the handle.
136 output->at(i) = (*it).release();
116 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 137 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
117 !validate_params->element_is_nullable && !output->at(i).is_valid(), 138 !validate_params->element_is_nullable && !output->at(i).is_valid(),
118 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE, 139 VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
119 MakeMessageWithArrayIndex( 140 MakeMessageWithArrayIndex(
120 "invalid handle in array expecting valid handles", input.size(), 141 "invalid handle in array expecting valid handles", num_elements,
121 i)); 142 i));
122 } 143 }
123 } 144 }
145
124 static void DeserializeElements(Array_Data<H>* input, 146 static void DeserializeElements(Array_Data<H>* input,
125 Array<ScopedHandleBase<H>>* output) { 147 Array<ScopedHandleBase<H>>* output) {
126 Array<ScopedHandleBase<H>> result(input->size()); 148 Array<ScopedHandleBase<H>> result(input->size());
127 for (size_t i = 0; i < input->size(); ++i) 149 for (size_t i = 0; i < input->size(); ++i)
128 result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i))); 150 result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i)));
129 output->Swap(&result); 151 output->Swap(&result);
130 } 152 }
131 }; 153 };
132 154
133 // This template must only apply to pointer mojo entity (structs and arrays). 155 // This template must only apply to pointer mojo entity (structs, arrays,
134 // This is done by ensuring that WrapperTraits<S>::DataType is a pointer. 156 // strings). This is done by ensuring that WrapperTraits<S>::DataType is a
157 // pointer.
135 template <typename S> 158 template <typename S>
136 struct ArraySerializer< 159 struct ArraySerializer<
137 S, 160 S,
138 typename EnableIf<IsPointer<typename WrapperTraits<S>::DataType>::value, 161 typename EnableIf<IsPointer<typename WrapperTraits<S>::DataType>::value,
139 typename WrapperTraits<S>::DataType>::type, 162 typename WrapperTraits<S>::DataType>::type,
140 false> { 163 false> {
141 typedef 164 typedef
142 typename RemovePointer<typename WrapperTraits<S>::DataType>::type S_Data; 165 typename RemovePointer<typename WrapperTraits<S>::DataType>::type S_Data;
143 static size_t GetSerializedSize(const Array<S>& input) { 166 static size_t GetSerializedSize(const Array<S>& input) {
144 size_t size = sizeof(Array_Data<S_Data*>) + 167 size_t size = sizeof(Array_Data<S_Data*>) +
145 input.size() * sizeof(StructPointer<S_Data>); 168 input.size() * sizeof(StructPointer<S_Data>);
146 for (size_t i = 0; i < input.size(); ++i) 169 for (size_t i = 0; i < input.size(); ++i)
147 size += GetSerializedSize_(input[i]); 170 size += GetSerializedSize_(*(UnwrapConstStructPtr<S>::value(input[i])));
148 return size; 171 return size;
149 } 172 }
150 173
151 static void SerializeElements(Array<S> input, 174 template <typename Iterator>
175 static void SerializeElements(Iterator it,
176 size_t num_elements,
152 Buffer* buf, 177 Buffer* buf,
153 Array_Data<S_Data*>* output, 178 Array_Data<S_Data*>* output,
154 const ArrayValidateParams* validate_params) { 179 const ArrayValidateParams* validate_params) {
155 for (size_t i = 0; i < input.size(); ++i) { 180 for (size_t i = 0; i < num_elements; ++i, ++it) {
156 S_Data* element; 181 S_Data* element;
157 SerializeCaller<S>::Run(input[i].Pass(), buf, &element, 182 SerializeCaller::Run(&(*it), buf, &element,
158 validate_params->element_validate_params); 183 validate_params->element_validate_params);
159 output->at(i) = element; 184 output->at(i) = element;
160 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 185 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
161 !validate_params->element_is_nullable && !element, 186 !validate_params->element_is_nullable && !element,
162 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 187 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
163 MakeMessageWithArrayIndex("null in array expecting valid pointers", 188 MakeMessageWithArrayIndex("null in array expecting valid pointers",
164 input.size(), i)); 189 num_elements, i));
165 } 190 }
166 } 191 }
192
167 static void DeserializeElements(Array_Data<S_Data*>* input, 193 static void DeserializeElements(Array_Data<S_Data*>* input,
168 Array<S>* output) { 194 Array<S>* output) {
169 Array<S> result(input->size()); 195 Array<S> result(input->size());
170 for (size_t i = 0; i < input->size(); ++i) { 196 for (size_t i = 0; i < input->size(); ++i) {
171 Deserialize_(input->at(i), &result[i]); 197 DeserializeCaller::Run(input->at(i), &result[i]);
172 } 198 }
173 output->Swap(&result); 199 output->Swap(&result);
174 } 200 }
175 201
176 private: 202 private:
177 template <typename T> 203 // SerializeCaller template is used by |ArraySerializer| to dispatch a
204 // serialize
viettrungluu 2015/09/25 20:08:08 nit: please re-wrap
vardhan 2015/09/28 21:55:44 Done.
205 // call on a non-POD type. This template is defined outside |ArraySerializer|
206 // since you cannot specialize a struct within a class definition.
178 struct SerializeCaller { 207 struct SerializeCaller {
179 static void Run(T input, 208 // This template needs to be suppressed if |T| is |String|, otherwise it
209 // takes precedence over the |String|-overloaded Run() below.
210 template <typename T,
211 typename = typename EnableIf<!IsSame<T, String>::value, T>::type>
212 static void Run(T* input,
180 Buffer* buf, 213 Buffer* buf,
181 typename WrapperTraits<T>::DataType* output, 214 typename WrapperTraits<T>::DataType* output,
182 const ArrayValidateParams* validate_params) { 215 const ArrayValidateParams* validate_params) {
183 MOJO_DCHECK(!validate_params) 216 MOJO_DCHECK(!validate_params)
184 << "Struct type should not have array validate params"; 217 << "Struct type should not have array validate params";
218 Serialize_(UnwrapStructPtr<T>::value(*input), buf, output);
219 }
185 220
186 Serialize_(input.Pass(), buf, output); 221 static void Run(const String* input,
222 Buffer* buf,
223 String_Data** output,
224 const ArrayValidateParams* validate_params) {
225 MOJO_DCHECK(validate_params &&
226 !validate_params->element_validate_params &&
227 !validate_params->element_is_nullable &&
228 validate_params->expected_num_elements == 0)
229 << "String type has unexpected array validate params";
230 SerializeString_(*input, buf, output);
231 }
232
233 template <typename T>
234 static void Run(Array<T>* input,
235 Buffer* buf,
236 typename Array<T>::Data_** output,
237 const ArrayValidateParams* validate_params) {
238 SerializeArray_(input, buf, output, validate_params);
239 }
240
241 template <typename Key, typename Value>
242 static void Run(Map<Key, Value>* input,
243 Buffer* buf,
244 typename Map<Key, Value>::Data_** output,
245 const ArrayValidateParams* validate_params) {
246 SerializeMap_(input, buf, output, validate_params);
187 } 247 }
188 }; 248 };
189 249
190 template <typename T> 250 struct DeserializeCaller {
191 struct SerializeCaller<Array<T>> { 251 template <typename T>
192 static void Run(Array<T> input, 252 static void Run(typename WrapperTraits<T>::DataType input, T* output) {
193 Buffer* buf, 253 Deserialize_(input, output);
194 typename Array<T>::Data_** output,
195 const ArrayValidateParams* validate_params) {
196 SerializeArray_(input.Pass(), buf, output, validate_params);
197 } 254 }
198 };
199 255
200 template <typename T, typename U> 256 // Since Deserialize_ takes in a |Struct*| (not |StructPtr|), we need to
201 struct SerializeCaller<Map<T, U>> { 257 // initialize the |StructPtr| here before deserializing into its underlying
202 static void Run(Map<T, U> input, 258 // data.
203 Buffer* buf, 259 // TODO(vardhan): Either all containers, or just Deserialize_(), should
204 typename Map<T, U>::Data_** output, 260 // support taking in an allocator.
205 const ArrayValidateParams* validate_params) { 261 template <typename T>
206 SerializeMap_(input.Pass(), buf, output, validate_params); 262 static void Run(typename WrapperTraits<StructPtr<T>>::DataType input,
263 StructPtr<T>* output) {
264 *output = T::New();
265 Deserialize_(input, output->get());
266 }
267
268 template <typename T>
269 static void Run(typename WrapperTraits<InlinedStructPtr<T>>::DataType input,
270 InlinedStructPtr<T>* output) {
271 *output = T::New();
272 Deserialize_(input, output->get());
207 } 273 }
208 }; 274 };
209 }; 275 };
210 276
211 // Handles serialization and deserialization of arrays of unions. 277 // Handles serialization and deserialization of arrays of unions.
212 template <typename U, typename U_Data> 278 template <typename U, typename U_Data>
213 struct ArraySerializer<U, U_Data, true> { 279 struct ArraySerializer<U, U_Data, true> {
214 static size_t GetSerializedSize(const Array<U>& input) { 280 static size_t GetSerializedSize(const Array<U>& input) {
215 size_t size = sizeof(Array_Data<U_Data>); 281 size_t size = sizeof(Array_Data<U_Data>);
216 for (size_t i = 0; i < input.size(); ++i) { 282 for (size_t i = 0; i < input.size(); ++i) {
217 // GetSerializedSize_ will account for both the data in the union and the 283 // GetSerializedSize_ will account for both the data in the union and the
218 // space in the array used to hold the union. 284 // space in the array used to hold the union.
219 size += GetSerializedSize_(input[i], false); 285 size += GetSerializedSize_(input[i], false);
220 } 286 }
221 return size; 287 return size;
222 } 288 }
223 289
224 static void SerializeElements(Array<U> input, 290 template <typename Iterator>
291 static void SerializeElements(Iterator it,
292 size_t num_elements,
225 Buffer* buf, 293 Buffer* buf,
226 Array_Data<U_Data>* output, 294 Array_Data<U_Data>* output,
227 const ArrayValidateParams* validate_params) { 295 const ArrayValidateParams* validate_params) {
228 for (size_t i = 0; i < input.size(); ++i) { 296 for (size_t i = 0; i < num_elements; ++i, ++it) {
229 U_Data* result = output->storage() + i; 297 U_Data* result = output->storage() + i;
230 SerializeUnion_(input[i].Pass(), buf, &result, true); 298 SerializeUnion_((*it).get(), buf, &result, true);
viettrungluu 2015/09/25 20:08:08 nit: it->get() instead of (*it).get()?
vardhan 2015/09/28 21:55:44 Done.
231 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 299 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
232 !validate_params->element_is_nullable && output->at(i).is_null(), 300 !validate_params->element_is_nullable && output->at(i).is_null(),
233 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 301 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
234 MakeMessageWithArrayIndex("null in array expecting valid unions", 302 MakeMessageWithArrayIndex("null in array expecting valid unions",
235 input.size(), i)); 303 num_elements, i));
236 } 304 }
237 } 305 }
238 306
239 static void DeserializeElements(Array_Data<U_Data>* input, Array<U>* output) { 307 static void DeserializeElements(Array_Data<U_Data>* input, Array<U>* output) {
240 Array<U> result(input->size()); 308 Array<U> result(input->size());
241 for (size_t i = 0; i < input->size(); ++i) { 309 for (size_t i = 0; i < input->size(); ++i) {
242 Deserialize_(&input->at(i), &result[i]); 310 auto& elem = input->at(i);
311 if (!elem.is_null()) {
312 using UnwrapedUnionType = typename RemoveStructPtr<U>::type;
313 result[i] = UnwrapedUnionType::New();
314 Deserialize_(&elem, result[i].get());
315 }
243 } 316 }
244 output->Swap(&result); 317 output->Swap(&result);
245 } 318 }
246 }; 319 };
247
248 // Handles serialization and deserialization of arrays of strings.
249 template <>
250 struct ArraySerializer<String, String_Data*> {
251 static size_t GetSerializedSize(const Array<String>& input) {
252 size_t size =
253 sizeof(Array_Data<String_Data*>) + input.size() * sizeof(StringPointer);
254 for (size_t i = 0; i < input.size(); ++i)
255 size += GetSerializedSize_(input[i]);
256 return size;
257 }
258
259 static void SerializeElements(Array<String> input,
260 Buffer* buf,
261 Array_Data<String_Data*>* output,
262 const ArrayValidateParams* validate_params) {
263 MOJO_DCHECK(
264 validate_params->element_validate_params &&
265 !validate_params->element_validate_params->element_validate_params &&
266 !validate_params->element_validate_params->element_is_nullable &&
267 validate_params->element_validate_params->expected_num_elements == 0)
268 << "String type has unexpected array validate params";
269
270 for (size_t i = 0; i < input.size(); ++i) {
271 String_Data* element;
272 Serialize_(input[i], buf, &element);
273 output->at(i) = element;
274 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
275 !validate_params->element_is_nullable && !element,
276 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
277 MakeMessageWithArrayIndex("null in array expecting valid strings",
278 input.size(), i));
279 }
280 }
281 static void DeserializeElements(Array_Data<String_Data*>* input,
282 Array<String>* output) {
283 Array<String> result(input->size());
284 for (size_t i = 0; i < input->size(); ++i)
285 Deserialize_(input->at(i), &result[i]);
286 output->Swap(&result);
287 }
288 };
289 320
290 } // namespace internal 321 } // namespace internal
291 322
292 template <typename E> 323 template <typename E>
293 inline size_t GetSerializedSize_(const Array<E>& input) { 324 inline size_t GetSerializedSize_(const Array<E>& input) {
294 if (!input) 325 if (!input)
295 return 0; 326 return 0;
296 typedef typename internal::WrapperTraits<E>::DataType F; 327 typedef typename internal::WrapperTraits<E>::DataType F;
297 return internal::ArraySerializer<E, F>::GetSerializedSize(input); 328 return internal::ArraySerializer<E, F>::GetSerializedSize(input);
298 } 329 }
299 330
300 template <typename E, typename F> 331 template <typename E, typename F>
301 inline void SerializeArray_( 332 inline void SerializeArray_(
302 Array<E> input, 333 Array<E>* input,
303 internal::Buffer* buf, 334 internal::Buffer* buf,
304 internal::Array_Data<F>** output, 335 internal::Array_Data<F>** output,
305 const internal::ArrayValidateParams* validate_params) { 336 const internal::ArrayValidateParams* validate_params) {
306 if (input) { 337 if (input && *input) {
viettrungluu 2015/09/25 20:08:08 Is input ever allowed to be null? Maybe you shoul
vardhan 2015/09/28 21:55:44 Doesn't look like it'll ever be null if it goes th
307 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( 338 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
308 validate_params->expected_num_elements != 0 && 339 validate_params->expected_num_elements != 0 &&
309 input.size() != validate_params->expected_num_elements, 340 input->size() != validate_params->expected_num_elements,
310 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER, 341 internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
311 internal::MakeMessageWithExpectedArraySize( 342 internal::MakeMessageWithExpectedArraySize(
312 "fixed-size array has wrong number of elements", input.size(), 343 "fixed-size array has wrong number of elements", input->size(),
313 validate_params->expected_num_elements)); 344 validate_params->expected_num_elements));
314 345
315 internal::Array_Data<F>* result = 346 internal::Array_Data<F>* result =
316 internal::Array_Data<F>::New(input.size(), buf); 347 internal::Array_Data<F>::New(input->size(), buf);
317 if (result) { 348 if (result) {
318 internal::ArraySerializer<E, F>::SerializeElements( 349 internal::ArraySerializer<E, F>::SerializeElements(
319 internal::Forward(input), buf, result, validate_params); 350 input->begin(), input->size(), buf, result, validate_params);
320 } 351 }
321 *output = result; 352 *output = result;
322 } else { 353 } else {
323 *output = nullptr; 354 *output = nullptr;
324 } 355 }
325 } 356 }
326 357
327 template <typename E, typename F> 358 template <typename E, typename F>
328 inline void Deserialize_(internal::Array_Data<F>* input, Array<E>* output) { 359 inline void Deserialize_(internal::Array_Data<F>* input, Array<E>* output) {
329 if (input) { 360 if (input) {
330 internal::ArraySerializer<E, F>::DeserializeElements(input, output); 361 internal::ArraySerializer<E, F>::DeserializeElements(input, output);
331 } else { 362 } else {
332 output->reset(); 363 output->reset();
333 } 364 }
334 } 365 }
335 366
336 } // namespace mojo 367 } // namespace mojo
337 368
338 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_ 369 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698