diff options
Diffstat (limited to 'src/pkg/encoding/hex/hex.go')
| -rw-r--r-- | src/pkg/encoding/hex/hex.go | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/pkg/encoding/hex/hex.go b/src/pkg/encoding/hex/hex.go new file mode 100644 index 0000000000..32ec42e245 --- /dev/null +++ b/src/pkg/encoding/hex/hex.go @@ -0,0 +1,108 @@ +// 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. + +// This package implements hexadecimal encoding and decoding. +package hex + +import ( + "os"; + "strconv"; + "strings"; +) + +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(src, dst []byte) int { + for i, v := range src { + dst[i*2] = hextable[v>>4]; + dst[i*2 + 1] = hextable[v&0x0f]; + } + + return len(src)*2; +} + +// OddLengthInputError results from decoding an odd length slice. +type OddLengthInputError struct{} + +func (OddLengthInputError) String() string { + return "odd length hex string"; +} + +// InvalidHexCharError results from finding an invalid character in a hex string. +type InvalidHexCharError byte + +func (e InvalidHexCharError) String() string { + return "invalid hex char: " + strconv.Itoa(int(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 OddLengthInputError or an +// InvalidHexCharError. +func Decode(src, dst []byte) (int, os.Error) { + if len(src)%2 == 1 { + return 0, OddLengthInputError{}; + } + + for i := 0; i < len(src)/2; i++ { + a, ok := fromHexChar(src[i*2]); + if !ok { + return 0, InvalidHexCharError(src[i*2]); + } + b, ok := fromHexChar(src[i*2 + 1]); + if !ok { + return 0, InvalidHexCharError(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', true; + case 'a' <= c && c <= 'f': + return c-'a'+10, true; + case '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(src, dst); + return string(dst); +} + +// DecodeString returns the bytes represented by the hexadecimal string s. +func DecodeString(s string) ([]byte, os.Error) { + src := strings.Bytes(s); + dst := make([]byte, DecodedLen(len(src))); + _, err := Decode(src, dst); + if err != nil { + return nil, err; + } + return dst, nil; +} |
