github.com/moqsien/xraycore@v1.8.5/common/units/bytesize.go (about) 1 package units 2 3 import ( 4 "errors" 5 "strconv" 6 "strings" 7 "unicode" 8 ) 9 10 var ( 11 errInvalidSize = errors.New("invalid size") 12 errInvalidUnit = errors.New("invalid or unsupported unit") 13 ) 14 15 // ByteSize is the size of bytes 16 type ByteSize uint64 17 18 const ( 19 _ = iota 20 // KB = 1KB 21 KB ByteSize = 1 << (10 * iota) 22 // MB = 1MB 23 MB 24 // GB = 1GB 25 GB 26 // TB = 1TB 27 TB 28 // PB = 1PB 29 PB 30 // EB = 1EB 31 EB 32 ) 33 34 func (b ByteSize) String() string { 35 unit := "" 36 value := float64(0) 37 switch { 38 case b == 0: 39 return "0" 40 case b < KB: 41 unit = "B" 42 value = float64(b) 43 case b < MB: 44 unit = "KB" 45 value = float64(b) / float64(KB) 46 case b < GB: 47 unit = "MB" 48 value = float64(b) / float64(MB) 49 case b < TB: 50 unit = "GB" 51 value = float64(b) / float64(GB) 52 case b < PB: 53 unit = "TB" 54 value = float64(b) / float64(TB) 55 case b < EB: 56 unit = "PB" 57 value = float64(b) / float64(PB) 58 default: 59 unit = "EB" 60 value = float64(b) / float64(EB) 61 } 62 result := strconv.FormatFloat(value, 'f', 2, 64) 63 result = strings.TrimSuffix(result, ".0") 64 return result + unit 65 } 66 67 // Parse parses ByteSize from string 68 func (b *ByteSize) Parse(s string) error { 69 s = strings.TrimSpace(s) 70 s = strings.ToUpper(s) 71 i := strings.IndexFunc(s, unicode.IsLetter) 72 if i == -1 { 73 return errInvalidUnit 74 } 75 76 bytesString, multiple := s[:i], s[i:] 77 bytes, err := strconv.ParseFloat(bytesString, 64) 78 if err != nil || bytes <= 0 { 79 return errInvalidSize 80 } 81 switch multiple { 82 case "B": 83 *b = ByteSize(bytes) 84 case "K", "KB", "KIB": 85 *b = ByteSize(bytes * float64(KB)) 86 case "M", "MB", "MIB": 87 *b = ByteSize(bytes * float64(MB)) 88 case "G", "GB", "GIB": 89 *b = ByteSize(bytes * float64(GB)) 90 case "T", "TB", "TIB": 91 *b = ByteSize(bytes * float64(TB)) 92 case "P", "PB", "PIB": 93 *b = ByteSize(bytes * float64(PB)) 94 case "E", "EB", "EIB": 95 *b = ByteSize(bytes * float64(EB)) 96 default: 97 return errInvalidUnit 98 } 99 return nil 100 }