OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [encoding/] [base32/] [base32.go] - Blame information for rev 774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2011 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
// Package base32 implements base32 encoding as specified by RFC 4648.
6
package base32
7
 
8
import (
9
        "io"
10
        "strconv"
11
)
12
 
13
/*
14
 * Encodings
15
 */
16
 
17
// An Encoding is a radix 32 encoding/decoding scheme, defined by a
18
// 32-character alphabet.  The most common is the "base32" encoding
19
// introduced for SASL GSSAPI and standardized in RFC 4648.
20
// The alternate "base32hex" encoding is used in DNSSEC.
21
type Encoding struct {
22
        encode    string
23
        decodeMap [256]byte
24
}
25
 
26
const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
27
const encodeHex = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
28
 
29
// NewEncoding returns a new Encoding defined by the given alphabet,
30
// which must be a 32-byte string.
31
func NewEncoding(encoder string) *Encoding {
32
        e := new(Encoding)
33
        e.encode = encoder
34
        for i := 0; i < len(e.decodeMap); i++ {
35
                e.decodeMap[i] = 0xFF
36
        }
37
        for i := 0; i < len(encoder); i++ {
38
                e.decodeMap[encoder[i]] = byte(i)
39
        }
40
        return e
41
}
42
 
43
// StdEncoding is the standard base32 encoding, as defined in
44
// RFC 4648.
45
var StdEncoding = NewEncoding(encodeStd)
46
 
47
// HexEncoding is the ``Extended Hex Alphabet'' defined in RFC 4648.
48
// It is typically used in DNS.
49
var HexEncoding = NewEncoding(encodeHex)
50
 
51
/*
52
 * Encoder
53
 */
54
 
55
// Encode encodes src using the encoding enc, writing
56
// EncodedLen(len(src)) bytes to dst.
57
//
58
// The encoding pads the output to a multiple of 8 bytes,
59
// so Encode is not appropriate for use on individual blocks
60
// of a large data stream.  Use NewEncoder() instead.
61
func (enc *Encoding) Encode(dst, src []byte) {
62
        if len(src) == 0 {
63
                return
64
        }
65
 
66
        for len(src) > 0 {
67
                dst[0] = 0
68
                dst[1] = 0
69
                dst[2] = 0
70
                dst[3] = 0
71
                dst[4] = 0
72
                dst[5] = 0
73
                dst[6] = 0
74
                dst[7] = 0
75
 
76
                // Unpack 8x 5-bit source blocks into a 5 byte
77
                // destination quantum
78
                switch len(src) {
79
                default:
80
                        dst[7] |= src[4] & 0x1F
81
                        dst[6] |= src[4] >> 5
82
                        fallthrough
83
                case 4:
84
                        dst[6] |= (src[3] << 3) & 0x1F
85
                        dst[5] |= (src[3] >> 2) & 0x1F
86
                        dst[4] |= src[3] >> 7
87
                        fallthrough
88
                case 3:
89
                        dst[4] |= (src[2] << 1) & 0x1F
90
                        dst[3] |= (src[2] >> 4) & 0x1F
91
                        fallthrough
92
                case 2:
93
                        dst[3] |= (src[1] << 4) & 0x1F
94
                        dst[2] |= (src[1] >> 1) & 0x1F
95
                        dst[1] |= (src[1] >> 6) & 0x1F
96
                        fallthrough
97
                case 1:
98
                        dst[1] |= (src[0] << 2) & 0x1F
99
                        dst[0] |= src[0] >> 3
100
                }
101
 
102
                // Encode 5-bit blocks using the base32 alphabet
103
                for j := 0; j < 8; j++ {
104
                        dst[j] = enc.encode[dst[j]]
105
                }
106
 
107
                // Pad the final quantum
108
                if len(src) < 5 {
109
                        dst[7] = '='
110
                        if len(src) < 4 {
111
                                dst[6] = '='
112
                                dst[5] = '='
113
                                if len(src) < 3 {
114
                                        dst[4] = '='
115
                                        if len(src) < 2 {
116
                                                dst[3] = '='
117
                                                dst[2] = '='
118
                                        }
119
                                }
120
                        }
121
                        break
122
                }
123
                src = src[5:]
124
                dst = dst[8:]
125
        }
126
}
127
 
128
// EncodeToString returns the base32 encoding of src.
129
func (enc *Encoding) EncodeToString(src []byte) string {
130
        buf := make([]byte, enc.EncodedLen(len(src)))
131
        enc.Encode(buf, src)
132
        return string(buf)
133
}
134
 
135
type encoder struct {
136
        err  error
137
        enc  *Encoding
138
        w    io.Writer
139
        buf  [5]byte    // buffered data waiting to be encoded
140
        nbuf int        // number of bytes in buf
141
        out  [1024]byte // output buffer
142
}
143
 
144
func (e *encoder) Write(p []byte) (n int, err error) {
145
        if e.err != nil {
146
                return 0, e.err
147
        }
148
 
149
        // Leading fringe.
150
        if e.nbuf > 0 {
151
                var i int
152
                for i = 0; i < len(p) && e.nbuf < 5; i++ {
153
                        e.buf[e.nbuf] = p[i]
154
                        e.nbuf++
155
                }
156
                n += i
157
                p = p[i:]
158
                if e.nbuf < 5 {
159
                        return
160
                }
161
                e.enc.Encode(e.out[0:], e.buf[0:])
162
                if _, e.err = e.w.Write(e.out[0:8]); e.err != nil {
163
                        return n, e.err
164
                }
165
                e.nbuf = 0
166
        }
167
 
168
        // Large interior chunks.
169
        for len(p) >= 5 {
170
                nn := len(e.out) / 8 * 5
171
                if nn > len(p) {
172
                        nn = len(p)
173
                }
174
                nn -= nn % 5
175
                if nn > 0 {
176
                        e.enc.Encode(e.out[0:], p[0:nn])
177
                        if _, e.err = e.w.Write(e.out[0 : nn/5*8]); e.err != nil {
178
                                return n, e.err
179
                        }
180
                }
181
                n += nn
182
                p = p[nn:]
183
        }
184
 
185
        // Trailing fringe.
186
        for i := 0; i < len(p); i++ {
187
                e.buf[i] = p[i]
188
        }
189
        e.nbuf = len(p)
190
        n += len(p)
191
        return
192
}
193
 
194
// Close flushes any pending output from the encoder.
195
// It is an error to call Write after calling Close.
196
func (e *encoder) Close() error {
197
        // If there's anything left in the buffer, flush it out
198
        if e.err == nil && e.nbuf > 0 {
199
                e.enc.Encode(e.out[0:], e.buf[0:e.nbuf])
200
                e.nbuf = 0
201
                _, e.err = e.w.Write(e.out[0:8])
202
        }
203
        return e.err
204
}
205
 
206
// NewEncoder returns a new base32 stream encoder.  Data written to
207
// the returned writer will be encoded using enc and then written to w.
208
// Base32 encodings operate in 5-byte blocks; when finished
209
// writing, the caller must Close the returned encoder to flush any
210
// partially written blocks.
211
func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser {
212
        return &encoder{enc: enc, w: w}
213
}
214
 
215
// EncodedLen returns the length in bytes of the base32 encoding
216
// of an input buffer of length n.
217
func (enc *Encoding) EncodedLen(n int) int { return (n + 4) / 5 * 8 }
218
 
219
/*
220
 * Decoder
221
 */
222
 
223
type CorruptInputError int64
224
 
225
func (e CorruptInputError) Error() string {
226
        return "illegal base32 data at input byte " + strconv.FormatInt(int64(e), 10)
227
}
228
 
229
// decode is like Decode but returns an additional 'end' value, which
230
// indicates if end-of-message padding was encountered and thus any
231
// additional data is an error.
232
func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
233
        osrc := src
234
        for len(src) > 0 && !end {
235
                // Decode quantum using the base32 alphabet
236
                var dbuf [8]byte
237
                dlen := 8
238
 
239
                // do the top bytes contain any data?
240
        dbufloop:
241
                for j := 0; j < 8; {
242
                        if len(src) == 0 {
243
                                return n, false, CorruptInputError(len(osrc) - len(src) - j)
244
                        }
245
                        in := src[0]
246
                        src = src[1:]
247
                        if in == '\r' || in == '\n' {
248
                                // Ignore this character.
249
                                continue
250
                        }
251
                        if in == '=' && j >= 2 && len(src) < 8 {
252
                                // We've reached the end and there's
253
                                // padding, the rest should be padded
254
                                for k := 0; k < 8-j-1; k++ {
255
                                        if len(src) > k && src[k] != '=' {
256
                                                return n, false, CorruptInputError(len(osrc) - len(src) + k - 1)
257
                                        }
258
                                }
259
                                dlen = j
260
                                end = true
261
                                break dbufloop
262
                        }
263
                        dbuf[j] = enc.decodeMap[in]
264
                        if dbuf[j] == 0xFF {
265
                                return n, false, CorruptInputError(len(osrc) - len(src) - 1)
266
                        }
267
                        j++
268
                }
269
 
270
                // Pack 8x 5-bit source blocks into 5 byte destination
271
                // quantum
272
                switch dlen {
273
                case 7, 8:
274
                        dst[4] = dbuf[6]<<5 | dbuf[7]
275
                        fallthrough
276
                case 6, 5:
277
                        dst[3] = dbuf[4]<<7 | dbuf[5]<<2 | dbuf[6]>>3
278
                        fallthrough
279
                case 4:
280
                        dst[2] = dbuf[3]<<4 | dbuf[4]>>1
281
                        fallthrough
282
                case 3:
283
                        dst[1] = dbuf[1]<<6 | dbuf[2]<<1 | dbuf[3]>>4
284
                        fallthrough
285
                case 2:
286
                        dst[0] = dbuf[0]<<3 | dbuf[1]>>2
287
                }
288
                dst = dst[5:]
289
                switch dlen {
290
                case 2:
291
                        n += 1
292
                case 3, 4:
293
                        n += 2
294
                case 5:
295
                        n += 3
296
                case 6, 7:
297
                        n += 4
298
                case 8:
299
                        n += 5
300
                }
301
        }
302
        return n, end, nil
303
}
304
 
305
// Decode decodes src using the encoding enc.  It writes at most
306
// DecodedLen(len(src)) bytes to dst and returns the number of bytes
307
// written.  If src contains invalid base32 data, it will return the
308
// number of bytes successfully written and CorruptInputError.
309
// New line characters (\r and \n) are ignored.
310
func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
311
        n, _, err = enc.decode(dst, src)
312
        return
313
}
314
 
315
// DecodeString returns the bytes represented by the base32 string s.
316
func (enc *Encoding) DecodeString(s string) ([]byte, error) {
317
        dbuf := make([]byte, enc.DecodedLen(len(s)))
318
        n, err := enc.Decode(dbuf, []byte(s))
319
        return dbuf[:n], err
320
}
321
 
322
type decoder struct {
323
        err    error
324
        enc    *Encoding
325
        r      io.Reader
326
        end    bool       // saw end of message
327
        buf    [1024]byte // leftover input
328
        nbuf   int
329
        out    []byte // leftover decoded output
330
        outbuf [1024 / 8 * 5]byte
331
}
332
 
333
func (d *decoder) Read(p []byte) (n int, err error) {
334
        if d.err != nil {
335
                return 0, d.err
336
        }
337
 
338
        // Use leftover decoded output from last read.
339
        if len(d.out) > 0 {
340
                n = copy(p, d.out)
341
                d.out = d.out[n:]
342
                return n, nil
343
        }
344
 
345
        // Read a chunk.
346
        nn := len(p) / 5 * 8
347
        if nn < 8 {
348
                nn = 8
349
        }
350
        if nn > len(d.buf) {
351
                nn = len(d.buf)
352
        }
353
        nn, d.err = io.ReadAtLeast(d.r, d.buf[d.nbuf:nn], 8-d.nbuf)
354
        d.nbuf += nn
355
        if d.nbuf < 8 {
356
                return 0, d.err
357
        }
358
 
359
        // Decode chunk into p, or d.out and then p if p is too small.
360
        nr := d.nbuf / 8 * 8
361
        nw := d.nbuf / 8 * 5
362
        if nw > len(p) {
363
                nw, d.end, d.err = d.enc.decode(d.outbuf[0:], d.buf[0:nr])
364
                d.out = d.outbuf[0:nw]
365
                n = copy(p, d.out)
366
                d.out = d.out[n:]
367
        } else {
368
                n, d.end, d.err = d.enc.decode(p, d.buf[0:nr])
369
        }
370
        d.nbuf -= nr
371
        for i := 0; i < d.nbuf; i++ {
372
                d.buf[i] = d.buf[i+nr]
373
        }
374
 
375
        if d.err == nil {
376
                d.err = err
377
        }
378
        return n, d.err
379
}
380
 
381
// NewDecoder constructs a new base32 stream decoder.
382
func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
383
        return &decoder{enc: enc, r: r}
384
}
385
 
386
// DecodedLen returns the maximum length in bytes of the decoded data
387
// corresponding to n bytes of base32-encoded data.
388
func (enc *Encoding) DecodedLen(n int) int { return n / 8 * 5 }

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.