3 /******************************************************************************
5 * Copyright (c) 2019 AT&T Intellectual Property.
6 * Copyright (c) 2018-2019 Nokia.
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 ******************************************************************************/
22 // Standard Includes: ANSI C/C++, MSA, and Third-Party Libraries
26 // Local Includes: Application specific classes, functions, and libraries
27 #include "asn/elements.hpp"
31 /********************************************************************************
33 **********************************S***********************************************/
34 inline void skip_row(std::ostream* str, size_t row_shift)
35 //{*str << std::string(row_shift, ' ');}
37 std::string s(row_shift, ' ');
38 str->write(s.data(), s.size());
41 inline void print_hex(std::ostream* str, size_t size, const uint8_t* data, size_t row_shift)
43 *str << std::setfill('0') << std::hex << std::noshowbase;
44 for (size_t i = 0; i < size; ++i)
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'; }
52 /********************************************************************************
56 *********************************************************************************/
59 /********************************************************************************
60 default implementation for IE
61 *********************************************************************************/
62 template <class IE, element_type IE_TYPE>
66 void print(IE const& ie, std::ostream& out, size_t row_shift)
68 Print<IE, IE::ie_type>::run(ie, &out, row_shift);
72 std::string get_printed(IE const& ie, size_t row_shift = 0)
74 std::stringstream out;
75 print(ie, out, row_shift);
80 /********************************************************************************
82 *********************************************************************************/
85 VisitorPrinter(std::ostream* str, size_t row_shift) : m_pStream(str), m_RowShift(row_shift) {}
87 template <typename IE>
88 bool operator() (IE & ie)
90 Print<IE, IE::ie_type>::run(ie, m_pStream, m_RowShift);
94 std::ostream* m_pStream;
98 /******************************************************************
100 *****************************************************************/
101 template <class Container, typename IE, class Enabler = void>
102 struct PrinterAdapter
104 static void inline run(IE const& ie, std::ostream* str, size_t row_shift, Container const& cont)
106 Print<IE, IE::ie_type>::run(ie, str, row_shift);
109 template <class Container, typename IE>
110 struct PrinterAdapter<Container, IE, std::enable_if_t< (IE::ie_type == element_type::T_OBJFIELD_FTV) >>
112 static void inline run(IE const& ie, std::ostream* str, size_t row_shift, Container const& cont)
114 VisitorPrinter vp(str, row_shift);
118 template <class Container, typename IE>
119 struct PrinterAdapter<Container, IE, std::enable_if_t< (IE::ie_type == element_type::T_OBJFIELD_TF)> >
121 static void inline run(IE const& ie, std::ostream* str, size_t row_shift, Container const& cont)
123 VisitorPrinter vp(str, row_shift);
128 /********************************************************************************
130 *********************************************************************************/
131 template <class Container>
132 struct SeqVisitorPrinter
134 SeqVisitorPrinter(Container const& cont, std::ostream* str, size_t row_shift) : m_pStream(str), m_RowShift(row_shift), m_cont(cont) {}
136 template <typename IE>
137 bool operator() (IE & ie)
139 if(!IE::optional || ie.is_valid())
140 PrinterAdapter<Container, IE>::run(ie, m_pStream, m_RowShift, m_cont);
144 std::ostream* m_pStream;
146 Container const& m_cont;
150 /********************************************************************************
152 *********************************************************************************/
155 struct Print<IE, element_type::T_NULL>
157 static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
159 skip_row(str, row_shift);
160 *str << IE::name() << std::endl;
164 /********************************************************************************
166 *********************************************************************************/
168 struct Print<IE, element_type::T_BOOLEAN>
170 static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
172 skip_row(str, row_shift);
173 *str << IE::name() << " = " << (ie.get() ? "true" : "false")<< std::endl;
177 /********************************************************************************
179 *********************************************************************************/
181 struct Print<IE, element_type::T_INTEGER>
183 static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
185 skip_row(str, row_shift);
186 *str << IE::name() << " = " << std::hex << std::showbase << (size_t)ie.get() << std::endl;
190 /********************************************************************************
192 *********************************************************************************/
194 struct Print<IE, element_type::T_ENUMERATED>
196 static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
198 skip_row(str, row_shift);
199 *str << IE::name() << " = " << std::hex << std::showbase << (size_t)ie.get() << std::endl;
203 /********************************************************************************
205 *********************************************************************************/
207 struct Print<IE, element_type::T_BITSTRING>
209 static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
211 skip_row(str, row_shift);
212 auto& val = ie.get_buffer();
213 *str << IE::name() << " = ";
215 print_hex(str, val.size() - 1, val.data(), row_shift + strlen(IE::name()) + 3);
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);
222 if (i && (0x00 == (i & 0x0f))) { skip_row(str, row_shift); }
223 *str << std::setw(2) << (int)c;
225 *str << " (" << std::dec << val.bitqty() << " bits)" << std::endl;
230 /********************************************************************************
232 *********************************************************************************/
234 struct Print<IE, element_type::T_OCTETSTRING>
236 static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
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);
246 /********************************************************************************
248 *********************************************************************************/
250 struct Print<IE, element_type::T_SEQUENCE>
252 static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
254 skip_row(str, row_shift);
255 *str << IE::name() << std::endl;
256 SeqVisitorPrinter<IE> vp(ie, str, row_shift + 1);
261 /********************************************************************************
263 *********************************************************************************/
265 struct Print<IE, element_type::T_SET>
267 static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
269 skip_row(str, row_shift);
270 *str << IE::name() << std::endl;
271 SeqVisitorPrinter<IE> vp(ie, str, row_shift + 1);
277 /********************************************************************************
279 *********************************************************************************/
281 struct Print<IE, element_type::T_CHOICE>
283 static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
285 VisitorPrinter vp(str, row_shift+1);
286 skip_row(str, row_shift); *str << IE::name() << ":\n";
291 /********************************************************************************
293 *********************************************************************************/
295 struct Print<IE, element_type::T_SEQUENCE_OF>
297 static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
299 skip_row(str, row_shift); *str << IE::name() << ":\n";
301 for (auto& elem : ie)
303 Print<typename IE::element_t, IE::element_t::ie_type>::run(elem, str, row_shift);
308 /********************************************************************************
310 *********************************************************************************/
312 struct Print<IE, element_type::T_SET_OF>
314 static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
316 skip_row(str, row_shift); *str << IE::name() << ":\n";
318 for (auto& elem : ie)
320 Print<typename IE::element_t, IE::element_t::ie_type>::run(elem, str, row_shift);
325 /********************************************************************************
327 *********************************************************************************/
329 struct Print<IE, element_type::T_OBJECTIDENTIFIER>
331 static void inline run(IE const& ie, std::ostream* str, size_t row_shift)
333 skip_row(str, row_shift);
334 *str << IE::name() << std::endl;