github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/mysql/hex.go (about) 1 // Copyright 2015 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package mysql 15 16 import ( 17 "encoding/hex" 18 "fmt" 19 "strconv" 20 "strings" 21 22 "github.com/insionng/yougam/libraries/juju/errors" 23 ) 24 25 // Hex is for mysql hexadecimal literal type. 26 type Hex struct { 27 // Value holds numeric value for hexadecimal literal. 28 Value int64 29 } 30 31 // String implements fmt.Stringer interface. 32 func (h Hex) String() string { 33 s := fmt.Sprintf("%X", h.Value) 34 if len(s)%2 != 0 { 35 return "0x0" + s 36 } 37 38 return "0x" + s 39 } 40 41 // ToNumber changes hexadecimal type to float64 for numeric operation. 42 // MySQL treats hexadecimal literal as double type. 43 func (h Hex) ToNumber() float64 { 44 return float64(h.Value) 45 } 46 47 // ToString returns the string representation for hexadecimal literal. 48 func (h Hex) ToString() string { 49 s := fmt.Sprintf("%x", h.Value) 50 if len(s)%2 != 0 { 51 s = "0" + s 52 } 53 54 // should never error. 55 b, _ := hex.DecodeString(s) 56 return string(b) 57 } 58 59 func uniformHexStrLit(s string) (string, error) { 60 if len(s) == 0 { 61 return "", errors.Errorf("invalid empty string for parsing hexadecimal literal") 62 } 63 64 if s[0] == 'x' || s[0] == 'X' { 65 // format is x'val' or X'val' 66 s = strings.Trim(s[1:], "'") 67 if len(s)%2 != 0 { 68 return "", errors.Errorf("invalid hexadecimal format, must even numbers, but %d", len(s)) 69 } 70 s = "0x" + s 71 } else if !strings.HasPrefix(s, "0x") { 72 // here means format is not x'val', X'val' or 0xval. 73 return "", errors.Errorf("invalid hexadecimal format %s", s) 74 } 75 return s, nil 76 } 77 78 // ParseHex parses hexadecimal literal string. 79 // The string format can be X'val', x'val' or 0xval. 80 // val must in (0...9, a...f, A...F). 81 func ParseHex(s string) (Hex, error) { 82 var err error 83 s, err = uniformHexStrLit(s) 84 if err != nil { 85 return Hex{}, errors.Trace(err) 86 } 87 n, err := strconv.ParseInt(s, 0, 64) 88 if err != nil { 89 return Hex{}, errors.Trace(err) 90 } 91 92 return Hex{Value: n}, nil 93 } 94 95 // ParseHexStr parses hexadecimal literal as string. 96 // See: https://dev.mysql.com/doc/refman/5.7/en/hexadecimal-literals.html 97 func ParseHexStr(s string) (string, error) { 98 var err error 99 s, err = uniformHexStrLit(s) 100 if err != nil { 101 return "", errors.Trace(err) 102 } 103 bs, err := hex.DecodeString(s[2:]) 104 if err != nil { 105 return "", errors.Trace(err) 106 } 107 return string(bs), nil 108 }