Path: blob/main/components/ws-daemon/pkg/quota/size.go
2499 views
// Copyright (c) 2020 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package quota56import (7"encoding/json"8"errors"9"fmt"10"regexp"11"strconv"1213"golang.org/x/xerrors"14)1516// Size denotes a filesize / amount of bytes17type Size int641819const (20// Byte is a single byte21Byte Size = 122// Kilobyte is 1024 bytes23Kilobyte Size = 1024 * Byte24// Megabyte is 1024 kilobytes25Megabyte Size = 1024 * Kilobyte26// Gigabyte is 1024 megabytes27Gigabyte Size = 1024 * Megabyte28// Terabyte is 1024 gigabyte29Terabyte Size = 1024 * Gigabyte30)3132var (33sizeRegexp = regexp.MustCompile(`^(\d+)(k|m|g|t)?$`)3435// ErrInvalidSize is returned by ParseSize if input was not a valid size36ErrInvalidSize = errors.New("invalid size")37)3839// ParseSize parses a number of bytes (e.g. 10) into a size.40// ParseSize supports units: k(ilobyte), m(egabyte), (g)igatebyte, (t)erabyte. E.g. 50m or 200g41func ParseSize(q string) (Size, error) {42matches := sizeRegexp.FindSubmatch([]byte(q))43if len(matches) == 0 {44return 0, ErrInvalidSize45}4647val, err := strconv.ParseUint(string(matches[1]), 10, 64)48if err != nil {49return 0, ErrInvalidSize50}51size := Size(val)5253unit := string(matches[2])54switch unit {55case "":56size = size * Byte57case "k":58size = size * Kilobyte59case "m":60size = size * Megabyte61case "g":62size = size * Gigabyte63case "t":64size = size * Terabyte65}6667return size, nil68}6970// String converts the size to a string71func (s Size) String() string {72if s == 0 {73return "0"74}7576steps := []struct {77Prefix string78Q Size79}{80{"t", Terabyte},81{"g", Gigabyte},82{"m", Megabyte},83{"k", Kilobyte},84}85for _, stp := range steps {86if s%stp.Q == 0 {87return fmt.Sprintf("%d%s", s/stp.Q, stp.Prefix)88}89}90return fmt.Sprintf("%d", s)91}9293// MarshalJSON marshals a duration to JSON94func (s Size) MarshalJSON() ([]byte, error) {95return json.Marshal(s.String())96}9798// UnmarshalJSON unmarshals a duration from JSON99func (s *Size) UnmarshalJSON(b []byte) error {100var v interface{}101if err := json.Unmarshal(b, &v); err != nil {102return err103}104switch value := v.(type) {105case string:106if value == "" {107*s = 0108return nil109}110111tmp, err := ParseSize(value)112if err != nil {113return err114}115*s = tmp116return nil117default:118return xerrors.Errorf("invalid size: %s", string(b))119}120}121122123