cdrom: fix a copy-paste mistake
[pcsx_rearmed.git] / deps / libretro-common / encodings / encoding_base64.c
CommitLineData
3719602c
PC
1/*
2 https://github.com/superwills/NibbleAndAHalf
3 base64.h -- Fast base64 encoding and decoding.
4 version 1.0.0, April 17, 2013 143a
5 Copyright (C) 2013 William Sherif
6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19 William Sherif
20 will.sherif@gmail.com
21 YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz
22
23
24 Modified for RetroArch formatting, logging, and header files.
25*/
26
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <encodings/base64.h>
31
32const static char* b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
33
34/* maps A=>0,B=>1.. */
35const static unsigned char unb64[]={
36 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40 0, 0, 0, 62, 0, 0, 0, 63, 52, 53,
41 54, 55, 56, 57, 58, 59, 60, 61, 0, 0,
42 0, 0, 0, 0, 0, 0, 1, 2, 3, 4,
43 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
44 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
45 25, 0, 0, 0, 0, 0, 0, 26, 27, 28,
46 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
47 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
48 49, 50, 51, 0, 0, 0, 0, 0, 0, 0,
49 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
52 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
53 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
56 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61 0, 0, 0, 0, 0, 0,
62}; /* This array has 256 elements */
63
64/*
65 Converts binary data of length=len to base64 characters.
66 Length of the resultant string is stored in flen
67 (you must pass pointer flen).
68*/
69char* base64(const void* binaryData, int len, int *flen)
70{
71 char* res;
72 int byteNo; /* I need this after the loop */
73 const unsigned char* bin = (const unsigned char*) binaryData;
74 int rc = 0; /* result counter */
75 int modulusLen = len % 3 ;
76 /* 2 gives 1 and 1 gives 2, but 0 gives 0. */
77 int pad = ((modulusLen&1)<<1) + ((modulusLen&2)>>1);
78
79 *flen = 4*(len + pad)/3;
80 if (!(res = (char*) malloc(*flen + 1))) /* and one for the NULL */
81 return 0;
82
83 for (byteNo=0; byteNo <= len-3; byteNo+=3)
84 {
85 unsigned char BYTE0 = bin[byteNo];
86 unsigned char BYTE1 = bin[byteNo+1];
87 unsigned char BYTE2 = bin[byteNo+2];
88
89 res[rc++] = b64[BYTE0 >> 2];
90 res[rc++] = b64[((0x3&BYTE0)<<4) + (BYTE1 >> 4)];
91 res[rc++] = b64[((0x0f&BYTE1)<<2) + (BYTE2>>6)];
92 res[rc++] = b64[0x3f&BYTE2];
93 }
94
95 if (pad==2)
96 {
97 res[rc++] = b64[bin[byteNo] >> 2];
98 res[rc++] = b64[(0x3&bin[byteNo])<<4];
99 res[rc++] = '=';
100 res[rc++] = '=';
101 }
102 else if (pad==1)
103 {
104 res[rc++] = b64[bin[byteNo] >> 2];
105 res[rc++] = b64[((0x3&bin[byteNo])<<4) + (bin[byteNo+1] >> 4)];
106 res[rc++] = b64[(0x0f&bin[byteNo+1])<<2];
107 res[rc++] = '=';
108 }
109
110 res[rc]=0; /* NULL TERMINATOR! ;) */
111 return res;
112}
113
114unsigned char* unbase64(const char* ascii, int len, int *flen)
115{
116 int charNo;
117 unsigned char *bin;
118 const unsigned char *safeAsciiPtr = (const unsigned char*) ascii;
119 int cb = 0;
120 int pad = 0;
121
122 if (len < 2) /* 2 accesses below would be OOB (Out Of Bounds). */
123 {
124 /* catch empty string, return NULL as result. */
125 /* ERROR: You passed an invalid base64 string (too short).
126 * You get NULL back. */
127 *flen = 0;
128 return 0;
129 }
130
131 if (safeAsciiPtr[len-1]=='=')
132 ++pad;
133 if (safeAsciiPtr[len-2]=='=')
134 ++pad;
135
136 *flen = 3*len/4 - pad;
137 if (!(bin = (unsigned char*)malloc(*flen)))
138 return 0;
139
140 for (charNo=0; charNo <= len-4-pad; charNo+=4)
141 {
142 int A = unb64[safeAsciiPtr[charNo]];
143 int B = unb64[safeAsciiPtr[charNo+1]];
144 int C = unb64[safeAsciiPtr[charNo+2]];
145 int D = unb64[safeAsciiPtr[charNo+3]];
146
147 bin[cb++] = (A<<2) | (B>>4);
148 bin[cb++] = (B<<4) | (C>>2);
149 bin[cb++] = (C<<6) | (D);
150 }
151
152 if (pad==1)
153 {
154 int A = unb64[safeAsciiPtr[charNo]];
155 int B = unb64[safeAsciiPtr[charNo+1]];
156 int C = unb64[safeAsciiPtr[charNo+2]];
157
158 bin[cb++] = (A<<2) | (B>>4);
159 bin[cb++] = (B<<4) | (C>>2);
160 }
161 else if (pad==2)
162 {
163 int A = unb64[safeAsciiPtr[charNo]];
164 int B = unb64[safeAsciiPtr[charNo+1]];
165
166 bin[cb++] = (A<<2) | (B>>4);
167 }
168
169 return bin;
170}
171