Main Page   Class Hierarchy   Alphabetical List   Compound List   Examples  
base64.h
1/***************************************************************************
2 copyright : (C) 2002-2008 by Stefano Barbato
3 email : stefano@codesink.org
4
5 $Id: base64.h,v 1.15 2008-10-07 11:06:26 tat Exp $
6 ***************************************************************************/
7#ifndef _MIMETIC_CODEC_BASE64_H_
8#define _MIMETIC_CODEC_BASE64_H_
9#include <mimetic/circular_buffer.h>
10#include <mimetic/codec/codec_base.h>
11#include <mimetic/codec/codec_chain.h>
12
13namespace mimetic
14{
15
16
17class Base64
18{
19 enum { LF = 0xA, CR = 0xD, NL = '\n' };
20 enum { default_maxlen = 76 };
21 enum { eq_sign = 100 };
22 static const signed char sEncTable[];
23 static const signed char sDecTable[];
24 static const int sDecTableSz;
25public:
26 class Encoder; class Decoder;
27 typedef Encoder encoder_type;
28 typedef Decoder decoder_type;
29
30
31/// Base64 encoder
32/*!
33
34 \sa encode decode
35 */
36class Encoder: public buffered_codec, public chainable_codec<Encoder>
37{
38 enum { pad_idx = 64 };
39 char_type m_ch[3];
40 int m_cidx;
41 int m_pos, m_maxlen;
42
43 template<typename OutIt>
44 inline void writeBuf(OutIt& out)
45 {
46 int pad_count = 3 - m_cidx;
47 m_cidx = 0;
48 int idx[4];
49 idx[0] = m_ch[0] >> 2;
50 switch(pad_count)
51 {
52 case 0:
53 idx[1] = (((m_ch[0] & 3) << 4) | (m_ch[1] >> 4));
54 idx[2] = ((m_ch[1] & 0xf) << 2) | (m_ch[2] >> 6);
55 idx[3] = m_ch[2] & 0x3f;
56 break;
57 case 1:
58 idx[1] = (((m_ch[0] & 3) << 4) | (m_ch[1] >> 4));
59 idx[2] = (m_ch[1] & 0xf) << 2 ;
60 idx[3] = pad_idx;
61 break;
62 case 2:
63 idx[1] = (m_ch[0] & 3) << 4;
64 idx[2] = idx[3] = pad_idx;
65 break;
66 }
67 for(int i = 0; i < 4; ++i)
68 {
69 *out = sEncTable[ idx[i] ]; ++out;
70 if(m_maxlen && ++m_pos > m_maxlen)
71 {
72 *out = NL; ++out;
73 m_pos = 1;
74 }
75 }
76 }
77public:
78 /*! return the multiplier of the required (max) size of the output buffer
79 * when encoding */
80 double codeSizeMultiplier() const
81 {
82 return 1.5;
83 }
84 /*! Constructor, maxlen is the maximum length of every encoded line */
85 Encoder(int maxlen = default_maxlen)
86 : m_cidx(0), m_pos(1), m_maxlen(maxlen)
87 {
88 }
89 /*! Returns the name of the codec ("Base64") */
90 const char* name() const { return "Base64"; }
91 /*!
92 Encodes [\p bit,\p eit) and write any encoded char to \p out.
93 */
94 template<typename InIt, typename OutIt>
95 void process(InIt bit, InIt eit, OutIt out)
96 {
97 for(; bit != eit; ++bit)
98 {
99 m_ch[m_cidx++] = (char_type)*bit;
100 if(m_cidx < 3)
101 continue;
102 writeBuf(out);
103 }
104 if(m_cidx > 0)
105 writeBuf(out);
106 }
107 /*!
108 Encodes \p c and write any encoded output char to \p out.
109 \warning You must call flush() when all chars have been
110 processed by the encode funcion.
111 \n
112 \code
113 while( (c = getchar()) != EOF )
114 b64.encode(c, out);
115 b64.flush();
116 \endcode
117 \n
118 \sa flush()
119 */
120 template<typename OutIt>
121 void process(char_type c, OutIt& out)
122 {
123 m_ch[m_cidx++] = c;
124 if(m_cidx < 3)
125 return;
126 writeBuf(out);
127 }
128 /*!
129 Write to \p out any buffered encoded char.
130 */
131 template<typename OutIt>
132 void flush(OutIt& out)
133 {
134 if(m_cidx > 0)
135 writeBuf(out);
136 }
137};
138
139/// Base64 decoder
140/*!
141
142 \sa encode decode
143 */
144class Decoder: public buffered_codec, public chainable_codec<Decoder>
145{
146 int m_cidx;
147 char_type m_ch[4];
148
149 template<typename OutIt>
150 inline void writeBuf(OutIt& out)
151 {
152 if(m_cidx < 4)
153 { // malformed, missing chars will be cosidered pad
154 switch(m_cidx)
155 {
156 case 0:
157 case 1:
158 return; // ignore;
159 case 2:
160 m_ch[2] = m_ch[3] = eq_sign;
161 break;
162 case 3:
163 m_ch[3] = eq_sign;
164 break;
165 }
166 }
167 m_cidx = 0;
168 *out = (m_ch[0] << 2 | ((m_ch[1] >> 4) & 0x3) ); ++out;
169 if(m_ch[2] == eq_sign) return;
170 *out = (m_ch[1] << 4 | ((m_ch[2] >> 2) & 0xF) ); ++out;
171 if(m_ch[3] == eq_sign) return;
172 *out = (m_ch[2] << 6 | m_ch[3]); ++out;
173 }
174public:
175 /*! Constructor */
177 : m_cidx(0)
178 {
179 }
180 /*! Returns the name of the codec ("Base64") */
181 const char* name() const { return "Base64"; }
182
183 /*!
184 Decodes [\p bit,\p eit) and write any decoded char to \p out.
185 */
186 template<typename InIt, typename OutIt>
187 inline void process(InIt bit, InIt eit, OutIt out)
188 {
189 char_type c;
190
191 for(; bit != eit; ++bit)
192 {
193 c = *bit;
194 if(c > sDecTableSz || sDecTable[c] == -1)
195 continue; // malformed or newline
196 m_ch[m_cidx++] = sDecTable[c];
197 if(m_cidx < 4)
198 continue;
199 writeBuf(out);
200 }
201 if(m_cidx > 0)
202 writeBuf(out);
203 }
204 /*!
205 Decodes \p c and write any decoded output char to \p out.
206
207 \warning You must call flush() when all chars have been
208 processed by the decode funcion.
209 \n
210 \code
211 while( (c = getchar()) != EOF )
212 b64.decode(c, out);
213 b64.flush();
214 \endcode
215 \n
216 \sa flush()
217 */
218 template<typename OutIt>
219 void process(char_type c, OutIt& out)
220 {
221 if(c > sDecTableSz || sDecTable[c] == -1)
222 return; // malformed or newline
223 m_ch[m_cidx++] = sDecTable[c];
224 if(m_cidx < 4)
225 return;
226 writeBuf(out);
227 }
228 /*!
229 Write to \p out any buffered decoded char.
230 */
231 template<typename OutIt>
232 void flush(OutIt& out)
233 {
234 if(m_cidx > 0)
235 writeBuf(out);
236 }
237};
238
239}; // Base64
240
241}
242#endif
243
Base64 decoder.
Definition: base64.h:145
void process(char_type c, OutIt &out)
Definition: base64.h:219
const char * name() const
Definition: base64.h:181
void process(InIt bit, InIt eit, OutIt out)
Definition: base64.h:187
Decoder()
Definition: base64.h:176
void flush(OutIt &out)
Definition: base64.h:232
Base64 encoder.
Definition: base64.h:37
void process(char_type c, OutIt &out)
Definition: base64.h:121
double codeSizeMultiplier() const
Definition: base64.h:80
const char * name() const
Definition: base64.h:90
void process(InIt bit, InIt eit, OutIt out)
Definition: base64.h:95
void flush(OutIt &out)
Definition: base64.h:132
Encoder(int maxlen=default_maxlen)
Definition: base64.h:85
Definition: body.h:18
Base class for buffered codecs.
Definition: codec_base.h:48