mirror of
https://source.quilibrium.com/quilibrium/ceremonyclient.git
synced 2024-11-14 12:15:18 +00:00
122 lines
2.4 KiB
Go
122 lines
2.4 KiB
Go
|
/*
|
||
|
Copyright 2013 The Perkeep 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 testkeys
|
||
|
|
||
|
import (
|
||
|
"strconv"
|
||
|
|
||
|
"github.com/cockroachdb/errors"
|
||
|
)
|
||
|
|
||
|
// parseUintBytes is like strconv.ParseUint, but using a []byte. Use of this
|
||
|
// function avoids an allocation when parsing an integer out of a []byte.
|
||
|
//
|
||
|
// This function is copied from go4.org/strconv.
|
||
|
func parseUintBytes(s []byte, base int, bitSize int) (n uint64, err error) {
|
||
|
var cutoff, maxVal uint64
|
||
|
|
||
|
if bitSize == 0 {
|
||
|
bitSize = int(strconv.IntSize)
|
||
|
}
|
||
|
|
||
|
s0 := s
|
||
|
switch {
|
||
|
case len(s) < 1:
|
||
|
err = strconv.ErrSyntax
|
||
|
goto Error
|
||
|
|
||
|
case 2 <= base && base <= 36:
|
||
|
// valid base; nothing to do
|
||
|
|
||
|
case base == 0:
|
||
|
// Look for octal, hex prefix.
|
||
|
switch {
|
||
|
case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
|
||
|
base = 16
|
||
|
s = s[2:]
|
||
|
if len(s) < 1 {
|
||
|
err = strconv.ErrSyntax
|
||
|
goto Error
|
||
|
}
|
||
|
case s[0] == '0':
|
||
|
base = 8
|
||
|
default:
|
||
|
base = 10
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
err = errors.New("invalid base " + strconv.Itoa(base))
|
||
|
goto Error
|
||
|
}
|
||
|
|
||
|
n = 0
|
||
|
cutoff = cutoff64(base)
|
||
|
maxVal = 1<<uint(bitSize) - 1
|
||
|
|
||
|
for i := 0; i < len(s); i++ {
|
||
|
var v byte
|
||
|
d := s[i]
|
||
|
switch {
|
||
|
case '0' <= d && d <= '9':
|
||
|
v = d - '0'
|
||
|
case 'a' <= d && d <= 'z':
|
||
|
v = d - 'a' + 10
|
||
|
case 'A' <= d && d <= 'Z':
|
||
|
v = d - 'A' + 10
|
||
|
default:
|
||
|
n = 0
|
||
|
err = strconv.ErrSyntax
|
||
|
goto Error
|
||
|
}
|
||
|
if int(v) >= base {
|
||
|
n = 0
|
||
|
err = strconv.ErrSyntax
|
||
|
goto Error
|
||
|
}
|
||
|
|
||
|
if n >= cutoff {
|
||
|
// n*base overflows
|
||
|
n = 1<<64 - 1
|
||
|
err = strconv.ErrRange
|
||
|
goto Error
|
||
|
}
|
||
|
n *= uint64(base)
|
||
|
|
||
|
n1 := n + uint64(v)
|
||
|
if n1 < n || n1 > maxVal {
|
||
|
// n+v overflows
|
||
|
n = 1<<64 - 1
|
||
|
err = strconv.ErrRange
|
||
|
goto Error
|
||
|
}
|
||
|
n = n1
|
||
|
}
|
||
|
|
||
|
return n, nil
|
||
|
|
||
|
Error:
|
||
|
return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err}
|
||
|
}
|
||
|
|
||
|
// Return the first number n such that n*base >= 1<<64.
|
||
|
func cutoff64(base int) uint64 {
|
||
|
if base < 2 {
|
||
|
return 0
|
||
|
}
|
||
|
return (1<<64-1)/uint64(base) + 1
|
||
|
}
|