Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / k8s.io / apimachinery / pkg / util / net / port_range.go
1 /*
2 Copyright 2015 The Kubernetes Authors.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8     http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 package net
18
19 import (
20         "fmt"
21         "strconv"
22         "strings"
23 )
24
25 // PortRange represents a range of TCP/UDP ports.  To represent a single port,
26 // set Size to 1.
27 type PortRange struct {
28         Base int
29         Size int
30 }
31
32 // Contains tests whether a given port falls within the PortRange.
33 func (pr *PortRange) Contains(p int) bool {
34         return (p >= pr.Base) && ((p - pr.Base) < pr.Size)
35 }
36
37 // String converts the PortRange to a string representation, which can be
38 // parsed by PortRange.Set or ParsePortRange.
39 func (pr PortRange) String() string {
40         if pr.Size == 0 {
41                 return ""
42         }
43         return fmt.Sprintf("%d-%d", pr.Base, pr.Base+pr.Size-1)
44 }
45
46 // Set parses a string of the form "value", "min-max", or "min+offset", inclusive at both ends, and
47 // sets the PortRange from it.  This is part of the flag.Value and pflag.Value
48 // interfaces.
49 func (pr *PortRange) Set(value string) error {
50         const (
51                 SinglePortNotation = 1 << iota
52                 HyphenNotation
53                 PlusNotation
54         )
55
56         value = strings.TrimSpace(value)
57         hyphenIndex := strings.Index(value, "-")
58         plusIndex := strings.Index(value, "+")
59
60         if value == "" {
61                 pr.Base = 0
62                 pr.Size = 0
63                 return nil
64         }
65
66         var err error
67         var low, high int
68         var notation int
69
70         if plusIndex == -1 && hyphenIndex == -1 {
71                 notation |= SinglePortNotation
72         }
73         if hyphenIndex != -1 {
74                 notation |= HyphenNotation
75         }
76         if plusIndex != -1 {
77                 notation |= PlusNotation
78         }
79
80         switch notation {
81         case SinglePortNotation:
82                 var port int
83                 port, err = strconv.Atoi(value)
84                 if err != nil {
85                         return err
86                 }
87                 low = port
88                 high = port
89         case HyphenNotation:
90                 low, err = strconv.Atoi(value[:hyphenIndex])
91                 if err != nil {
92                         return err
93                 }
94                 high, err = strconv.Atoi(value[hyphenIndex+1:])
95                 if err != nil {
96                         return err
97                 }
98         case PlusNotation:
99                 var offset int
100                 low, err = strconv.Atoi(value[:plusIndex])
101                 if err != nil {
102                         return err
103                 }
104                 offset, err = strconv.Atoi(value[plusIndex+1:])
105                 if err != nil {
106                         return err
107                 }
108                 high = low + offset
109         default:
110                 return fmt.Errorf("unable to parse port range: %s", value)
111         }
112
113         if low > 65535 || high > 65535 {
114                 return fmt.Errorf("the port range cannot be greater than 65535: %s", value)
115         }
116
117         if high < low {
118                 return fmt.Errorf("end port cannot be less than start port: %s", value)
119         }
120
121         pr.Base = low
122         pr.Size = 1 + high - low
123         return nil
124 }
125
126 // Type returns a descriptive string about this type.  This is part of the
127 // pflag.Value interface.
128 func (*PortRange) Type() string {
129         return "portRange"
130 }
131
132 // ParsePortRange parses a string of the form "min-max", inclusive at both
133 // ends, and initializs a new PortRange from it.
134 func ParsePortRange(value string) (*PortRange, error) {
135         pr := &PortRange{}
136         err := pr.Set(value)
137         if err != nil {
138                 return nil, err
139         }
140         return pr, nil
141 }
142
143 func ParsePortRangeOrDie(value string) *PortRange {
144         pr, err := ParsePortRange(value)
145         if err != nil {
146                 panic(fmt.Sprintf("couldn't parse port range %q: %v", value, err))
147         }
148         return pr
149 }