github.com/moreal/bencodex-go@v0.0.0-20231021172012-18277a477d15/internal/decoder/int.go (about)

     1  package decoder
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"strconv"
     7  )
     8  
     9  var (
    10  	pow10i64 = [...]int64{
    11  		1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09,
    12  		1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18,
    13  	}
    14  	pow10i64Len = len(pow10i64)
    15  )
    16  
    17  func (d *Decoder) parseInt(data []byte) (int64, error) {
    18  	isNegative := false
    19  	if data[0] == '-' {
    20  		data = data[1:]
    21  		isNegative = true
    22  	}
    23  	maxDigit := len(data)
    24  	if maxDigit > pow10i64Len {
    25  		return 0, errors.New("bencode: invalid length of number")
    26  	}
    27  	sum := int64(0)
    28  	for i, b := range data {
    29  		if b < '0' || b > '9' {
    30  			return 0, errors.New("bencode: invalid integer byte: " + strconv.FormatUint(uint64(b), 10))
    31  		}
    32  		c := int64(b) - 48
    33  		digitValue := pow10i64[maxDigit-i-1]
    34  		sum += c * digitValue
    35  	}
    36  	if isNegative {
    37  		return -1 * sum, nil
    38  	}
    39  	return sum, nil
    40  }
    41  
    42  func (d *Decoder) decodeInt() (interface{}, error) {
    43  	d.cursor += 1
    44  	index := bytes.IndexByte(d.data[d.cursor:], 'e')
    45  	if index == -1 {
    46  		return nil, errors.New("bencode: invalid integer field")
    47  	}
    48  	index += d.cursor
    49  	integer, err := d.parseInt(d.data[d.cursor:index])
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  	d.cursor = index + 1
    54  	return integer, nil
    55  }