2 /******************************************************************************
4 * Copyright (c) 2019 AT&T Intellectual Property.
5 * Copyright (c) 2018-2019 Nokia.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************************/
21 // Standard Includes: ANSI C/C++, MSA, and Third-Party Libraries
23 // Local Includes: Application specific classes, functions, and libraries
24 #include "asn/per/common.hpp"
25 #include "asn/per/length.hpp"
30 template <class Range, class Enable = void>
31 struct BinaryIntegerLength;
33 /***************************************************************************************
34 * Encoding of a non-negative-binary-integer (X.691 10.3)
35 ***************************************************************************************/
36 template <class Range>
37 struct NonnegativeBinaryInteger
39 static void inline run(u64 val, EncoderCtx& ctx)
43 size_t const len = sizeof(val) - (__builtin_clzll(val) >> 3);
45 BinaryIntegerLength< Range >::run(ctx, len);
46 Tools::bit_accessor::padByte(ctx.refBuffer());
49 size_t shift = (len - 1) << 3;
50 for(size_t i = 0; i < len; ++i)
52 buff[i] = static_cast<uint8_t>(val >> shift);
56 ctx.refBuffer().putBytes(buff, len);
60 BinaryIntegerLength< Range >::run(ctx, 1);
61 Tools::bit_accessor::padByte(ctx.refBuffer());
62 ctx.refBuffer().putByte(0);
66 static void inline run(T& retval, DecoderCtx& ctx, bool extended_val)
69 size_t len = (size_t)BinaryIntegerLength< Range >::run(ctx, extended_val);
70 Tools::bit_accessor::padByte(ctx.refBuffer());
71 u8 const* data = ctx.refBuffer().getBytes(len);
75 for (size_t i = 0; i < len; ++i)
84 /***************************************************************************************
85 * Encoding of a 2's-complement-binary-integer (X.691 10.4)
86 ***************************************************************************************/
89 struct TwosComplementBinaryInteger
91 static void inline run(IE const& ie, EncoderCtx& ctx)
93 Tools::bit_accessor::padByte(ctx.refBuffer());
97 u64 mask = static_cast<u64>(-128);
105 buf[i] = static_cast<u8>(tval);
106 if (!(val & mask) || (val & mask) == mask)
114 ctx.refBuffer().putByte(len) && ctx.refBuffer().putBytes(&buf[i], len);
116 static void inline run(IE& ie, DecoderCtx& ctx)
118 Tools::bit_accessor::padByte(ctx.refBuffer());
120 u8 const* data = nullptr;
121 typename IE::value_type val = 0;
123 u8 const* len = ctx.refBuffer().getBytes(1);
125 if (len && (*len) <= 8 && (data = ctx.refBuffer().getBytes(*len)))
127 for (u8 i = 0; i < *len; ++i)
137 /***************************************************************************************
138 * Encoding of a normally small non-negativebinary integer (X.691 10.6)
139 ***************************************************************************************/
140 template <class IE, typename TValue = typename IE::value_type>
141 struct NormallySmallNonnegativeBinaryInteger
143 static void inline run(IE const& ie, EncoderCtx& ctx, typename IE::constraint_t::boundary_type val)
147 Tools::bit_accessor::put(static_cast<u8>(val), 7, ctx.refBuffer()); //7 bits ('0' indicator + value)
151 Tools::bit_accessor::put(1, 1, ctx.refBuffer()); //1 bit ('1' indicator)
152 NonnegativeBinaryInteger<typename IE::constraint_t>::run(val, ctx);
155 static TValue inline run(DecoderCtx& ctx)
157 u8 ext = Tools::bit_accessor::get(1, ctx.refBuffer());
160 NonnegativeBinaryInteger<typename IE::constraint_t>::run(rval, ctx, true);
163 return Tools::bit_accessor::get(6, ctx.refBuffer());