forked from lug/matterbridge
		
	
		
			
				
	
	
		
			109 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package bytes
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"regexp"
 | |
| 	"strconv"
 | |
| )
 | |
| 
 | |
| type (
 | |
| 	// Bytes struct
 | |
| 	Bytes struct{}
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	_ = 1.0 << (10 * iota) // ignore first value by assigning to blank identifier
 | |
| 	KB
 | |
| 	MB
 | |
| 	GB
 | |
| 	TB
 | |
| 	PB
 | |
| 	EB
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	pattern = regexp.MustCompile(`(?i)^(-?\d+(?:\.\d+)?)\s?([KMGTPE]B?|B?)$`)
 | |
| 	global  = New()
 | |
| )
 | |
| 
 | |
| // New creates a Bytes instance.
 | |
| func New() *Bytes {
 | |
| 	return &Bytes{}
 | |
| }
 | |
| 
 | |
| // Format formats bytes integer to human readable string.
 | |
| // For example, 31323 bytes will return 30.59KB.
 | |
| func (*Bytes) Format(b int64) string {
 | |
| 	multiple := ""
 | |
| 	value := float64(b)
 | |
| 
 | |
| 	switch {
 | |
| 	case b >= EB:
 | |
| 		value /= EB
 | |
| 		multiple = "EB"
 | |
| 	case b >= PB:
 | |
| 		value /= PB
 | |
| 		multiple = "PB"
 | |
| 	case b >= TB:
 | |
| 		value /= TB
 | |
| 		multiple = "TB"
 | |
| 	case b >= GB:
 | |
| 		value /= GB
 | |
| 		multiple = "GB"
 | |
| 	case b >= MB:
 | |
| 		value /= MB
 | |
| 		multiple = "MB"
 | |
| 	case b >= KB:
 | |
| 		value /= KB
 | |
| 		multiple = "KB"
 | |
| 	case b == 0:
 | |
| 		return "0"
 | |
| 	default:
 | |
| 		return strconv.FormatInt(b, 10) + "B"
 | |
| 	}
 | |
| 
 | |
| 	return fmt.Sprintf("%.2f%s", value, multiple)
 | |
| }
 | |
| 
 | |
| // Parse parses human readable bytes string to bytes integer.
 | |
| // For example, 6GB (6G is also valid) will return 6442450944.
 | |
| func (*Bytes) Parse(value string) (i int64, err error) {
 | |
| 	parts := pattern.FindStringSubmatch(value)
 | |
| 	if len(parts) < 3 {
 | |
| 		return 0, fmt.Errorf("error parsing value=%s", value)
 | |
| 	}
 | |
| 	bytesString := parts[1]
 | |
| 	multiple := parts[2]
 | |
| 	bytes, err := strconv.ParseFloat(bytesString, 64)
 | |
| 	if err != nil {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	switch multiple {
 | |
| 	default:
 | |
| 		return int64(bytes), nil
 | |
| 	case "K", "KB":
 | |
| 		return int64(bytes * KB), nil
 | |
| 	case "M", "MB":
 | |
| 		return int64(bytes * MB), nil
 | |
| 	case "G", "GB":
 | |
| 		return int64(bytes * GB), nil
 | |
| 	case "T", "TB":
 | |
| 		return int64(bytes * TB), nil
 | |
| 	case "P", "PB":
 | |
| 		return int64(bytes * PB), nil
 | |
| 	case "E", "EB":
 | |
| 		return int64(bytes * EB), nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Format wraps global Bytes's Format function.
 | |
| func Format(b int64) string {
 | |
| 	return global.Format(b)
 | |
| }
 | |
| 
 | |
| // Parse wraps global Bytes's Parse function.
 | |
| func Parse(val string) (int64, error) {
 | |
| 	return global.Parse(val)
 | |
| }
 | 
