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