github.com/MangoDowner/go-gm@v0.0.0-20180818020936-8baa2bd4408c/src/net/port.go (about)

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package net
     6  
     7  // parsePort parses service as a decimal interger and returns the
     8  // corresponding value as port. It is the caller's responsibility to
     9  // parse service as a non-decimal integer when needsLookup is true.
    10  //
    11  // Some system resolvers will return a valid port number when given a number
    12  // over 65536 (see https://github.com/golang/go/issues/11715). Alas, the parser
    13  // can't bail early on numbers > 65536. Therefore reasonably large/small
    14  // numbers are parsed in full and rejected if invalid.
    15  func parsePort(service string) (port int, needsLookup bool) {
    16  	if service == "" {
    17  		// Lock in the legacy behavior that an empty string
    18  		// means port 0. See golang.org/issue/13610.
    19  		return 0, false
    20  	}
    21  	const (
    22  		max    = uint32(1<<32 - 1)
    23  		cutoff = uint32(1 << 30)
    24  	)
    25  	neg := false
    26  	if service[0] == '+' {
    27  		service = service[1:]
    28  	} else if service[0] == '-' {
    29  		neg = true
    30  		service = service[1:]
    31  	}
    32  	var n uint32
    33  	for _, d := range service {
    34  		if '0' <= d && d <= '9' {
    35  			d -= '0'
    36  		} else {
    37  			return 0, true
    38  		}
    39  		if n >= cutoff {
    40  			n = max
    41  			break
    42  		}
    43  		n *= 10
    44  		nn := n + uint32(d)
    45  		if nn < n || nn > max {
    46  			n = max
    47  			break
    48  		}
    49  		n = nn
    50  	}
    51  	if !neg && n >= cutoff {
    52  		port = int(cutoff - 1)
    53  	} else if neg && n > cutoff {
    54  		port = int(cutoff)
    55  	} else {
    56  		port = int(n)
    57  	}
    58  	if neg {
    59  		port = -port
    60  	}
    61  	return port, false
    62  }