github.com/coreservice-io/utils@v0.3.0/bytes_util/convert.go (about)

     1  package bytes_util
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"strconv"
     7  	"strings"
     8  )
     9  
    10  type (
    11  	// Bytes struct
    12  	Bytes struct{}
    13  )
    14  
    15  const (
    16  	_ = 1.0 << (10 * iota) // ignore first value by assigning to blank identifier
    17  	KB
    18  	MB
    19  	GB
    20  	TB
    21  	PB
    22  	EB
    23  )
    24  
    25  var (
    26  	pattern = regexp.MustCompile(`(?i)^(-?\d+(?:\.\d+)?)\s?([KMGTPE]B?|B?)$`)
    27  )
    28  
    29  // Format formats bytes integer to human readable string.
    30  // For example, 31323 bytes will return 30.59KB.
    31  func Format(b int64) string {
    32  	multiple := ""
    33  	value := float64(b)
    34  
    35  	switch {
    36  	case b >= EB:
    37  		value /= EB
    38  		multiple = "EB"
    39  	case b >= PB:
    40  		value /= PB
    41  		multiple = "PB"
    42  	case b >= TB:
    43  		value /= TB
    44  		multiple = "TB"
    45  	case b >= GB:
    46  		value /= GB
    47  		multiple = "GB"
    48  	case b >= MB:
    49  		value /= MB
    50  		multiple = "MB"
    51  	case b >= KB:
    52  		value /= KB
    53  		multiple = "KB"
    54  	case b == 0:
    55  		return "0"
    56  	default:
    57  		return strconv.FormatInt(b, 10) + "B"
    58  	}
    59  
    60  	return fmt.Sprintf("%.2f%s", value, multiple)
    61  }
    62  
    63  // Parse parses human readable bytes string to bytes integer.
    64  // For example, 6GB (6G is also valid) will return 6442450944.
    65  func Parse(value string) (i int64, err error) {
    66  	value = strings.Trim(value, " ")
    67  	value = strings.Trim(value, ",")
    68  	parts := pattern.FindStringSubmatch(value)
    69  	if len(parts) < 3 {
    70  		return 0, fmt.Errorf("error parsing value=%s", value)
    71  	}
    72  	bytesString := parts[1]
    73  	multiple := strings.ToUpper(parts[2])
    74  	bytes, err := strconv.ParseFloat(bytesString, 64)
    75  	if err != nil {
    76  		return
    77  	}
    78  
    79  	switch multiple {
    80  	default:
    81  		return int64(bytes), nil
    82  	case "K", "KB":
    83  		return int64(bytes * KB), nil
    84  	case "M", "MB":
    85  		return int64(bytes * MB), nil
    86  	case "G", "GB":
    87  		return int64(bytes * GB), nil
    88  	case "T", "TB":
    89  		return int64(bytes * TB), nil
    90  	case "P", "PB":
    91  		return int64(bytes * PB), nil
    92  	case "E", "EB":
    93  		return int64(bytes * EB), nil
    94  	}
    95  }