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  }