X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=sim%2Fe2-interface.git;a=blobdiff_plain;f=e2sim%2Fe2apv1sim%2Fricsim%2Fsrc%2FASN1%2Fasn%2Fber%2Ftag.hpp;fp=e2sim%2Fe2apv1sim%2Fricsim%2Fsrc%2FASN1%2Fasn%2Fber%2Ftag.hpp;h=dba97332e997044c3cbfdbb0bd30d14fc32eb129;hp=0000000000000000000000000000000000000000;hb=3ebf932d23dcbec9ed19f4a51f9d00a0a54f5124;hpb=6896318f2b4ff01b4a88b16019c3dc93b0b693f5 diff --git a/e2sim/e2apv1sim/ricsim/src/ASN1/asn/ber/tag.hpp b/e2sim/e2apv1sim/ricsim/src/ASN1/asn/ber/tag.hpp new file mode 100755 index 0000000..dba9733 --- /dev/null +++ b/e2sim/e2apv1sim/ricsim/src/ASN1/asn/ber/tag.hpp @@ -0,0 +1,163 @@ +#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 + +#define IE_CLASS_SHIFT 6 +#define IE_PC_SHIFT 5 +#define IE_BIG_TAG_FST_OCTET 0b011111 + +namespace asn { +namespace ber { + +constexpr tag_value_t invalid_tag = std::numeric_limits::max(); + +/*************************************************************************************** +* Tag +***************************************************************************************/ +template +struct Tag; + +template +struct Tag > +{ + static constexpr tag_value_t value() + { + tag_value_t v = static_cast(IE::asn_identifier_t::class_type); + v <<= IE_CLASS_SHIFT; + v = constructed ? (v | (1u << IE_PC_SHIFT)) : v; + v |= static_cast(IE::asn_identifier_t::tag_value); + return v; + } + + static void inline encode(EncoderCtx& ctx) + { + ctx.refBuffer().putByte(static_cast(value())); + } +}; + + +template +struct Tag= 31) > > +{ + static constexpr tag_value_t value() + { + static_assert(IE::asn_identifier_t::tag_value > 0, "null tag value"); + + tag_value_t v = static_cast(IE::asn_identifier_t::class_type); + v <<= IE_CLASS_SHIFT; + v = constructed ? (v | (1u << IE_PC_SHIFT)) : v; + v |= IE_BIG_TAG_FST_OCTET; + + size_t leadbits = __builtin_clzll(IE::asn_identifier_t::tag_value); + tag_value_t tv = IE::asn_identifier_t::tag_value << leadbits; + size_t length = sizeof(tag_value_t)*CHAR_BIT - leadbits; + + size_t shift = sizeof(tag_value_t)*CHAR_BIT - 7; + + size_t lb = length % 7; + if(lb) + { + v <<= 8; + v |= 0x80; + v |= static_cast(tv >> (shift + 7 - lb)); + tv <<= lb; + length -= lb; + } + + while(length) + { + v <<= 8; + v |= 0x80; + v |= static_cast(tv >> shift); + tv <<= 7; + length -= 7; + } + v &= ((tag_value_t)-1) & ~((tag_value_t) 0x80); + + return v; + } + + static void inline encode(EncoderCtx& ctx) + { + size_t size = 0; + tag_value_t tv = data(size); + ctx.refBuffer().putBytes(reinterpret_cast(&tv), size); + } + +private: + + static constexpr tag_value_t data(size_t& size) + { + tag_value_t rv = 0; + tag_value_t tv = value(); + size = sizeof(tag_value_t) - (__builtin_clzll(tv) >> 3); + + uint8_t* ptr = reinterpret_cast(&rv); + + size_t shift = (size - 1) * 8; + for(size_t i = 0; i < size; ++i) + { + ptr[i] = static_cast(tv >> shift); + shift -= 8; + } + + return rv; + } +}; + +inline +tag_value_t get_tag(DecoderCtx& ctx) +{ + tag_value_t rv = 0; + auto & buffer = ctx.refBuffer(); + uint8_t const* data = buffer.getBytes(1); + + if (data) + { + rv = data[0]; + if((data[0] & 0x1F) == IE_BIG_TAG_FST_OCTET) + { + size_t limit = sizeof(tag_value_t) - 1; + while((data = buffer.getBytes(1))) + { + if(!limit) + { + ctx.refErrorCtx().sizeRangeError(0); + break; + } + + rv <<= 8; + rv |= data[0]; + --limit; + + if(!(data[0] & 0x80)) + break; + } + } + } + return rv; +} + +} //namespace ber +} //namespace asn +