...

Source file src/github.com/dustin/go-humanize/bigbytes.go

Documentation: github.com/dustin/go-humanize

     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  }
   190  

View as plain text