Bond
 
Loading...
Searching...
No Matches
simple_json_reader_impl.h
1// Copyright (c) Microsoft. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
4#pragma once
5
6#include <bond/core/config.h>
7
8#include "simple_json_reader.h"
9
10namespace bond
11{
12
13template <typename BufferT>
14inline const typename SimpleJsonReader<BufferT>::Field*
15SimpleJsonReader<BufferT>::FindField(uint16_t id, const Metadata& metadata, BondDataType type, bool is_enum)
16{
17 rapidjson::Value::ConstMemberIterator it = MemberBegin();
18
19 if (it != MemberEnd())
20 {
21 const char* name = detail::FieldName(metadata).c_str();
22 detail::JsonTypeMatching jsonType(type, type, is_enum);
23
24 // Match member by type of value and either metadata name, or string reprentation of id
25 for (rapidjson::Value::ConstMemberIterator end = MemberEnd(); it != end; ++it)
26 {
27 if (jsonType.TypeMatch(it->value))
28 {
29 if (strcmp(it->name.GetString(), name) == 0)
30 {
31 // metadata name match
32 return &it->value;
33 }
34
35 uint16_t parsedId;
36 if (detail::try_lexical_convert(it->name.GetString(), parsedId) && id == parsedId)
37 {
38 // string id match
39 return &it->value;
40 }
41 }
42 }
43 }
44
45 return NULL;
46}
47
48// deserialize std::vector<bool>
49template <typename Protocols, typename A, typename T, typename Buffer>
50inline void DeserializeContainer(std::vector<bool, A>& var, const T& /*element*/, SimpleJsonReader<Buffer>& reader)
51{
52 rapidjson::Value::ConstValueIterator it = reader.ArrayBegin();
53 resize_list(var, reader.ArraySize());
54
55 for (enumerator<std::vector<bool, A> > items(var); items.more(); ++it)
56 {
57 items.next() = it->IsTrue();
58 }
59}
60
61
62// deserialize blob
63template <typename Protocols, typename T, typename Buffer>
64inline void DeserializeContainer(blob& var, const T& /*element*/, SimpleJsonReader<Buffer>& reader)
65{
66 if (uint32_t size = reader.ArraySize())
67 {
68 boost::shared_ptr<char[]> buffer = boost::make_shared_noinit<char[]>(size);
69 uint32_t i = 0;
70
71 for (rapidjson::Value::ConstValueIterator it = reader.ArrayBegin(), end = reader.ArrayEnd(); it != end && i < size; ++it)
72 if (it->IsInt())
73 buffer[i++] = static_cast<blob::value_type>(it->GetInt());
74
75 var.assign(buffer, i);
76 }
77 else
78 var.clear();
79}
80
81
82// deserialize list
83template <typename Protocols, typename X, typename T, typename Buffer>
84inline typename boost::enable_if<is_list_container<X> >::type
85DeserializeContainer(X& var, const T& element, SimpleJsonReader<Buffer>& reader)
86{
87 detail::JsonTypeMatching type(get_type_id<typename element_type<X>::type>::value,
88 GetTypeId(element),
89 std::is_enum<typename element_type<X>::type>::value);
90
91 rapidjson::Value::ConstValueIterator it = reader.ArrayBegin();
92 resize_list(var, reader.ArraySize());
93
94 for (enumerator<X> items(var); items.more(); ++it)
95 {
96 if (type.ComplexTypeMatch(*it))
97 {
98 SimpleJsonReader<Buffer> input(reader, *it);
99 DeserializeElement<Protocols>(var, items.next(), detail::MakeValue(input, element));
100 }
101 else if (type.BasicTypeMatch(*it))
102 {
103 SimpleJsonReader<Buffer> input(reader, *it);
104 DeserializeElement<Protocols>(var, items.next(), value<typename element_type<X>::type, SimpleJsonReader<Buffer>&>(input));
105 }
106 else
107 {
108 items.next();
109 }
110 }
111}
112
113
114// deserialize set
115template <typename Protocols, typename X, typename T, typename Buffer>
116inline typename boost::enable_if<is_set_container<X> >::type
117DeserializeContainer(X& var, const T& element, SimpleJsonReader<Buffer>& reader)
118{
119 detail::JsonTypeMatching type(get_type_id<typename element_type<X>::type>::value,
120 GetTypeId(element),
121 std::is_enum<typename element_type<X>::type>::value);
122 clear_set(var);
123
124 typename element_type<X>::type e(make_element(var));
125
126 for (rapidjson::Value::ConstValueIterator it = reader.ArrayBegin(), end = reader.ArrayEnd(); it != end; ++it)
127 {
128 if (type.BasicTypeMatch(*it))
129 {
130 detail::Read(*it, e);
131 set_insert(var, e);
132 }
133 }
134}
135
136
137// deserialize map
138template <typename Protocols, typename X, typename T, typename Buffer>
139inline typename boost::enable_if<is_map_container<X> >::type
140DeserializeMap(X& var, BondDataType keyType, const T& element, SimpleJsonReader<Buffer>& reader)
141{
142 detail::JsonTypeMatching key_type(
143 get_type_id<typename element_type<X>::type::first_type>::value,
144 keyType,
145 std::is_enum<typename element_type<X>::type::first_type>::value);
146
147 detail::JsonTypeMatching value_type(
148 get_type_id<typename element_type<X>::type::second_type>::value,
149 GetTypeId(element),
150 std::is_enum<typename element_type<X>::type::second_type>::value);
151
152 clear_map(var);
153
154 typename element_type<X>::type::first_type key(make_key(var));
155
156 for (rapidjson::Value::ConstValueIterator it = reader.ArrayBegin(), end = reader.ArrayEnd(); it != end; ++it)
157 {
158 if (key_type.BasicTypeMatch(*it))
159 {
160 detail::Read(*it, key);
161 }
162 else
163 {
164 bond::InvalidKeyTypeException();
165 }
166
167 ++it;
168
169 if (it == end)
170 {
171 bond::ElementNotFoundException(key);
172 }
173
174 SimpleJsonReader<Buffer> input(reader, *it);
175
176 if (value_type.ComplexTypeMatch(*it))
177 detail::MakeValue(input, element).template Deserialize<Protocols>(mapped_at(var, key));
178 else
179 value<typename element_type<X>::type::second_type, SimpleJsonReader<Buffer>&>(input).Deserialize(mapped_at(var, key));
180 }
181}
182
183}
namespace bond
Definition: apply.h:17
void Deserialize(Reader input, T &obj)
Deserialize an object from a protocol reader.
Definition: bond.h:27