#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