github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/jsoni/iter_int.go (about)

     1  package jsoni
     2  
     3  import (
     4  	"math"
     5  	"strconv"
     6  )
     7  
     8  var intDigits []int8
     9  
    10  const (
    11  	uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1
    12  	uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1
    13  	maxFloat64             = 1<<53 - 1
    14  )
    15  
    16  func init() {
    17  	intDigits = make([]int8, 256)
    18  	for i := 0; i < len(intDigits); i++ {
    19  		intDigits[i] = invalidCharForNumber
    20  	}
    21  	for i := int8('0'); i <= int8('9'); i++ {
    22  		intDigits[i] = i - int8('0')
    23  	}
    24  }
    25  
    26  // ReadUint read uint
    27  func (iter *Iterator) ReadUint() uint {
    28  	if strconv.IntSize == 32 {
    29  		return uint(iter.ReadUint32())
    30  	}
    31  	return uint(iter.ReadUint64())
    32  }
    33  
    34  // ReadInt read int
    35  func (iter *Iterator) ReadInt() int {
    36  	if strconv.IntSize == 32 {
    37  		return int(iter.ReadInt32())
    38  	}
    39  	return int(iter.ReadInt64())
    40  }
    41  
    42  // ReadInt8 read int8
    43  func (iter *Iterator) ReadInt8() (ret int8) {
    44  	c := iter.nextToken()
    45  	if c == '-' {
    46  		val := iter.readUint32(iter.readByte())
    47  		if val > math.MaxInt8+1 {
    48  			iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10))
    49  			return
    50  		}
    51  		return -int8(val)
    52  	}
    53  	val := iter.readUint32(c)
    54  	if val > math.MaxInt8 {
    55  		iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10))
    56  		return
    57  	}
    58  	return int8(val)
    59  }
    60  
    61  // ReadUint8 read uint8
    62  func (iter *Iterator) ReadUint8() (ret uint8) {
    63  	val := iter.readUint32(iter.nextToken())
    64  	if val > math.MaxUint8 {
    65  		iter.ReportError("ReadUint8", "overflow: "+strconv.FormatInt(int64(val), 10))
    66  		return
    67  	}
    68  	return uint8(val)
    69  }
    70  
    71  // ReadInt16 read int16
    72  func (iter *Iterator) ReadInt16() (ret int16) {
    73  	c := iter.nextToken()
    74  	if c == '-' {
    75  		val := iter.readUint32(iter.readByte())
    76  		if val > math.MaxInt16+1 {
    77  			iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10))
    78  			return
    79  		}
    80  		return -int16(val)
    81  	}
    82  	val := iter.readUint32(c)
    83  	if val > math.MaxInt16 {
    84  		iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10))
    85  		return
    86  	}
    87  	return int16(val)
    88  }
    89  
    90  // ReadUint16 read uint16
    91  func (iter *Iterator) ReadUint16() (ret uint16) {
    92  	val := iter.readUint32(iter.nextToken())
    93  	if val > math.MaxUint16 {
    94  		iter.ReportError("ReadUint16", "overflow: "+strconv.FormatInt(int64(val), 10))
    95  		return
    96  	}
    97  	return uint16(val)
    98  }
    99  
   100  // ReadInt32 read int32
   101  func (iter *Iterator) ReadInt32() (ret int32) {
   102  	c := iter.nextToken()
   103  	if c == '-' {
   104  		val := iter.readUint32(iter.readByte())
   105  		if val > math.MaxInt32+1 {
   106  			iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10))
   107  			return
   108  		}
   109  		return -int32(val)
   110  	}
   111  	val := iter.readUint32(c)
   112  	if val > math.MaxInt32 {
   113  		iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10))
   114  		return
   115  	}
   116  	return int32(val)
   117  }
   118  
   119  // ReadUint32 read uint32
   120  func (iter *Iterator) ReadUint32() (ret uint32) {
   121  	return iter.readUint32(iter.nextToken())
   122  }
   123  
   124  func (iter *Iterator) readUint32(c byte) (ret uint32) {
   125  	ind := intDigits[c]
   126  	if ind == 0 {
   127  		iter.assertInteger()
   128  		return 0 // single zero
   129  	}
   130  	if ind == invalidCharForNumber {
   131  		iter.ReportError("readUint32", "unexpected character: "+string([]byte{byte(ind)}))
   132  		return
   133  	}
   134  	value := uint32(ind)
   135  	if iter.tail-iter.head > 10 {
   136  		i := iter.head
   137  		ind2 := intDigits[iter.buf[i]]
   138  		if ind2 == invalidCharForNumber {
   139  			iter.head = i
   140  			iter.assertInteger()
   141  			return value
   142  		}
   143  		i++
   144  		ind3 := intDigits[iter.buf[i]]
   145  		if ind3 == invalidCharForNumber {
   146  			iter.head = i
   147  			iter.assertInteger()
   148  			return value*10 + uint32(ind2)
   149  		}
   150  		// iter.head = i + 1
   151  		// value = value * 100 + uint32(ind2) * 10 + uint32(ind3)
   152  		i++
   153  		ind4 := intDigits[iter.buf[i]]
   154  		if ind4 == invalidCharForNumber {
   155  			iter.head = i
   156  			iter.assertInteger()
   157  			return value*100 + uint32(ind2)*10 + uint32(ind3)
   158  		}
   159  		i++
   160  		ind5 := intDigits[iter.buf[i]]
   161  		if ind5 == invalidCharForNumber {
   162  			iter.head = i
   163  			iter.assertInteger()
   164  			return value*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4)
   165  		}
   166  		i++
   167  		ind6 := intDigits[iter.buf[i]]
   168  		if ind6 == invalidCharForNumber {
   169  			iter.head = i
   170  			iter.assertInteger()
   171  			return value*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5)
   172  		}
   173  		i++
   174  		ind7 := intDigits[iter.buf[i]]
   175  		if ind7 == invalidCharForNumber {
   176  			iter.head = i
   177  			iter.assertInteger()
   178  			return value*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6)
   179  		}
   180  		i++
   181  		ind8 := intDigits[iter.buf[i]]
   182  		if ind8 == invalidCharForNumber {
   183  			iter.head = i
   184  			iter.assertInteger()
   185  			return value*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7)
   186  		}
   187  		i++
   188  		ind9 := intDigits[iter.buf[i]]
   189  		value = value*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8)
   190  		iter.head = i
   191  		if ind9 == invalidCharForNumber {
   192  			iter.assertInteger()
   193  			return value
   194  		}
   195  	}
   196  	for {
   197  		for i := iter.head; i < iter.tail; i++ {
   198  			ind = intDigits[iter.buf[i]]
   199  			if ind == invalidCharForNumber {
   200  				iter.head = i
   201  				iter.assertInteger()
   202  				return value
   203  			}
   204  			if value > uint32SafeToMultiply10 {
   205  				value2 := (value << 3) + (value << 1) + uint32(ind)
   206  				if value2 < value {
   207  					iter.ReportError("readUint32", "overflow")
   208  					return
   209  				}
   210  				value = value2
   211  				continue
   212  			}
   213  			value = (value << 3) + (value << 1) + uint32(ind)
   214  		}
   215  		if !iter.loadMore() {
   216  			iter.assertInteger()
   217  			return value
   218  		}
   219  	}
   220  }
   221  
   222  // ReadInt64 read int64
   223  func (iter *Iterator) ReadInt64() (ret int64) {
   224  	c := iter.nextToken()
   225  	if c == '-' {
   226  		val := iter.readUint64(iter.readByte())
   227  		if val > math.MaxInt64+1 {
   228  			iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10))
   229  			return
   230  		}
   231  		return -int64(val)
   232  	}
   233  	val := iter.readUint64(c)
   234  	if val > math.MaxInt64 {
   235  		iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10))
   236  		return
   237  	}
   238  	return int64(val)
   239  }
   240  
   241  // ReadUint64 read uint64
   242  func (iter *Iterator) ReadUint64() uint64 { return iter.readUint64(iter.nextToken()) }
   243  
   244  func (iter *Iterator) readUint64(c byte) (ret uint64) {
   245  	ind := intDigits[c]
   246  	if ind == 0 {
   247  		iter.assertInteger()
   248  		return 0 // single zero
   249  	}
   250  	if ind == invalidCharForNumber {
   251  		iter.ReportError("readUint64", "unexpected character: "+string([]byte{byte(ind)}))
   252  		return
   253  	}
   254  	value := uint64(ind)
   255  	if iter.tail-iter.head > 10 {
   256  		i := iter.head
   257  		ind2 := intDigits[iter.buf[i]]
   258  		if ind2 == invalidCharForNumber {
   259  			iter.head = i
   260  			iter.assertInteger()
   261  			return value
   262  		}
   263  		i++
   264  		ind3 := intDigits[iter.buf[i]]
   265  		if ind3 == invalidCharForNumber {
   266  			iter.head = i
   267  			iter.assertInteger()
   268  			return value*10 + uint64(ind2)
   269  		}
   270  		// iter.head = i + 1
   271  		// value = value * 100 + uint32(ind2) * 10 + uint32(ind3)
   272  		i++
   273  		ind4 := intDigits[iter.buf[i]]
   274  		if ind4 == invalidCharForNumber {
   275  			iter.head = i
   276  			iter.assertInteger()
   277  			return value*100 + uint64(ind2)*10 + uint64(ind3)
   278  		}
   279  		i++
   280  		ind5 := intDigits[iter.buf[i]]
   281  		if ind5 == invalidCharForNumber {
   282  			iter.head = i
   283  			iter.assertInteger()
   284  			return value*1000 + uint64(ind2)*100 + uint64(ind3)*10 + uint64(ind4)
   285  		}
   286  		i++
   287  		ind6 := intDigits[iter.buf[i]]
   288  		if ind6 == invalidCharForNumber {
   289  			iter.head = i
   290  			iter.assertInteger()
   291  			return value*10000 + uint64(ind2)*1000 + uint64(ind3)*100 + uint64(ind4)*10 + uint64(ind5)
   292  		}
   293  		i++
   294  		ind7 := intDigits[iter.buf[i]]
   295  		if ind7 == invalidCharForNumber {
   296  			iter.head = i
   297  			iter.assertInteger()
   298  			return value*100000 + uint64(ind2)*10000 + uint64(ind3)*1000 + uint64(ind4)*100 + uint64(ind5)*10 + uint64(ind6)
   299  		}
   300  		i++
   301  		ind8 := intDigits[iter.buf[i]]
   302  		if ind8 == invalidCharForNumber {
   303  			iter.head = i
   304  			iter.assertInteger()
   305  			return value*1000000 + uint64(ind2)*100000 + uint64(ind3)*10000 + uint64(ind4)*1000 + uint64(ind5)*100 + uint64(ind6)*10 + uint64(ind7)
   306  		}
   307  		i++
   308  		ind9 := intDigits[iter.buf[i]]
   309  		value = value*10000000 + uint64(ind2)*1000000 + uint64(ind3)*100000 + uint64(ind4)*10000 + uint64(ind5)*1000 + uint64(ind6)*100 + uint64(ind7)*10 + uint64(ind8)
   310  		iter.head = i
   311  		if ind9 == invalidCharForNumber {
   312  			iter.assertInteger()
   313  			return value
   314  		}
   315  	}
   316  	for {
   317  		for i := iter.head; i < iter.tail; i++ {
   318  			ind = intDigits[iter.buf[i]]
   319  			if ind == invalidCharForNumber {
   320  				iter.head = i
   321  				iter.assertInteger()
   322  				return value
   323  			}
   324  			if value > uint64SafeToMultiple10 {
   325  				value2 := (value << 3) + (value << 1) + uint64(ind)
   326  				if value2 < value {
   327  					iter.ReportError("readUint64", "overflow")
   328  					return
   329  				}
   330  				value = value2
   331  				continue
   332  			}
   333  			value = (value << 3) + (value << 1) + uint64(ind)
   334  		}
   335  		if !iter.loadMore() {
   336  			iter.assertInteger()
   337  			return value
   338  		}
   339  	}
   340  }
   341  
   342  func (iter *Iterator) assertInteger() {
   343  	if iter.head < iter.tail && iter.buf[iter.head] == '.' {
   344  		iter.ReportError("assertInteger", "can not decode float as int")
   345  	}
   346  }