+++ /dev/null
-#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 <boost/intrusive/list.hpp>
-#include <cstring>
-
-// Local Includes: Application specific classes, functions, and libraries
-#include "asn/constraints.hpp"
-#include "asn/identifier.hpp"
-
-namespace asn {
-
-enum class element_type : uint8_t
-{
- T_BOOLEAN
- ,T_INTEGER
- ,T_ENUMERATED
- ,T_REAL
- ,T_BITSTRING
- ,T_OCTETSTRING
- ,T_NULL
- ,T_SEQUENCE
- ,T_SEQUENCE_OF
- ,T_SET
- ,T_SET_OF
- ,T_CHOICE
- ,T_OBJECTIDENTIFIER
- ,T_OBJFIELD_FTV
- ,T_OBJFIELD_TF
-};
-
-/***************************************************************************************
-* BASE
-***************************************************************************************/
-
-struct base
-{
- static constexpr bool optional = false;
- static constexpr bool extension = false;
-
- static constexpr char const* name() {return "";}
-
- void setpresent(bool p) {is_set = p;}
- void clear() {is_set = false;}
-
- bool is_valid() const {return is_set;}
-
-protected:
- base() {}
- void set() {is_set = true;}
-protected:
- bool is_set {false};
-
- base& operator=(const base&) = delete;
- base (const base&) = delete;
-};
-
-/***************************************************************************************
-* IE_NULL
-***************************************************************************************/
-
-struct nulltype : base
-{
- using asn_identifier_t = identifier<class_type_t::UNIVERSAL, static_cast<tag_value_t>(tag_rvalue_t::NULL_TYPE), tag_type_t::IMPLICIT>;
-
- static constexpr element_type ie_type = element_type::T_NULL;
- static constexpr const char* name() {return "NULL";}
-
- void clear() {}
-};
-
-/***************************************************************************************
-* T_BOOLEAN
-***************************************************************************************/
-
-struct boolean : base
-{
- using asn_identifier_t = identifier<class_type_t::UNIVERSAL, static_cast<tag_value_t>(tag_rvalue_t::BOOLEAN), tag_type_t::IMPLICIT>;
-
- static constexpr element_type ie_type = element_type::T_BOOLEAN;
- static constexpr const char* name() {return "BOOLEAN";}
-
- using value_type = bool;
-
- void set(value_type vl) { m_value = vl; base::set();}
- value_type get() const { return m_value; }
- void clear() { m_value = false; base::clear();}
-
-private:
- value_type m_value {false};
-};
-
-/***************************************************************************************
-* T_INTEGER
-***************************************************************************************/
-template < class Constraint = constraints<false> >
-struct integer : base
-{
- using asn_identifier_t = identifier<class_type_t::UNIVERSAL, static_cast<tag_value_t>(tag_rvalue_t::INTEGER), tag_type_t::IMPLICIT>;
-
- static constexpr element_type ie_type = element_type::T_INTEGER;
- static constexpr const char* name() {return "INTEGER";}
-
- using constraint_t = Constraint;
- using value_type = int64_t;
-
- bool equal(value_type v) const {return m_value == v;}
-
- void set(value_type v) { m_value = v; base::set();}
- value_type get() const { return m_value; }
-
- void clear() { m_value = 0; base::clear();}
-
-private:
- value_type m_value;
-};
-
-/***************************************************************************************
-* T_ENUMERATED
-***************************************************************************************/
-template<int TotalNumEntries, int NumExtEntries, bool Extended>
-struct enumerated : base
-{
- using asn_identifier_t = identifier<class_type_t::UNIVERSAL, static_cast<tag_value_t>(tag_rvalue_t::ENUMERATED), tag_type_t::IMPLICIT>;
-
- static constexpr element_type ie_type = element_type::T_ENUMERATED;
- static constexpr const char* name() {return "ENUMERATED";}
-
- using constraint_t = seq_range<TotalNumEntries, NumExtEntries, Extended>;
- using value_type = typename constraint_t::value_type;
-
- bool equal(value_type v) const {return m_value == v;}
- void set(value_type vl) { m_value = vl; base::set();}
- value_type get() const { return m_value; }
- void clear() { m_value = constraint_t::default_value; base::clear();}
-
-private:
- value_type m_value;
-};
-
-/***************************************************************************************
-* T_OCTETSTRING
-***************************************************************************************/
-template< class Constraint = constraints<false> >
-struct ostring : base
-{
- using asn_identifier_t = identifier<class_type_t::UNIVERSAL, static_cast<tag_value_t>(tag_rvalue_t::OCTET_STRING), tag_type_t::IMPLICIT>;
-
- static constexpr element_type ie_type = element_type::T_OCTETSTRING;
- static constexpr const char* name() {return "OCTET STING";}
- using constraint_t = Constraint;
-
- struct value_type
- {
- value_type() {}
- value_type(size_t size, const char* data) : m_size(size), m_data(reinterpret_cast<const uint8_t*>(data)) {}
-
- size_t size() const { return m_size; }
- const uint8_t* data() const { return m_data; }
-
- using const_iterator = uint8_t const*;
- const_iterator begin() const { return data(); }
- const_iterator end() const { return begin() + size(); }
-
- void assign(void const* p, size_t sz) { m_data = static_cast<uint8_t const*>(p); m_size = sz; }
-
- private:
- const uint8_t* m_data{ 0 };
- size_t m_size{ 0 };
- };
-
- value_type const& get() const { return m_value; }
-
- //Use std::string, std::vector or IE_OSTR::value_type
- template<typename T> value_type const& set(T const& tval)
- {
- set(tval.size(), tval.data());
- base::set();
- return m_value;
- }
-
- void set(size_t size, void const* data)
- {
- m_value.assign(data, size);
- base::set();
- }
-
- template<class AT>
- ostring& emplace(AT& allocator, size_t size, uint8_t const * data_in)
- {
- if(size)
- {
- base::clear();
- uint8_t* data_out = allocator.alloc_bytes(size);
- if (data_out)
- {
- memcpy(data_out, data_in, size);
- set(size, data_out);
- }
- }
- else
- base::set();
- return *this;
- }
-
- template<class AT, class T>
- ostring& emplace(AT& allocator, T const& tval)
- {
- return emplace(allocator, tval.size(), reinterpret_cast<const uint8_t*>(tval.data()));
- }
-
- void clear() { m_value = value_type{}; base::clear();}
-
-private:
- value_type m_value;
-};
-
-/***************************************************************************************
-* T_BITSTRING
-***************************************************************************************/
-template<class Constraint = constraints<false> >
-struct bstring : base
-{
- using asn_identifier_t = identifier<class_type_t::UNIVERSAL, static_cast<tag_value_t>(tag_rvalue_t::BIT_STRING), tag_type_t::IMPLICIT>;
-
- static constexpr element_type ie_type = element_type::T_BITSTRING;
- static constexpr const char* name() {return "BIT STING";}
- using constraint_t = Constraint;
-
- struct value_type
- {
- value_type() {}
- value_type(size_t size, const char* data, size_t bitqty) : m_size(size), m_data(reinterpret_cast<const uint8_t*>(data)), m_bitqty(bitqty){}
-
- size_t size() const { return m_size; }
- const uint8_t* data() const { return m_data; }
- size_t bitqty() const { return m_bitqty; }
-
- void assign(void const* p, size_t sz, size_t bits) { m_data = static_cast<uint8_t const*>(p); m_size = sz; m_bitqty = bits; }
-
- private:
- const uint8_t* m_data{ nullptr };
- size_t m_size{ 0 };
- size_t m_bitqty{ 0 };
- };
-
- value_type const& get_buffer() const { return m_value; }
-
- size_t get_bitqty() const { return m_value.bitqty(); }
-
- //Use std::string, std::vector or IE_BSTR::value_type
- template<typename T> value_type const& set_buffer(T& tval, size_t bitqty)
- {
- m_value.assign(tval.data(), tval.size(), bitqty);
- base::set();
- return m_value;
- }
-
- void set_buffer(size_t bitqty, const uint8_t* data)
- {
- m_value.assign(data, (bitqty +7) >> 3, bitqty);
- base::set();
- }
-
- template<class AT>
- bstring& emplace_buffer(AT& allocator, size_t bitqty, uint8_t const * data_in)
- {
- size_t size = (bitqty +7) >> 3;
- uint8_t* data_out = allocator.alloc_bytes(size);
- if (!data_out) {
- throw std::bad_alloc();
- }
- memcpy(data_out, data_in, size);
- set_buffer(bitqty, data_out);
- return *this;
- }
-
- void clear() { m_value = value_type{}; base::clear();}
-
- uint64_t get_number() const
- {
- uint64_t retval{0};
- size_t i = 0;
- for(; i < m_value.size() - 1; ++i)
- {
- retval <<= 8;
- retval |= m_value.data()[i];
- }
-
- uint8_t shift = m_value.bitqty() % 8;
- if (shift)
- {
- retval <<= shift;
- }
- else
- {
- retval <<= 8;
- }
-
- retval |= m_value.data()[i];
-
- return retval;
- }
-
- template<class AT>
- void set_number(AT& allocator, size_t bitqty, uint64_t data)
- {
- size_t size = (bitqty +7) >> 3;
- uint8_t* data_out = allocator.alloc_bytes(size);
- if (!data_out) {
- throw std::bad_alloc();
- }
-
- const uint8_t shift = bitqty % 8;
- if (shift)
- {
- data_out[size-1] = data & (0xFF >> (8 - shift));
- data >>= shift;
- }
- else
- {
- data_out[size-1] = data & (0xFF);
- data >>= 8;
- }
-
- for (size_t i = 1; i <= size - 1; i++)
- {
- data_out[size-1-i] = data & (0xFF);
- data >>= 8;
- }
-
- m_value.assign(data_out, size, bitqty);
- base::set();
- }
-
-private:
- value_type m_value;
-};
-
-/***************************************************************************************
-* T_CHOICE
-***************************************************************************************/
-template<int TotalNumEntries, int NumExtEntries, bool Extended>
-struct choice : base
-{
- using asn_identifier_t = identifier<class_type_t::UNSPECIFIED, static_cast<tag_value_t>(tag_rvalue_t::CHOICE), tag_type_t::IMPLICIT>;
-
- static constexpr element_type ie_type = element_type::T_CHOICE;
- static constexpr const char* name() {return "CHOICE";}
-
- using constraint_t = seq_range<TotalNumEntries, NumExtEntries, Extended>;
- using index_type = size_t;
- using value_type = size_t;
-
- static constexpr index_type fst_index = 1;
- static constexpr index_type ext_index = fst_index + TotalNumEntries;
-
- static index_type normalize(index_type idx) {return idx - fst_index;}
- static index_type denormalize(index_type idx) {return idx + fst_index;}
-};
-
-/***************************************************************************************
-* T_SEQUENCE
-***************************************************************************************/
-template<int TotalNumEntries, int NumExtEntries, bool Extended, int NumOptEntries = 0>
-struct sequence : base
-{
- using asn_identifier_t = identifier<class_type_t::UNIVERSAL, static_cast<tag_value_t>(tag_rvalue_t::SEQUENCE), tag_type_t::IMPLICIT>;
-
- static constexpr element_type ie_type = element_type::T_SEQUENCE;
- static constexpr const char* name() {return "SEQUENCE";}
-
- static constexpr bound_t num_total_entries = TotalNumEntries;
- static constexpr bound_t num_opt_entries = NumOptEntries;
- static constexpr bound_t num_ext_entries = NumExtEntries;
-
- using constraint_t = seq_range<TotalNumEntries, NumExtEntries, Extended>;
-
-};
-
-/***************************************************************************************
-* T_SEQUENCE_OF
-***************************************************************************************/
-template<typename T, class Constraint = constraints<false> >
-struct sequenceof : base
-{
- using asn_identifier_t = identifier<class_type_t::UNIVERSAL, static_cast<tag_value_t>(tag_rvalue_t::SEQUENCE_OF), tag_type_t::IMPLICIT>;
-
- static constexpr element_type ie_type = element_type::T_SEQUENCE_OF;
- static constexpr const char* name() {return "SEQUENCE OF";}
-
- struct value_type : T, boost::intrusive::list_base_hook< boost::intrusive::link_mode<boost::intrusive::auto_unlink> >
- {
- value_type(){}
- private:
- value_type& operator=(const value_type&) = delete;
- value_type (const value_type&) = delete;
- };
-
- using values_t = boost::intrusive::list<value_type, boost::intrusive::constant_time_size<false>>;
- using constraint_t = Constraint;
- using element_t = T;
-
- void clear() { m_list.clear(); base::clear();}
- size_t size() const { return m_list.size(); }
- template<class Predicate>
- void sort(Predicate const& p) { m_list.sort(p); }
-
- template<class V>
- void set(V& v) {for(auto & e : v) {m_list.push_back(e);} base::set();}
-
- void push_back(value_type& v) { m_list.push_back(v); base::set();}
-
- template<class AT> //Note: Allocator must return word alligned buffer!
- T& emplace_back(AT& allocator)
- {
- uint8_t* data = allocator.alloc_bytes(sizeof(value_type));
- if(!data)
- throw std::bad_alloc();
- value_type* v = new (data) value_type;
- push_back(*v);
- return *v;
- };
-
- using iterator = typename values_t::iterator;
- iterator begin() { return m_list.begin(); }
- iterator end() { return m_list.end(); }
-
- using const_iterator = typename values_t::const_iterator;
- const_iterator begin() const { return m_list.begin(); }
- const_iterator end() const { return m_list.end(); }
-
- sequenceof(){}
-
-private:
- values_t m_list;
-};
-
-/***************************************************************************************
-* T_OBJFIELD_FTV
-***************************************************************************************/
-template<typename T, bool>
-struct fixedtypefield : T
-{
- static constexpr element_type ie_type = element_type::T_OBJFIELD_FTV;
-
- T& ref_nested() {return *this;}
- T const & ref_nested() const {return *this;}
-};
-
-/***************************************************************************************
-* T_OBJFIELD_TF
-***************************************************************************************/
-template<bool>
-struct typefield : base
-{
- static constexpr element_type ie_type = element_type::T_OBJFIELD_TF;
- static constexpr const char* name() {return "type-field";}
-
- typefield& ref_nested() {return *this;}
- typefield const& ref_nested() const {return *this;}
-
- bool is_unknown() const {return false;}
-};
-
-/***************************************************************************************
-* T_OBJECTIDENTIFIER
-***************************************************************************************/
-struct oid : ostring<>
-{
- using asn_identifier_t = identifier<class_type_t::UNIVERSAL, static_cast<tag_value_t>(tag_rvalue_t::OBJECT_IDENTIFIER), tag_type_t::IMPLICIT>;
-
- static constexpr element_type ie_type = element_type::T_OBJECTIDENTIFIER;
- static constexpr const char* name() {return "OBJECT IDENTIFIER";}
-};
-
-/***************************************************************************************
-* T_PRINTABLESTRING
-***************************************************************************************/
-template<class Constraint = constraints<false> >
-struct printable_string : ostring<Constraint>
-{
- using asn_identifier_t = identifier<class_type_t::UNIVERSAL, static_cast<tag_value_t>(tag_rvalue_t::PrintableString), tag_type_t::IMPLICIT>;
- static constexpr const char* name() {return "PrintableString";}
-};
-
-/***************************************************************************************
-* T_IA5_STRING
-***************************************************************************************/
-template<class Constraint = constraints<false> >
-struct ia5_string : ostring<Constraint>
-{
- using asn_identifier_t = identifier<class_type_t::UNIVERSAL, static_cast<tag_value_t>(tag_rvalue_t::IA5String), tag_type_t::IMPLICIT>;
- static constexpr const char* name() {return "IA5String";}
-};
-
-/***************************************************************************************
-* T_GRAPHIC_STRING
-***************************************************************************************/
-template<class Constraint = asn::constraints<false> >
-struct graphic_string : ostring<Constraint>
-{
- using asn_identifier_t = identifier<class_type_t::UNIVERSAL, static_cast<tag_value_t>(tag_rvalue_t::GraphicString), tag_type_t::IMPLICIT>;
- static constexpr const char* name() {return "IA5String";}
-};
-
-/***************************************************************************************
-* T_UTF8_STRING
-***************************************************************************************/
-template<class Constraint = asn::constraints<false> >
-struct utf8_string : ostring<Constraint>
-{
- using asn_identifier_t = identifier<class_type_t::UNIVERSAL, static_cast<tag_value_t>(tag_rvalue_t::UTF8String), tag_type_t::IMPLICIT>;
- static constexpr const char* name() {return "UTF8String";}
-};
-
-/***************************************************************************************
-* T_SET
-***************************************************************************************/
-template<int TotalNumEntries, int NumExtEntries, bool Extended, int NumOptEntries = 0>
-struct set : base
-{
- using asn_identifier_t = identifier<class_type_t::UNIVERSAL, static_cast<tag_value_t>(tag_rvalue_t::SET), tag_type_t::IMPLICIT>;
-
- static constexpr element_type ie_type = element_type::T_SET;
- static constexpr const char* name() {return "SET";}
-
- static constexpr bound_t num_total_entries = TotalNumEntries;
- static constexpr bound_t num_opt_entries = NumOptEntries;
- static constexpr bound_t num_ext_entries = NumExtEntries;
-
- using constraint_t = seq_range<TotalNumEntries, NumExtEntries, Extended>;
-};
-
-/***************************************************************************************
-* T_SET_OF
-***************************************************************************************/
-template<typename T, class Constraint = constraints<false> >
-struct setof : sequenceof<T, Constraint>
-{
- using asn_identifier_t = identifier<class_type_t::UNIVERSAL, static_cast<tag_value_t>(tag_rvalue_t::SET_OF), tag_type_t::IMPLICIT>;
-
- static constexpr element_type ie_type = element_type::T_SET_OF;
- static constexpr const char* name() {return "SET OF";}
-};
-} //namespace asn