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"
29 template < class IE, class Enable = void>
33 template <class IE, class Enabler = void>
34 struct OctetstringNoExt
36 static void inline run(IE const& ie, EncoderCtx& ctx)
38 bound_t size = ie.get().size();
39 LengthDeterminant<typename IE::constraint_t>::run(ctx, size);
40 Tools::bit_accessor::padByte(ctx.refBuffer());
41 ctx.refBuffer().putBytes(ie.get().data(), size);
43 static void inline run(IE& ie, DecoderCtx& ctx)
45 size_t len = LengthDeterminant<typename IE::constraint_t>::run(ctx, false);
46 Tools::bit_accessor::padByte(ctx.refBuffer());
47 u8 const* data_in = ctx.refBuffer().getBytes(len);
59 struct OctetstringNoExt<IE, std::enable_if_t< (IE::constraint_t::upper_bound == 0)> >
61 static void inline run(IE const& ie, EncoderCtx& ctx) {/* do nothing */ }
62 static void inline run(IE& ie, DecoderCtx& ctx) { ie.setpresent(true); }
65 //16.6 Up to two octets, fixed length
67 struct OctetstringNoExt<IE, std::enable_if_t<
68 ((IE::constraint_t::upper_bound == IE::constraint_t::lower_bound) && (IE::constraint_t::upper_bound == 1))
71 static void inline run(IE const& ie, EncoderCtx& ctx)
73 Tools::bit_accessor::put(static_cast<u8>(ie.get().data()[0]), 8, ctx.refBuffer());
75 static void inline run(IE& ie, DecoderCtx& ctx)
77 u8 data_in = Tools::bit_accessor::get(8, ctx.refBuffer());
78 u8* data_out = ctx.refAllocator().alloc_bytes(1);
80 data_out[0] = data_in;
84 ctx.refErrorCtx().allocatorNoMem(0, 1);
89 struct OctetstringNoExt<IE, std::enable_if_t<
90 ((IE::constraint_t::upper_bound == IE::constraint_t::lower_bound) && (IE::constraint_t::upper_bound == 2))
93 static void inline run(IE const& ie, EncoderCtx& ctx)
95 Tools::bit_accessor::put(static_cast<u8>(ie.get().data()[0]), 8, ctx.refBuffer());
96 Tools::bit_accessor::put(static_cast<u8>(ie.get().data()[1]), 8, ctx.refBuffer());
98 static void inline run(IE& ie, DecoderCtx& ctx)
101 data_in[0] = Tools::bit_accessor::get(8, ctx.refBuffer());
102 data_in[1] = Tools::bit_accessor::get(8, ctx.refBuffer());
103 u8* data_out = ctx.refAllocator().alloc_bytes(sizeof(data_in));
105 data_out[0] = data_in[0];
106 data_out[1] = data_in[1];
107 ie.set(sizeof(data_in), data_out);
110 ctx.refErrorCtx().allocatorNoMem(0, sizeof(data_in));
114 //16.7 More than 2 octets, up to 64K, fixed length
116 struct OctetstringNoExt<IE, std::enable_if_t<
117 ((IE::constraint_t::upper_bound == IE::constraint_t::lower_bound) && (IE::constraint_t::upper_bound < 65536) && (IE::constraint_t::upper_bound > 2))
120 static void inline run(IE const& ie, EncoderCtx& ctx)
122 Tools::bit_accessor::padByte(ctx.refBuffer());
123 ctx.refBuffer().putBytes(ie.get().data(), ie.get().size());
125 static void inline run(IE& ie, DecoderCtx& ctx)
127 Tools::bit_accessor::padByte(ctx.refBuffer());
128 const size_t len = (size_t)IE::constraint_t::upper_bound;
129 u8 const* data_in = ctx.refBuffer().getBytes(len);
132 ie.set(len, data_in);
137 /**************************************************/
139 //16.3 : Extension present
141 struct Octetstring<IE, std::enable_if_t<(IE::constraint_t::extended == true)> >
143 static void inline run(IE const& ie, EncoderCtx& ctx)
145 bound_t size = ie.get().size();
146 if (size <= IE::constraint_t::upper_bound && size >= IE::constraint_t::lower_bound)
148 Tools::bit_accessor::put(0, 1, ctx.refBuffer());
149 OctetstringNoExt<IE>::run(ie, ctx);
153 Tools::bit_accessor::put(1, 1, ctx.refBuffer());
154 Tools::bit_accessor::padByte(ctx.refBuffer());
155 LengthDeterminant<typename IE::constraint_t>::run(ctx, size);
156 Tools::bit_accessor::padByte(ctx.refBuffer());
157 ctx.refBuffer().putBytes(ie.get().data(), size);
160 static void inline run(IE& ie, DecoderCtx& ctx)
162 u8 ext = Tools::bit_accessor::get(1, ctx.refBuffer());
165 Tools::bit_accessor::padByte(ctx.refBuffer());
166 size_t len = LengthDeterminant<typename IE::constraint_t>::run(ctx, true);
167 Tools::bit_accessor::padByte(ctx.refBuffer());
168 u8 const* data_in = ctx.refBuffer().getBytes(len);
171 ie.set(len, data_in);
175 OctetstringNoExt<IE>::run(ie, ctx);
179 //16.4 : No extension
181 struct Octetstring<IE, std::enable_if_t<(IE::constraint_t::extended == false)> >
183 static void inline run(IE const& ie, EncoderCtx& ctx)
185 if ( ie.get().size() > size_t(IE::constraint_t::upper_bound) ||
186 (IE::constraint_t::lower_bound >= 0 && ie.get().size() < size_t(IE::constraint_t::lower_bound)))
188 ctx.refErrorCtx().sizeRangeError(ie.get().size(), size_t(IE::constraint_t::lower_bound),
189 size_t(IE::constraint_t::upper_bound));
193 OctetstringNoExt<IE>::run(ie, ctx);
196 static void inline run(IE& ie, DecoderCtx& ctx)
198 OctetstringNoExt<IE>::run(ie, ctx);
199 if ( ie.get().size() > size_t(IE::constraint_t::upper_bound) ||
200 (IE::constraint_t::lower_bound >= 0 && ie.get().size() < size_t(IE::constraint_t::lower_bound)))
202 ctx.refErrorCtx().sizeRangeError(ie.get().size(), size_t(IE::constraint_t::lower_bound),
203 size_t(IE::constraint_t::upper_bound));