This repository has been archived by the owner on Nov 20, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
/
lbase64.c
119 lines (108 loc) · 2.33 KB
/
lbase64.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
* lbase64.c
* base64 encoding and decoding for Lua 5.1
* Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br>
* 23 Mar 2010 22:22:38
* This code is hereby placed in the public domain.
*/
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#define MYNAME "base64"
#define MYVERSION MYNAME " library for " LUA_VERSION " / Mar 2010"
#define uint unsigned int
static const char code[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static void encode(luaL_Buffer *b, uint c1, uint c2, uint c3, int n)
{
unsigned long tuple=c3+256UL*(c2+256UL*c1);
int i;
char s[4];
for (i=0; i<4; i++) {
s[3-i] = code[tuple % 64];
tuple /= 64;
}
for (i=n+1; i<4; i++) s[i]='=';
luaL_addlstring(b,s,4);
}
static int Lencode(lua_State *L) /** encode(s) */
{
size_t l;
const unsigned char *s=(const unsigned char*)luaL_checklstring(L,1,&l);
luaL_Buffer b;
int n;
luaL_buffinit(L,&b);
for (n=l/3; n--; s+=3) encode(&b,s[0],s[1],s[2],3);
switch (l%3)
{
case 1: encode(&b,s[0],0,0,1); break;
case 2: encode(&b,s[0],s[1],0,2); break;
}
luaL_pushresult(&b);
return 1;
}
static void decode(luaL_Buffer *b, int c1, int c2, int c3, int c4, int n)
{
unsigned long tuple=c4+64L*(c3+64L*(c2+64L*c1));
char s[3];
switch (--n)
{
case 3: s[2]=tuple;
case 2: s[1]=tuple >> 8;
case 1: s[0]=tuple >> 16;
}
luaL_addlstring(b,s,n);
}
static int Ldecode(lua_State *L) /** decode(s) */
{
size_t l;
const char *s=luaL_checklstring(L,1,&l);
luaL_Buffer b;
int n=0;
char t[4];
luaL_buffinit(L,&b);
for (;;)
{
int c=*s++;
switch (c)
{
const char *p;
default:
p=strchr(code,c); if (p==NULL) return 0;
t[n++]= p-code;
if (n==4)
{
decode(&b,t[0],t[1],t[2],t[3],4);
n=0;
}
break;
case '=':
switch (n)
{
case 1: decode(&b,t[0],0,0,0,1); break;
case 2: decode(&b,t[0],t[1],0,0,2); break;
case 3: decode(&b,t[0],t[1],t[2],0,3); break;
}
case 0:
luaL_pushresult(&b);
return 1;
case '\n': case '\r': case '\t': case ' ': case '\f': case '\b':
break;
}
}
return 0;
}
static const luaL_Reg R[] =
{
{ "encode", Lencode },
{ "decode", Ldecode },
{ NULL, NULL }
};
LUALIB_API int luaopen_base64(lua_State *L)
{
luaL_register(L,MYNAME,R);
lua_pushliteral(L,"version"); /** version */
lua_pushliteral(L,MYVERSION);
lua_settable(L,-3);
return 1;
}