URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [encoding/] [hex/] [hex.go] - Rev 747
Compare with Previous | Blame | View Log
// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.// Package hex implements hexadecimal encoding and decoding.package heximport ("bytes""errors""fmt""io")const hextable = "0123456789abcdef"// EncodedLen returns the length of an encoding of n source bytes.func EncodedLen(n int) int { return n * 2 }// Encode encodes src into EncodedLen(len(src))// bytes of dst. As a convenience, it returns the number// of bytes written to dst, but this value is always EncodedLen(len(src)).// Encode implements hexadecimal encoding.func Encode(dst, src []byte) int {for i, v := range src {dst[i*2] = hextable[v>>4]dst[i*2+1] = hextable[v&0x0f]}return len(src) * 2}// ErrLength results from decoding an odd length slice.var ErrLength = errors.New("encoding/hex: odd length hex string")// InvalidByteError values describe errors resulting from an invalid byte in a hex string.type InvalidByteError bytefunc (e InvalidByteError) Error() string {return fmt.Sprintf("encoding/hex: invalid byte: %#U", rune(e))}func DecodedLen(x int) int { return x / 2 }// Decode decodes src into DecodedLen(len(src)) bytes, returning the actual// number of bytes written to dst.//// If Decode encounters invalid input, it returns an error describing the failure.func Decode(dst, src []byte) (int, error) {if len(src)%2 == 1 {return 0, ErrLength}for i := 0; i < len(src)/2; i++ {a, ok := fromHexChar(src[i*2])if !ok {return 0, InvalidByteError(src[i*2])}b, ok := fromHexChar(src[i*2+1])if !ok {return 0, InvalidByteError(src[i*2+1])}dst[i] = (a << 4) | b}return len(src) / 2, nil}// fromHexChar converts a hex character into its value and a success flag.func fromHexChar(c byte) (byte, bool) {switch {case '0' <= c && c <= '9':return c - '0', truecase 'a' <= c && c <= 'f':return c - 'a' + 10, truecase 'A' <= c && c <= 'F':return c - 'A' + 10, true}return 0, false}// EncodeToString returns the hexadecimal encoding of src.func EncodeToString(src []byte) string {dst := make([]byte, EncodedLen(len(src)))Encode(dst, src)return string(dst)}// DecodeString returns the bytes represented by the hexadecimal string s.func DecodeString(s string) ([]byte, error) {src := []byte(s)dst := make([]byte, DecodedLen(len(src)))_, err := Decode(dst, src)if err != nil {return nil, err}return dst, nil}// Dump returns a string that contains a hex dump of the given data. The format// of the hex dump matches the output of `hexdump -C` on the command line.func Dump(data []byte) string {var buf bytes.Bufferdumper := Dumper(&buf)dumper.Write(data)dumper.Close()return string(buf.Bytes())}// Dumper returns a WriteCloser that writes a hex dump of all written data to// w. The format of the dump matches the output of `hexdump -C` on the command// line.func Dumper(w io.Writer) io.WriteCloser {return &dumper{w: w}}type dumper struct {w io.WriterrightChars [18]bytebuf [14]byteused int // number of bytes in the current linen uint // number of bytes, total}func toChar(b byte) byte {if b < 32 || b > 126 {return '.'}return b}func (h *dumper) Write(data []byte) (n int, err error) {// Output lines look like:// 00000010 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d |./0123456789:;<=|// ^ offset ^ extra space ^ ASCII of line.for i := range data {if h.used == 0 {// At the beginning of a line we print the current// offset in hex.h.buf[0] = byte(h.n >> 24)h.buf[1] = byte(h.n >> 16)h.buf[2] = byte(h.n >> 8)h.buf[3] = byte(h.n)Encode(h.buf[4:], h.buf[:4])h.buf[12] = ' 'h.buf[13] = ' '_, err = h.w.Write(h.buf[4:])}Encode(h.buf[:], data[i:i+1])h.buf[2] = ' 'l := 3if h.used == 7 {// There's an additional space after the 8th byte.h.buf[3] = ' 'l = 4} else if h.used == 15 {// At the end of the line there's an extra space and// the bar for the right column.h.buf[3] = ' 'h.buf[4] = '|'l = 5}_, err = h.w.Write(h.buf[:l])if err != nil {return}n++h.rightChars[h.used] = toChar(data[i])h.used++h.n++if h.used == 16 {h.rightChars[16] = '|'h.rightChars[17] = '\n'_, err = h.w.Write(h.rightChars[:])if err != nil {return}h.used = 0}}return}func (h *dumper) Close() (err error) {// See the comments in Write() for the details of this format.if h.used == 0 {return}h.buf[0] = ' 'h.buf[1] = ' 'h.buf[2] = ' 'h.buf[3] = ' 'h.buf[4] = '|'nBytes := h.usedfor h.used < 16 {l := 3if h.used == 7 {l = 4} else if h.used == 15 {l = 5}_, err = h.w.Write(h.buf[:l])if err != nil {return}h.used++}h.rightChars[nBytes] = '|'h.rightChars[nBytes+1] = '\n'_, err = h.w.Write(h.rightChars[:nBytes+2])return}
