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