gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

hex.go (3505B)


      1 // Copyright 2016 Tom Thorogood. All rights reserved.
      2 // Use of this source code is governed by a
      3 // Modified BSD License license that can be found in
      4 // the LICENSE file.
      5 //
      6 // Copyright 2009 The Go Authors. All rights reserved.
      7 // Use of this source code is governed by a BSD-style
      8 // license that can be found in the LICENSE file.
      9 
     10 // Package hex is an efficient hexadecimal implementation for Golang.
     11 package hex
     12 
     13 import (
     14 	"errors"
     15 	"fmt"
     16 )
     17 
     18 var errLength = errors.New("go-hex: odd length hex string")
     19 
     20 var (
     21 	lower = []byte("0123456789abcdef")
     22 	upper = []byte("0123456789ABCDEF")
     23 )
     24 
     25 // InvalidByteError values describe errors resulting from an invalid byte in a hex string.
     26 type InvalidByteError byte
     27 
     28 func (e InvalidByteError) Error() string {
     29 	return fmt.Sprintf("go-hex: invalid byte: %#U", rune(e))
     30 }
     31 
     32 // EncodedLen returns the length of an encoding of n source bytes.
     33 func EncodedLen(n int) int {
     34 	return n * 2
     35 }
     36 
     37 // DecodedLen returns the length of a decoding of n source bytes.
     38 func DecodedLen(n int) int {
     39 	return n / 2
     40 }
     41 
     42 // Encode encodes src into EncodedLen(len(src))
     43 // bytes of dst. As a convenience, it returns the number
     44 // of bytes written to dst, but this value is always EncodedLen(len(src)).
     45 // Encode implements lowercase hexadecimal encoding.
     46 func Encode(dst, src []byte) int {
     47 	return RawEncode(dst, src, lower)
     48 }
     49 
     50 // EncodeUpper encodes src into EncodedLen(len(src))
     51 // bytes of dst. As a convenience, it returns the number
     52 // of bytes written to dst, but this value is always EncodedLen(len(src)).
     53 // EncodeUpper implements uppercase hexadecimal encoding.
     54 func EncodeUpper(dst, src []byte) int {
     55 	return RawEncode(dst, src, upper)
     56 }
     57 
     58 // EncodeToString returns the lowercase hexadecimal encoding of src.
     59 func EncodeToString(src []byte) string {
     60 	return RawEncodeToString(src, lower)
     61 }
     62 
     63 // EncodeUpperToString returns the uppercase hexadecimal encoding of src.
     64 func EncodeUpperToString(src []byte) string {
     65 	return RawEncodeToString(src, upper)
     66 }
     67 
     68 // RawEncodeToString returns the hexadecimal encoding of src for a given
     69 // alphabet.
     70 func RawEncodeToString(src, alpha []byte) string {
     71 	dst := make([]byte, EncodedLen(len(src)))
     72 	RawEncode(dst, src, alpha)
     73 	return string(dst)
     74 }
     75 
     76 // DecodeString returns the bytes represented by the hexadecimal string s.
     77 func DecodeString(s string) ([]byte, error) {
     78 	src := []byte(s)
     79 	dst := make([]byte, DecodedLen(len(src)))
     80 
     81 	if _, err := Decode(dst, src); err != nil {
     82 		return nil, err
     83 	}
     84 
     85 	return dst, nil
     86 }
     87 
     88 // MustDecodeString is like DecodeString but panics if the string cannot be
     89 // parsed. It simplifies safe initialization of global variables holding
     90 // binary data.
     91 func MustDecodeString(str string) []byte {
     92 	dst, err := DecodeString(str)
     93 	if err != nil {
     94 		panic(err)
     95 	}
     96 
     97 	return dst
     98 }
     99 
    100 func encodeGeneric(dst, src, alpha []byte) {
    101 	for i, v := range src {
    102 		dst[i*2] = alpha[v>>4]
    103 		dst[i*2+1] = alpha[v&0x0f]
    104 	}
    105 }
    106 
    107 func decodeGeneric(dst, src []byte) (uint64, bool) {
    108 	for i := 0; i < len(src)/2; i++ {
    109 		a, ok := fromHexChar(src[i*2])
    110 		if !ok {
    111 			return uint64(i * 2), false
    112 		}
    113 
    114 		b, ok := fromHexChar(src[i*2+1])
    115 		if !ok {
    116 			return uint64(i*2 + 1), false
    117 		}
    118 
    119 		dst[i] = (a << 4) | b
    120 	}
    121 
    122 	return 0, true
    123 }
    124 
    125 // fromHexChar converts a hex character into its value and a success flag.
    126 func fromHexChar(c byte) (byte, bool) {
    127 	switch {
    128 	case '0' <= c && c <= '9':
    129 		return c - '0', true
    130 	case 'a' <= c && c <= 'f':
    131 		return c - 'a' + 10, true
    132 	case 'A' <= c && c <= 'F':
    133 		return c - 'A' + 10, true
    134 	}
    135 
    136 	return 0, false
    137 }