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

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

Issue 2112093002: Mojo C++ bindings: Merge EncodePointers/DecodePointers into Serialize/Deserialize, respectively. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@61_array_fix
Patch Set: . Created 4 years, 5 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 | « mojo/public/cpp/bindings/BUILD.gn ('k') | mojo/public/cpp/bindings/lib/array_serialization.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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_INTERNAL_H_ 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 return sizeof(ArrayHeader) + sizeof(StorageType) * num_elements; 51 return sizeof(ArrayHeader) + sizeof(StorageType) * num_elements;
52 } 52 }
53 static Ref ToRef(StorageType* storage, size_t offset) { 53 static Ref ToRef(StorageType* storage, size_t offset) {
54 return storage[offset]; 54 return storage[offset];
55 } 55 }
56 static ConstRef ToConstRef(const StorageType* storage, size_t offset) { 56 static ConstRef ToConstRef(const StorageType* storage, size_t offset) {
57 return storage[offset]; 57 return storage[offset];
58 } 58 }
59 }; 59 };
60 60
61 template <typename P>
62 struct ArrayDataTraits<P*> {
63 using StorageType = Pointer<P>;
64 using Ref = P*&;
65 using ConstRef = P* const&;
66
67 static const uint32_t kMaxNumElements =
68 (std::numeric_limits<uint32_t>::max() - sizeof(ArrayHeader)) /
69 sizeof(StorageType);
70
71 static uint32_t GetStorageSize(uint32_t num_elements) {
72 DCHECK(num_elements <= kMaxNumElements);
73 return sizeof(ArrayHeader) + sizeof(StorageType) * num_elements;
74 }
75 static Ref ToRef(StorageType* storage, size_t offset) {
76 return storage[offset].ptr;
77 }
78 static ConstRef ToConstRef(const StorageType* storage, size_t offset) {
79 return storage[offset].ptr;
80 }
81 };
82
83 // Specialization of Arrays for bools, optimized for space. It has the 61 // Specialization of Arrays for bools, optimized for space. It has the
84 // following differences from a generalized Array: 62 // following differences from a generalized Array:
85 // * Each element takes up a single bit of memory. 63 // * Each element takes up a single bit of memory.
86 // * Accessing a non-const single element uses a helper class |BitRef|, which 64 // * Accessing a non-const single element uses a helper class |BitRef|, which
87 // emulates a reference to a bool. 65 // emulates a reference to a bool.
88 template <> 66 template <>
89 struct ArrayDataTraits<bool> { 67 struct ArrayDataTraits<bool> {
90 // Helper class to emulate a reference to a bool, used for direct element 68 // Helper class to emulate a reference to a bool, used for direct element
91 // access. 69 // access.
92 class BitRef { 70 class BitRef {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 // wrapper type instead of the data type, that way we can use MojomTypeTraits 112 // wrapper type instead of the data type, that way we can use MojomTypeTraits
135 // to determine the categories. 113 // to determine the categories.
136 114
137 template <typename T, bool is_union, bool is_handle_or_interface> 115 template <typename T, bool is_union, bool is_handle_or_interface>
138 struct ArraySerializationHelper; 116 struct ArraySerializationHelper;
139 117
140 template <typename T> 118 template <typename T>
141 struct ArraySerializationHelper<T, false, false> { 119 struct ArraySerializationHelper<T, false, false> {
142 using ElementType = typename ArrayDataTraits<T>::StorageType; 120 using ElementType = typename ArrayDataTraits<T>::StorageType;
143 121
144 static void EncodePointers(const ArrayHeader* header,
145 ElementType* elements) {}
146
147 static void DecodePointers(const ArrayHeader* header,
148 ElementType* elements) {}
149
150 static bool ValidateElements(const ArrayHeader* header, 122 static bool ValidateElements(const ArrayHeader* header,
151 const ElementType* elements, 123 const ElementType* elements,
152 ValidationContext* validation_context, 124 ValidationContext* validation_context,
153 const ContainerValidateParams* validate_params) { 125 const ContainerValidateParams* validate_params) {
154 DCHECK(!validate_params->element_is_nullable) 126 DCHECK(!validate_params->element_is_nullable)
155 << "Primitive type should be non-nullable"; 127 << "Primitive type should be non-nullable";
156 DCHECK(!validate_params->element_validate_params) 128 DCHECK(!validate_params->element_validate_params)
157 << "Primitive type should not have array validate params"; 129 << "Primitive type should not have array validate params";
158 130
159 if (!validate_params->validate_enum_func) 131 if (!validate_params->validate_enum_func)
160 return true; 132 return true;
161 133
162 // Enum validation. 134 // Enum validation.
163 for (uint32_t i = 0; i < header->num_elements; ++i) { 135 for (uint32_t i = 0; i < header->num_elements; ++i) {
164 if (!validate_params->validate_enum_func(elements[i], validation_context)) 136 if (!validate_params->validate_enum_func(elements[i], validation_context))
165 return false; 137 return false;
166 } 138 }
167 return true; 139 return true;
168 } 140 }
169 }; 141 };
170 142
171 template <typename T> 143 template <typename T>
172 struct ArraySerializationHelper<T, false, true> { 144 struct ArraySerializationHelper<T, false, true> {
173 using ElementType = typename ArrayDataTraits<T>::StorageType; 145 using ElementType = typename ArrayDataTraits<T>::StorageType;
174 146
175 static void EncodePointers(const ArrayHeader* header,
176 ElementType* elements) {}
177
178 static void DecodePointers(const ArrayHeader* header,
179 ElementType* elements) {}
180
181 static bool ValidateElements(const ArrayHeader* header, 147 static bool ValidateElements(const ArrayHeader* header,
182 const ElementType* elements, 148 const ElementType* elements,
183 ValidationContext* validation_context, 149 ValidationContext* validation_context,
184 const ContainerValidateParams* validate_params) { 150 const ContainerValidateParams* validate_params) {
185 DCHECK(!validate_params->element_validate_params) 151 DCHECK(!validate_params->element_validate_params)
186 << "Handle or interface type should not have array validate params"; 152 << "Handle or interface type should not have array validate params";
187 153
188 for (uint32_t i = 0; i < header->num_elements; ++i) { 154 for (uint32_t i = 0; i < header->num_elements; ++i) {
189 if (!validate_params->element_is_nullable && 155 if (!validate_params->element_is_nullable &&
190 !IsHandleOrInterfaceValid(elements[i])) { 156 !IsHandleOrInterfaceValid(elements[i])) {
(...skipping 11 matching lines...) Expand all
202 .c_str()); 168 .c_str());
203 return false; 169 return false;
204 } 170 }
205 if (!ValidateHandleOrInterface(elements[i], validation_context)) 171 if (!ValidateHandleOrInterface(elements[i], validation_context))
206 return false; 172 return false;
207 } 173 }
208 return true; 174 return true;
209 } 175 }
210 }; 176 };
211 177
212 template <typename P> 178 template <typename T>
213 struct ArraySerializationHelper<P*, false, false> { 179 struct ArraySerializationHelper<Pointer<T>, false, false> {
214 using ElementType = typename ArrayDataTraits<P*>::StorageType; 180 using ElementType = typename ArrayDataTraits<Pointer<T>>::StorageType;
215
216 static void EncodePointers(const ArrayHeader* header, ElementType* elements) {
217 for (uint32_t i = 0; i < header->num_elements; ++i)
218 Encode(&elements[i]);
219 }
220
221 static void DecodePointers(const ArrayHeader* header, ElementType* elements) {
222 for (uint32_t i = 0; i < header->num_elements; ++i)
223 Decode(&elements[i]);
224 }
225 181
226 static bool ValidateElements(const ArrayHeader* header, 182 static bool ValidateElements(const ArrayHeader* header,
227 const ElementType* elements, 183 const ElementType* elements,
228 ValidationContext* validation_context, 184 ValidationContext* validation_context,
229 const ContainerValidateParams* validate_params) { 185 const ContainerValidateParams* validate_params) {
230 for (uint32_t i = 0; i < header->num_elements; ++i) { 186 for (uint32_t i = 0; i < header->num_elements; ++i) {
231 if (!validate_params->element_is_nullable && !elements[i].offset) { 187 if (!validate_params->element_is_nullable && !elements[i].offset) {
232 ReportValidationError( 188 ReportValidationError(
233 validation_context, 189 validation_context,
234 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 190 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
235 MakeMessageWithArrayIndex("null in array expecting valid pointers", 191 MakeMessageWithArrayIndex("null in array expecting valid pointers",
236 header->num_elements, 192 header->num_elements,
237 i).c_str()); 193 i).c_str());
238 return false; 194 return false;
239 } 195 }
240 if (!ValidateCaller<P>::Run(elements[i], validation_context, 196 if (!ValidateCaller<T>::Run(elements[i], validation_context,
241 validate_params->element_validate_params)) { 197 validate_params->element_validate_params)) {
242 return false; 198 return false;
243 } 199 }
244 } 200 }
245 return true; 201 return true;
246 } 202 }
247 203
248 private: 204 private:
249 template <typename T> 205 template <typename U,
206 bool is_array_or_map = IsSpecializationOf<Array_Data, U>::value ||
207 IsSpecializationOf<Map_Data, U>::value>
250 struct ValidateCaller { 208 struct ValidateCaller {
251 static bool Run(const Pointer<T>& data, 209 static bool Run(const Pointer<U>& data,
252 ValidationContext* validation_context, 210 ValidationContext* validation_context,
253 const ContainerValidateParams* validate_params) { 211 const ContainerValidateParams* validate_params) {
254 DCHECK(!validate_params) 212 DCHECK(!validate_params)
255 << "Struct type should not have array validate params"; 213 << "Struct type should not have array validate params";
256 214
257 return ValidateStruct(data, validation_context); 215 return ValidateStruct(data, validation_context);
258 } 216 }
259 }; 217 };
260 218
261 template <typename Key, typename Value> 219 template <typename U>
262 struct ValidateCaller<Map_Data<Key, Value>> { 220 struct ValidateCaller<U, true> {
263 static bool Run(const Pointer<Map_Data<Key, Value>>& data, 221 static bool Run(const Pointer<U>& data,
264 ValidationContext* validation_context, 222 ValidationContext* validation_context,
265 const ContainerValidateParams* validate_params) { 223 const ContainerValidateParams* validate_params) {
266 return ValidateMap(data, validation_context, validate_params); 224 return ValidateContainer(data, validation_context, validate_params);
267 }
268 };
269
270 template <typename T>
271 struct ValidateCaller<Array_Data<T>> {
272 static bool Run(const Pointer<Array_Data<T>>& data,
273 ValidationContext* validation_context,
274 const ContainerValidateParams* validate_params) {
275 return ValidateArray(data, validation_context, validate_params);
276 } 225 }
277 }; 226 };
278 }; 227 };
279 228
280 template <typename U> 229 template <typename U>
281 struct ArraySerializationHelper<U, true, false> { 230 struct ArraySerializationHelper<U, true, false> {
282 using ElementType = typename ArrayDataTraits<U>::StorageType; 231 using ElementType = typename ArrayDataTraits<U>::StorageType;
283 232
284 static void EncodePointers(const ArrayHeader* header, ElementType* elements) {
285 for (uint32_t i = 0; i < header->num_elements; ++i)
286 elements[i].EncodePointers();
287 }
288
289 static void DecodePointers(const ArrayHeader* header, ElementType* elements) {
290 for (uint32_t i = 0; i < header->num_elements; ++i)
291 elements[i].DecodePointers();
292 }
293
294 static bool ValidateElements(const ArrayHeader* header, 233 static bool ValidateElements(const ArrayHeader* header,
295 const ElementType* elements, 234 const ElementType* elements,
296 ValidationContext* validation_context, 235 ValidationContext* validation_context,
297 const ContainerValidateParams* validate_params) { 236 const ContainerValidateParams* validate_params) {
298 for (uint32_t i = 0; i < header->num_elements; ++i) { 237 for (uint32_t i = 0; i < header->num_elements; ++i) {
299 if (!validate_params->element_is_nullable && elements[i].is_null()) { 238 if (!validate_params->element_is_nullable && elements[i].is_null()) {
300 ReportValidationError( 239 ReportValidationError(
301 validation_context, 240 validation_context,
302 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, 241 VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
303 MakeMessageWithArrayIndex("null in array expecting valid unions", 242 MakeMessageWithArrayIndex("null in array expecting valid unions",
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 StorageType* storage() { 338 StorageType* storage() {
400 return reinterpret_cast<StorageType*>(reinterpret_cast<char*>(this) + 339 return reinterpret_cast<StorageType*>(reinterpret_cast<char*>(this) +
401 sizeof(*this)); 340 sizeof(*this));
402 } 341 }
403 342
404 const StorageType* storage() const { 343 const StorageType* storage() const {
405 return reinterpret_cast<const StorageType*>( 344 return reinterpret_cast<const StorageType*>(
406 reinterpret_cast<const char*>(this) + sizeof(*this)); 345 reinterpret_cast<const char*>(this) + sizeof(*this));
407 } 346 }
408 347
409 void EncodePointers() { Helper::EncodePointers(&header_, storage()); }
410 void DecodePointers() { Helper::DecodePointers(&header_, storage()); }
411
412 private: 348 private:
413 Array_Data(uint32_t num_bytes, uint32_t num_elements) { 349 Array_Data(uint32_t num_bytes, uint32_t num_elements) {
414 header_.num_bytes = num_bytes; 350 header_.num_bytes = num_bytes;
415 header_.num_elements = num_elements; 351 header_.num_elements = num_elements;
416 } 352 }
417 ~Array_Data() = delete; 353 ~Array_Data() = delete;
418 354
419 internal::ArrayHeader header_; 355 internal::ArrayHeader header_;
420 356
421 // Elements of type internal::ArrayDataTraits<T>::StorageType follow. 357 // Elements of type internal::ArrayDataTraits<T>::StorageType follow.
422 }; 358 };
423 static_assert(sizeof(Array_Data<char>) == 8, "Bad sizeof(Array_Data)"); 359 static_assert(sizeof(Array_Data<char>) == 8, "Bad sizeof(Array_Data)");
424 360
425 // UTF-8 encoded 361 // UTF-8 encoded
426 using String_Data = Array_Data<char>; 362 using String_Data = Array_Data<char>;
427 363
428 } // namespace internal 364 } // namespace internal
429 } // namespace mojo 365 } // namespace mojo
430 366
431 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ 367 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/BUILD.gn ('k') | mojo/public/cpp/bindings/lib/array_serialization.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698