gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

bigbytes.go (4850B)


      1 package humanize
      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 	// BigRiByte is 1,024 y bytes in bit.Ints
     32 	BigRiByte = (&big.Int{}).Mul(BigYiByte, bigIECExp)
     33 	// BigQiByte is 1,024 r bytes in bit.Ints
     34 	BigQiByte = (&big.Int{}).Mul(BigRiByte, bigIECExp)
     35 )
     36 
     37 var (
     38 	bigSIExp = big.NewInt(1000)
     39 
     40 	// BigSIByte is one SI byte in big.Ints
     41 	BigSIByte = big.NewInt(1)
     42 	// BigKByte is 1,000 SI bytes in big.Ints
     43 	BigKByte = (&big.Int{}).Mul(BigSIByte, bigSIExp)
     44 	// BigMByte is 1,000 SI k bytes in big.Ints
     45 	BigMByte = (&big.Int{}).Mul(BigKByte, bigSIExp)
     46 	// BigGByte is 1,000 SI m bytes in big.Ints
     47 	BigGByte = (&big.Int{}).Mul(BigMByte, bigSIExp)
     48 	// BigTByte is 1,000 SI g bytes in big.Ints
     49 	BigTByte = (&big.Int{}).Mul(BigGByte, bigSIExp)
     50 	// BigPByte is 1,000 SI t bytes in big.Ints
     51 	BigPByte = (&big.Int{}).Mul(BigTByte, bigSIExp)
     52 	// BigEByte is 1,000 SI p bytes in big.Ints
     53 	BigEByte = (&big.Int{}).Mul(BigPByte, bigSIExp)
     54 	// BigZByte is 1,000 SI e bytes in big.Ints
     55 	BigZByte = (&big.Int{}).Mul(BigEByte, bigSIExp)
     56 	// BigYByte is 1,000 SI z bytes in big.Ints
     57 	BigYByte = (&big.Int{}).Mul(BigZByte, bigSIExp)
     58 	// BigRByte is 1,000 SI y bytes in big.Ints
     59 	BigRByte = (&big.Int{}).Mul(BigYByte, bigSIExp)
     60 	// BigQByte is 1,000 SI r bytes in big.Ints
     61 	BigQByte = (&big.Int{}).Mul(BigRByte, bigSIExp)
     62 )
     63 
     64 var bigBytesSizeTable = map[string]*big.Int{
     65 	"b":   BigByte,
     66 	"kib": BigKiByte,
     67 	"kb":  BigKByte,
     68 	"mib": BigMiByte,
     69 	"mb":  BigMByte,
     70 	"gib": BigGiByte,
     71 	"gb":  BigGByte,
     72 	"tib": BigTiByte,
     73 	"tb":  BigTByte,
     74 	"pib": BigPiByte,
     75 	"pb":  BigPByte,
     76 	"eib": BigEiByte,
     77 	"eb":  BigEByte,
     78 	"zib": BigZiByte,
     79 	"zb":  BigZByte,
     80 	"yib": BigYiByte,
     81 	"yb":  BigYByte,
     82 	"rib": BigRiByte,
     83 	"rb":  BigRByte,
     84 	"qib": BigQiByte,
     85 	"qb":  BigQByte,
     86 	// Without suffix
     87 	"":   BigByte,
     88 	"ki": BigKiByte,
     89 	"k":  BigKByte,
     90 	"mi": BigMiByte,
     91 	"m":  BigMByte,
     92 	"gi": BigGiByte,
     93 	"g":  BigGByte,
     94 	"ti": BigTiByte,
     95 	"t":  BigTByte,
     96 	"pi": BigPiByte,
     97 	"p":  BigPByte,
     98 	"ei": BigEiByte,
     99 	"e":  BigEByte,
    100 	"z":  BigZByte,
    101 	"zi": BigZiByte,
    102 	"y":  BigYByte,
    103 	"yi": BigYiByte,
    104 	"r":  BigRByte,
    105 	"ri": BigRiByte,
    106 	"q":  BigQByte,
    107 	"qi": BigQiByte,
    108 }
    109 
    110 var ten = big.NewInt(10)
    111 
    112 func humanateBigBytes(s, base *big.Int, sizes []string) string {
    113 	if s.Cmp(ten) < 0 {
    114 		return fmt.Sprintf("%d B", s)
    115 	}
    116 	c := (&big.Int{}).Set(s)
    117 	val, mag := oomm(c, base, len(sizes)-1)
    118 	suffix := sizes[mag]
    119 	f := "%.0f %s"
    120 	if val < 10 {
    121 		f = "%.1f %s"
    122 	}
    123 
    124 	return fmt.Sprintf(f, val, suffix)
    125 
    126 }
    127 
    128 // BigBytes produces a human readable representation of an SI size.
    129 //
    130 // See also: ParseBigBytes.
    131 //
    132 // BigBytes(82854982) -> 83 MB
    133 func BigBytes(s *big.Int) string {
    134 	sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", "RB", "QB"}
    135 	return humanateBigBytes(s, bigSIExp, sizes)
    136 }
    137 
    138 // BigIBytes produces a human readable representation of an IEC size.
    139 //
    140 // See also: ParseBigBytes.
    141 //
    142 // BigIBytes(82854982) -> 79 MiB
    143 func BigIBytes(s *big.Int) string {
    144 	sizes := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", "RiB", "QiB"}
    145 	return humanateBigBytes(s, bigIECExp, sizes)
    146 }
    147 
    148 // ParseBigBytes parses a string representation of bytes into the number
    149 // of bytes it represents.
    150 //
    151 // See also: BigBytes, BigIBytes.
    152 //
    153 // ParseBigBytes("42 MB") -> 42000000, nil
    154 // ParseBigBytes("42 mib") -> 44040192, nil
    155 func ParseBigBytes(s string) (*big.Int, error) {
    156 	lastDigit := 0
    157 	hasComma := false
    158 	for _, r := range s {
    159 		if !(unicode.IsDigit(r) || r == '.' || r == ',') {
    160 			break
    161 		}
    162 		if r == ',' {
    163 			hasComma = true
    164 		}
    165 		lastDigit++
    166 	}
    167 
    168 	num := s[:lastDigit]
    169 	if hasComma {
    170 		num = strings.Replace(num, ",", "", -1)
    171 	}
    172 
    173 	val := &big.Rat{}
    174 	_, err := fmt.Sscanf(num, "%f", val)
    175 	if err != nil {
    176 		return nil, err
    177 	}
    178 
    179 	extra := strings.ToLower(strings.TrimSpace(s[lastDigit:]))
    180 	if m, ok := bigBytesSizeTable[extra]; ok {
    181 		mv := (&big.Rat{}).SetInt(m)
    182 		val.Mul(val, mv)
    183 		rv := &big.Int{}
    184 		rv.Div(val.Num(), val.Denom())
    185 		return rv, nil
    186 	}
    187 
    188 	return nil, fmt.Errorf("unhandled size name: %v", extra)
    189 }