#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 #include // Local Includes: Application specific classes, functions, and libraries #include "asn/per/common.hpp" #include "asn/per/binary_integer.hpp" namespace asn { namespace per { /*************************************************************************************** * Encoding of a constrained whole number (X.691 10.5) ***************************************************************************************/ template struct length_determinant; template struct length_determinant > { static constexpr bound_t value = 0; }; template struct length_determinant > { static constexpr bound_t value = 1; }; template struct length_determinant 1) > > { static constexpr bound_t value = boost::static_log2<(R - 1)>::value + 1; }; /*************************************************************************************** ***************************************************************************************/ template struct ConstrainedWholeNumber; //Bit-field case template struct ConstrainedWholeNumber > { //non-negative-binary-integer X.691 10.5 static void inline run(EncoderCtx& ctx, const V& val) { Tools::bit_accessor::put(static_cast(val - Range::lower_bound), length_determinant<(Range::upper_bound - Range::lower_bound + 1)>::value, ctx.refBuffer()); } static V inline run(DecoderCtx& ctx) { return Range::lower_bound + Tools::bit_accessor::get( length_determinant<(Range::upper_bound - Range::lower_bound + 1)>::value, ctx.refBuffer()); } }; //One octet case template struct ConstrainedWholeNumber > { //non-negative-binary-integer X.691 10.5 static void inline run(EncoderCtx& ctx, const V& val) { Tools::bit_accessor::padByte(ctx.refBuffer()); ctx.refBuffer().putByte(static_cast(val - Range::lower_bound)); } static V inline run(DecoderCtx& ctx) { V rval = 0; Tools::bit_accessor::padByte(ctx.refBuffer()); u8 const* data = ctx.refBuffer().getBytes(1); if (data) rval = Range::lower_bound + data[0]; return rval; } }; //Two octets case template struct ConstrainedWholeNumber (Range::lower_bound + 255)) && (Range::upper_bound <= (Range::lower_bound + 65535))> > { //non-negative-binary-integer X.691 10.5 static void inline run(EncoderCtx& ctx, const V& v) { u64 val = static_cast(v - Range::lower_bound); Tools::bit_accessor::padByte(ctx.refBuffer()); ctx.refBuffer().putByte((u8)(val >> 8)); ctx.refBuffer().putByte((u8)val); } static V inline run(DecoderCtx& ctx) { V rval = 0; Tools::bit_accessor::padByte(ctx.refBuffer()); u8 const* data = ctx.refBuffer().getBytes(2); if (data) { rval = data[0]; rval = rval << 8; rval |= data[1]; rval += Range::lower_bound; } return rval; } }; //Indefinite case template struct ConstrainedWholeNumber Range::lower_bound + 65535) > > { struct NormalizedValueRange { using boundary_type = typename Range::boundary_type; static constexpr bool extended = Range::extended; static constexpr boundary_type lower_bound = 0; static constexpr boundary_type upper_bound = Range::upper_bound - Range::lower_bound; }; //non-negative-binary-integer X.691 10.5 static void inline run(EncoderCtx& ctx, const V& val) { NonnegativeBinaryInteger::run(val - Range::lower_bound, ctx); } static V inline run(DecoderCtx& ctx) { V rval = 0; NonnegativeBinaryInteger::run(rval, ctx, false); return rval + Range::lower_bound; } }; } //namespace per } //namespace asn