Bond
 
Loading...
Searching...
No Matches
bonded_void.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 "bonded.h"
9#include "detail/nonassignable.h"
10#include "schema.h"
11#include "select_protocol.h"
12
13namespace bond
14{
15
16
20template <typename Reader>
21class bonded<void, Reader>
22 : detail::nonassignable
23{
24public:
26 bonded(Reader data, const RuntimeSchema& schema, bool base = false)
27 : _data(data),
28 _schema(schema),
29 _skip(true),
30 _base(base)
31 {}
32
34 bonded(const bonded& other)
35 : _data(other._data),
36 _schema(other._schema),
37 _skip(true),
38 _base(false)
39 {}
40
42 template <typename T, typename ReaderT>
43 explicit bonded(const bonded<T, ReaderT>& other)
44 : _data(other._data),
45 _schema(other._schema.get() ? other._schema : GetRuntimeSchema<T>()),
46 _skip(true),
47 _base(false)
48 {}
49
50
52 bonded(bonded&& other) BOND_NOEXCEPT_IF(
53 BOND_NOEXCEPT_EXPR(detail::move_data<Reader>(other._data))
54 && std::is_nothrow_move_constructible<RuntimeSchema>::value)
55 : _data(detail::move_data<Reader>(other._data)),
56 _schema(std::move(other._schema)),
57 _skip(std::move(other._skip)),
58 _base(std::move(other._base))
59 {
60 other._skip = false;
61 }
62
63
64 ~bonded()
65 {
66 // Skip the struct if it wasn't deserialized
67 if (_skip)
68 detail::Skip(_data, *this, std::nothrow);
69 }
70
71
73 template <typename Protocols = BuiltInProtocols, typename Writer>
74 typename boost::disable_if<uses_marshaled_bonded<typename Writer::Reader> >::type
75 Serialize(Writer& output) const
76 {
77 Apply<Protocols>(SerializeTo<Protocols>(output), *this);
78 }
79
80
81 template <typename Protocols = BuiltInProtocols, typename Writer>
82 typename boost::enable_if<uses_marshaled_bonded<typename Writer::Reader> >::type
83 Serialize(Writer& output) const
84 {
85 if (_schema.GetType().bonded_type)
86 detail::MarshalToBlob<Protocols>(*this, output);
87 else
88 Apply<Protocols>(SerializeTo<Protocols>(output), *this);
89 }
90
91
93 template <typename T, typename Protocols = BuiltInProtocols>
94 T Deserialize() const
95 {
96 T tmp;
97 Apply<Protocols>(To<T, Protocols>(tmp), *this);
98 return tmp;
99 }
100
101
103 template <typename Protocols = BuiltInProtocols, typename T>
104 void Deserialize(T& var) const
105 {
106 Apply<Protocols>(To<T, Protocols>(var), *this);
107 }
108
109
111 template <typename Protocols = BuiltInProtocols, typename T>
112 typename boost::enable_if<uses_marshaled_bonded<Reader, T> >::type
113 Deserialize(bonded<T>& var) const
114 {
115 if (_schema.GetType().bonded_type)
116 {
117 bonded<T> tmp;
118 _SelectProtocolAndApply<Protocols>(boost::ref(tmp));
119 tmp.template Deserialize<Protocols>(var);
120 }
121 else
122 {
123 var = bonded<T>(*this);
124 }
125 }
126
127
129 template <typename Protocols = BuiltInProtocols, typename T>
130 typename boost::disable_if<uses_marshaled_bonded<Reader, T> >::type
131 Deserialize(bonded<T>& var) const
132 {
133 var = bonded<T>(*this);
134 }
135
138 void Skip()
139 {
140 _skip = false;
141 detail::Skip(_data, *this);
142 }
143
144
145 template <typename Protocols, typename Transform, typename U, typename ReaderT>
146 friend typename boost::disable_if<detail::need_double_pass<Transform>, bool>::type inline
147 detail::ApplyTransform(const Transform& transform, const bonded<U, ReaderT>& bonded);
148
149 template <typename Protocols, typename Transform, typename U, typename ReaderT>
150 friend typename boost::enable_if<detail::need_double_pass<Transform>, bool>::type inline
151 detail::ApplyTransform(const Transform& transform, const bonded<U, ReaderT>& bonded);
152
153 template <typename T, typename ReaderT>
154 friend class bonded;
155
156private:
157 // Apply transform to serialized data
158 template <typename Protocols, typename Transform>
159 typename boost::enable_if<uses_marshaled_bonded<Reader, Transform>, bool>::type
160 _Apply(const Transform& transform) const
161 {
162 if (_schema.GetType().bonded_type)
163 {
164 return _SelectProtocolAndApply<Protocols>(transform);
165 }
166 else
167 {
168 _skip = false;
169 return detail::Parse<void, Protocols>(transform, _data, _schema, nullptr, _base);
170 }
171 }
172
173 template <typename Protocols, typename Transform>
174 typename boost::disable_if<uses_marshaled_bonded<Reader, Transform>, bool>::type
175 _Apply(const Transform& transform) const
176 {
177 _skip = false;
178 return detail::Parse<void, Protocols>(transform, _data, _schema, nullptr, _base);
179 }
180
181
182 template <typename Protocols, typename Transform>
183 bool _SelectProtocolAndApply(const Transform& transform) const
184 {
185 BOOST_STATIC_ASSERT(uses_marshaled_bonded<Reader>::value);
186
187 _skip = false;
188 auto input = CreateInputBuffer(_data.GetBuffer(), detail::ReadBlob(_data));
189 return SelectProtocolAndApply<Protocols>(_schema, input, transform).second;
190 }
191
192
193 Reader _data;
194 const RuntimeSchema _schema;
195 mutable bool _skip;
196 const bool _base;
197};
198
199} // namespace bond
Represents runtime schema See User's Manual
Definition: runtime_schema.h:26
bonded(bonded &&other) BOND_NOEXCEPT_IF(&&std
Move constructor.
Definition: bonded_void.h:52
bonded(const bonded< T, ReaderT > &other)
Explicit cast from bonded<T>
Definition: bonded_void.h:43
bonded(Reader data, const RuntimeSchema &schema, bool base=false)
Initialize from serialized data and runtime schema.
Definition: bonded_void.h:26
bonded(const bonded &other)
Copy constructor.
Definition: bonded_void.h:34
Represents data for a struct T known at compile-time.
Definition: bonded.h:63
void Serialize(Writer &output) const
Serialize bonded using specified protocol writer.
Definition: bonded.h:167
X Deserialize() const
Deserialize an object of type X.
Definition: bonded.h:174
void Skip()
Skip struct data in the underlying payload.
Definition: bonded.h:214
namespace bond
Definition: apply.h:17
RuntimeSchema GetRuntimeSchema()
Returns an instance of RuntimeSchema for a user defined struct.
Definition: schema.h:330
STL namespace.