ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/include/common/base64.h
Revision: 1.4
Committed: Wed Sep 5 11:23:13 2007 UTC (19 years, 1 month ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.3: +2 -2 lines
Log Message:
removed GPLed code and put license back to BSD

File Contents

# User Rev Content
1 pippijn 1.1 /*
2 pippijn 1.2 * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
3 pippijn 1.4 * Rights to this code are as documented in doc/pod/license.pod.
4 pippijn 1.2 *
5     * Base64 encoding / decoding algorithm.
6     *
7 pippijn 1.4 * $Id: base64.h,v 1.3 2007-08-28 17:08:07 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     char result;
29     int stepcnt;
30     };
31    
32     static size_t enc_block (char const * const text, size_t inlen, char *code, state *st);
33     static size_t enc_blockend (char *code, state *st);
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 *outtext)
49     {
50     return enc_blockend (outtext, &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 inlen, char *outtext)
65     {
66     return enc_block (code, inlen, outtext, &m_state);
67     }
68    
69     bool encode (char const * const code, size_t const inlen, char **outtext)
70     {
71     size_t outlen = 1 + (((inlen + 2) / 3) * 4);
72     if (inlen > outlen)
73     {
74     *outtext = NULL;
75     return 0;
76     }
77    
78     *outtext = new char[outlen];
79    
80     if (*outtext)
81     encode (code, inlen, *outtext);
82    
83     return outlen - 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 plainchar;
98     };
99    
100     static size_t dec_block (char const * const code, size_t const inlen, char *outtext, state *st);
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 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     size_t decode (char const * const code, size_t const inlen, char *outtext)
138     {
139     return dec_block (code, inlen, outtext, &m_state);
140     }
141    
142     bool decode (char const * const code, size_t const inlen, char **outtext, size_t *outlen)
143     {
144     size_t needlen = 3 * (inlen / 4) + 3;
145     *outtext = new char[needlen];
146     if (!*outtext)
147     return false;
148    
149     if (!decode (code, inlen, *outtext))
150     {
151     delete[] *outtext;
152     *outtext = NULL;
153     return false;
154     }
155    
156     (*outtext)[needlen] = '\0';
157     if (outlen)
158     *outlen = needlen;
159    
160     return true;
161     }
162     };
163     } // namespace base64
164    
165     #endif // BASE64_H