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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2009 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 hex implements hexadecimal encoding and decoding.
6
package hex
7
 
8
import (
9
        "bytes"
10
        "errors"
11
        "fmt"
12
        "io"
13
)
14
 
15
const hextable = "0123456789abcdef"
16
 
17
// EncodedLen returns the length of an encoding of n source bytes.
18
func EncodedLen(n int) int { return n * 2 }
19
 
20
// Encode encodes src into EncodedLen(len(src))
21
// bytes of dst.  As a convenience, it returns the number
22
// of bytes written to dst, but this value is always EncodedLen(len(src)).
23
// Encode implements hexadecimal encoding.
24
func Encode(dst, src []byte) int {
25
        for i, v := range src {
26
                dst[i*2] = hextable[v>>4]
27
                dst[i*2+1] = hextable[v&0x0f]
28
        }
29
 
30
        return len(src) * 2
31
}
32
 
33
// ErrLength results from decoding an odd length slice.
34
var ErrLength = errors.New("encoding/hex: odd length hex string")
35
 
36
// InvalidByteError values describe errors resulting from an invalid byte in a hex string.
37
type InvalidByteError byte
38
 
39
func (e InvalidByteError) Error() string {
40
        return fmt.Sprintf("encoding/hex: invalid byte: %#U", rune(e))
41
}
42
 
43
func DecodedLen(x int) int { return x / 2 }
44
 
45
// Decode decodes src into DecodedLen(len(src)) bytes, returning the actual
46
// number of bytes written to dst.
47
//
48
// If Decode encounters invalid input, it returns an error describing the failure.
49
func Decode(dst, src []byte) (int, error) {
50
        if len(src)%2 == 1 {
51
                return 0, ErrLength
52
        }
53
 
54
        for i := 0; i < len(src)/2; i++ {
55
                a, ok := fromHexChar(src[i*2])
56
                if !ok {
57
                        return 0, InvalidByteError(src[i*2])
58
                }
59
                b, ok := fromHexChar(src[i*2+1])
60
                if !ok {
61
                        return 0, InvalidByteError(src[i*2+1])
62
                }
63
                dst[i] = (a << 4) | b
64
        }
65
 
66
        return len(src) / 2, nil
67
}
68
 
69
// fromHexChar converts a hex character into its value and a success flag.
70
func fromHexChar(c byte) (byte, bool) {
71
        switch {
72
        case '0' <= c && c <= '9':
73
                return c - '0', true
74
        case 'a' <= c && c <= 'f':
75
                return c - 'a' + 10, true
76
        case 'A' <= c && c <= 'F':
77
                return c - 'A' + 10, true
78
        }
79
 
80
        return 0, false
81
}
82
 
83
// EncodeToString returns the hexadecimal encoding of src.
84
func EncodeToString(src []byte) string {
85
        dst := make([]byte, EncodedLen(len(src)))
86
        Encode(dst, src)
87
        return string(dst)
88
}
89
 
90
// DecodeString returns the bytes represented by the hexadecimal string s.
91
func DecodeString(s string) ([]byte, error) {
92
        src := []byte(s)
93
        dst := make([]byte, DecodedLen(len(src)))
94
        _, err := Decode(dst, src)
95
        if err != nil {
96
                return nil, err
97
        }
98
        return dst, nil
99
}
100
 
101
// Dump returns a string that contains a hex dump of the given data. The format
102
// of the hex dump matches the output of `hexdump -C` on the command line.
103
func Dump(data []byte) string {
104
        var buf bytes.Buffer
105
        dumper := Dumper(&buf)
106
        dumper.Write(data)
107
        dumper.Close()
108
        return string(buf.Bytes())
109
}
110
 
111
// Dumper returns a WriteCloser that writes a hex dump of all written data to
112
// w. The format of the dump matches the output of `hexdump -C` on the command
113
// line.
114
func Dumper(w io.Writer) io.WriteCloser {
115
        return &dumper{w: w}
116
}
117
 
118
type dumper struct {
119
        w          io.Writer
120
        rightChars [18]byte
121
        buf        [14]byte
122
        used       int  // number of bytes in the current line
123
        n          uint // number of bytes, total
124
}
125
 
126
func toChar(b byte) byte {
127
        if b < 32 || b > 126 {
128
                return '.'
129
        }
130
        return b
131
}
132
 
133
func (h *dumper) Write(data []byte) (n int, err error) {
134
        // Output lines look like:
135
        // 00000010  2e 2f 30 31 32 33 34 35  36 37 38 39 3a 3b 3c 3d  |./0123456789:;<=|
136
        // ^ offset                          ^ extra space              ^ ASCII of line.
137
        for i := range data {
138
                if h.used == 0 {
139
                        // At the beginning of a line we print the current
140
                        // offset in hex.
141
                        h.buf[0] = byte(h.n >> 24)
142
                        h.buf[1] = byte(h.n >> 16)
143
                        h.buf[2] = byte(h.n >> 8)
144
                        h.buf[3] = byte(h.n)
145
                        Encode(h.buf[4:], h.buf[:4])
146
                        h.buf[12] = ' '
147
                        h.buf[13] = ' '
148
                        _, err = h.w.Write(h.buf[4:])
149
                }
150
                Encode(h.buf[:], data[i:i+1])
151
                h.buf[2] = ' '
152
                l := 3
153
                if h.used == 7 {
154
                        // There's an additional space after the 8th byte.
155
                        h.buf[3] = ' '
156
                        l = 4
157
                } else if h.used == 15 {
158
                        // At the end of the line there's an extra space and
159
                        // the bar for the right column.
160
                        h.buf[3] = ' '
161
                        h.buf[4] = '|'
162
                        l = 5
163
                }
164
                _, err = h.w.Write(h.buf[:l])
165
                if err != nil {
166
                        return
167
                }
168
                n++
169
                h.rightChars[h.used] = toChar(data[i])
170
                h.used++
171
                h.n++
172
                if h.used == 16 {
173
                        h.rightChars[16] = '|'
174
                        h.rightChars[17] = '\n'
175
                        _, err = h.w.Write(h.rightChars[:])
176
                        if err != nil {
177
                                return
178
                        }
179
                        h.used = 0
180
                }
181
        }
182
        return
183
}
184
 
185
func (h *dumper) Close() (err error) {
186
        // See the comments in Write() for the details of this format.
187
        if h.used == 0 {
188
                return
189
        }
190
        h.buf[0] = ' '
191
        h.buf[1] = ' '
192
        h.buf[2] = ' '
193
        h.buf[3] = ' '
194
        h.buf[4] = '|'
195
        nBytes := h.used
196
        for h.used < 16 {
197
                l := 3
198
                if h.used == 7 {
199
                        l = 4
200
                } else if h.used == 15 {
201
                        l = 5
202
                }
203
                _, err = h.w.Write(h.buf[:l])
204
                if err != nil {
205
                        return
206
                }
207
                h.used++
208
        }
209
        h.rightChars[nBytes] = '|'
210
        h.rightChars[nBytes+1] = '\n'
211
        _, err = h.w.Write(h.rightChars[:nBytes+2])
212
        return
213
}

powered by: WebSVN 2.1.0

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