Fixes added and UT-coverage improved over 85%
[ric-plt/submgr.git] / e2ap / pkg / conv / bcd.go
1 /*
2 ==================================================================================
3   Copyright (c) 2019 AT&T Intellectual Property.
4   Copyright (c) 2019 Nokia
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================================
18 */
19
20 package conv
21
22 //
23 //
24
25 //-----------------------------------------------------------------------------
26 //
27 //-----------------------------------------------------------------------------
28 type bcdbase struct {
29         convtbl string
30 }
31
32 func (bcd *bcdbase) index(c byte) int {
33         for cpos, cchar := range bcd.convtbl {
34                 if cchar == rune(c) {
35                         return cpos
36                 }
37         }
38         return -1
39 }
40
41 func (bcd *bcdbase) byte(i int) byte {
42         if i < 0 || i > 15 {
43                 return '?'
44         }
45         return bcd.convtbl[i]
46 }
47
48 //-----------------------------------------------------------------------------
49 //
50 // 5 digit example
51 // String format   : D1D2D3D4D5
52 // BCD Coded format: 0xD1D2 0xD3D4 0xD50f
53 // String format   : D1D2D3D4D5F
54 //
55 // 6 digit example
56 // String format   : D1D2D3D4D5D6
57 // BCD Coded format: 0xD1D2 0xD3D4 0xD5D6
58 // String format   : D1D2D3D4D5D6
59 //
60 //-----------------------------------------------------------------------------
61 type Bcd struct {
62         bcdbase
63 }
64
65 func (bcd *Bcd) Encode(str string) []byte {
66         buf := make([]byte, len(str)/2+len(str)%2)
67         for i := 0; i < len(str); i++ {
68                 var schar int = bcd.index(str[i])
69                 if schar < 0 {
70                         return nil
71                 }
72                 if i%2 > 0 {
73                         buf[i/2] &= 0xf0
74                         buf[i/2] |= ((uint8)(schar) & 0x0f)
75                 } else {
76                         buf[i/2] = 0x0f | (uint8)(schar)<<4
77                 }
78
79         }
80         return buf
81 }
82
83 func (bcd *Bcd) Decode(buf []byte) string {
84         var strbytes []byte
85         for i := 0; i < len(buf); i++ {
86                 var b byte
87
88                 b = bcd.byte(int(buf[i] >> 4))
89                 //if b == '?' {
90                 //      return ""
91                 //}
92                 strbytes = append(strbytes, b)
93
94                 b = bcd.byte(int(buf[i] & 0x0f))
95                 //if b == '?' {
96                 //      return ""
97                 //}
98                 strbytes = append(strbytes, b)
99         }
100         return string(strbytes)
101 }
102
103 //-----------------------------------------------------------------------------
104 //
105 // 5 digit example
106 // String format   : D1D2D3D4D5
107 // TBCD Coded format: 0xD2D1 0xD4D3 0x0fD5
108 // String format   : D1D2D3D4D5F
109 //
110 // 6 digit example
111 // String format   : D1D2D3D4D5
112 // TBCD Coded format: 0xD2D1 0xD4D3 0xD6D5
113 // String format   : D1D2D3D4D5D6
114 //
115 //-----------------------------------------------------------------------------
116 type Tbcd struct {
117         bcdbase
118 }
119
120 func (bcd *Tbcd) Encode(str string) []byte {
121         buf := make([]byte, len(str)/2+len(str)%2)
122         for i := 0; i < len(str); i++ {
123                 var schar int = bcd.index(str[i])
124                 if schar < 0 {
125                         return nil
126                 }
127                 if i%2 > 0 {
128                         buf[i/2] &= 0x0f
129                         buf[i/2] |= (uint8)(schar) << 4
130                 } else {
131                         buf[i/2] = 0xf0 | ((uint8)(schar) & 0x0f)
132                 }
133         }
134         return buf
135 }
136
137 func (bcd *Tbcd) Decode(buf []byte) string {
138         var strbytes []byte
139         for i := 0; i < len(buf); i++ {
140                 var b byte
141                 b = bcd.byte(int(buf[i] & 0x0f))
142                 //if b == '?' {
143                 //      return ""
144                 //}
145                 strbytes = append(strbytes, b)
146
147                 b = bcd.byte(int(buf[i] >> 4))
148                 //if b == '?' {
149                 //      return ""
150                 //}
151                 strbytes = append(strbytes, b)
152         }
153         return string(strbytes)
154 }
155
156 //-----------------------------------------------------------------------------
157 //
158 //-----------------------------------------------------------------------------
159
160 func NewBcd(convTbl string) *Bcd {
161         b := &Bcd{}
162         if len(convTbl) == 16 {
163                 b.convtbl = convTbl
164         } else {
165                 b.convtbl = "0123456789?????f"
166         }
167         return b
168 }
169
170 func NewTbcd(convTbl string) *Tbcd {
171         b := &Tbcd{}
172         if len(convTbl) == 16 {
173                 b.convtbl = convTbl
174         } else {
175                 b.convtbl = "0123456789*#abcf"
176         }
177         return b
178 }
179
180 //-----------------------------------------------------------------------------
181 //
182 //-----------------------------------------------------------------------------
183
184 var BCD *Bcd
185 var TBCD *Tbcd
186
187 //-----------------------------------------------------------------------------
188 //
189 //-----------------------------------------------------------------------------
190
191 func init() {
192         BCD = NewBcd("")
193         TBCD = NewTbcd("")
194 }