ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/include/common/base64.h
Revision: 1.2
Committed: Wed Jul 25 01:05:17 2007 UTC (19 years, 3 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.1: +6 -2 lines
Log Message:
- moved to GPL
- added license information to files

File Contents

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