LMMS
Loading...
Searching...
No Matches
base64.c
Go to the documentation of this file.
1/*
2 Copyright 2011-2020 David Robillard <d@drobilla.net>
3
4 Permission to use, copy, modify, and/or distribute this software for any
5 purpose with or without fee is hereby granted, provided that the above
6 copyright notice and this permission notice appear in all copies.
7
8 THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*/
16
17#include "base64.h"
18
19#include "serd_internal.h"
20#include "string_utils.h"
21
22#include "serd/serd.h"
23
24#include <stdbool.h>
25#include <stdint.h>
26#include <stdlib.h>
27#include <string.h>
28
34static const uint8_t b64_map[] =
35 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
36
44static const char b64_unmap[] =
45 "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$m$$$ncdefghijkl$$$$$$"
46 "$/0123456789:;<=>?@ABCDEFGH$$$$$$IJKLMNOPQRSTUVWXYZ[\\]^_`ab$$$$"
47 "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"
48 "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$";
49
51static inline void
52encode_chunk(uint8_t out[4], const uint8_t in[3], size_t n_in)
53{
54 out[0] = b64_map[in[0] >> 2];
55 out[1] = b64_map[((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4)];
56
57 out[2] = (n_in > 1) ? (b64_map[((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6)])
58 : (uint8_t)'=';
59
60 out[3] = ((n_in > 2) ? b64_map[in[2] & 0x3F] : (uint8_t)'=');
61}
62
63size_t
64serd_base64_get_length(const size_t size, const bool wrap_lines)
65{
66 return (size + 2) / 3 * 4 + (wrap_lines * ((size - 1) / 57));
67}
68
69bool
71 const void* const buf,
72 const size_t size,
73 const bool wrap_lines)
74{
75 bool has_newline = false;
76
77 for (size_t i = 0, j = 0; i < size; i += 3, j += 4) {
78 uint8_t in[4] = {0, 0, 0, 0};
79 size_t n_in = MIN(3, size - i);
80 memcpy(in, (const uint8_t*)buf + i, n_in);
81
82 if (wrap_lines && i > 0 && (i % 57) == 0) {
83 str[j++] = '\n';
84 has_newline = true;
85 }
86
87 encode_chunk(str + j, in, n_in);
88 }
89
90 return has_newline;
91}
92
93static inline uint8_t
95{
96 return (uint8_t)(b64_unmap[in] - 47);
97}
98
100static inline size_t
102{
103 out[0] = (uint8_t)(((unmap(in[0]) << 2)) | unmap(in[1]) >> 4);
104 out[1] = (uint8_t)(((unmap(in[1]) << 4) & 0xF0) | unmap(in[2]) >> 2);
105 out[2] = (uint8_t)(((unmap(in[2]) << 6) & 0xC0) | unmap(in[3]));
106 return 1 + (in[2] != '=') + ((in[2] != '=') && (in[3] != '='));
107}
108
109void*
110serd_base64_decode(const uint8_t* str, size_t len, size_t* size)
111{
112 void* buf = malloc((len * 3) / 4 + 2);
113
114 *size = 0;
115 for (size_t i = 0, j = 0; i < len; j += 3) {
116 uint8_t in[] = "====";
117 size_t n_in = 0;
118 for (; i < len && n_in < 4; ++n_in) {
119 for (; i < len && !is_base64(str[i]); ++i) {
120 // Skip junk
121 }
122
123 in[n_in] = str[i++];
124 }
125
126 if (n_in > 1) {
127 *size += decode_chunk(in, (uint8_t*)buf + j);
128 }
129 }
130
131 return buf;
132}
bool serd_base64_encode(uint8_t *const str, const void *const buf, const size_t size, const bool wrap_lines)
Definition base64.c:70
static const uint8_t b64_map[]
Definition base64.c:34
static void encode_chunk(uint8_t out[4], const uint8_t in[3], size_t n_in)
Definition base64.c:52
static size_t decode_chunk(const uint8_t in[4], uint8_t out[3])
Definition base64.c:101
static const char b64_unmap[]
Definition base64.c:44
size_t serd_base64_get_length(const size_t size, const bool wrap_lines)
Definition base64.c:64
static uint8_t unmap(const uint8_t in)
Definition base64.c:94
register unsigned j
Definition inflate.c:1576
register unsigned i
Definition inflate.c:1575
void * serd_base64_decode(const uint8_t *str, size_t len, size_t *size)
Definition base64.c:110
float in
Definition lilv_test.c:1460
float out
Definition lilv_test.c:1461
unsigned char uint8_t
Definition mid.cpp:98
static bool is_base64(const uint8_t c)
Definition string_utils.h:87
memcpy(hh, h, RAND_HEAD_LEN)
ulg size
Definition extract.c:2350
#define MIN(a, b)
Definition unzpriv.h:2649
char * malloc()