RIC:1060: Change in PTL
[ric-plt/e2.git] / RIC-E2-TERMINATION / base64.cpp
1 /*
2  * Copyright 2019 AT&T Intellectual Property
3  * Copyright 2019 Nokia
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17  
18  /*
19  * This source code is part of the near-RT RIC (RAN Intelligent Controller)
20  * platform project (RICP).
21  */
22
23 //
24 // Created by adi ENZEL on 9/26/19.
25 //
26
27 #include "base64.h"
28
29 int base64::encode(const unsigned char *src, int srcLen, char unsigned *dst, long &dstLen) {
30     unsigned char *pos;
31     const unsigned char *end, *in;
32
33     if (dstLen <= 0 || srcLen <= 0) {
34         mdclog_write(MDCLOG_ERR, "source or destination length are 0. dst =%ld source = %d",
35                      dstLen, srcLen);
36         return -1;
37     }
38     if (dstLen < (srcLen * 4 / 3)) {
39         mdclog_write(MDCLOG_ERR, "Destination size %ld must be at least 140 percent from source size %d",
40                      dstLen, srcLen);
41         return -1;
42     }
43     if (dst == nullptr) {
44         mdclog_write(MDCLOG_ERR, "Destination must be allocated and freed by caller the function not allocate the memory");
45         return -1;
46     }
47     if (src == nullptr) {
48         mdclog_write(MDCLOG_ERR, "source is null pointer");
49         return -1;
50     }
51
52     end = src + srcLen;
53     in = src;
54     pos = dst;
55     while (end - in >= 3) {
56         *pos++ = base64_table[in[0] >> (unsigned int)2];
57         *pos++ = base64_table[((in[0] & 0x03) << (unsigned int)4) | (in[1] >> (unsigned int)4)];
58         *pos++ = base64_table[((in[1] & 0x0f) << (unsigned int)2) | (in[2] >> (unsigned int)6)];
59         *pos++ = base64_table[in[2] & (unsigned int)0x3f];
60         in += 3;
61     }
62
63     if (end - in) {
64         *pos++ = base64_table[in[0] >> (unsigned int)2];
65         if (end - in == 1) {
66             *pos++ = base64_table[(in[0] & 0x03) << (unsigned int)4];
67             *pos++ = '=';
68         } else {
69             *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> (unsigned int)4)];
70             *pos++ = base64_table[(in[1] & 0x0f) << 2];
71         }
72         *pos++ = '=';
73     }
74
75     *pos = '\0';
76     dstLen = pos - dst;return 0;
77 }
78
79 int base64::decode(const unsigned char *src, int srcLen, char unsigned *dst, long dstLen) {
80     unsigned char inv_table[INVERSE_TABLE_SIZE];
81     memset(inv_table, 0x80, INVERSE_TABLE_SIZE);
82     for (ulong i = 0; i < sizeof(base64_table) - 1; i++) {
83         inv_table[base64_table[i]] = (unsigned char) i;
84     }
85     inv_table['='] = 0;
86
87
88     if (dstLen == 0 || dstLen  < (int)(srcLen / 4 * 3)) {
89         mdclog_write(MDCLOG_ERR, "Destination size %ld can be up to 40  smaller then source size %d",
90                      dstLen, srcLen);
91         return -1;
92     }
93     if (dst == nullptr) {
94         mdclog_write(MDCLOG_ERR, "Destination must be allocated and freed by caller the function not allocate the memory");
95         return -1;
96     }
97
98     unsigned char *pos, block[4], tmp;
99     long i;
100     int pad = 0;
101
102     size_t count = 0;
103
104     for (i = 0; i < srcLen; i++) {
105         if (inv_table[src[i]] != 0x80) {
106             count++;
107         }
108     }
109
110     if (count == 0 || count % 4)
111         return -1;
112
113     pos = dst;
114     count = 0;
115     for (i = 0; i < srcLen; i++) {
116         tmp = inv_table[src[i]];
117         if (tmp == 0x80) {
118             continue;
119         }
120         block[count] = tmp;
121
122         if (src[i] == '=') {
123             pad++;
124         }
125
126         count++;
127         if (count == 4) {
128             *pos++ = (block[0] << 2) | ((unsigned char)block[1] >> (unsigned int)4);
129             *pos++ = (block[1] << 4) | ((unsigned char)block[2] >> (unsigned int)2);
130             *pos++ = (block[2] << 6) | block[3];
131             count = 0;
132             if (pad) {
133                 if (pad == 1) {
134                     pos--;
135                 }
136                 else if (pad == 2) {
137                     pos -= 2;
138                 }
139                 else {
140                     return -1;
141                 }
142                 break;
143             }
144         }
145     }
146
147     dstLen = pos - dst;
148     return 0;
149 }