| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- 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:]...)
- }
|