github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/pkg/parsers/parsers.go (about)

     1  // Package parsers provides helper functions to parse and validate different type
     2  // of string. It can be hosts, unix addresses, tcp addresses, filters, kernel
     3  // operating system versions.
     4  package parsers // import "github.com/Prakhar-Agarwal-byte/moby/pkg/parsers"
     5  
     6  import (
     7  	"fmt"
     8  	"strconv"
     9  	"strings"
    10  )
    11  
    12  // ParseKeyValueOpt parses and validates the specified string as a key/value
    13  // pair (key=value).
    14  func ParseKeyValueOpt(opt string) (key string, value string, err error) {
    15  	k, v, ok := strings.Cut(opt, "=")
    16  	if !ok {
    17  		return "", "", fmt.Errorf("unable to parse key/value option: %s", opt)
    18  	}
    19  	return strings.TrimSpace(k), strings.TrimSpace(v), nil
    20  }
    21  
    22  // ParseUintListMaximum parses and validates the specified string as the value
    23  // found in some cgroup file (e.g. `cpuset.cpus`, `cpuset.mems`), which could be
    24  // one of the formats below. Note that duplicates are actually allowed in the
    25  // input string. It returns a `map[int]bool` with available elements from `val`
    26  // set to `true`. Values larger than `maximum` cause an error if max is non zero,
    27  // in order to stop the map becoming excessively large.
    28  // Supported formats:
    29  //
    30  //	7
    31  //	1-6
    32  //	0,3-4,7,8-10
    33  //	0-0,0,1-7
    34  //	03,1-3      <- this is gonna get parsed as [1,2,3]
    35  //	3,2,1
    36  //	0-2,3,1
    37  func ParseUintListMaximum(val string, maximum int) (map[int]bool, error) {
    38  	return parseUintList(val, maximum)
    39  }
    40  
    41  // ParseUintList parses and validates the specified string as the value
    42  // found in some cgroup file (e.g. `cpuset.cpus`, `cpuset.mems`), which could be
    43  // one of the formats below. Note that duplicates are actually allowed in the
    44  // input string. It returns a `map[int]bool` with available elements from `val`
    45  // set to `true`.
    46  // Supported formats:
    47  //
    48  //	7
    49  //	1-6
    50  //	0,3-4,7,8-10
    51  //	0-0,0,1-7
    52  //	03,1-3      <- this is gonna get parsed as [1,2,3]
    53  //	3,2,1
    54  //	0-2,3,1
    55  func ParseUintList(val string) (map[int]bool, error) {
    56  	return parseUintList(val, 0)
    57  }
    58  
    59  func parseUintList(val string, maximum int) (map[int]bool, error) {
    60  	if val == "" {
    61  		return map[int]bool{}, nil
    62  	}
    63  
    64  	availableInts := make(map[int]bool)
    65  	split := strings.Split(val, ",")
    66  	errInvalidFormat := fmt.Errorf("invalid format: %s", val)
    67  
    68  	for _, r := range split {
    69  		if !strings.Contains(r, "-") {
    70  			v, err := strconv.Atoi(r)
    71  			if err != nil {
    72  				return nil, errInvalidFormat
    73  			}
    74  			if maximum != 0 && v > maximum {
    75  				return nil, fmt.Errorf("value of out range, maximum is %d", maximum)
    76  			}
    77  			availableInts[v] = true
    78  		} else {
    79  			minS, maxS, _ := strings.Cut(r, "-")
    80  			min, err := strconv.Atoi(minS)
    81  			if err != nil {
    82  				return nil, errInvalidFormat
    83  			}
    84  			max, err := strconv.Atoi(maxS)
    85  			if err != nil {
    86  				return nil, errInvalidFormat
    87  			}
    88  			if max < min {
    89  				return nil, errInvalidFormat
    90  			}
    91  			if maximum != 0 && max > maximum {
    92  				return nil, fmt.Errorf("value of out range, maximum is %d", maximum)
    93  			}
    94  			for i := min; i <= max; i++ {
    95  				availableInts[i] = true
    96  			}
    97  		}
    98  	}
    99  	return availableInts, nil
   100  }