#pragma once /****************************************************************************** * * Copyright (c) 2019 AT&T Intellectual Property. * Copyright (c) 2018-2019 Nokia. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ // Standard Includes: ANSI C/C++, MSA, and Third-Party Libraries #include #include // Local Includes: Application specific classes, functions, and libraries #include "asn/elements.hpp" namespace asn{ /******************************************************************************** Utility **********************************S***********************************************/ inline void skip_row(std::ostream* str, size_t row_shift) //{*str << std::string(row_shift, ' ');} { std::string s(row_shift, ' '); str->write(s.data(), s.size()); } inline void print_hex(std::ostream* str, size_t size, const uint8_t* data, size_t row_shift) { *str << std::setfill('0') << std::hex << std::noshowbase; for (size_t i = 0; i < size; ++i) { if (i && (0x00 == (i & 0x0f))) { skip_row(str, row_shift); } *str << std::setw(2) << (int)data[i] << " "; if (0x0f == (i & 0x0f)) { *str << '\n'; } } } /******************************************************************************** Print *********************************************************************************/ /******************************************************************************** default implementation for IE *********************************************************************************/ template struct Print; template void print(IE const& ie, std::ostream& out, size_t row_shift) { Print::run(ie, &out, row_shift); } template std::string get_printed(IE const& ie, size_t row_shift = 0) { std::stringstream out; print(ie, out, row_shift); return out.str(); } /******************************************************************************** VisitorPrinter *********************************************************************************/ struct VisitorPrinter { VisitorPrinter(std::ostream* str, size_t row_shift) : m_pStream(str), m_RowShift(row_shift) {} template bool operator() (IE & ie) { Print::run(ie, m_pStream, m_RowShift); return true; } std::ostream* m_pStream; size_t m_RowShift; }; /****************************************************************** * PrinterAdapter *****************************************************************/ template struct PrinterAdapter { static void inline run(IE const& ie, std::ostream* str, size_t row_shift, Container const& cont) { Print::run(ie, str, row_shift); } }; template struct PrinterAdapter> { static void inline run(IE const& ie, std::ostream* str, size_t row_shift, Container const& cont) { VisitorPrinter vp(str, row_shift); ie.encode(vp, cont); } }; template struct PrinterAdapter > { static void inline run(IE const& ie, std::ostream* str, size_t row_shift, Container const& cont) { VisitorPrinter vp(str, row_shift); ie.encode(vp, cont); } }; /******************************************************************************** SeqVisitorPrinter *********************************************************************************/ template struct SeqVisitorPrinter { SeqVisitorPrinter(Container const& cont, std::ostream* str, size_t row_shift) : m_pStream(str), m_RowShift(row_shift), m_cont(cont) {} template bool operator() (IE & ie) { if(!IE::optional || ie.is_valid()) PrinterAdapter::run(ie, m_pStream, m_RowShift, m_cont); return true; } std::ostream* m_pStream; size_t m_RowShift; Container const& m_cont; }; /******************************************************************************** T_NULL *********************************************************************************/ template struct Print { static void inline run(IE const& ie, std::ostream* str, size_t row_shift) { skip_row(str, row_shift); *str << IE::name() << std::endl; } }; /******************************************************************************** T_BOOLEAN *********************************************************************************/ template struct Print { static void inline run(IE const& ie, std::ostream* str, size_t row_shift) { skip_row(str, row_shift); *str << IE::name() << " = " << (ie.get() ? "true" : "false")<< std::endl; } }; /******************************************************************************** T_INTEGER *********************************************************************************/ template struct Print { static void inline run(IE const& ie, std::ostream* str, size_t row_shift) { skip_row(str, row_shift); *str << IE::name() << " = " << std::hex << std::showbase << (size_t)ie.get() << std::endl; } }; /******************************************************************************** T_ENUMERATED *********************************************************************************/ template struct Print { static void inline run(IE const& ie, std::ostream* str, size_t row_shift) { skip_row(str, row_shift); *str << IE::name() << " = " << std::hex << std::showbase << (size_t)ie.get() << std::endl; } }; /******************************************************************************** T_BITSTRING *********************************************************************************/ template struct Print { static void inline run(IE const& ie, std::ostream* str, size_t row_shift) { skip_row(str, row_shift); auto& val = ie.get_buffer(); *str << IE::name() << " = "; print_hex(str, val.size() - 1, val.data(), row_shift + strlen(IE::name()) + 3); size_t i = val.size() - 1; uint8_t c = val.data()[i]; uint8_t b = val.bitqty() % 8; if (b != 0) c = c << (8 - b); if (i && (0x00 == (i & 0x0f))) { skip_row(str, row_shift); } *str << std::setw(2) << (int)c; *str << " (" << std::dec << val.bitqty() << " bits)" << std::endl; } }; /******************************************************************************** T_OCTETSTRING *********************************************************************************/ template struct Print { static void inline run(IE const& ie, std::ostream* str, size_t row_shift) { skip_row(str, row_shift); *str << IE::name() << " = "; auto & val = ie.get(); print_hex(str, val.size(), val.data(), row_shift + strlen(IE::name()) + 3); *str << std::endl; } }; /******************************************************************************** T_SEQUENCE *********************************************************************************/ template struct Print { static void inline run(IE const& ie, std::ostream* str, size_t row_shift) { skip_row(str, row_shift); *str << IE::name() << std::endl; SeqVisitorPrinter vp(ie, str, row_shift + 1); ie.encode(vp); } }; /******************************************************************************** T_SET *********************************************************************************/ template struct Print { static void inline run(IE const& ie, std::ostream* str, size_t row_shift) { skip_row(str, row_shift); *str << IE::name() << std::endl; SeqVisitorPrinter vp(ie, str, row_shift + 1); ie.encode(vp); } }; /******************************************************************************** T_CHOICE *********************************************************************************/ template struct Print { static void inline run(IE const& ie, std::ostream* str, size_t row_shift) { VisitorPrinter vp(str, row_shift+1); skip_row(str, row_shift); *str << IE::name() << ":\n"; ie.encode(vp); } }; /******************************************************************************** T_SEQUENCE_OF *********************************************************************************/ template struct Print { static void inline run(IE const& ie, std::ostream* str, size_t row_shift) { skip_row(str, row_shift); *str << IE::name() << ":\n"; ++row_shift; for (auto& elem : ie) { Print::run(elem, str, row_shift); } } }; /******************************************************************************** T_SET_OF *********************************************************************************/ template struct Print { static void inline run(IE const& ie, std::ostream* str, size_t row_shift) { skip_row(str, row_shift); *str << IE::name() << ":\n"; ++row_shift; for (auto& elem : ie) { Print::run(elem, str, row_shift); } } }; /******************************************************************************** T_OBJECTIDENTIFIER *********************************************************************************/ template struct Print { static void inline run(IE const& ie, std::ostream* str, size_t row_shift) { skip_row(str, row_shift); *str << IE::name() << std::endl; } }; } //namespace asn