ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/include/common/base64.h
Revision: 1.7
Committed: Sat Sep 22 14:27:26 2007 UTC (19 years ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +1 -1 lines
State: FILE REMOVED
Log Message:
split up ermyth into ermyth-modules, libermyth (currently just ermyth-util) and ermyth-core

File Contents

# User Rev Content
1 pippijn 1.6 /**
2     * base64.h: Base64 encoding / decoding algorithm.
3     *
4 pippijn 1.2 * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
5 pippijn 1.6 * Rights to this code are as documented in doc/pod/gplicense.pod.
6 pippijn 1.2 *
7 pippijn 1.7 * $Id: base64.h,v 1.6 2007-09-16 18:54:42 pippijn Exp $
8 pippijn 1.1 */
9    
10     #ifndef BASE64_H
11     #define BASE64_H
12    
13     #include <cstddef>
14 pippijn 1.3 #include <climits>
15 pippijn 1.1
16     namespace base64
17     {
18     class encoder
19     {
20     enum step
21     {
22     step_a, step_b, step_c
23     };
24    
25     struct state
26     {
27     enum step step;
28 pippijn 1.5 char retval;
29     int cnt;
30 pippijn 1.1 };
31    
32 pippijn 1.5 static size_t enc_block (char const * const txt, size_t ilen, char *code, state *s);
33     static size_t enc_blockend (char *code, state *s);
34 pippijn 1.1
35     static size_t const CHARS_PER_LINE = 72;
36    
37     static char enc_value (char val)
38     {
39     static char const * const enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
40     if (val > 63)
41     return '=';
42     return enc[(size_t) val];
43     }
44    
45     state m_state;
46     size_t m_bufsize;
47    
48 pippijn 1.5 size_t enc_end (char *otxt)
49 pippijn 1.1 {
50 pippijn 1.5 return enc_blockend (otxt, &m_state);
51 pippijn 1.1 }
52    
53     public:
54     encoder (size_t bufsize = 4096)
55     : m_bufsize (bufsize)
56     {
57     }
58    
59     size_t encode (char val)
60     {
61     return enc_value (val);
62     }
63    
64 pippijn 1.5 size_t encode (char const * const code, size_t const ilen, char *otxt)
65 pippijn 1.1 {
66 pippijn 1.5 return enc_block (code, ilen, otxt, &m_state);
67 pippijn 1.1 }
68    
69 pippijn 1.5 bool encode (char const * const code, size_t const ilen, char **otxt)
70 pippijn 1.1 {
71 pippijn 1.5 size_t olen = 1 + (((ilen + 2) / 3) * 4);
72     if (ilen > olen)
73 pippijn 1.1 {
74 pippijn 1.5 *otxt = NULL;
75 pippijn 1.1 return 0;
76     }
77    
78 pippijn 1.5 *otxt = new char[olen];
79 pippijn 1.1
80 pippijn 1.5 if (*otxt)
81     encode (code, ilen, *otxt);
82 pippijn 1.1
83 pippijn 1.5 return olen - 1;
84 pippijn 1.1 }
85     };
86    
87     class decoder
88     {
89     enum step
90     {
91     step_a, step_b, step_c, step_d
92     };
93    
94     struct state
95     {
96     enum step step;
97 pippijn 1.5 char c;
98 pippijn 1.1 };
99    
100 pippijn 1.5 static size_t dec_block (char const * const code, size_t const ilen, char *otxt, state *s);
101 pippijn 1.1
102     static size_t dec_value (char val)
103     {
104     static char const dec[] = {
105     62, -1, -1, -1, 63, 52, 53, 54, 55, 56,
106     57, 58, 59, 60, 61, -1, -1, -1, -2, -1,
107     -1, -1, 0, 1, 2, 3, 4, 5, 6, 7,
108     8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
109     18, 19, 20, 21, 22, 23, 24, 25, -1, -1,
110     -1, -1, -1, -1, 26, 27, 28, 29, 30, 31,
111     32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
112     42, 43, 44, 45, 46, 47, 48, 49, 50, 51
113     };
114    
115     static char const decsize = sizeof (dec);
116    
117     val -= 43;
118     if (val < 0 || val > decsize)
119 pippijn 1.3 return ULONG_MAX;
120 pippijn 1.1 return dec[(size_t) val];
121     }
122    
123     state m_state;
124     size_t m_bufsize;
125    
126     public:
127     decoder (size_t bufsize = 4096)
128     : m_bufsize (bufsize)
129     {
130     }
131    
132     size_t decode (char val)
133     {
134     return dec_value (val);
135     }
136    
137 pippijn 1.5 size_t decode (char const * const code, size_t const ilen, char *otxt)
138 pippijn 1.1 {
139 pippijn 1.5 return dec_block (code, ilen, otxt, &m_state);
140 pippijn 1.1 }
141    
142 pippijn 1.5 bool decode (char const * const code, size_t const ilen, char **otxt, size_t *olen)
143 pippijn 1.1 {
144 pippijn 1.5 size_t reqlen = 3 * (ilen / 4) + 3;
145     *otxt = new char[reqlen];
146     if (!*otxt)
147 pippijn 1.1 return false;
148    
149 pippijn 1.5 if (!decode (code, ilen, *otxt))
150 pippijn 1.1 {
151 pippijn 1.5 delete[] *otxt;
152     *otxt = NULL;
153 pippijn 1.1 return false;
154     }
155    
156 pippijn 1.5 (*otxt)[reqlen] = '\0';
157     if (olen)
158     *olen = reqlen;
159 pippijn 1.1
160     return true;
161     }
162     };
163     } // namespace base64
164    
165     #endif // BASE64_H