internal/configutil/size.go (73 lines of code) (raw):

// Licensed to Elasticsearch B.V. under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Elasticsearch B.V. licenses this file to you under // the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package configutil import ( "fmt" "strconv" "strings" "unicode" ) // Size represents a size in bytes. type Size int64 // Common power-of-two sizes. const ( Byte Size = 1 KByte Size = 1024 MByte Size = 1024 * 1024 GByte Size = 1024 * 1024 * 1024 ) // Bytes returns s as a number of bytes. func (s Size) Bytes() int64 { return int64(s) } // String returns s in its most compact string representation. func (s Size) String() string { if s == 0 { return "0B" } switch { case s%GByte == 0: return fmt.Sprintf("%dGB", s/GByte) case s%MByte == 0: return fmt.Sprintf("%dMB", s/MByte) case s%KByte == 0: return fmt.Sprintf("%dKB", s/KByte) default: return fmt.Sprintf("%dB", s) } } // ParseSize parses s as a size, in bytes. // // Valid size units are "b", "kb", "mb", "gb". func ParseSize(s string) (Size, error) { orig := s var mul Size = 1 if strings.HasPrefix(s, "-") { mul = -1 s = s[1:] } sep := -1 for i, c := range s { if sep == -1 { if c < '0' || c > '9' { sep = i break } } } if sep == -1 { return 0, fmt.Errorf("missing unit in size %s (allowed units: B, KB, MB, GB)", orig) } n, err := strconv.ParseInt(s[:sep], 10, 32) if err != nil { return 0, fmt.Errorf("invalid size %s", orig) } switch strings.ToLower(s[sep:]) { case "gb": mul = GByte case "mb": mul = MByte case "kb": mul = KByte case "b": default: for _, c := range s[sep:] { if unicode.IsSpace(c) { return 0, fmt.Errorf("invalid character %q in size %s", c, orig) } } return 0, fmt.Errorf("invalid unit in size %s (allowed units: B, KB, MB, GB)", orig) } return mul * Size(n), nil }