github.com/waldiirawan/apm-agent-go/v2@v2.2.2/internal/configutil/size.go (about) 1 // Licensed to Elasticsearch B.V. under one or more contributor 2 // license agreements. See the NOTICE file distributed with 3 // this work for additional information regarding copyright 4 // ownership. Elasticsearch B.V. licenses this file to you under 5 // the Apache License, Version 2.0 (the "License"); you may 6 // not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, 12 // software distributed under the License is distributed on an 13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 // KIND, either express or implied. See the License for the 15 // specific language governing permissions and limitations 16 // under the License. 17 18 package configutil 19 20 import ( 21 "fmt" 22 "strconv" 23 "strings" 24 "unicode" 25 ) 26 27 // Size represents a size in bytes. 28 type Size int64 29 30 // Common power-of-two sizes. 31 const ( 32 Byte Size = 1 33 KByte Size = 1024 34 MByte Size = 1024 * 1024 35 GByte Size = 1024 * 1024 * 1024 36 ) 37 38 // Bytes returns s as a number of bytes. 39 func (s Size) Bytes() int64 { 40 return int64(s) 41 } 42 43 // String returns s in its most compact string representation. 44 func (s Size) String() string { 45 if s == 0 { 46 return "0B" 47 } 48 switch { 49 case s%GByte == 0: 50 return fmt.Sprintf("%dGB", s/GByte) 51 case s%MByte == 0: 52 return fmt.Sprintf("%dMB", s/MByte) 53 case s%KByte == 0: 54 return fmt.Sprintf("%dKB", s/KByte) 55 default: 56 return fmt.Sprintf("%dB", s) 57 } 58 } 59 60 // ParseSize parses s as a size, in bytes. 61 // 62 // Valid size units are "b", "kb", "mb", "gb". 63 func ParseSize(s string) (Size, error) { 64 orig := s 65 var mul Size = 1 66 if strings.HasPrefix(s, "-") { 67 mul = -1 68 s = s[1:] 69 } 70 71 sep := -1 72 for i, c := range s { 73 if sep == -1 { 74 if c < '0' || c > '9' { 75 sep = i 76 break 77 } 78 } 79 } 80 if sep == -1 { 81 return 0, fmt.Errorf("missing unit in size %s (allowed units: B, KB, MB, GB)", orig) 82 } 83 84 n, err := strconv.ParseInt(s[:sep], 10, 32) 85 if err != nil { 86 return 0, fmt.Errorf("invalid size %s", orig) 87 } 88 switch strings.ToLower(s[sep:]) { 89 case "gb": 90 mul = GByte 91 case "mb": 92 mul = MByte 93 case "kb": 94 mul = KByte 95 case "b": 96 default: 97 for _, c := range s[sep:] { 98 if unicode.IsSpace(c) { 99 return 0, fmt.Errorf("invalid character %q in size %s", c, orig) 100 } 101 } 102 return 0, fmt.Errorf("invalid unit in size %s (allowed units: B, KB, MB, GB)", orig) 103 } 104 return mul * Size(n), nil 105 }