summaryrefslogtreecommitdiff
path: root/src/mime/base64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mime/base64.cc')
-rw-r--r--src/mime/base64.cc132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/mime/base64.cc b/src/mime/base64.cc
new file mode 100644
index 0000000..842bbd3
--- /dev/null
+++ b/src/mime/base64.cc
@@ -0,0 +1,132 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mime/enc.h>
21
22static unsigned char char2six[256]={
23 65,65,65,65,65,65,65,65,
24 65,65,65,65,65,65,65,65,
25 65,65,65,65,65,65,65,65,
26 65,65,65,65,65,65,65,65,
27 65,65,65,65,65,65,65,65,
28 65,65,65,62,65,65,65,63,
29 52,53,54,55,56,57,58,59,
30 60,61,65,65,65,64,65,65,
31 65, 0, 1, 2, 3, 4, 5, 6,
32 7, 8, 9,10,11,12,13,14,
33 15,16,17,18,19,20,21,22,
34 23,24,25,65,65,65,65,65,
35 65,26,27,28,29,30,31,32,
36 33,34,35,36,37,38,39,40,
37 41,42,43,44,45,46,47,48,
38 49,50,51,65,65,65,65,65,
39 65,65,65,65,65,65,65,65,
40 65,65,65,65,65,65,65,65,
41 65,65,65,65,65,65,65,65,
42 65,65,65,65,65,65,65,65,
43 65,65,65,65,65,65,65,65,
44 65,65,65,65,65,65,65,65,
45 65,65,65,65,65,65,65,65,
46 65,65,65,65,65,65,65,65,
47 65,65,65,65,65,65,65,65,
48 65,65,65,65,65,65,65,65,
49 65,65,65,65,65,65,65,65,
50 65,65,65,65,65,65,65,65,
51 65,65,65,65,65,65,65,65,
52 65,65,65,65,65,65,65,65,
53 65,65,65,65,65,65,65,65,
54 65,65,65,65,65,65,65,65
55};
56static unsigned char six2char[64]={
57 'A','B','C','D','E','F','G','H',
58 'I','J','K','L','M','N','O','P',
59 'Q','R','S','T','U','V','W','X',
60 'Y','Z','a','b','c','d','e','f',
61 'g','h','i','j','k','l','m','n',
62 'o','p','q','r','s','t','u','v',
63 'w','x','y','z','0','1','2','3',
64 '4','5','6','7','8','9','+','/'
65};
66inline void tri2quad(mstream& out,unsigned code,int m=4)
67{
68 char buf[4];
69 buf[3]=six2char[code&63U]; code>>=6;
70 buf[2]=six2char[code&63U]; code>>=6;
71 buf[1]=six2char[code&63U]; code>>=6;
72 buf[0]=six2char[code&63U];
73 out.write(buf,m);
74}
75inline void quad2tri(mstream& out,unsigned code,int m=3)
76{
77 char buf[3];
78 buf[2]=code&255U; code>>=8;
79 buf[1]=code&255U; code>>=8;
80 buf[0]=code&255U;
81 out.write(buf,m);
82}
83
84void encode64(mstream& out,const sref& in)
85{
86 unsigned m=0,code=0,wrap=0;
87 for(const char* p=in.begin();p!=in.end();p++) {
88 code<<=8;
89 code|=(unsigned char)*p;
90 if(++m==3) {
91 tri2quad(out,code);
92 m=0;
93 if(++wrap==15) { out<<CRLF; wrap=0; }
94 }
95 }
96 if(m==1) {
97 code<<=16;
98 tri2quad(out,code,2);
99 out<<"==";
100 if(++wrap==15) { out<<CRLF; wrap=0; }
101 }
102 else if(m==2) {
103 code<<=8;
104 tri2quad(out,code,3);
105 out.put('=');
106 if(++wrap==15) { out<<CRLF; wrap=0; }
107 }
108 if(wrap>0) out<<CRLF;
109}
110
111void decode64(mstream& out,const sref& in)
112{
113 unsigned m=0,code=0,six=0;
114 for(const char* p=in.begin();p!=in.end();p++) {
115 six=char2six[(unsigned char)*p];
116 if(six>=64) continue;
117 code<<=6;
118 code|=six;
119 if(++m==4) {
120 quad2tri(out,code);
121 m=0;
122 }
123 }
124 if(m==2) {
125 code<<=12;
126 quad2tri(out,code,1);
127 }
128 else if(m==3) {
129 code<<=6;
130 quad2tri(out,code,2);
131 }
132}