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