Enhanced SIM for E2AP v1 for TS UC
[sim/e2-interface.git] / e2sim / e2apv1sim / src / ASN1 / asn / per / choice.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 #include "asn/per/visitor.hpp"
26
27 namespace asn {
28 namespace per {
29
30 /********************************************************************************
31 Choice
32 *********************************************************************************/
33
34 /**************************************************/
35 //22.6-7 Default
36 template <class IE, class Enabler = void>
37 struct ChoiceNoExt
38 {
39         static void inline run(IE const& ie, EncoderCtx& ctx)
40         {
41                 ConstrainedWholeNumber<typename IE::constraint_t, typename IE::index_type>::run(ctx, IE::normalize(ie.get_index()));
42                 VisitorEncoder ve{ ctx };
43                 ie.encode(ve);
44         }
45         static void inline run(IE& ie, DecoderCtx& ctx)
46         {
47                 typename IE::index_type idx = ConstrainedWholeNumber<typename IE::constraint_t, typename IE::index_type>::run(ctx);
48                 VisitorDecoder ve{ ctx };
49                 ie.decode(IE::denormalize(idx), ve);
50         }
51 };
52
53 //22.4 One alternative 
54 template <class IE>
55 struct ChoiceNoExt<IE, std::enable_if_t<(IE::constraint_t::upper_bound == 0)> >
56 {
57         static void inline run(IE const& ie, EncoderCtx& ctx)
58         {
59                 VisitorEncoder ve{ ctx };
60                 ie.encode(ve);
61         }
62         static void inline run(IE& ie, DecoderCtx& ctx)
63         {
64                 VisitorDecoder ve{ ctx };
65                 ie.decode(IE::denormalize(0), ve);
66         }
67 };
68
69 /**************************************************/
70
71 template <class IE, class Enable = void>
72 struct Choice;
73
74 //22.5 Extension present
75 template <class IE>
76 struct Choice<IE, std::enable_if_t<(IE::constraint_t::extended == true)> >
77 {
78         static void inline run(IE const& ie, EncoderCtx& ctx)
79         {
80                 auto idx = IE::normalize(ie.get_index());
81                 if (idx <= IE::constraint_t::upper_bound)
82                 {
83                         Tools::bit_accessor::put(0, 1, ctx.refBuffer());
84                         ChoiceNoExt<IE>::run(ie, ctx);
85                 }
86                 else
87                 {
88                         Tools::bit_accessor::put(1, 1, ctx.refBuffer());
89                         NormallySmallNonnegativeBinaryInteger<IE>::run(ie, ctx, idx - IE::constraint_t::upper_bound - 1);
90                         OpenTypeVisitorEncoder ve{ ctx };
91                         ie.encode(ve);
92                 }
93         }
94         static void inline run(IE& ie, DecoderCtx& ctx)
95         {
96                 u8 ext = Tools::bit_accessor::get(1, ctx.refBuffer());
97                 if (ext)
98                 {
99                         typename IE::index_type idx = IE::constraint_t::upper_bound + 1 + NormallySmallNonnegativeBinaryInteger<IE, typename IE::index_type>::run(ctx);
100                         if (idx >= IE::constraint_t::total_num_entries)
101                         {
102                                 ie.set_unknown();
103                                 size_t size = LengthDeterminantDefault::run(ctx);
104                                 DecoderCtx::buf_type& buffer = ctx.refBuffer();
105                                 if (buffer.getBytesLeft() < size)
106                                         ctx.refErrorCtx().lengthErrorBytes(buffer.getBytesLeft(), size);
107                                 else
108                                         buffer.advance(size);
109                         }
110                         else
111                         {
112                                 OpenTypeVisitorDecoder ve{ ctx };
113                                 ie.decode(IE::denormalize(idx), ve);
114                         }
115                 }
116                 else
117                         ChoiceNoExt<IE>::run(ie, ctx);
118         }
119 };
120
121 //22.6 No extension
122 template <class IE>
123 struct Choice<IE, std::enable_if_t<(IE::constraint_t::extended == false)> >
124 {
125         static void inline run(IE const& ie, EncoderCtx& ctx)
126         {
127                 ChoiceNoExt<IE>::run(ie, ctx);
128         }
129         static void inline run(IE& ie, DecoderCtx& ctx)
130         {
131                 ChoiceNoExt<IE>::run(ie, ctx);
132         }
133 };
134
135 } //namespace per
136 } //namespace asn