This source file includes following definitions.
- pmi_base64_encsym
- pmi_base64_decsym
- pmi_base64_encode_block
- pmi_base64_decode_block
- pmi_encode
- pmi_decode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <assert.h>
23 #include <string.h>
24 #include "pmi2_utils.h"
25
26
27 static inline unsigned char pmi_base64_encsym (unsigned char value) {
28 assert (value < 64);
29
30 if (value < 26) {
31 return 'A' + value;
32 } else if (value < 52) {
33 return 'a' + (value - 26);
34 } else if (value < 62) {
35 return '0' + (value - 52);
36 }
37
38 return (62 == value) ? '+' : '/';
39 }
40
41 static inline unsigned char pmi_base64_decsym (unsigned char value) {
42 if ('+' == value) {
43 return 62;
44 } else if ('/' == value) {
45 return 63;
46 } else if (' ' == value) {
47 return 64;
48 } else if (value <= '9') {
49 return (value - '0') + 52;
50 } else if (value <= 'Z') {
51 return (value - 'A');
52 } else if (value <= 'z') {
53 return (value - 'a') + 26;
54 }
55
56 return 64;
57 }
58
59 static inline void pmi_base64_encode_block (const unsigned char in[3], char out[4], int len) {
60 out[0] = pmi_base64_encsym (in[0] >> 2);
61 out[1] = pmi_base64_encsym (((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4));
62
63 out[2] = 1 < len ? pmi_base64_encsym(((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6)) : ' ';
64 out[3] = 2 < len ? pmi_base64_encsym(in[2] & 0x3f) : ' ';
65 }
66
67 static inline int pmi_base64_decode_block (const char in[4], unsigned char out[3]) {
68 char in_dec[4];
69
70 in_dec[0] = pmi_base64_decsym (in[0]);
71 in_dec[1] = pmi_base64_decsym (in[1]);
72 in_dec[2] = pmi_base64_decsym (in[2]);
73 in_dec[3] = pmi_base64_decsym (in[3]);
74
75 out[0] = in_dec[0] << 2 | in_dec[1] >> 4;
76 if (64 == in_dec[2]) {
77 return 1;
78 }
79
80 out[1] = in_dec[1] << 4 | in_dec[2] >> 2;
81 if (64 == in_dec[3]) {
82 return 2;
83 }
84
85 out[2] = ((in_dec[2] << 6) & 0xc0) | in_dec[3];
86 return 3;
87 }
88
89
90
91 char *pmi_encode(const void *val, size_t vallen)
92 {
93 char *outdata, *tmp;
94 size_t i;
95
96 outdata = calloc (((2 + vallen) * 4) / 3 + 2, 1);
97 if (NULL == outdata) {
98 return NULL;
99 }
100
101 for (i = 0, tmp = outdata ; i < vallen ; i += 3, tmp += 4) {
102 pmi_base64_encode_block((unsigned char *) val + i, tmp, vallen - i);
103 }
104
105 tmp[0] = (unsigned char)'\0';
106
107 return outdata;
108 }
109
110 uint8_t *pmi_decode (const char *data, size_t *retlen)
111 {
112 size_t input_len = strlen(data) / 4;
113 unsigned char *ret;
114 int out_len;
115 size_t i;
116
117
118 *retlen = 0;
119
120 ret = calloc (1, 3 * input_len + 1);
121 if (NULL == ret) {
122 return ret;
123 }
124
125 for (i = 0, out_len = 0 ; i < input_len ; i++, data += 4) {
126 out_len += pmi_base64_decode_block(data, ret + 3 * i);
127 }
128
129 ret[out_len] = '\0';
130 *retlen = out_len;
131 return ret;
132 }