github.com/cs3org/reva/v2@v2.27.7/pkg/bytesize/bytesize.go (about)

     1  // Copyright 2018-2022 CERN
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  
    19  // Package bytesize provides easy conversions from human readable strings (eg. 10MB) to bytes
    20  package bytesize
    21  
    22  import (
    23  	"fmt"
    24  	"strconv"
    25  	"strings"
    26  )
    27  
    28  // ByteSize is the size in bytes
    29  type ByteSize uint64
    30  
    31  // List of available byte sizes
    32  // NOTE: max is exabyte as we convert to uint64
    33  const (
    34  	KB ByteSize = 1000
    35  	MB ByteSize = 1000 * KB
    36  	GB ByteSize = 1000 * MB
    37  	TB ByteSize = 1000 * GB
    38  	PB ByteSize = 1000 * TB
    39  	EB ByteSize = 1000 * PB
    40  
    41  	KiB ByteSize = 1024
    42  	MiB ByteSize = 1024 * KiB
    43  	GiB ByteSize = 1024 * MiB
    44  	TiB ByteSize = 1024 * GiB
    45  	PiB ByteSize = 1024 * TiB
    46  	EiB ByteSize = 1024 * PiB
    47  )
    48  
    49  // Parse parses a Bytesize from a string
    50  func Parse(s string) (ByteSize, error) {
    51  	sanitized := strings.TrimSpace(s)
    52  	if !strings.HasSuffix(sanitized, "B") {
    53  		u, err := strconv.Atoi(sanitized)
    54  		return ByteSize(u), err
    55  	}
    56  
    57  	var (
    58  		value int
    59  		unit  string
    60  	)
    61  
    62  	template := "%d%s"
    63  	_, err := fmt.Sscanf(sanitized, template, &value, &unit)
    64  	if err != nil {
    65  		return 0, err
    66  	}
    67  
    68  	bytes := ByteSize(value)
    69  	switch unit {
    70  	case "KB":
    71  		bytes *= KB
    72  	case "MB":
    73  		bytes *= MB
    74  	case "GB":
    75  		bytes *= GB
    76  	case "TB":
    77  		bytes *= TB
    78  	case "PB":
    79  		bytes *= PB
    80  	case "EB":
    81  		bytes *= EB
    82  	case "KiB":
    83  		bytes *= KiB
    84  	case "MiB":
    85  		bytes *= MiB
    86  	case "GiB":
    87  		bytes *= GiB
    88  	case "TiB":
    89  		bytes *= TiB
    90  	case "PiB":
    91  		bytes *= PiB
    92  	case "EiB":
    93  		bytes *= EiB
    94  	default:
    95  		return 0, fmt.Errorf("unknown unit '%s'. Use common abbreviations such as KB, MiB, GB", unit)
    96  	}
    97  
    98  	return bytes, nil
    99  }
   100  
   101  // Bytes converts the ByteSize to an uint64
   102  func (b ByteSize) Bytes() uint64 {
   103  	return uint64(b)
   104  }
   105  
   106  // String converts the ByteSize to a string
   107  func (b ByteSize) String() string {
   108  	return strconv.FormatUint(uint64(b), 10)
   109  }