Enhanced SIM for E2AP v1 for TS UC
[sim/e2-interface.git] / e2sim / e2apv1sim / src / ASN1 / asn / printer.hpp
1 #pragma once
2
3 /******************************************************************************
4 *
5 *   Copyright (c) 2019 AT&T Intellectual Property.
6 *   Copyright (c) 2018-2019 Nokia.
7 *
8 *   Licensed under the Apache License, Version 2.0 (the "License");
9 *   you may not use this file except in compliance with the License.
10 *   You may obtain a copy of the License at
11 *
12 *       http://www.apache.org/licenses/LICENSE-2.0
13 *
14 *   Unless required by applicable law or agreed to in writing, software
15 *   distributed under the License is distributed on an "AS IS" BASIS,
16 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 *   See the License for the specific language governing permissions and
18 *   limitations under the License.
19 *
20 ******************************************************************************/
21
22 // Standard Includes: ANSI C/C++, MSA, and Third-Party Libraries
23 #include <iostream>
24 #include <iomanip>
25
26 // Local Includes: Application specific classes, functions, and libraries
27 #include "asn/elements.hpp"
28
29 namespace asn{
30
31 /********************************************************************************
32 Utility
33 **********************************S***********************************************/
34 inline void skip_row(std::ostream* str, size_t row_shift)
35         //{*str << std::string(row_shift, ' ');}
36 {
37         std::string s(row_shift, ' ');
38         str->write(s.data(), s.size());
39 }
40
41 inline void print_hex(std::ostream* str, size_t size, const uint8_t* data, size_t row_shift)
42 {
43         *str << std::setfill('0') << std::hex << std::noshowbase;
44         for (size_t i = 0; i < size; ++i)
45         {
46                 if (i && (0x00 == (i & 0x0f))) { skip_row(str, row_shift); }
47                 *str << std::setw(2) << (int)data[i] << " ";
48                 if (0x0f == (i & 0x0f)) { *str << '\n'; }
49         }
50 }
51
52 /********************************************************************************
53
54 Print
55
56 *********************************************************************************/
57
58
59 /********************************************************************************
60 default implementation for IE
61 *********************************************************************************/
62 template <class IE, element_type IE_TYPE>
63 struct Print;
64
65 template <class IE>
66 void print(IE const& ie, std::ostream& out, size_t row_shift)
67 {
68         Print<IE, IE::ie_type>::run(ie, &out, row_shift);
69 }
70
71 template <class IE>
72 std::string get_printed(IE const& ie, size_t row_shift = 0)
73 {
74         std::stringstream out;
75         print(ie, out, row_shift);
76         return out.str();
77 }
78
79
80 /********************************************************************************
81 VisitorPrinter
82 *********************************************************************************/
83 struct VisitorPrinter
84 {
85         VisitorPrinter(std::ostream* str, size_t row_shift) : m_pStream(str), m_RowShift(row_shift) {}
86
87         template <typename IE>
88         bool operator() (IE & ie)
89         {
90                 Print<IE, IE::ie_type>::run(ie, m_pStream, m_RowShift);
91                 return true;
92         }
93
94         std::ostream*   m_pStream;
95         size_t                  m_RowShift;
96 };
97
98 /******************************************************************
99  * PrinterAdapter
100  *****************************************************************/
101 template <class Container, typename IE, class Enabler = void>
102 struct PrinterAdapter
103 {
104         static void inline run(IE const& ie, std::ostream* str, size_t row_shift, Container const& cont)
105         {
106                 Print<IE, IE::ie_type>::run(ie, str, row_shift);
107         }
108 };
109 template <class Container, typename IE>
110 struct PrinterAdapter<Container, IE, std::enable_if_t< (IE::ie_type == element_type::T_OBJFIELD_FTV) >>
111 {
112         static void inline run(IE const& ie, std::ostream* str, size_t row_shift, Container const& cont)
113         {
114                 VisitorPrinter vp(str, row_shift);
115                 ie.encode(vp, cont);
116         }
117 };
118 template <class Container, typename IE>
119 struct PrinterAdapter<Container, IE, std::enable_if_t< (IE::ie_type == element_type::T_OBJFIELD_TF)> >
120 {
121         static void inline run(IE const& ie, std::ostream* str, size_t row_shift, Container const& cont)
122         {
123                 VisitorPrinter vp(str, row_shift);
124                 ie.encode(vp, cont);
125         }
126 };
127
128 /********************************************************************************
129 SeqVisitorPrinter
130 *********************************************************************************/
131 template <class Container>
132 struct SeqVisitorPrinter
133 {
134         SeqVisitorPrinter(Container const& cont, std::ostream* str, size_t row_shift) : m_pStream(str), m_RowShift(row_shift), m_cont(cont) {}
135
136         template <typename IE>
137         bool operator() (IE & ie)
138         {
139                 if(!IE::optional || ie.is_valid())
140                         PrinterAdapter<Container, IE>::run(ie, m_pStream, m_RowShift, m_cont);
141                 return true;
142         }
143
144         std::ostream*           m_pStream;
145         size_t                          m_RowShift;
146         Container const&        m_cont;
147 };
148
149
150 /********************************************************************************
151 T_NULL
152 *********************************************************************************/
153
154 template <class IE>
155 struct Print<IE, element_type::T_NULL>
156 {
157         static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
158         {
159                 skip_row(str, row_shift);
160                 *str << IE::name() << std::endl;
161         }
162 };
163
164 /********************************************************************************
165 T_BOOLEAN
166 *********************************************************************************/
167 template <class IE>
168 struct Print<IE, element_type::T_BOOLEAN>
169 {
170         static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
171         {
172                 skip_row(str, row_shift);
173                 *str << IE::name() << " = " << (ie.get() ? "true" : "false")<< std::endl;
174         }
175 };
176
177 /********************************************************************************
178 T_INTEGER
179 *********************************************************************************/
180 template <class IE>
181 struct Print<IE, element_type::T_INTEGER>
182 {
183         static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
184         {
185                 skip_row(str, row_shift);
186                 *str << IE::name() << " = " << std::hex << std::showbase << (size_t)ie.get() << std::endl;
187         }
188 };
189
190 /********************************************************************************
191 T_ENUMERATED
192 *********************************************************************************/
193 template <class IE>
194 struct Print<IE, element_type::T_ENUMERATED>
195 {
196         static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
197         {
198                 skip_row(str, row_shift);
199                 *str << IE::name() << " = " << std::hex << std::showbase << (size_t)ie.get() << std::endl;
200         }
201 };
202
203 /********************************************************************************
204 T_BITSTRING
205 *********************************************************************************/
206 template <class IE>
207 struct Print<IE, element_type::T_BITSTRING>
208 {
209         static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
210         {
211                 skip_row(str, row_shift);
212                 auto& val = ie.get_buffer();
213                 *str << IE::name() << " = ";
214
215                 print_hex(str, val.size() - 1, val.data(), row_shift + strlen(IE::name()) + 3);
216
217                 size_t  i = val.size() - 1;
218                 uint8_t c = val.data()[i];
219                 uint8_t b = val.bitqty() % 8;
220                 if (b != 0) c = c << (8 - b);
221
222                 if (i && (0x00 == (i & 0x0f))) { skip_row(str, row_shift); }
223                 *str << std::setw(2) << (int)c;
224
225                 *str << " (" << std::dec << val.bitqty() << " bits)" << std::endl;
226
227         }
228 };
229
230 /********************************************************************************
231 T_OCTETSTRING
232 *********************************************************************************/
233 template <class IE>
234 struct Print<IE, element_type::T_OCTETSTRING>
235 {
236         static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
237         {
238                 skip_row(str, row_shift);
239                 *str << IE::name() << " = ";
240                 auto & val = ie.get();
241                 print_hex(str, val.size(), val.data(), row_shift + strlen(IE::name()) + 3);
242                 *str << std::endl;
243         }
244 };
245
246 /********************************************************************************
247 T_SEQUENCE
248 *********************************************************************************/
249 template <class IE>
250 struct Print<IE, element_type::T_SEQUENCE>
251 {
252         static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
253         {
254                 skip_row(str, row_shift);
255                 *str << IE::name() << std::endl;
256                 SeqVisitorPrinter<IE> vp(ie, str, row_shift + 1);
257                 ie.encode(vp);
258         }
259 };
260
261 /********************************************************************************
262 T_SET
263 *********************************************************************************/
264 template <class IE>
265 struct Print<IE, element_type::T_SET>
266 {
267         static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
268         {
269                 skip_row(str, row_shift);
270                 *str << IE::name() << std::endl;
271                 SeqVisitorPrinter<IE> vp(ie, str, row_shift + 1);
272                 ie.encode(vp);
273         }
274 };
275
276
277 /********************************************************************************
278 T_CHOICE
279 *********************************************************************************/
280 template <class IE>
281 struct Print<IE, element_type::T_CHOICE>
282 {
283         static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
284         {
285                 VisitorPrinter vp(str, row_shift+1);
286                 skip_row(str, row_shift); *str << IE::name() << ":\n";
287                 ie.encode(vp);
288         }
289 };
290
291 /********************************************************************************
292 T_SEQUENCE_OF
293 *********************************************************************************/
294 template <class IE>
295 struct Print<IE, element_type::T_SEQUENCE_OF>
296 {
297         static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
298         {
299                 skip_row(str, row_shift); *str << IE::name() << ":\n";
300                 ++row_shift;
301                 for (auto& elem : ie)
302                 {
303                         Print<typename IE::element_t, IE::element_t::ie_type>::run(elem, str, row_shift);
304                 }
305         }
306 };
307
308 /********************************************************************************
309 T_SET_OF
310 *********************************************************************************/
311 template <class IE>
312 struct Print<IE, element_type::T_SET_OF>
313 {
314         static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
315         {
316                 skip_row(str, row_shift); *str << IE::name() << ":\n";
317                 ++row_shift;
318                 for (auto& elem : ie)
319                 {
320                         Print<typename IE::element_t, IE::element_t::ie_type>::run(elem, str, row_shift);
321                 }
322         }
323 };
324
325 /********************************************************************************
326 T_OBJECTIDENTIFIER
327 *********************************************************************************/
328 template <class IE>
329 struct Print<IE, element_type::T_OBJECTIDENTIFIER>
330 {
331         static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
332         {
333                 skip_row(str, row_shift);
334                 *str << IE::name() << std::endl;
335         }
336 };
337
338 } //namespace asn