mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-02 11:48:43 -07:00
152 lines
3.4 KiB
Go
152 lines
3.4 KiB
Go
// Copyright 2012-2019 The NATS Authors
|
|
// Licensed 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 server
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"math"
|
|
"net"
|
|
"net/url"
|
|
"reflect"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// Ascii numbers 0-9
|
|
const (
|
|
asciiZero = 48
|
|
asciiNine = 57
|
|
)
|
|
|
|
// parseSize expects decimal positive numbers. We
|
|
// return -1 to signal error.
|
|
func parseSize(d []byte) (n int) {
|
|
l := len(d)
|
|
if l == 0 {
|
|
return -1
|
|
}
|
|
var (
|
|
i int
|
|
dec byte
|
|
)
|
|
|
|
// Note: Use `goto` here to avoid for loop in order
|
|
// to have the function be inlined.
|
|
// See: https://github.com/golang/go/issues/14768
|
|
loop:
|
|
dec = d[i]
|
|
if dec < asciiZero || dec > asciiNine {
|
|
return -1
|
|
}
|
|
n = n*10 + (int(dec) - asciiZero)
|
|
|
|
i++
|
|
if i < l {
|
|
goto loop
|
|
}
|
|
return n
|
|
}
|
|
|
|
// parseInt64 expects decimal positive numbers. We
|
|
// return -1 to signal error
|
|
func parseInt64(d []byte) (n int64) {
|
|
if len(d) == 0 {
|
|
return -1
|
|
}
|
|
for _, dec := range d {
|
|
if dec < asciiZero || dec > asciiNine {
|
|
return -1
|
|
}
|
|
n = n*10 + (int64(dec) - asciiZero)
|
|
}
|
|
return n
|
|
}
|
|
|
|
// Helper to move from float seconds to time.Duration
|
|
func secondsToDuration(seconds float64) time.Duration {
|
|
ttl := seconds * float64(time.Second)
|
|
return time.Duration(ttl)
|
|
}
|
|
|
|
// Parse a host/port string with a default port to use
|
|
// if none (or 0 or -1) is specified in `hostPort` string.
|
|
func parseHostPort(hostPort string, defaultPort int) (host string, port int, err error) {
|
|
if hostPort != "" {
|
|
host, sPort, err := net.SplitHostPort(hostPort)
|
|
switch err.(type) {
|
|
case *net.AddrError:
|
|
// try appending the current port
|
|
host, sPort, err = net.SplitHostPort(fmt.Sprintf("%s:%d", hostPort, defaultPort))
|
|
}
|
|
if err != nil {
|
|
return "", -1, err
|
|
}
|
|
port, err = strconv.Atoi(strings.TrimSpace(sPort))
|
|
if err != nil {
|
|
return "", -1, err
|
|
}
|
|
if port == 0 || port == -1 {
|
|
port = defaultPort
|
|
}
|
|
return strings.TrimSpace(host), port, nil
|
|
}
|
|
return "", -1, errors.New("no hostport specified")
|
|
}
|
|
|
|
// Returns true if URL u1 represents the same URL than u2,
|
|
// false otherwise.
|
|
func urlsAreEqual(u1, u2 *url.URL) bool {
|
|
return reflect.DeepEqual(u1, u2)
|
|
}
|
|
|
|
// comma produces a string form of the given number in base 10 with
|
|
// commas after every three orders of magnitude.
|
|
//
|
|
// e.g. comma(834142) -> 834,142
|
|
//
|
|
// This function was copied from the github.com/dustin/go-humanize
|
|
// package and is Copyright Dustin Sallings <dustin@spy.net>
|
|
func comma(v int64) string {
|
|
sign := ""
|
|
|
|
// Min int64 can't be negated to a usable value, so it has to be special cased.
|
|
if v == math.MinInt64 {
|
|
return "-9,223,372,036,854,775,808"
|
|
}
|
|
|
|
if v < 0 {
|
|
sign = "-"
|
|
v = 0 - v
|
|
}
|
|
|
|
parts := []string{"", "", "", "", "", "", ""}
|
|
j := len(parts) - 1
|
|
|
|
for v > 999 {
|
|
parts[j] = strconv.FormatInt(v%1000, 10)
|
|
switch len(parts[j]) {
|
|
case 2:
|
|
parts[j] = "0" + parts[j]
|
|
case 1:
|
|
parts[j] = "00" + parts[j]
|
|
}
|
|
v = v / 1000
|
|
j--
|
|
}
|
|
parts[j] = strconv.Itoa(int(v))
|
|
return sign + strings.Join(parts[j:], ",")
|
|
}
|