1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
|
package utils
// smallInts contains precomputed string representations for small integers 0-99
var smallInts [100]string
// smallNegInts contains precomputed string representations for small negative integers -1 to -99
var smallNegInts [100]string
// uint8Strs contains precomputed string representations for all uint8 values.
var uint8Strs [256]string
// int8Strs contains precomputed string representations for all int8 values indexed by uint8(value).
var int8Strs [256]string
func init() {
for i := range 100 {
smallInts[i] = formatUintSmall(uint64(i))
if i > 0 {
smallNegInts[i] = "-" + smallInts[i]
}
}
for i := range 256 {
v := uint8(i)
uint8Strs[i] = formatUint8Slow(v)
sv := int8(i)
if sv >= 0 {
int8Strs[i] = uint8Strs[sv]
} else {
int8Strs[i] = "-" + uint8Strs[uint8(-sv)]
}
}
}
func formatUintSmall(n uint64) string {
if n < 10 {
return string(byte(n) + '0')
}
return string([]byte{byte(n/10) + '0', byte(n%10) + '0'})
}
func formatUint8Slow(n uint8) string {
if n < 100 {
return smallInts[n]
}
return string([]byte{n/100 + '0', (n/10)%10 + '0', n%10 + '0'})
}
// formatUintBuf writes the digits of n into buf from the end and returns the start index.
// buf must be at least 20 bytes.
func formatUintBuf(buf *[20]byte, n uint64) int {
i := 20
for n >= 10 {
i--
buf[i] = byte(n%10) + '0'
n /= 10
}
i--
buf[i] = byte(n) + '0'
return i
}
// FormatUint formats a uint64 as a decimal string.
// It is faster than strconv.FormatUint for most inputs.
func FormatUint(n uint64) string {
if n < 100 {
return smallInts[n]
}
var buf [20]byte
i := formatUintBuf(&buf, n)
return string(buf[i:])
}
// FormatInt formats an int64 as a decimal string.
// It is faster than strconv.FormatInt for most inputs.
func FormatInt(n int64) string {
if n >= 0 && n < 100 {
return smallInts[n]
}
if n < 0 && n > -100 {
return smallNegInts[-n]
}
if n >= 0 {
var buf [20]byte
i := formatUintBuf(&buf, uint64(n))
return string(buf[i:])
}
var buf [20]byte
i := formatUintBuf(&buf, uint64(-n))
i--
buf[i] = '-'
return string(buf[i:])
}
// FormatUint32 formats a uint32 as a decimal string.
func FormatUint32(n uint32) string {
if n < 100 {
return smallInts[n]
}
var buf [10]byte // max 4294967295
i := 10
for n >= 10 {
i--
buf[i] = byte(n%10) + '0' //nolint:gosec // i is always in bounds: starts at 10, decrements max 10 times for uint32
n /= 10
}
i--
buf[i] = byte(n) + '0' //nolint:gosec // i is always >= 0 after loop
return string(buf[i:])
}
// FormatInt32 formats an int32 as a decimal string.
func FormatInt32(n int32) string {
if n >= 0 && n < 100 {
return smallInts[n]
}
if n < 0 && n > -100 {
return smallNegInts[-n]
}
if n >= 0 {
return FormatUint32(uint32(n))
}
var buf [11]byte // max -2147483648
un := uint32(-n)
i := 11
for un >= 10 {
i--
buf[i] = byte(un%10) + '0'
un /= 10
}
i--
buf[i] = byte(un) + '0'
i--
buf[i] = '-'
return string(buf[i:])
}
// FormatUint16 formats a uint16 as a decimal string.
func FormatUint16(n uint16) string {
if n < 100 {
return smallInts[n]
}
var buf [5]byte // max 65535
i := 5
for n >= 10 {
i--
buf[i] = byte(n%10) + '0' //nolint:gosec // i is always in bounds: starts at 5, decrements max 5 times for uint16
n /= 10
}
i--
buf[i] = byte(n) + '0' //nolint:gosec // i is always >= 0 after loop
return string(buf[i:])
}
// FormatInt16 formats an int16 as a decimal string.
func FormatInt16(n int16) string {
if n >= 0 && n < 100 {
return smallInts[n]
}
if n < 0 && n > -100 {
return smallNegInts[-n]
}
if n >= 0 {
return FormatUint16(uint16(n))
}
var buf [6]byte // max -32768
un := uint16(-n)
i := 6
for un >= 10 {
i--
buf[i] = byte(un%10) + '0' //nolint:gosec // i is always in bounds
un /= 10
}
i--
buf[i] = byte(un) + '0' //nolint:gosec // i is always >= 1 after loop
i--
buf[i] = '-' //nolint:gosec // i is always >= 0 after decrement
return string(buf[i:])
}
// FormatUint8 formats a uint8 as a decimal string.
func FormatUint8(n uint8) string {
return uint8Strs[n]
}
// FormatInt8 formats an int8 as a decimal string.
func FormatInt8(n int8) string {
return int8Strs[uint8(n)]
}
// AppendUint appends the decimal string representation of n to dst.
func AppendUint(dst []byte, n uint64) []byte {
if n < 100 {
return append(dst, smallInts[n]...)
}
var buf [20]byte
i := formatUintBuf(&buf, n)
return append(dst, buf[i:]...)
}
// AppendInt appends the decimal string representation of n to dst.
func AppendInt(dst []byte, n int64) []byte {
if n >= 0 {
return AppendUint(dst, uint64(n))
}
if n > -100 {
return append(dst, smallNegInts[-n]...)
}
var buf [20]byte
i := formatUintBuf(&buf, uint64(-n))
i--
buf[i] = '-' //nolint:gosec // i is always >= 0: formatUintBuf returns at least 1 for any input, so i >= 0 after decrement
return append(dst, buf[i:]...)
}
|