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&);
21std::size_t size_per(asn_TYPE_descriptor_t&, const void*);
22std::size_t size_oer(asn_TYPE_descriptor_t&, const void*);
23ByteBuffer encode_per(asn_TYPE_descriptor_t&, const void*);
24bool decode_per(asn_TYPE_descriptor_t&, void**, const ByteBuffer&);
25bool decode_per(asn_TYPE_descriptor_t&, void**, const void* buffer, std::size_t size);
26ByteBuffer encode_oer(asn_TYPE_descriptor_t&, const void*);
27bool decode_oer(asn_TYPE_descriptor_t&, void**, const ByteBuffer&);
28bool decode_oer(asn_TYPE_descriptor_t&, void**, const void* buffer, std::size_t size);
29
30template<class T>
31T* allocate()
32{
33 return static_cast<T*>(allocate(sizeof(T)));
34}
35
36template<class T>
38{
39
40public:
41 typedef T asn1c_type;
42
43 asn1c_wrapper_common(asn_TYPE_descriptor_t& desc) :
44 m_struct(vanetza::asn1::allocate<asn1c_type>()), m_type(desc) {}
45 ~asn1c_wrapper_common() { vanetza::asn1::free(m_type, m_struct); }
46
47 // copy semantics
49 m_struct(static_cast<asn1c_type*>(copy(other.m_type, other.m_struct))), m_type(other.m_type) {}
50 asn1c_wrapper_common& operator=(const asn1c_wrapper_common& other)
51 {
52 asn1c_wrapper_common tmp = other;
53 swap(tmp);
54 return *this;
55 }
56
57 // move semantics
59 m_struct(nullptr), m_type(other.m_type) { swap(other); }
60 asn1c_wrapper_common& operator=(asn1c_wrapper_common&& other) noexcept
61 {
62 swap(other);
63 return *this;
64 }
65
66 // dereferencing
67 asn1c_type& operator*() { return *m_struct; }
68 asn1c_type* operator->() { return m_struct; }
69 const asn1c_type& operator*() const { return *m_struct; }
70 const asn1c_type* operator->() const { return m_struct; }
71
72 // direct access to content structure
73 const asn1c_type* content() const { return m_struct; }
74 asn1c_type* content() { return m_struct; }
75
76 /**
77 * Check ASN.1 constraints
78 * \param error (optional) copy of error message
79 * \return true if valid
80 */
81 bool validate() const
82 {
83 return vanetza::asn1::validate(m_type, m_struct);
84 }
85
86 /**
87 * Check ASN.1 constraints
88 * \param error Error message if any constraint failed
89 * \return true if valid
90 */
91 bool validate(std::string& error) const
92 {
93 return vanetza::asn1::validate(m_type, m_struct, error);
94 }
95
96 /**
97 * Swap ASN.1 wrapper content
98 * \param other wrapper
99 */
100 void swap(asn1c_wrapper_common& other) noexcept
101 {
102 std::swap(m_struct, other.m_struct);
103 std::swap(m_type, other.m_type);
104 }
105
106protected:
107 asn1c_type* m_struct;
108 asn_TYPE_descriptor_t& m_type;
109};
110
111template<typename T>
112void swap(asn1c_wrapper_common<T>& lhs, asn1c_wrapper_common<T>& rhs)
113{
114 lhs.swap(rhs);
115}
116
117
118template<class T>
120{
121public:
123 using base::base;
124
125 /**
126 * Encode ASN.1 struct into byte buffer
127 * \return byte buffer containing serialized ASN.1 struct
128 */
129 ByteBuffer encode() const
130 {
131 return vanetza::asn1::encode_per(base::m_type, base::m_struct);
132 }
133
134 /**
135 * Try to decode ASN.1 struct from byte buffer
136 * \param buffer input data
137 * \return true if decoding has been successful
138 */
139 bool decode(const ByteBuffer& buffer)
140 {
141 return vanetza::asn1::decode_per(base::m_type, (void**)&(base::m_struct), buffer);
142 }
143
144 bool decode(ByteBuffer::const_iterator begin, ByteBuffer::const_iterator end)
145 {
146 return vanetza::asn1::decode_per(base::m_type, (void**)&(base::m_struct), &(*begin), std::distance(begin, end));
147 }
148
149 bool decode(const void* buffer, std::size_t len)
150 {
151 return vanetza::asn1::decode_per(base::m_type, (void**)&(base::m_struct), buffer, len);
152 }
153
154 /**
155 * Get size of encoded ASN.1 struct
156 * \return size in bytes
157 */
158 std::size_t size() const
159 {
160 return vanetza::asn1::size_per(base::m_type, base::m_struct);
161 }
162};
163
164template<class T>
165using asn1c_wrapper = asn1c_per_wrapper<T>;
166
167
168template<class T>
170{
171public:
173 using base::base;
174
175 /**
176 * Encode ASN.1 struct into byte buffer
177 * \return byte buffer containing serialized ASN.1 struct
178 */
179 ByteBuffer encode() const
180 {
181 return vanetza::asn1::encode_oer(base::m_type, base::m_struct);
182 }
183
184 /**
185 * Try to decode ASN.1 struct from byte buffer
186 * \param buffer input data
187 * \deprecated use decode_per instead
188 * \return true if decoding has been successful
189 */
190 bool decode(const ByteBuffer& buffer)
191 {
192 return vanetza::asn1::decode_oer(base::m_type, (void**)&(base::m_struct), buffer);
193 }
194
195 bool decode(ByteBuffer::const_iterator begin, ByteBuffer::const_iterator end)
196 {
197 return vanetza::asn1::decode_oer(base::m_type, (void**)&(base::m_struct), &(*begin), std::distance(begin, end));
198 }
199
200 bool decode(const void* buffer, std::size_t len)
201 {
202 return vanetza::asn1::decode_oer(base::m_type, (void**)&(base::m_struct), buffer, len);
203 }
204
205 /**
206 * Get size of encoded ASN.1 struct
207 * \return size in bytes
208 */
209 std::size_t size() const
210 {
211 return vanetza::asn1::size_oer(base::m_type, base::m_struct);
212 }
213};
214
215} // namespace asn1
216} // namespace vanetza
217
218#endif /* ASN1C_WRAPPER_HPP_ZCNDO8E5 */
219
bool decode(const ByteBuffer &buffer)
bool decode(const ByteBuffer &buffer)
void swap(asn1c_wrapper_common &other) noexcept
bool validate(std::string &error) const