OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Package base64 implements base64 encoding as specified by RFC 4648. | 5 // Package base64 implements base64 encoding as specified by RFC 4648. |
6 package base64 | 6 package base64 |
7 | 7 |
8 import ( | 8 import ( |
9 "io"; | 9 "io"; |
10 "os"; | 10 "os"; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 | 94 |
95 // Pad the final quantum | 95 // Pad the final quantum |
96 if len(src) < 3 { | 96 if len(src) < 3 { |
97 dst[3] = '='; | 97 dst[3] = '='; |
98 if len(src) < 2 { | 98 if len(src) < 2 { |
99 dst[2] = '=' | 99 dst[2] = '=' |
100 } | 100 } |
101 break; | 101 break; |
102 } | 102 } |
103 | 103 |
104 » » src = src[3:len(src)]; | 104 » » src = src[3:]; |
105 » » dst = dst[4:len(dst)]; | 105 » » dst = dst[4:]; |
106 } | 106 } |
107 } | 107 } |
108 | 108 |
109 type encoder struct { | 109 type encoder struct { |
110 err os.Error; | 110 err os.Error; |
111 enc *Encoding; | 111 enc *Encoding; |
112 w io.Writer; | 112 w io.Writer; |
113 buf [3]byte; // buffered data waiting to be encoded | 113 buf [3]byte; // buffered data waiting to be encoded |
114 nbuf int; // number of bytes in buf | 114 nbuf int; // number of bytes in buf |
115 out [1024]byte; // output buffer | 115 out [1024]byte; // output buffer |
116 } | 116 } |
117 | 117 |
118 func (e *encoder) Write(p []byte) (n int, err os.Error) { | 118 func (e *encoder) Write(p []byte) (n int, err os.Error) { |
119 if e.err != nil { | 119 if e.err != nil { |
120 return 0, e.err | 120 return 0, e.err |
121 } | 121 } |
122 | 122 |
123 // Leading fringe. | 123 // Leading fringe. |
124 if e.nbuf > 0 { | 124 if e.nbuf > 0 { |
125 var i int; | 125 var i int; |
126 for i = 0; i < len(p) && e.nbuf < 3; i++ { | 126 for i = 0; i < len(p) && e.nbuf < 3; i++ { |
127 e.buf[e.nbuf] = p[i]; | 127 e.buf[e.nbuf] = p[i]; |
128 e.nbuf++; | 128 e.nbuf++; |
129 } | 129 } |
130 n += i; | 130 n += i; |
131 » » p = p[i:len(p)]; | 131 » » p = p[i:]; |
132 if e.nbuf < 3 { | 132 if e.nbuf < 3 { |
133 return | 133 return |
134 } | 134 } |
135 e.enc.Encode(&e.out, &e.buf); | 135 e.enc.Encode(&e.out, &e.buf); |
136 if _, e.err = e.w.Write(e.out[0:4]); e.err != nil { | 136 if _, e.err = e.w.Write(e.out[0:4]); e.err != nil { |
137 return n, e.err | 137 return n, e.err |
138 } | 138 } |
139 e.nbuf = 0; | 139 e.nbuf = 0; |
140 } | 140 } |
141 | 141 |
142 // Large interior chunks. | 142 // Large interior chunks. |
143 for len(p) >= 3 { | 143 for len(p) >= 3 { |
144 nn := len(e.out) / 4 * 3; | 144 nn := len(e.out) / 4 * 3; |
145 if nn > len(p) { | 145 if nn > len(p) { |
146 nn = len(p) | 146 nn = len(p) |
147 } | 147 } |
148 nn -= nn % 3; | 148 nn -= nn % 3; |
149 if nn > 0 { | 149 if nn > 0 { |
150 e.enc.Encode(&e.out, p[0:nn]); | 150 e.enc.Encode(&e.out, p[0:nn]); |
151 if _, e.err = e.w.Write(e.out[0 : nn/3*4]); e.err != nil
{ | 151 if _, e.err = e.w.Write(e.out[0 : nn/3*4]); e.err != nil
{ |
152 return n, e.err | 152 return n, e.err |
153 } | 153 } |
154 } | 154 } |
155 n += nn; | 155 n += nn; |
156 » » p = p[nn:len(p)]; | 156 » » p = p[nn:]; |
157 } | 157 } |
158 | 158 |
159 // Trailing fringe. | 159 // Trailing fringe. |
160 for i := 0; i < len(p); i++ { | 160 for i := 0; i < len(p); i++ { |
161 e.buf[i] = p[i] | 161 e.buf[i] = p[i] |
162 } | 162 } |
163 e.nbuf = len(p); | 163 e.nbuf = len(p); |
164 n += len(p); | 164 n += len(p); |
165 return; | 165 return; |
166 } | 166 } |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 } | 272 } |
273 | 273 |
274 func (d *decoder) Read(p []byte) (n int, err os.Error) { | 274 func (d *decoder) Read(p []byte) (n int, err os.Error) { |
275 if d.err != nil { | 275 if d.err != nil { |
276 return 0, d.err | 276 return 0, d.err |
277 } | 277 } |
278 | 278 |
279 // Use leftover decoded output from last read. | 279 // Use leftover decoded output from last read. |
280 if len(d.out) > 0 { | 280 if len(d.out) > 0 { |
281 n = copy(p, d.out); | 281 n = copy(p, d.out); |
282 » » d.out = d.out[n:len(d.out)]; | 282 » » d.out = d.out[n:]; |
283 return n, nil; | 283 return n, nil; |
284 } | 284 } |
285 | 285 |
286 // Read a chunk. | 286 // Read a chunk. |
287 nn := len(p) / 3 * 4; | 287 nn := len(p) / 3 * 4; |
288 if nn < 4 { | 288 if nn < 4 { |
289 nn = 4 | 289 nn = 4 |
290 } | 290 } |
291 if nn > len(d.buf) { | 291 if nn > len(d.buf) { |
292 nn = len(d.buf) | 292 nn = len(d.buf) |
293 } | 293 } |
294 nn, d.err = io.ReadAtLeast(d.r, d.buf[d.nbuf:nn], 4-d.nbuf); | 294 nn, d.err = io.ReadAtLeast(d.r, d.buf[d.nbuf:nn], 4-d.nbuf); |
295 d.nbuf += nn; | 295 d.nbuf += nn; |
296 if d.nbuf < 4 { | 296 if d.nbuf < 4 { |
297 return 0, d.err | 297 return 0, d.err |
298 } | 298 } |
299 | 299 |
300 // Decode chunk into p, or d.out and then p if p is too small. | 300 // Decode chunk into p, or d.out and then p if p is too small. |
301 nr := d.nbuf / 4 * 4; | 301 nr := d.nbuf / 4 * 4; |
302 nw := d.nbuf / 4 * 3; | 302 nw := d.nbuf / 4 * 3; |
303 if nw > len(p) { | 303 if nw > len(p) { |
304 nw, d.end, d.err = d.enc.decode(&d.outbuf, d.buf[0:nr]); | 304 nw, d.end, d.err = d.enc.decode(&d.outbuf, d.buf[0:nr]); |
305 d.out = d.outbuf[0:nw]; | 305 d.out = d.outbuf[0:nw]; |
306 n = copy(p, d.out); | 306 n = copy(p, d.out); |
307 » » d.out = d.out[n:len(d.out)]; | 307 » » d.out = d.out[n:]; |
308 } else { | 308 } else { |
309 n, d.end, d.err = d.enc.decode(p, d.buf[0:nr]) | 309 n, d.end, d.err = d.enc.decode(p, d.buf[0:nr]) |
310 } | 310 } |
311 d.nbuf -= nr; | 311 d.nbuf -= nr; |
312 for i := 0; i < d.nbuf; i++ { | 312 for i := 0; i < d.nbuf; i++ { |
313 d.buf[i] = d.buf[i+nr] | 313 d.buf[i] = d.buf[i+nr] |
314 } | 314 } |
315 | 315 |
316 if d.err == nil { | 316 if d.err == nil { |
317 d.err = err | 317 d.err = err |
318 } | 318 } |
319 return n, d.err; | 319 return n, d.err; |
320 } | 320 } |
321 | 321 |
322 // NewDecoder constructs a new base64 stream decoder. | 322 // NewDecoder constructs a new base64 stream decoder. |
323 func NewDecoder(enc *Encoding, r io.Reader) io.Reader { | 323 func NewDecoder(enc *Encoding, r io.Reader) io.Reader { |
324 return &decoder{enc: enc, r: r} | 324 return &decoder{enc: enc, r: r} |
325 } | 325 } |
326 | 326 |
327 // DecodeLen returns the maximum length in bytes of the decoded data | 327 // DecodeLen returns the maximum length in bytes of the decoded data |
328 // corresponding to n bytes of base64-encoded data. | 328 // corresponding to n bytes of base64-encoded data. |
329 func (enc *Encoding) DecodedLen(n int) int { return n / 4 * 3 } | 329 func (enc *Encoding) DecodedLen(n int) int { return n / 4 * 3 } |
OLD | NEW |