github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/man/bigbytes.go (about) 1 package man 2 3 import ( 4 "fmt" 5 "math/big" 6 "strings" 7 "unicode" 8 ) 9 10 var ( 11 bigIECExp = big.NewInt(1024) 12 13 // BigByte is one byte in bit.Ints 14 BigByte = big.NewInt(1) 15 // BigKiByte is 1,024 bytes in bit.Ints 16 BigKiByte = (&big.Int{}).Mul(BigByte, bigIECExp) 17 // BigMiByte is 1,024 k bytes in bit.Ints 18 BigMiByte = (&big.Int{}).Mul(BigKiByte, bigIECExp) 19 // BigGiByte is 1,024 m bytes in bit.Ints 20 BigGiByte = (&big.Int{}).Mul(BigMiByte, bigIECExp) 21 // BigTiByte is 1,024 g bytes in bit.Ints 22 BigTiByte = (&big.Int{}).Mul(BigGiByte, bigIECExp) 23 // BigPiByte is 1,024 t bytes in bit.Ints 24 BigPiByte = (&big.Int{}).Mul(BigTiByte, bigIECExp) 25 // BigEiByte is 1,024 p bytes in bit.Ints 26 BigEiByte = (&big.Int{}).Mul(BigPiByte, bigIECExp) 27 // BigZiByte is 1,024 e bytes in bit.Ints 28 BigZiByte = (&big.Int{}).Mul(BigEiByte, bigIECExp) 29 // BigYiByte is 1,024 z bytes in bit.Ints 30 BigYiByte = (&big.Int{}).Mul(BigZiByte, bigIECExp) 31 ) 32 33 var ( 34 bigSIExp = big.NewInt(1000) 35 36 // BigSIByte is one SI byte in big.Ints 37 BigSIByte = big.NewInt(1) 38 // BigKByte is 1,000 SI bytes in big.Ints 39 BigKByte = (&big.Int{}).Mul(BigSIByte, bigSIExp) 40 // BigMByte is 1,000 SI k bytes in big.Ints 41 BigMByte = (&big.Int{}).Mul(BigKByte, bigSIExp) 42 // BigGByte is 1,000 SI m bytes in big.Ints 43 BigGByte = (&big.Int{}).Mul(BigMByte, bigSIExp) 44 // BigTByte is 1,000 SI g bytes in big.Ints 45 BigTByte = (&big.Int{}).Mul(BigGByte, bigSIExp) 46 // BigPByte is 1,000 SI t bytes in big.Ints 47 BigPByte = (&big.Int{}).Mul(BigTByte, bigSIExp) 48 // BigEByte is 1,000 SI p bytes in big.Ints 49 BigEByte = (&big.Int{}).Mul(BigPByte, bigSIExp) 50 // BigZByte is 1,000 SI e bytes in big.Ints 51 BigZByte = (&big.Int{}).Mul(BigEByte, bigSIExp) 52 // BigYByte is 1,000 SI z bytes in big.Ints 53 BigYByte = (&big.Int{}).Mul(BigZByte, bigSIExp) 54 ) 55 56 var bigBytesSizeTable = map[string]*big.Int{ 57 "b": BigByte, "kib": BigKiByte, "kb": BigKByte, "mib": BigMiByte, "mb": BigMByte, 58 "gib": BigGiByte, "gb": BigGByte, "tib": BigTiByte, "tb": BigTByte, "pib": BigPiByte, 59 "pb": BigPByte, "eib": BigEiByte, "eb": BigEByte, "zib": BigZiByte, "zb": BigZByte, 60 "yib": BigYiByte, "yb": BigYByte, 61 // Without suffix 62 "": BigByte, "ki": BigKiByte, "k": BigKByte, "mi": BigMiByte, "m": BigMByte, 63 "gi": BigGiByte, "g": BigGByte, "ti": BigTiByte, "t": BigTByte, "pi": BigPiByte, 64 "p": BigPByte, "ei": BigEiByte, "e": BigEByte, "z": BigZByte, "zi": BigZiByte, 65 "y": BigYByte, "yi": BigYiByte, 66 } 67 68 var ten = big.NewInt(10) 69 70 func humanateBigBytes(s, base *big.Int, sizes []string) string { 71 if s.Cmp(ten) < 0 { 72 return fmt.Sprintf("%dB", s) 73 } 74 c := (&big.Int{}).Set(s) 75 val, mag := oomm(c, base, len(sizes)-1) 76 suffix := sizes[mag] 77 f := strings.TrimSuffix(fmt.Sprintf("%.1f", val), ".0") 78 return f + suffix 79 } 80 81 // BigBytes produces a human readable representation of an SI size. 82 // 83 // See also: ParseBigBytes. 84 // 85 // BigBytes(82854982) -> 83MB 86 func BigBytes(s *big.Int) string { 87 sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} 88 return humanateBigBytes(s, bigSIExp, sizes) 89 } 90 91 // BigIBytes produces a human readable representation of an IEC size. 92 // 93 // See also: ParseBigBytes. 94 // 95 // BigIBytes(82854982) -> 79MiB 96 func BigIBytes(s *big.Int) string { 97 sizes := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} 98 return humanateBigBytes(s, bigIECExp, sizes) 99 } 100 101 // ParseBigBytes parses a string representation of bytes into the number 102 // of bytes it represents. 103 // 104 // See also: BigBytes, BigIBytes. 105 // 106 // ParseBigBytes("42 MB") -> 42000000, nil 107 // ParseBigBytes("42 mib") -> 44040192, nil 108 func ParseBigBytes(s string) (*big.Int, error) { 109 lastDigit := 0 110 hasComma := false 111 for _, r := range s { 112 if !(unicode.IsDigit(r) || r == '.' || r == ',') { 113 break 114 } 115 if r == ',' { 116 hasComma = true 117 } 118 lastDigit++ 119 } 120 121 num := s[:lastDigit] 122 if hasComma { 123 num = strings.Replace(num, ",", "", -1) 124 } 125 126 val := &big.Rat{} 127 _, err := fmt.Sscanf(num, "%f", val) 128 if err != nil { 129 return nil, err 130 } 131 132 extra := strings.ToLower(strings.TrimSpace(s[lastDigit:])) 133 if m, ok := bigBytesSizeTable[extra]; ok { 134 mv := (&big.Rat{}).SetInt(m) 135 val.Mul(val, mv) 136 rv := &big.Int{} 137 rv.Div(val.Num(), val.Denom()) 138 return rv, nil 139 } 140 141 return nil, fmt.Errorf("unhandled size name: %v", extra) 142 }