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 
13 namespace mimetic
14 {
15 
16 
17 class Base64
18 {
19  enum { LF = 0xA, CR = 0xD, NL = '\n' };
20  enum { default_maxlen = 76 };
21  enum { eq_sign = 100 };
22  static const char sEncTable[];
23  static const char sDecTable[];
24  static const int sDecTableSz;
25 public:
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  */
36 class 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  }
77 public:
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  */
144 class 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  }
174 public:
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 
void process(char_type c, OutIt &out)
Definition: base64.h:121
Encoder(int maxlen=default_maxlen)
Definition: base64.h:85
const char * name() const
Definition: base64.h:90
void process(char_type c, OutIt &out)
Definition: base64.h:219
Base class for buffered codecs.
Definition: codec_base.h:47
void flush(OutIt &out)
Definition: base64.h:132
Decoder()
Definition: base64.h:176
Base64 encoder.
Definition: base64.h:36
double codeSizeMultiplier() const
Definition: base64.h:80
void process(InIt bit, InIt eit, OutIt out)
Definition: base64.h:187
Base64 decoder.
Definition: base64.h:144
void flush(OutIt &out)
Definition: base64.h:232
const char * name() const
Definition: base64.h:181
void process(InIt bit, InIt eit, OutIt out)
Definition: base64.h:95