ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/include/common/base64.h
Revision: 1.7
Committed: Sat Sep 22 14:27:26 2007 UTC (16 years, 8 months 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

# Content
1 /**
2 * base64.h: Base64 encoding / decoding algorithm.
3 *
4 * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
5 * Rights to this code are as documented in doc/pod/gplicense.pod.
6 *
7 * $Id: base64.h,v 1.6 2007-09-16 18:54:42 pippijn Exp $
8 */
9
10 #ifndef BASE64_H
11 #define BASE64_H
12
13 #include <cstddef>
14 #include <climits>
15
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 char retval;
29 int cnt;
30 };
31
32 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
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 size_t enc_end (char *otxt)
49 {
50 return enc_blockend (otxt, &m_state);
51 }
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 size_t encode (char const * const code, size_t const ilen, char *otxt)
65 {
66 return enc_block (code, ilen, otxt, &m_state);
67 }
68
69 bool encode (char const * const code, size_t const ilen, char **otxt)
70 {
71 size_t olen = 1 + (((ilen + 2) / 3) * 4);
72 if (ilen > olen)
73 {
74 *otxt = NULL;
75 return 0;
76 }
77
78 *otxt = new char[olen];
79
80 if (*otxt)
81 encode (code, ilen, *otxt);
82
83 return olen - 1;
84 }
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 char c;
98 };
99
100 static size_t dec_block (char const * const code, size_t const ilen, char *otxt, state *s);
101
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 return ULONG_MAX;
120 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 size_t decode (char const * const code, size_t const ilen, char *otxt)
138 {
139 return dec_block (code, ilen, otxt, &m_state);
140 }
141
142 bool decode (char const * const code, size_t const ilen, char **otxt, size_t *olen)
143 {
144 size_t reqlen = 3 * (ilen / 4) + 3;
145 *otxt = new char[reqlen];
146 if (!*otxt)
147 return false;
148
149 if (!decode (code, ilen, *otxt))
150 {
151 delete[] *otxt;
152 *otxt = NULL;
153 return false;
154 }
155
156 (*otxt)[reqlen] = '\0';
157 if (olen)
158 *olen = reqlen;
159
160 return true;
161 }
162 };
163 } // namespace base64
164
165 #endif // BASE64_H