Initial import
[project/uclient.git] / uclient-utils.c
1 #include <stdint.h>
2 #include <stdlib.h>
3 #include <ctype.h>
4
5 #include "uclient-utils.h"
6
7 static const char *b64 =
8 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
9
10 void base64_encode(const void *inbuf, unsigned int len, void *outbuf)
11 {
12 unsigned char *out = outbuf;
13 const uint8_t *in = inbuf;
14 unsigned int i;
15 int pad = len % 3;
16
17 for (i = 0; i < len - pad; i += 3) {
18 uint32_t in3 = (in[0] << 16) | (in[1] << 8) | in[2];
19 int k;
20
21 for (k = 3; k >= 0; k--) {
22 out[k] = b64[in3 & 0x3f];
23 in3 >>= 6;
24 }
25 in += 3;
26 out += 4;
27 }
28
29 if (pad) {
30 uint32_t in2 = in[0] << (16 - 6);
31
32 out[3] = '=';
33
34 if (pad > 1) {
35 in2 |= in[1] << (8 - 6);
36 out[2] = b64[in2 & 0x3f];
37 } else {
38 out[2] = '=';
39 }
40
41 in2 >>= 6;
42 out[1] = b64[in2 & 0x3f];
43 in2 >>= 6;
44 out[0] = b64[in2 & 0x3f];
45
46 out += 4;
47 }
48
49 *out = '\0';
50 }
51
52 int uclient_urldecode(const char *in, char *out, bool decode_plus)
53 {
54 static char dec[3];
55 int ret = 0;
56 char c;
57
58 while ((c = *(in++))) {
59 if (c == '%') {
60 if (!isxdigit(in[0]) || !isxdigit(in[1]))
61 return -1;
62
63 dec[0] = in[0];
64 dec[1] = in[1];
65 c = strtol(dec, NULL, 16);
66 in += 2;
67 } else if (decode_plus && c == '+') {
68 c = ' ';
69 }
70
71 *(out++) = c;
72 ret++;
73 }
74
75 *out = 0;
76 return ret;
77 }