]> git.proxmox.com Git - mirror_frr.git/blob - lib/base64.c
Merge pull request #10712 from patrasar/pim_nexthop_prefix_to_pimaddr
[mirror_frr.git] / lib / base64.c
1 /*
2 * This is part of the libb64 project, and has been placed in the public domain.
3 * For details, see http://sourceforge.net/projects/libb64
4 */
5
6 #ifdef HAVE_CONFIG_H
7 #include "config.h"
8 #endif
9
10 #include "base64.h"
11
12 static const int CHARS_PER_LINE = 72;
13 static const char *ENCODING =
14 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
15
16 void base64_init_encodestate(struct base64_encodestate *state_in)
17 {
18 state_in->step = step_A;
19 state_in->result = 0;
20 state_in->stepcount = 0;
21 }
22
23 char base64_encode_value(char value_in)
24 {
25 if (value_in > 63)
26 return '=';
27 return ENCODING[(int)value_in];
28 }
29
30 int base64_encode_block(const char *plaintext_in, int length_in, char *code_out,
31 struct base64_encodestate *state_in)
32 {
33 const char *plainchar = plaintext_in;
34 const char *const plaintextend = plaintext_in + length_in;
35 char *codechar = code_out;
36 char result;
37 char fragment;
38
39 result = state_in->result;
40
41 switch (state_in->step) {
42 while (1) {
43 case step_A:
44 if (plainchar == plaintextend) {
45 state_in->result = result;
46 state_in->step = step_A;
47 return codechar - code_out;
48 }
49 fragment = *plainchar++;
50 result = (fragment & 0x0fc) >> 2;
51 *codechar++ = base64_encode_value(result);
52 result = (fragment & 0x003) << 4;
53 /* fall through */
54 case step_B:
55 if (plainchar == plaintextend) {
56 state_in->result = result;
57 state_in->step = step_B;
58 return codechar - code_out;
59 }
60 fragment = *plainchar++;
61 result |= (fragment & 0x0f0) >> 4;
62 *codechar++ = base64_encode_value(result);
63 result = (fragment & 0x00f) << 2;
64 /* fall through */
65 case step_C:
66 if (plainchar == plaintextend) {
67 state_in->result = result;
68 state_in->step = step_C;
69 return codechar - code_out;
70 }
71 fragment = *plainchar++;
72 result |= (fragment & 0x0c0) >> 6;
73 *codechar++ = base64_encode_value(result);
74 result = (fragment & 0x03f) >> 0;
75 *codechar++ = base64_encode_value(result);
76
77 ++(state_in->stepcount);
78 if (state_in->stepcount == CHARS_PER_LINE/4) {
79 *codechar++ = '\n';
80 state_in->stepcount = 0;
81 }
82 }
83 }
84 /* control should not reach here */
85 return codechar - code_out;
86 }
87
88 int base64_encode_blockend(char *code_out, struct base64_encodestate *state_in)
89 {
90 char *codechar = code_out;
91
92 switch (state_in->step) {
93 case step_B:
94 *codechar++ = base64_encode_value(state_in->result);
95 *codechar++ = '=';
96 *codechar++ = '=';
97 break;
98 case step_C:
99 *codechar++ = base64_encode_value(state_in->result);
100 *codechar++ = '=';
101 break;
102 case step_A:
103 break;
104 }
105 *codechar++ = '\n';
106
107 return codechar - code_out;
108 }
109
110
111 signed char base64_decode_value(signed char value_in)
112 {
113 static const signed char decoding[] = {
114 62, -1, -1, -1, 63, 52, 53, 54,
115 55, 56, 57, 58, 59, 60, 61, -1,
116 -1, -1, -2, -1, -1, -1, 0, 1,
117 2, 3, 4, 5, 6, 7, 8, 9,
118 10, 11, 12, 13, 14, 15, 16, 17,
119 18, 19, 20, 21, 22, 23, 24, 25,
120 -1, -1, -1, -1, -1, -1, 26, 27,
121 28, 29, 30, 31, 32, 33, 34, 35,
122 36, 37, 38, 39, 40, 41, 42, 43,
123 44, 45, 46, 47, 48, 49, 50, 51
124 };
125 value_in -= 43;
126 if (value_in < 0 || value_in >= 80)
127 return -1;
128 return decoding[(int)value_in];
129 }
130
131 void base64_init_decodestate(struct base64_decodestate *state_in)
132 {
133 state_in->step = step_a;
134 state_in->plainchar = 0;
135 }
136
137 int base64_decode_block(const char *code_in, int length_in, char *plaintext_out,
138 struct base64_decodestate *state_in)
139 {
140 const char *codec = code_in;
141 char *plainc = plaintext_out;
142 signed char fragmt;
143
144 *plainc = state_in->plainchar;
145
146 switch (state_in->step) {
147 while (1) {
148 case step_a:
149 do {
150 if (codec == code_in+length_in) {
151 state_in->step = step_a;
152 state_in->plainchar = *plainc;
153 return plainc - plaintext_out;
154 }
155 fragmt = base64_decode_value(*codec++);
156 } while (fragmt < 0);
157 *plainc = (fragmt & 0x03f) << 2;
158 /* fall through */
159 case step_b:
160 do {
161 if (codec == code_in+length_in) {
162 state_in->step = step_b;
163 state_in->plainchar = *plainc;
164 return plainc - plaintext_out;
165 }
166 fragmt = base64_decode_value(*codec++);
167 } while (fragmt < 0);
168 *plainc++ |= (fragmt & 0x030) >> 4;
169 *plainc = (fragmt & 0x00f) << 4;
170 /* fall through */
171 case step_c:
172 do {
173 if (codec == code_in+length_in) {
174 state_in->step = step_c;
175 state_in->plainchar = *plainc;
176 return plainc - plaintext_out;
177 }
178 fragmt = base64_decode_value(*codec++);
179 } while (fragmt < 0);
180 *plainc++ |= (fragmt & 0x03c) >> 2;
181 *plainc = (fragmt & 0x003) << 6;
182 /* fall through */
183 case step_d:
184 do {
185 if (codec == code_in+length_in) {
186 state_in->step = step_d;
187 state_in->plainchar = *plainc;
188 return plainc - plaintext_out;
189 }
190 fragmt = base64_decode_value(*codec++);
191 } while (fragmt < 0);
192 *plainc++ |= (fragmt & 0x03f);
193 }
194 }
195 /* control should not reach here */
196 return plainc - plaintext_out;
197 }