Vanetza
Loading...
Searching...
No Matches
asn1c_wrapper.hpp
1#ifndef ASN1C_WRAPPER_HPP_ZCNDO8E5
2#define ASN1C_WRAPPER_HPP_ZCNDO8E5
3
4#include <vanetza/asn1/support/asn_system.h>
5#include <vanetza/asn1/support/constr_TYPE.h>
6#include <vanetza/common/byte_buffer.hpp>
7#include <cstddef>
8#include <string>
9#include <utility>
10
11namespace vanetza
12{
13namespace asn1
14{
15
16void* allocate(std::size_t);
17void free(asn_TYPE_descriptor_t&, void*);
18void* copy(asn_TYPE_descriptor_t&, const void*);
19bool validate(asn_TYPE_descriptor_t&, const void*);
20bool validate(asn_TYPE_descriptor_t&, const void*, std::string&);
21int compare(asn_TYPE_descriptor_t&, const void*, const void*);
22int print(FILE* stream, asn_TYPE_descriptor_t&, const void*);
23std::size_t size_per(asn_TYPE_descriptor_t&, const void*);
24std::size_t size_oer(asn_TYPE_descriptor_t&, const void*);
25std::size_t size_xer(asn_TYPE_descriptor_t&, const void*);
26ByteBuffer encode_per(asn_TYPE_descriptor_t&, const void*);
27bool decode_per(asn_TYPE_descriptor_t&, void**, const ByteBuffer&);
28bool decode_per(asn_TYPE_descriptor_t&, void**, const void* buffer, std::size_t size);
29ByteBuffer encode_oer(asn_TYPE_descriptor_t&, const void*);
30bool decode_oer(asn_TYPE_descriptor_t&, void**, const ByteBuffer&);
31bool decode_oer(asn_TYPE_descriptor_t&, void**, const void* buffer, std::size_t size);
32ByteBuffer encode_xer(asn_TYPE_descriptor_t&, const void*);
33bool decode_xer(asn_TYPE_descriptor_t&, void**, const ByteBuffer&);
34bool decode_xer(asn_TYPE_descriptor_t&, void**, const void* buffer, std::size_t size);
35
36template<class T>
37T* allocate()
38{
39 return static_cast<T*>(allocate(sizeof(T)));
40}
41
42template<class T>
43class asn1c_wrapper_common
44{
45
46public:
47 typedef T asn1c_type;
48
49 asn1c_wrapper_common(asn_TYPE_descriptor_t& desc) :
50 m_struct(vanetza::asn1::allocate<asn1c_type>()), m_type(desc) {}
51 asn1c_wrapper_common(asn_TYPE_descriptor_t& desc, const T* ptr) :
52 m_struct(static_cast<T*>(copy(desc, ptr))), m_type(desc) {}
53 ~asn1c_wrapper_common() { vanetza::asn1::free(m_type, m_struct); }
54
55 // copy semantics
56 asn1c_wrapper_common(const asn1c_wrapper_common& other) :
57 m_struct(static_cast<asn1c_type*>(copy(other.m_type, other.m_struct))), m_type(other.m_type) {}
58 asn1c_wrapper_common& operator=(const asn1c_wrapper_common& other)
59 {
60 asn1c_wrapper_common tmp = other;
61 swap(tmp);
62 return *this;
63 }
64
65 // move semantics
66 asn1c_wrapper_common(asn1c_wrapper_common&& other) noexcept :
67 m_struct(nullptr), m_type(other.m_type) { swap(other); }
68 asn1c_wrapper_common& operator=(asn1c_wrapper_common&& other) noexcept
69 {
70 swap(other);
71 return *this;
72 }
73
74 // dereferencing
75 asn1c_type& operator*() { return *m_struct; }
76 asn1c_type* operator->() { return m_struct; }
77 const asn1c_type& operator*() const { return *m_struct; }
78 const asn1c_type* operator->() const { return m_struct; }
79
80 // direct access to content structure
81 const asn1c_type* content() const { return m_struct; }
82 asn1c_type* content() { return m_struct; }
83
84 // compare semantics
85 bool operator==(const asn1c_wrapper_common& rhs) const
86 {
87 return vanetza::asn1::compare(m_type, m_struct, rhs.m_struct) == 0;
88 }
89 bool operator!=(const asn1c_wrapper_common& rhs) const
90 {
91 return vanetza::asn1::compare(m_type, m_struct, rhs.m_struct) != 0;
92 }
93
94 /**
95 * Check ASN.1 constraints
96 * \param error (optional) copy of error message
97 * \return true if valid
98 */
99 bool validate() const
100 {
101 return vanetza::asn1::validate(m_type, m_struct);
102 }
103
104 /**
105 * Check ASN.1 constraints
106 * \param error Error message if any constraint failed
107 * \return true if valid
108 */
109 bool validate(std::string& error) const
110 {
111 return vanetza::asn1::validate(m_type, m_struct, error);
112 }
113
114 /**
115 * Compare ASN.1 types
116 * \param other Other ASN.1 type to compare with
117 * \return 0 if equal, <0 if other is "greater", >0 if other is "smaller"
118 */
119 int compare(const asn1c_wrapper_common& other) const
120 {
121 return vanetza::asn1::compare(m_type, m_struct, other.m_struct);
122 }
123
124 /**
125 * Print ASN.1 type to standard output
126 * \return 0 on success, -1 on error
127 */
128 int print() const
129 {
130 return vanetza::asn1::print(stdout, m_type, m_struct);
131 }
132
133 /**
134 * Print ASN.1 type to some file stream
135 * \param stream Output stream
136 * \return 0 on success, -1 on error
137 */
138 int print(FILE* stream) const
139 {
140 return vanetza::asn1::print(stream, m_type, m_struct);
141 }
142
143 /**
144 * Swap ASN.1 wrapper content
145 * \param other wrapper
146 */
147 void swap(asn1c_wrapper_common& other) noexcept
148 {
149 std::swap(m_struct, other.m_struct);
150 std::swap(m_type, other.m_type);
151 }
152
153protected:
154 asn1c_type* m_struct;
155 asn_TYPE_descriptor_t& m_type;
156};
157
158template<typename T>
159void swap(asn1c_wrapper_common<T>& lhs, asn1c_wrapper_common<T>& rhs)
160{
161 lhs.swap(rhs);
162}
163
164
165template<class T>
166class asn1c_per_wrapper : public asn1c_wrapper_common<T>
167{
168public:
169 using base = asn1c_wrapper_common<T>;
170 using base::base;
171
172 /**
173 * Encode ASN.1 struct into byte buffer
174 * \return byte buffer containing serialized ASN.1 struct
175 */
176 ByteBuffer encode() const
177 {
178 return vanetza::asn1::encode_per(base::m_type, base::m_struct);
179 }
180
181 /**
182 * Try to decode ASN.1 struct from byte buffer
183 * \param buffer input data
184 * \return true if decoding has been successful
185 */
186 bool decode(const ByteBuffer& buffer)
187 {
188 return vanetza::asn1::decode_per(base::m_type, (void**)&(base::m_struct), buffer);
189 }
190
191 bool decode(ByteBuffer::const_iterator begin, ByteBuffer::const_iterator end)
192 {
193 return vanetza::asn1::decode_per(base::m_type, (void**)&(base::m_struct), &(*begin), std::distance(begin, end));
194 }
195
196 bool decode(const void* buffer, std::size_t len)
197 {
198 return vanetza::asn1::decode_per(base::m_type, (void**)&(base::m_struct), buffer, len);
199 }
200
201 /**
202 * Get size of encoded ASN.1 struct
203 * \return size in bytes
204 */
205 std::size_t size() const
206 {
207 return vanetza::asn1::size_per(base::m_type, base::m_struct);
208 }
209};
210
211template<class T>
212using asn1c_wrapper = asn1c_per_wrapper<T>;
213
214
215template<class T>
216class asn1c_oer_wrapper : public asn1c_wrapper_common<T>
217{
218public:
219 using base = asn1c_wrapper_common<T>;
220 using base::base;
221
222 /**
223 * Encode ASN.1 struct into byte buffer
224 * \return byte buffer containing serialized ASN.1 struct
225 */
226 ByteBuffer encode() const
227 {
228 return vanetza::asn1::encode_oer(base::m_type, base::m_struct);
229 }
230
231 /**
232 * Try to decode ASN.1 struct from byte buffer
233 * \param buffer input data
234 * \deprecated use decode_per instead
235 * \return true if decoding has been successful
236 */
237 bool decode(const ByteBuffer& buffer)
238 {
239 return vanetza::asn1::decode_oer(base::m_type, (void**)&(base::m_struct), buffer);
240 }
241
242 bool decode(ByteBuffer::const_iterator begin, ByteBuffer::const_iterator end)
243 {
244 return vanetza::asn1::decode_oer(base::m_type, (void**)&(base::m_struct), &(*begin), std::distance(begin, end));
245 }
246
247 bool decode(const void* buffer, std::size_t len)
248 {
249 return vanetza::asn1::decode_oer(base::m_type, (void**)&(base::m_struct), buffer, len);
250 }
251
252 /**
253 * Get size of encoded ASN.1 struct
254 * \return size in bytes
255 */
256 std::size_t size() const
257 {
258 return vanetza::asn1::size_oer(base::m_type, base::m_struct);
259 }
260};
261
262template<class T>
263class asn1c_xer_wrapper : public asn1c_wrapper_common<T>
264{
265public:
266 using base = asn1c_wrapper_common<T>;
267 using base::base;
268
269 /**
270 * Encode ASN.1 struct into byte buffer
271 * \return byte buffer containing serialized ASN.1 struct
272 */
273 ByteBuffer encode() const
274 {
275 return vanetza::asn1::encode_xer(base::m_type, base::m_struct);
276 }
277
278 /**
279 * Try to decode ASN.1 struct from byte buffer
280 * \param buffer input data
281 * \return true if decoding has been successful
282 */
283 bool decode(const ByteBuffer& buffer)
284 {
285 return vanetza::asn1::decode_xer(base::m_type, (void**)&(base::m_struct), buffer);
286 }
287
288 bool decode(ByteBuffer::const_iterator begin, ByteBuffer::const_iterator end)
289 {
290 return vanetza::asn1::decode_xer(base::m_type, (void**)&(base::m_struct), &(*begin), std::distance(begin, end));
291 }
292
293 bool decode(const void* buffer, std::size_t len)
294 {
295 return vanetza::asn1::decode_xer(base::m_type, (void**)&(base::m_struct), buffer, len);
296 }
297
298 /**
299 * Get size of encoded ASN.1 struct
300 * \return size in bytes
301 */
302 std::size_t size() const
303 {
304 return vanetza::asn1::size_xer(base::m_type, base::m_struct);
305 }
306};
307
308} // namespace asn1
309} // namespace vanetza
310
311#endif /* ASN1C_WRAPPER_HPP_ZCNDO8E5 */
312
bool decode(const ByteBuffer &buffer)
bool decode(const ByteBuffer &buffer)
void swap(asn1c_wrapper_common &other) noexcept
int compare(const asn1c_wrapper_common &other) const
bool validate(std::string &error) const
bool decode(const ByteBuffer &buffer)