Enhanced SIM for E2AP v1 for TS UC
[sim/e2-interface.git] / e2sim / e2apv1sim / src / ASN1 / asn / per / sequence_of.hpp
1 #pragma once
2 /******************************************************************************
3 *
4 *   Copyright (c) 2019 AT&T Intellectual Property.
5 *   Copyright (c) 2018-2019 Nokia.
6 *
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
10 *
11 *       http://www.apache.org/licenses/LICENSE-2.0
12 *
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.
18 *
19 ******************************************************************************/
20
21 // Standard Includes: ANSI C/C++, MSA, and Third-Party Libraries
22
23 // Local Includes: Application specific classes, functions, and libraries
24 #include "asn/per/common.hpp"
25
26 namespace asn {
27 namespace per {
28
29 template <class IE, class Enable = void>
30 struct SequenceOf;
31
32 //19.6 Default
33 template <class IE, class Enabler = void>
34 struct SequenceOfNoExt
35 {
36         static void inline run(IE const& ie, EncoderCtx& ctx)
37         {
38                 LengthDeterminant<typename IE::constraint_t>::run(ctx, ie.size());
39         }
40         static void inline run(IE& ie, DecoderCtx& ctx)
41         {
42                 size_t len = LengthDeterminant<typename IE::constraint_t>::run(ctx, false);
43                 for (size_t i = 0; i < len; ++i)
44                 {
45                         u8* data = ctx.refAllocator().alloc_bytes(sizeof(typename IE::value_type));
46                         if (data)
47                         {
48                                 typename IE::value_type * v = new (data) typename IE::value_type;
49                                 v->clear();
50                                 ie.push_back(*v);
51                         }
52                         else
53                         {
54                                 ctx.refErrorCtx().allocatorNoMem(0, sizeof(typename IE::value_type));
55                                 break;
56                         }
57                 }
58         }
59 };
60
61 //16.6 
62 template <class IE>
63 struct SequenceOfNoExt<IE, std::enable_if_t<
64         ((IE::constraint_t::upper_bound == IE::constraint_t::lower_bound) && (IE::constraint_t::upper_bound < 65536))
65 >>
66 {
67         static void inline run(IE const& ie, EncoderCtx& ctx) {/*do nothing*/ }
68         static void inline run(IE& ie, DecoderCtx& ctx)
69         {
70                 for (size_t i = 0; i < IE::constraint_t::upper_bound; ++i)
71                 {
72                         u8* data = ctx.refAllocator().alloc_bytes(sizeof(typename IE::value_type));
73                         if (data)
74                         {
75                                 typename IE::value_type * v = new (data) typename IE::value_type;
76                                 v->clear();
77                                 ie.push_back(*v);
78                         }
79                         else
80                         {
81                                 ctx.refErrorCtx().allocatorNoMem(0, sizeof(typename IE::value_type));
82                                 break;
83                         }
84                 }
85         }
86 };
87
88 /**************************************************/
89
90 //19.4 Extension present
91 template <class IE>
92 struct SequenceOf<IE, std::enable_if_t< (IE::constraint_t::extended == true)> >
93 {
94         static void inline run(IE const& ie, EncoderCtx& ctx)
95         {
96                 if (ie.size() <= IE::constraint_t::upper_bound && ie.size() >= IE::constraint_t::lower_bound)
97                 {
98                         Tools::bit_accessor::put(0, 1, ctx.refBuffer());
99                         SequenceOfNoExt<IE>::run(ie, ctx);
100                 }
101                 else
102                 {
103                         Tools::bit_accessor::put(1, 1, ctx.refBuffer());
104                         LengthDeterminant<typename IE::constraint_t>::run(ctx, ie.size());
105                 }
106         }
107         static void inline run(IE& ie, DecoderCtx& ctx)
108         {
109                 u8 ext = Tools::bit_accessor::get(1, ctx.refBuffer());
110                 if (ext)
111                 {
112                         size_t len = LengthDeterminant<typename IE::constraint_t>::run(ctx, true);
113                         for (size_t i = 0; i < len; ++i)
114                         {
115                                 u8* data = ctx.refAllocator().alloc_bytes(sizeof(typename IE::value_type));
116                                 if (data)
117                                 {
118                                         typename IE::value_type * v = new (data) typename IE::value_type;
119                                         //v->clear();
120                                         ie.push_back(*v);
121                                 }
122                                 else
123                                 {
124                                         ctx.refErrorCtx().allocatorNoMem(0, sizeof(typename IE::value_type));
125                                         break;
126                                 }
127                         }
128                 }
129                 else
130                         SequenceOfNoExt<IE>::run(ie, ctx);
131         }
132 };
133
134 //19.5-6 No extension
135 template <class IE>
136 struct SequenceOf<IE, std::enable_if_t< (IE::constraint_t::extended == false)> >
137 {
138         static void inline run(IE const& ie, EncoderCtx& ctx)
139         {
140                 if (IE::constraint_t::lower_bound >= 0 && ie.size() < size_t(IE::constraint_t::lower_bound))
141                 {
142                         ctx.refErrorCtx().sizeRangeError(ie.size(), size_t(IE::constraint_t::lower_bound));
143                 }
144                 else
145                 {
146                         SequenceOfNoExt<IE>::run(ie, ctx);
147                 }
148         }
149         static void inline run(IE& ie, DecoderCtx& ctx)
150         {
151                 SequenceOfNoExt<IE>::run(ie, ctx);
152         }
153 };
154
155 } //namespace per
156 } //namespace asn