1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_
#include "mojo/public/cpp/bindings/lib/array_internal.h"
#include "mojo/public/cpp/bindings/lib/map_data_internal.h"
#include "mojo/public/cpp/bindings/lib/map_internal.h"
#include "mojo/public/cpp/bindings/lib/string_serialization.h"
#include "mojo/public/cpp/bindings/map.h"
namespace mojo {
template <typename Key, typename Value>
inline size_t GetSerializedSize_(const Map<Key, Value>& input);
template <typename ValidateParams, typename E, typename F>
inline void SerializeArray_(Array<E> input,
internal::Buffer* buf,
internal::Array_Data<F>** output);
namespace internal {
template <typename MapType,
typename DataType,
bool kValueIsMoveOnlyType = IsMoveOnlyType<MapType>::value>
struct MapSerializer;
template <typename MapType, typename DataType>
struct MapSerializer<MapType, DataType, false> {
static size_t GetBaseArraySize(size_t count) {
return Align(count * sizeof(DataType));
}
static size_t GetItemSize(const MapType& item) { return 0; }
};
template <>
struct MapSerializer<bool, bool, false> {
static size_t GetBaseArraySize(size_t count) {
return Align((count + 7) / 8);
}
static size_t GetItemSize(bool item) { return 0; }
};
template <typename H>
struct MapSerializer<ScopedHandleBase<H>, H, true> {
static size_t GetBaseArraySize(size_t count) {
return Align(count * sizeof(H));
}
static size_t GetItemSize(const H& item) { return 0; }
};
// This template must only apply to pointer mojo entity (structs and arrays).
// This is done by ensuring that WrapperTraits<S>::DataType is a pointer.
template <typename S>
struct MapSerializer<
S,
typename EnableIf<IsPointer<typename WrapperTraits<S>::DataType>::value,
typename WrapperTraits<S>::DataType>::type,
true> {
typedef
typename RemovePointer<typename WrapperTraits<S>::DataType>::type S_Data;
static size_t GetBaseArraySize(size_t count) {
return count * sizeof(StructPointer<S_Data>);
}
static size_t GetItemSize(const S& item) { return GetSerializedSize_(item); }
};
template <>
struct MapSerializer<String, String_Data*, false> {
static size_t GetBaseArraySize(size_t count) {
return count * sizeof(StringPointer);
}
static size_t GetItemSize(const String& item) {
return GetSerializedSize_(item);
}
};
} // namespace internal
// TODO(erg): This can't go away yet. We still need to calculate out the size
// of a struct header, and two arrays.
template <typename MapKey, typename MapValue>
inline size_t GetSerializedSize_(const Map<MapKey, MapValue>& input) {
if (!input)
return 0;
typedef typename internal::WrapperTraits<MapKey>::DataType DataKey;
typedef typename internal::WrapperTraits<MapValue>::DataType DataValue;
size_t count = input.size();
size_t struct_overhead = sizeof(mojo::internal::Map_Data<DataKey, DataValue>);
size_t key_base_size =
sizeof(internal::ArrayHeader) +
internal::MapSerializer<MapKey, DataKey>::GetBaseArraySize(count);
size_t value_base_size =
sizeof(internal::ArrayHeader) +
internal::MapSerializer<MapValue, DataValue>::GetBaseArraySize(count);
size_t key_data_size = 0;
size_t value_data_size = 0;
for (auto it = input.begin(); it != input.end(); ++it) {
key_data_size +=
internal::MapSerializer<MapKey, DataKey>::GetItemSize(it.GetKey());
value_data_size +=
internal::MapSerializer<MapValue, DataValue>::GetItemSize(
it.GetValue());
}
return struct_overhead + key_base_size + key_data_size + value_base_size +
value_data_size;
}
// We don't need a KeyValidateParams, because we konw exactly what params are
// needed. (Keys are primitive types or non-nullable strings.)
template <typename ValueValidateParams,
typename MapKey,
typename MapValue,
typename DataKey,
typename DataValue>
inline void SerializeMap_(Map<MapKey, MapValue> input,
internal::Buffer* buf,
internal::Map_Data<DataKey, DataValue>** output) {
if (input) {
internal::Map_Data<DataKey, DataValue>* result =
internal::Map_Data<DataKey, DataValue>::New(buf);
if (result) {
Array<MapKey> keys;
Array<MapValue> values;
input.DecomposeMapTo(&keys, &values);
SerializeArray_<internal::MapKeyValidateParams<DataKey>>(
keys.Pass(), buf, &result->keys.ptr);
SerializeArray_<ValueValidateParams>(
values.Pass(), buf, &result->values.ptr);
}
*output = result;
} else {
*output = nullptr;
}
}
template <typename MapKey,
typename MapValue,
typename DataKey,
typename DataValue>
inline void Deserialize_(internal::Map_Data<DataKey, DataValue>* input,
Map<MapKey, MapValue>* output) {
if (input) {
Array<MapKey> keys;
Array<MapValue> values;
Deserialize_(input->keys.ptr, &keys);
Deserialize_(input->values.ptr, &values);
*output = Map<MapKey, MapValue>(keys.Pass(), values.Pass());
} else {
output->reset();
}
}
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_
|