go_dreamfactory/lego/sys/codec/utils/int.go
2022-07-11 15:54:54 +08:00

544 lines
12 KiB
Go

package utils
import (
"errors"
"math"
"strconv"
)
var digits []uint32
var intDigits []int8
const uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1
const uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1
const maxFloat64 = 1<<53 - 1
func init() {
digits = make([]uint32, 1000)
for i := uint32(0); i < 1000; i++ {
digits[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0'
if i < 10 {
digits[i] += 2 << 24
} else if i < 100 {
digits[i] += 1 << 24
}
}
intDigits = make([]int8, 256)
for i := 0; i < len(intDigits); i++ {
intDigits[i] = invalidCharForNumber
}
for i := int8('0'); i <= int8('9'); i++ {
intDigits[i] = i - int8('0')
}
}
//Read Int For String--------------------------------------------------------------------------------------------------------------------------------
func ReadInt8ForString(buf []byte) (ret int8, n int, err error) {
var (
val uint32
)
c := buf[0]
if c == '-' {
val, n, err = ReadUint32ForString(buf[1:])
if val > math.MaxInt8+1 {
err = errors.New("ReadInt8ForString overflow: " + strconv.FormatInt(int64(val), 10))
return
}
ret = -int8(val)
return
}
val, n, err = ReadUint32ForString(buf)
if val > math.MaxInt8 {
err = errors.New("ReadInt8ForString overflow: " + strconv.FormatInt(int64(val), 10))
return
}
ret = int8(val)
return
}
func ReadInt16ForString(buf []byte) (ret int16, n int, err error) {
var (
val uint32
)
c := buf[0]
if c == '-' {
val, n, err = ReadUint32ForString(buf[1:])
if val > math.MaxInt16+1 {
err = errors.New("ReadInt16ForString overflow: " + strconv.FormatInt(int64(val), 10))
return
}
ret = -int16(val)
return
}
val, n, err = ReadUint32ForString(buf)
if val > math.MaxInt16 {
err = errors.New("ReadInt16ForString overflow: " + strconv.FormatInt(int64(val), 10))
return
}
ret = int16(val)
return
}
func ReadInt32ForString(buf []byte) (ret int32, n int, err error) {
var (
val uint32
)
c := buf[0]
if c == '-' {
val, n, err = ReadUint32ForString(buf[1:])
if val > math.MaxInt32+1 {
err = errors.New("ReadInt32ForString overflow: " + strconv.FormatInt(int64(val), 10))
return
}
ret = -int32(val)
return
}
val, n, err = ReadUint32ForString(buf)
if val > math.MaxInt32 {
err = errors.New("ReadInt32ForString overflow: " + strconv.FormatInt(int64(val), 10))
return
}
ret = int32(val)
return
}
func ReadInt64ForString(buf []byte) (ret int64, n int, err error) {
var (
val uint64
)
c := buf[0]
if c == '-' {
val, n, err = ReadUint64ForString(buf[1:])
if val > math.MaxInt64+1 {
err = errors.New("ReadInt64ForString overflow: " + strconv.FormatInt(int64(val), 10))
return
}
ret = -int64(val)
return
}
val, n, err = ReadUint64ForString(buf)
if val > math.MaxInt64 {
err = errors.New("ReadInt64ForString overflow: " + strconv.FormatInt(int64(val), 10))
return
}
ret = int64(val)
return
}
func ReadUint8ForString(buf []byte) (ret uint8, n int, err error) {
var (
val uint32
)
val, n, err = ReadUint32ForString(buf)
if val > math.MaxUint8 {
err = errors.New("ReadUInt8ForString overflow: " + strconv.FormatInt(int64(val), 10))
return
}
ret = uint8(val)
return
}
func ReadUint16ForString(buf []byte) (ret uint16, n int, err error) {
var (
val uint32
)
val, n, err = ReadUint32ForString(buf)
if val > math.MaxUint16 {
err = errors.New("ReadUInt16ForString overflow: " + strconv.FormatInt(int64(val), 10))
return
}
ret = uint16(val)
return
}
func ReadUint32ForString(buf []byte) (ret uint32, n int, err error) {
ind := intDigits[buf[0]]
if ind == 0 {
err = assertInteger(buf[1:])
return
}
if ind == invalidCharForNumber {
err = errors.New("ReadUint32ForString unexpected character: " + string([]byte{byte(ind)}))
return
}
ret = uint32(ind)
if len(buf) > 10 {
i := 0
ind2 := intDigits[buf[i]]
if ind2 == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
return
}
i++
ind3 := intDigits[buf[i]]
if ind3 == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
ret = ret*10 + uint32(ind2)
return
}
i++
ind4 := intDigits[buf[i]]
if ind4 == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
ret = ret*100 + uint32(ind2)*10 + uint32(ind3)
return
}
i++
ind5 := intDigits[buf[i]]
if ind5 == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
ret = ret*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4)
return
}
i++
ind6 := intDigits[buf[i]]
if ind6 == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
ret = ret*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5)
return
}
i++
ind7 := intDigits[buf[i]]
if ind7 == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
ret = ret*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6)
return
}
i++
ind8 := intDigits[buf[i]]
if ind8 == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
ret = ret*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7)
return
}
i++
ind9 := intDigits[buf[i]]
ret = ret*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8)
n = i
if ind9 == invalidCharForNumber {
err = assertInteger(buf[i:])
return
}
}
for i := 1; i < len(buf); i++ {
ind = intDigits[buf[i]]
if ind == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
return
}
if ret > uint32SafeToMultiply10 {
value2 := (ret << 3) + (ret << 1) + uint32(ind)
if value2 < ret {
err = errors.New("ReadUint32ForString overflow")
return
}
ret = value2
continue
}
ret = (ret << 3) + (ret << 1) + uint32(ind)
}
return
}
func ReadUint64ForString(buf []byte) (ret uint64, n int, err error) {
ind := intDigits[buf[0]]
if ind == 0 {
err = assertInteger(buf[1:])
return
}
if ind == invalidCharForNumber {
err = errors.New("ReadUint64ForString unexpected character: " + string([]byte{byte(ind)}))
return
}
ret = uint64(ind)
if len(buf) > 10 {
i := 0
ind2 := intDigits[buf[i]]
if ind2 == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
return
}
i++
ind3 := intDigits[buf[i]]
if ind3 == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
ret = ret*10 + uint64(ind2)
return
}
i++
ind4 := intDigits[buf[i]]
if ind4 == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
ret = ret*100 + uint64(ind2)*10 + uint64(ind3)
return
}
i++
ind5 := intDigits[buf[i]]
if ind5 == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
ret = ret*1000 + uint64(ind2)*100 + uint64(ind3)*10 + uint64(ind4)
return
}
i++
ind6 := intDigits[buf[i]]
if ind6 == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
ret = ret*10000 + uint64(ind2)*1000 + uint64(ind3)*100 + uint64(ind4)*10 + uint64(ind5)
return
}
i++
ind7 := intDigits[buf[i]]
if ind7 == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
ret = ret*100000 + uint64(ind2)*10000 + uint64(ind3)*1000 + uint64(ind4)*100 + uint64(ind5)*10 + uint64(ind6)
return
}
i++
ind8 := intDigits[buf[i]]
if ind8 == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
ret = ret*1000000 + uint64(ind2)*100000 + uint64(ind3)*10000 + uint64(ind4)*1000 + uint64(ind5)*100 + uint64(ind6)*10 + uint64(ind7)
return
}
i++
ind9 := intDigits[buf[i]]
ret = ret*10000000 + uint64(ind2)*1000000 + uint64(ind3)*100000 + uint64(ind4)*10000 + uint64(ind5)*1000 + uint64(ind6)*100 + uint64(ind7)*10 + uint64(ind8)
n = i
if ind9 == invalidCharForNumber {
err = assertInteger(buf[i:])
return
}
}
for i := 1; i < len(buf); i++ {
ind = intDigits[buf[i]]
if ind == invalidCharForNumber {
n = i
err = assertInteger(buf[i:])
return
}
if ret > uint64SafeToMultiple10 {
value2 := (ret << 3) + (ret << 1) + uint64(ind)
if value2 < ret {
err = errors.New("ReadUint64ForString overflow")
return
}
ret = value2
continue
}
ret = (ret << 3) + (ret << 1) + uint64(ind)
}
return
}
func assertInteger(buf []byte) (err error) {
if len(buf) > 0 && buf[0] == '.' {
err = errors.New("assertInteger can not decode float as int")
}
return
}
//Write Int To String--------------------------------------------------------------------------------------------------------------------------------
func WriteChar(buff *[]byte, c byte) {
*buff = append(*buff, c)
}
// WriteUint8 write uint8 to stream
func WriteUint8ToString(buf *[]byte, val uint8) {
*buf = writeFirstBuf(*buf, digits[val])
return
}
// WriteInt8 write int8 to stream
func WriteInt8ToString(buf *[]byte, nval int8) {
var val uint8
if nval < 0 {
val = uint8(-nval)
*buf = append(*buf, '-')
} else {
val = uint8(nval)
}
*buf = writeFirstBuf(*buf, digits[val])
return
}
// WriteUint16 write uint16 to stream
func WriteUint16ToString(buf *[]byte, val uint16) {
q1 := val / 1000
if q1 == 0 {
*buf = writeFirstBuf(*buf, digits[val])
return
}
r1 := val - q1*1000
*buf = writeFirstBuf(*buf, digits[q1])
*buf = writeBuf(*buf, digits[r1])
return
}
// WriteInt16 write int16 to stream
func WriteInt16ToString(buf *[]byte, nval int16) {
var val uint16
if nval < 0 {
val = uint16(-nval)
*buf = append(*buf, '-')
} else {
val = uint16(nval)
}
WriteUint16ToString(buf, val)
return
}
// WriteUint32 write uint32 to stream
func WriteUint32ToString(buf *[]byte, val uint32) {
q1 := val / 1000
if q1 == 0 {
*buf = writeFirstBuf(*buf, digits[val])
return
}
r1 := val - q1*1000
q2 := q1 / 1000
if q2 == 0 {
*buf = writeFirstBuf(*buf, digits[q1])
*buf = writeBuf(*buf, digits[r1])
return
}
r2 := q1 - q2*1000
q3 := q2 / 1000
if q3 == 0 {
*buf = writeFirstBuf(*buf, digits[q2])
} else {
r3 := q2 - q3*1000
*buf = append(*buf, byte(q3+'0'))
*buf = writeBuf(*buf, digits[r3])
}
*buf = writeBuf(*buf, digits[r2])
*buf = writeBuf(*buf, digits[r1])
return
}
// WriteInt32 write int32 to stream
func WriteInt32ToString(buf *[]byte, nval int32) {
var val uint32
if nval < 0 {
val = uint32(-nval)
*buf = append(*buf, '-')
} else {
val = uint32(nval)
}
WriteUint32ToString(buf, val)
return
}
// WriteUint64 write uint64 to stream
func WriteUint64ToString(buf *[]byte, val uint64) {
q1 := val / 1000
if q1 == 0 {
*buf = writeFirstBuf(*buf, digits[val])
return
}
r1 := val - q1*1000
q2 := q1 / 1000
if q2 == 0 {
*buf = writeFirstBuf(*buf, digits[q1])
*buf = writeBuf(*buf, digits[r1])
return
}
r2 := q1 - q2*1000
q3 := q2 / 1000
if q3 == 0 {
*buf = writeFirstBuf(*buf, digits[q2])
*buf = writeBuf(*buf, digits[r2])
*buf = writeBuf(*buf, digits[r1])
return
}
r3 := q2 - q3*1000
q4 := q3 / 1000
if q4 == 0 {
*buf = writeFirstBuf(*buf, digits[q3])
*buf = writeBuf(*buf, digits[r3])
*buf = writeBuf(*buf, digits[r2])
*buf = writeBuf(*buf, digits[r1])
return
}
r4 := q3 - q4*1000
q5 := q4 / 1000
if q5 == 0 {
*buf = writeFirstBuf(*buf, digits[q4])
*buf = writeBuf(*buf, digits[r4])
*buf = writeBuf(*buf, digits[r3])
*buf = writeBuf(*buf, digits[r2])
*buf = writeBuf(*buf, digits[r1])
return
}
r5 := q4 - q5*1000
q6 := q5 / 1000
if q6 == 0 {
*buf = writeFirstBuf(*buf, digits[q5])
} else {
*buf = writeFirstBuf(*buf, digits[q6])
r6 := q5 - q6*1000
*buf = writeBuf(*buf, digits[r6])
}
*buf = writeBuf(*buf, digits[r5])
*buf = writeBuf(*buf, digits[r4])
*buf = writeBuf(*buf, digits[r3])
*buf = writeBuf(*buf, digits[r2])
*buf = writeBuf(*buf, digits[r1])
return
}
// WriteInt64 write int64 to stream
func WriteInt64ToString(buf *[]byte, nval int64) {
var val uint64
if nval < 0 {
val = uint64(-nval)
*buf = append(*buf, '-')
} else {
val = uint64(nval)
}
WriteUint64ToString(buf, val)
return
}
// WriteInt write int to stream
func WriteIntToString(buf *[]byte, val int) {
WriteInt64ToString(buf, int64(val))
return
}
// WriteUint write uint to stream
func WriteUint(buf *[]byte, val uint) {
WriteUint64ToString(buf, uint64(val))
return
}
func writeFirstBuf(space []byte, v uint32) []byte {
start := v >> 24
if start == 0 {
space = append(space, byte(v>>16), byte(v>>8))
} else if start == 1 {
space = append(space, byte(v>>8))
}
space = append(space, byte(v))
return space
}
func writeBuf(buf []byte, v uint32) []byte {
return append(buf, byte(v>>16), byte(v>>8), byte(v))
}