X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=sim%2Fe2-interface.git;a=blobdiff_plain;f=e2sim%2Fe2apv1sim%2Fe2sim%2Fsrc%2FASN1%2Fasn%2Fper%2Flength.hpp;fp=e2sim%2Fe2apv1sim%2Fe2sim%2Fsrc%2FASN1%2Fasn%2Fper%2Flength.hpp;h=488a83041a6365178321dd84cd50dd752ec65935;hp=0000000000000000000000000000000000000000;hb=3ebf932d23dcbec9ed19f4a51f9d00a0a54f5124;hpb=6896318f2b4ff01b4a88b16019c3dc93b0b693f5 diff --git a/e2sim/e2apv1sim/e2sim/src/ASN1/asn/per/length.hpp b/e2sim/e2apv1sim/e2sim/src/ASN1/asn/per/length.hpp new file mode 100755 index 0000000..488a830 --- /dev/null +++ b/e2sim/e2apv1sim/e2sim/src/ASN1/asn/per/length.hpp @@ -0,0 +1,238 @@ +#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 + +// Local Includes: Application specific classes, functions, and libraries +#include "asn/per/common.hpp" +#include "asn/per/whole_number.hpp" + +namespace asn { +namespace per { + +/******************************************************************************** +* Encoding of a length determinant (X.691 10.9) +*********************************************************************************/ + +template +struct LengthDeterminant; + +struct LengthDeterminantDefault //Unconstrained length +{ + static u8 bytes_needed(size_t len) + { + if (len <= 127) + return 1; + return 2; + } + + static void run(EncoderCtx& ctx, size_t len) + { + if (len <= 127) + { + Tools::bit_accessor::padByte(ctx.refBuffer()); + ctx.refBuffer().putByte(static_cast(len)); + } + else if (len < 16384) + { + Tools::bit_accessor::padByte(ctx.refBuffer()); + len += 0x8000; + ctx.refBuffer().putByte(static_cast(len >> 8)); + ctx.refBuffer().putByte(static_cast(len)); + } + else + { + //todo: 10.9.3.8.1 for len >= 16K + } + } + static size_t run(DecoderCtx& ctx) + { + size_t rval = 0; + Tools::bit_accessor::padByte(ctx.refBuffer()); + + u8 const* data = ctx.refBuffer().getBytes(1); + if (data) + { + if (*data & 0x80) + { + rval = (*data & 0x7F) << 8; + data = ctx.refBuffer().getBytes(1); + if (data) + rval |= *data; + } + else + rval = *data; + } + return rval; + } +}; + +//10.9.3.3 +template +struct LengthDeterminant> +{ + static void run(EncoderCtx& ctx, size_t len) + { + ConstrainedWholeNumber::run(ctx, len); + } + static size_t inline run(DecoderCtx& ctx, bool extended_len) + { + return ConstrainedWholeNumber::run(ctx); + } +}; +template +struct LengthDeterminant> +{ + static void run(EncoderCtx& ctx, size_t len) + { + if (len > Range::upper_bound || len < Range::lower_bound) + LengthDeterminantDefault::run(ctx, len); + else + ConstrainedWholeNumber::run(ctx, len); + } + static size_t inline run(DecoderCtx& ctx, bool extended_len) + { + if (extended_len) + return LengthDeterminantDefault::run(ctx); + + return ConstrainedWholeNumber::run(ctx); + } +}; + +template +struct LengthDeterminant= 65536) > > +{ + static void run(EncoderCtx& ctx, size_t len) + { + LengthDeterminantDefault::run(ctx, len); + } + static size_t inline run(DecoderCtx& ctx, bool extended_len) + { + return LengthDeterminantDefault::run(ctx); + } +}; + +//10.9.3.4 : for "normally small length". bitmaps, sequence types +template +struct NormallySmallLength; + +template +struct NormallySmallLength > +{ + static_assert(Length > 0, "NormallySmallLength must be > 0"); + + static void run(EncoderCtx& ctx) + { + Tools::bit_accessor::put((u8)(Length - 1), 7, ctx.refBuffer()); + } + static size_t run(DecoderCtx& ctx) + { + u8 ext = Tools::bit_accessor::get(1, ctx.refBuffer()); + if (ext) + return LengthDeterminantDefault::run(ctx); + return Tools::bit_accessor::get(6, ctx.refBuffer()) + 1; + } +}; + +template +struct NormallySmallLength 64)> > +{ + static void run(EncoderCtx& ctx) + { + Tools::bit_accessor::put(1, 1, ctx.refBuffer()); + LengthDeterminantDefault::run(ctx, Length); + } +}; + +/* +* BinaryIntegerLength +*/ + +template +struct NBytes +{ + static constexpr bound_t value = std::log2( N ) / 8 + 1; +}; + +template +struct NBytes > +{ + static constexpr bound_t value = 1; +}; + +template +struct NRange +{ + static constexpr bound_t lower_bound = B1; + static constexpr bound_t upper_bound = B2; +}; + +template +struct NRange > +{ + static constexpr bound_t lower_bound = B2; + static constexpr bound_t upper_bound = B1; +}; + +template +struct BinaryIntegerLength +{ + typedef NRange< + NBytes::value, + NBytes::value + > nrange; + + using boundary_type = typename Range::boundary_type; + static constexpr bool extended = Range::extended; + static constexpr bound_t lower_bound = nrange::lower_bound; + static constexpr bound_t upper_bound = nrange::upper_bound; + + static void run(EncoderCtx& ctx, size_t len) + { + LengthDeterminant::run(ctx, len); + } + static size_t inline run(DecoderCtx& ctx, bool extended_len) + { + return LengthDeterminant::run(ctx, extended_len); + } +}; + +template +struct BinaryIntegerLength> +{ + static void run(EncoderCtx& ctx, size_t len) + { + LengthDeterminantDefault::run(ctx, len); + } + static size_t inline run(DecoderCtx& ctx, bool extended_len) + { + return LengthDeterminantDefault::run(ctx); + } +}; + +} //namespace per +} //namespace asn