X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=sim%2Fe2-interface.git;a=blobdiff_plain;f=e2sim%2Fe2apv1sim%2Fsrc%2FASN1%2Fasn%2Fber%2Fvisitor.hpp;fp=e2sim%2Fe2apv1sim%2Fsrc%2FASN1%2Fasn%2Fber%2Fvisitor.hpp;h=98c1f05db2e4c7fabc8402f602d63fecd00db867;hp=0000000000000000000000000000000000000000;hb=0eba05c4ff0c99974d3f3a63b65cbe2adb209e51;hpb=c380e183231711cf9f8bc72d0eb52e532dd07085 diff --git a/e2sim/e2apv1sim/src/ASN1/asn/ber/visitor.hpp b/e2sim/e2apv1sim/src/ASN1/asn/ber/visitor.hpp new file mode 100755 index 0000000..98c1f05 --- /dev/null +++ b/e2sim/e2apv1sim/src/ASN1/asn/ber/visitor.hpp @@ -0,0 +1,177 @@ +#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 + +// Local Includes: Application specific classes, functions, and libraries + +namespace asn { +namespace ber { + +/*************************************************************************************** +* VisitorEncoder +***************************************************************************************/ +struct VisitorEncoder +{ + VisitorEncoder(EncoderCtx& ctx) : m_ctx(ctx){} + + template bool operator() (ELM const& elm) + { + if(m_ctx) + Element::run(elm, m_ctx); + return static_cast(m_ctx); + } +private: + EncoderCtx& m_ctx; +}; + +/*************************************************************************************** +* VisitorDecoder +***************************************************************************************/ +struct VisitorDecoder +{ + VisitorDecoder(DecoderCtx& ctx, tag_value_t tag) : m_ctx(ctx), m_tag(tag){} + + template bool operator() (ELM& elm) + { + if(m_ctx) + Element::run(elm, m_ctx, &m_tag); + return static_cast(m_ctx); + } + +private: + DecoderCtx& m_ctx; + tag_value_t m_tag; +}; + +/*************************************************************************************** +* VisitorAdapter +***************************************************************************************/ +template +struct VisitorAdapter //default +{ + static void inline run(IE const& ie, EncoderCtx& ctx, Container const& cont) + { + Element::run(ie, ctx); + } + static void inline run(IE& ie, DecoderCtx& ctx, Container const& cont, tag_value_t tag) + { + Element::run(ie, ctx, &tag); + } +}; + +template +struct VisitorAdapter > +{ + static void inline run(IE const& ie, EncoderCtx& ctx, Container const& cont) + { + VisitorEncoder v(ctx); + bool rv = ie.encode(v, cont); + if(!rv && static_cast(ctx)) + { + ctx.refErrorCtx().errorNoObject(Container::name()); + } + } + static void inline run(IE& ie, DecoderCtx& ctx, Container const& cont, tag_value_t tag) + { + VisitorDecoder v(ctx, tag); + bool rv = ie.decode(v, cont); + if(!rv && static_cast(ctx)) + { + ctx.refErrorCtx().errorNoObject(Container::name()); + } + } +}; + +/*************************************************************************************** +* VisitorEncoderSeq +***************************************************************************************/ +template +struct VisitorEncoderSeq +{ + VisitorEncoderSeq(EncoderCtx& ctx, CONT const& cont) : m_ctx(ctx), m_cont(cont){} + + template void operator() (ELM const& elm) + { + if(ELM::optional) + { + if(elm.is_valid()) + VisitorAdapter::run(elm, m_ctx, m_cont); + } + else + VisitorAdapter::run(elm, m_ctx, m_cont); + } + + EncoderCtx& m_ctx; + CONT const& m_cont; +}; + + +/*************************************************************************************** +* VisitorDecoderSeq +***************************************************************************************/ +template +struct VisitorDecoderSeq +{ + VisitorDecoderSeq(DecoderCtx& ctx, CONT const& cont) : m_ctx(ctx), m_cont(cont){} + + template void operator() (ELM& elm) + { + if(m_ctx) + { + tag_value_t tag; + + if(invalid_tag == m_tag && m_ctx.refBuffer().getBytesLeft()) + { + m_tag = get_tag(m_ctx); + } + tag = m_tag; + + if(m_ctx) + { + if (!Element::is_matched(tag)) + { + if(!ELM::optional) + { + m_ctx.refErrorCtx().tagError(static_cast(tag)); + } + } + else + { + m_tag = invalid_tag; + VisitorAdapter::run(elm, m_ctx, m_cont, tag); + elm.setpresent(true); + } + } + } + } + + tag_value_t get_unhandled_tag() const {return m_tag;} + + DecoderCtx& m_ctx; + tag_value_t m_tag {invalid_tag}; + CONT const& m_cont; +}; + +} //namespace ber +} //namespace asn