1
2
3
4
5
6 package base64
7
8 import (
9 "io"
10 "os"
11 "strconv"
12 )
13
14 15 16
17
18
19
20
21
22
23 type Encoding struct {
24 encode string
25 decodeMap [256]byte
26 }
27
28 const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
29 const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
30
31
32
33 func NewEncoding(encoder string) *Encoding {
34 e := new(Encoding)
35 e.encode = encoder
36 for i := 0; i < len(e.decodeMap); i++ {
37 e.decodeMap[i] = 0xFF
38 }
39 for i := 0; i < len(encoder); i++ {
40 e.decodeMap[encoder[i]] = byte(i)
41 }
42 return e
43 }
44
45
46
47 var StdEncoding = NewEncoding(encodeStd)
48
49
50
51 var URLEncoding = NewEncoding(encodeURL)
52
53 54 55
56
57
58
59
60
61
62
63 func (enc *Encoding) Encode(dst, src []byte) {
64 if len(src) == 0 {
65 return
66 }
67
68 for len(src) > 0 {
69 dst[0] = 0
70 dst[1] = 0
71 dst[2] = 0
72 dst[3] = 0
73
74
75
76 switch len(src) {
77 default:
78 dst[3] |= src[2] & 0x3F
79 dst[2] |= src[2] >> 6
80 fallthrough
81 case 2:
82 dst[2] |= (src[1] << 2) & 0x3F
83 dst[1] |= src[1] >> 4
84 fallthrough
85 case 1:
86 dst[1] |= (src[0] << 4) & 0x3F
87 dst[0] |= src[0] >> 2
88 }
89
90
91 for j := 0; j < 4; j++ {
92 dst[j] = enc.encode[dst[j]]
93 }
94
95
96 if len(src) < 3 {
97 dst[3] = '='
98 if len(src) < 2 {
99 dst[2] = '='
100 }
101 break
102 }
103
104 src = src[3:]
105 dst = dst[4:]
106 }
107 }
108
109
110 func (enc *Encoding) EncodeToString(src []byte) string {
111 buf := make([]byte, enc.EncodedLen(len(src)))
112 enc.Encode(buf, src)
113 return string(buf)
114 }
115
116 type encoder struct {
117 err os.Error
118 enc *Encoding
119 w io.Writer
120 buf [3]byte
121 nbuf int
122 out [1024]byte
123 }
124
125 func (e *encoder) Write(p []byte) (n int, err os.Error) {
126 if e.err != nil {
127 return 0, e.err
128 }
129
130
131 if e.nbuf > 0 {
132 var i int
133 for i = 0; i < len(p) && e.nbuf < 3; i++ {
134 e.buf[e.nbuf] = p[i]
135 e.nbuf++
136 }
137 n += i
138 p = p[i:]
139 if e.nbuf < 3 {
140 return
141 }
142 e.enc.Encode(e.out[0:], e.buf[0:])
143 if _, e.err = e.w.Write(e.out[0:4]); e.err != nil {
144 return n, e.err
145 }
146 e.nbuf = 0
147 }
148
149
150 for len(p) >= 3 {
151 nn := len(e.out) / 4 * 3
152 if nn > len(p) {
153 nn = len(p)
154 }
155 nn -= nn % 3
156 if nn > 0 {
157 e.enc.Encode(e.out[0:], p[0:nn])
158 if _, e.err = e.w.Write(e.out[0 : nn/3*4]); e.err != nil {
159 return n, e.err
160 }
161 }
162 n += nn
163 p = p[nn:]
164 }
165
166
167 for i := 0; i < len(p); i++ {
168 e.buf[i] = p[i]
169 }
170 e.nbuf = len(p)
171 n += len(p)
172 return
173 }
174
175
176
177 func (e *encoder) Close() os.Error {
178
179 if e.err == nil && e.nbuf > 0 {
180 e.enc.Encode(e.out[0:], e.buf[0:e.nbuf])
181 e.nbuf = 0
182 _, e.err = e.w.Write(e.out[0:4])
183 }
184 return e.err
185 }
186
187
188
189
190
191
192 func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser {
193 return &encoder{enc: enc, w: w}
194 }
195
196
197
198 func (enc *Encoding) EncodedLen(n int) int { return (n + 2) / 3 * 4 }
199
200 201 202
203
204 type CorruptInputError int64
205
206 func (e CorruptInputError) String() string {
207 return "illegal base64 data at input byte " + strconv.Itoa64(int64(e))
208 }
209
210
211
212
213
214 func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err os.Error) {
215 for i := 0; i < len(src)/4 && !end; i++ {
216
217 var dbuf [4]byte
218 dlen := 4
219
220 dbufloop:
221 for j := 0; j < 4; j++ {
222 in := src[i*4+j]
223 if in == '=' && j >= 2 && i == len(src)/4-1 {
224
225
226 if src[i*4+3] != '=' {
227 return n, false, CorruptInputError(i*4 + 2)
228 }
229 dlen = j
230 end = true
231 break dbufloop
232 }
233 dbuf[j] = enc.decodeMap[in]
234 if dbuf[j] == 0xFF {
235 return n, false, CorruptInputError(i*4 + j)
236 }
237 }
238
239
240
241 switch dlen {
242 case 4:
243 dst[i*3+2] = dbuf[2]<<6 | dbuf[3]
244 fallthrough
245 case 3:
246 dst[i*3+1] = dbuf[1]<<4 | dbuf[2]>>2
247 fallthrough
248 case 2:
249 dst[i*3+0] = dbuf[0]<<2 | dbuf[1]>>4
250 }
251 n += dlen - 1
252 }
253
254 return n, end, nil
255 }
256
257
258
259
260
261 func (enc *Encoding) Decode(dst, src []byte) (n int, err os.Error) {
262 if len(src)%4 != 0 {
263 return 0, CorruptInputError(len(src) / 4 * 4)
264 }
265
266 n, _, err = enc.decode(dst, src)
267 return
268 }
269
270
271 func (enc *Encoding) DecodeString(s string) ([]byte, os.Error) {
272 dbuf := make([]byte, enc.DecodedLen(len(s)))
273 n, err := enc.Decode(dbuf, []byte(s))
274 return dbuf[:n], err
275 }
276
277 type decoder struct {
278 err os.Error
279 enc *Encoding
280 r io.Reader
281 end bool
282 buf [1024]byte
283 nbuf int
284 out []byte
285 outbuf [1024 / 4 * 3]byte
286 }
287
288 func (d *decoder) Read(p []byte) (n int, err os.Error) {
289 if d.err != nil {
290 return 0, d.err
291 }
292
293
294 if len(d.out) > 0 {
295 n = copy(p, d.out)
296 d.out = d.out[n:]
297 return n, nil
298 }
299
300
301 nn := len(p) / 3 * 4
302 if nn < 4 {
303 nn = 4
304 }
305 if nn > len(d.buf) {
306 nn = len(d.buf)
307 }
308 nn, d.err = io.ReadAtLeast(d.r, d.buf[d.nbuf:nn], 4-d.nbuf)
309 d.nbuf += nn
310 if d.nbuf < 4 {
311 return 0, d.err
312 }
313
314
315 nr := d.nbuf / 4 * 4
316 nw := d.nbuf / 4 * 3
317 if nw > len(p) {
318 nw, d.end, d.err = d.enc.decode(d.outbuf[0:], d.buf[0:nr])
319 d.out = d.outbuf[0:nw]
320 n = copy(p, d.out)
321 d.out = d.out[n:]
322 } else {
323 n, d.end, d.err = d.enc.decode(p, d.buf[0:nr])
324 }
325 d.nbuf -= nr
326 for i := 0; i < d.nbuf; i++ {
327 d.buf[i] = d.buf[i+nr]
328 }
329
330 if d.err == nil {
331 d.err = err
332 }
333 return n, d.err
334 }
335
336
337 func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
338 return &decoder{enc: enc, r: r}
339 }
340
341
342
343 func (enc *Encoding) DecodedLen(n int) int { return n / 4 * 3 }