github.com/pubgo/xprocess@v0.1.11/xutil/convert.go (about) 1 package xutil 2 3 import ( 4 "reflect" 5 "strconv" 6 "strings" 7 "unsafe" 8 ) 9 10 // #nosec G103 11 // GetString returns a string pointer without allocation 12 func UnsafeString(b []byte) string { 13 return *(*string)(unsafe.Pointer(&b)) 14 } 15 16 // #nosec G103 17 // GetBytes returns a byte pointer without allocation 18 func UnsafeBytes(s string) (bs []byte) { 19 sh := (*reflect.StringHeader)(unsafe.Pointer(&s)) 20 bh := (*reflect.SliceHeader)(unsafe.Pointer(&bs)) 21 bh.Data = sh.Data 22 bh.Len = sh.Len 23 bh.Cap = sh.Len 24 return 25 } 26 27 // CopyString copies a string to make it immutable 28 func CopyString(s string) string { 29 return string(UnsafeBytes(s)) 30 } 31 32 // CopyBytes copies a slice to make it immutable 33 func CopyBytes(b []byte) []byte { 34 tmp := make([]byte, len(b)) 35 copy(tmp, b) 36 return tmp 37 } 38 39 const ( 40 uByte = 1 << (10 * iota) 41 uKilobyte 42 uMegabyte 43 uGigabyte 44 uTerabyte 45 uPetabyte 46 uExabyte 47 ) 48 49 // ByteSize returns a human-readable byte string of the form 10M, 12.5K, and so forth. 50 // The unit that results in the smallest number greater than or equal to 1 is always chosen. 51 func ByteSize(bytes uint64) string { 52 unit := "" 53 value := float64(bytes) 54 switch { 55 case bytes >= uExabyte: 56 unit = "EB" 57 value = value / uExabyte 58 case bytes >= uPetabyte: 59 unit = "PB" 60 value = value / uPetabyte 61 case bytes >= uTerabyte: 62 unit = "TB" 63 value = value / uTerabyte 64 case bytes >= uGigabyte: 65 unit = "GB" 66 value = value / uGigabyte 67 case bytes >= uMegabyte: 68 unit = "MB" 69 value = value / uMegabyte 70 case bytes >= uKilobyte: 71 unit = "KB" 72 value = value / uKilobyte 73 case bytes >= uByte: 74 unit = "B" 75 default: 76 return "0B" 77 } 78 result := strconv.FormatFloat(value, 'f', 1, 64) 79 result = strings.TrimSuffix(result, ".0") 80 return result + unit 81 }