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%2Fper%2Fbinary_integer.hpp;fp=e2sim%2Fe2apv1sim%2Fricsim%2Fsrc%2FASN1%2Fasn%2Fper%2Fbinary_integer.hpp;h=6ba2f1591d2a982fcc797c4ad6d1a279df7a3d94;hp=0000000000000000000000000000000000000000;hb=3ebf932d23dcbec9ed19f4a51f9d00a0a54f5124;hpb=6896318f2b4ff01b4a88b16019c3dc93b0b693f5 diff --git a/e2sim/e2apv1sim/ricsim/src/ASN1/asn/per/binary_integer.hpp b/e2sim/e2apv1sim/ricsim/src/ASN1/asn/per/binary_integer.hpp new file mode 100755 index 0000000..6ba2f15 --- /dev/null +++ b/e2sim/e2apv1sim/ricsim/src/ASN1/asn/per/binary_integer.hpp @@ -0,0 +1,168 @@ +#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 +#include "asn/per/common.hpp" +#include "asn/per/length.hpp" + +namespace asn { +namespace per { + +template +struct BinaryIntegerLength; + +/*************************************************************************************** +* Encoding of a non-negative-binary-integer (X.691 10.3) +***************************************************************************************/ +template +struct NonnegativeBinaryInteger +{ + static void inline run(u64 val, EncoderCtx& ctx) + { + if(val) + { + size_t const len = sizeof(val) - (__builtin_clzll(val) >> 3); + + BinaryIntegerLength< Range >::run(ctx, len); + Tools::bit_accessor::padByte(ctx.refBuffer()); + + u8 buff[len]; + size_t shift = (len - 1) << 3; + for(size_t i = 0; i < len; ++i) + { + buff[i] = static_cast(val >> shift); + shift -= 8; + } + + ctx.refBuffer().putBytes(buff, len); + } + else + { + BinaryIntegerLength< Range >::run(ctx, 1); + Tools::bit_accessor::padByte(ctx.refBuffer()); + ctx.refBuffer().putByte(0); + } + } + template + static void inline run(T& retval, DecoderCtx& ctx, bool extended_val) + { + retval = 0; + size_t len = (size_t)BinaryIntegerLength< Range >::run(ctx, extended_val); + Tools::bit_accessor::padByte(ctx.refBuffer()); + u8 const* data = ctx.refBuffer().getBytes(len); + + if (data) + { + for (size_t i = 0; i < len; ++i) + { + retval = retval << 8; + retval |= data[i]; + } + } + } +}; + +/*************************************************************************************** +* Encoding of a 2's-complement-binary-integer (X.691 10.4) +***************************************************************************************/ + +template +struct TwosComplementBinaryInteger +{ + static void inline run(IE const& ie, EncoderCtx& ctx) + { + Tools::bit_accessor::padByte(ctx.refBuffer()); + + u64 val = ie.get(); + u64 tval = val; + u64 mask = static_cast(-128); + u8 len = 1; + u8 i = 7; + + u8 buf[8]; + + while (len < 8) + { + buf[i] = static_cast(tval); + if (!(val & mask) || (val & mask) == mask) + break; + mask = mask << 8; + tval = tval >> 8; + len++; + i--; + } + + ctx.refBuffer().putByte(len) && ctx.refBuffer().putBytes(&buf[i], len); + } + static void inline run(IE& ie, DecoderCtx& ctx) + { + Tools::bit_accessor::padByte(ctx.refBuffer()); + + u8 const* data = nullptr; + typename IE::value_type val = 0; + + u8 const* len = ctx.refBuffer().getBytes(1); + + if (len && (*len) <= 8 && (data = ctx.refBuffer().getBytes(*len))) + { + for (u8 i = 0; i < *len; ++i) + { + val = val << 8; + val |= data[i]; + } + } + ie.set(val); + } +}; + +/*************************************************************************************** +* Encoding of a normally small non-negativebinary integer (X.691 10.6) +***************************************************************************************/ +template +struct NormallySmallNonnegativeBinaryInteger +{ + static void inline run(IE const& ie, EncoderCtx& ctx, typename IE::constraint_t::boundary_type val) + { + if (val <= 63) + { + Tools::bit_accessor::put(static_cast(val), 7, ctx.refBuffer()); //7 bits ('0' indicator + value) + } + else + { + Tools::bit_accessor::put(1, 1, ctx.refBuffer()); //1 bit ('1' indicator) + NonnegativeBinaryInteger::run(val, ctx); + } + } + static TValue inline run(DecoderCtx& ctx) + { + u8 ext = Tools::bit_accessor::get(1, ctx.refBuffer()); + if (ext) { + TValue rval = 0; + NonnegativeBinaryInteger::run(rval, ctx, true); + return rval; + } + return Tools::bit_accessor::get(6, ctx.refBuffer()); + } +}; + +} //namespace per +} //namespace asn