github.com/tobgu/qframe@v0.4.0/internal/strings/convert.go (about) 1 package strings 2 3 import ( 4 "strconv" 5 "unicode" 6 "unicode/utf8" 7 "unsafe" 8 ) 9 10 func ParseInt(b []byte) (i int, err error) { 11 s := UnsafeBytesToString(b) 12 return strconv.Atoi(s) 13 } 14 15 func ParseFloat(b []byte) (float64, error) { 16 s := UnsafeBytesToString(b) 17 return strconv.ParseFloat(s, 64) 18 } 19 20 func ParseBool(b []byte) (bool, error) { 21 return strconv.ParseBool(UnsafeBytesToString(b)) 22 } 23 24 func UnsafeBytesToString(in []byte) string { 25 return unsafe.String(unsafe.SliceData(in), len(in)) 26 } 27 28 func QuotedBytes(s string) []byte { 29 result := make([]byte, 0, len(s)+2) 30 result = append(result, byte('"')) 31 result = append(result, []byte(s)...) 32 return append(result, byte('"')) 33 } 34 35 // This is a modified, zero alloc, version of the stdlib function strings.ToUpper. 36 // The passed in byte buffer is used to hold the converted string. The returned 37 // string is not safe to use when bP goes out of scope and the content may 38 // be overwritten upon next call to this function. 39 func ToUpper(bP *[]byte, s string) string { 40 // nbytes is the number of bytes encoded in b. 41 var nbytes int 42 43 var b []byte 44 for i, c := range s { 45 r := unicode.ToUpper(c) 46 if r == c { 47 continue 48 } 49 50 if len(*bP) >= len(s)+utf8.UTFMax { 51 b = *bP 52 } else { 53 b = make([]byte, len(s)+utf8.UTFMax) 54 } 55 nbytes = copy(b, s[:i]) 56 if r >= 0 { 57 if r <= utf8.RuneSelf { 58 b[nbytes] = byte(r) 59 nbytes++ 60 } else { 61 nbytes += utf8.EncodeRune(b[nbytes:], r) 62 } 63 } 64 65 if c == utf8.RuneError { 66 // RuneError is the result of either decoding 67 // an invalid sequence or '\uFFFD'. Determine 68 // the correct number of bytes we need to advance. 69 _, w := utf8.DecodeRuneInString(s[i:]) 70 i += w 71 } else { 72 i += utf8.RuneLen(c) 73 } 74 75 s = s[i:] 76 break 77 } 78 79 if b == nil { 80 return s 81 } 82 83 for _, c := range s { 84 r := unicode.ToUpper(c) 85 86 // common case 87 if (0 <= r && r <= utf8.RuneSelf) && nbytes < len(b) { 88 b[nbytes] = byte(r) 89 nbytes++ 90 continue 91 } 92 93 // b is not big enough or r is not a ASCII rune. 94 if r >= 0 { 95 if nbytes+utf8.UTFMax >= len(b) { 96 // Grow the buffer. 97 nb := make([]byte, 2*len(b)) 98 copy(nb, b[:nbytes]) 99 b = nb 100 } 101 nbytes += utf8.EncodeRune(b[nbytes:], r) 102 } 103 } 104 105 *bP = b 106 return UnsafeBytesToString(b[:nbytes]) 107 } 108 109 // InterfaceSliceToStringSlice converts a slice of interface{} to a slice of strings. 110 // If the input is not a slice of interface{} it is returned unmodified. If the input 111 // slice does not consist of strings (only) the input is returned unmodified. 112 func InterfaceSliceToStringSlice(input interface{}) interface{} { 113 ifSlice, ok := input.([]interface{}) 114 if !ok { 115 return input 116 } 117 118 result := make([]string, len(ifSlice)) 119 for i, intfc := range ifSlice { 120 s, ok := intfc.(string) 121 if !ok { 122 return input 123 } 124 result[i] = s 125 } 126 127 return result 128 }