github.com/quantosnetwork/Quantos@v0.0.0-20220306172517-e20b28c5a29a/decoder/decoder.go (about)

     1  package decoder
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"github.com/quantosnetwork/Quantos/crypto"
     7  	"strconv"
     8  )
     9  
    10  type Decoder struct {
    11  	data   []byte
    12  	length int
    13  	cursor int
    14  }
    15  
    16  func (d *Decoder) Decode(data []byte) (interface{}, error) {
    17  	d.data = data
    18  	d.length = len(data)
    19  	return d.decode()
    20  }
    21  
    22  func (d *Decoder) decode() (interface{}, error) {
    23  	switch d.data[d.cursor] {
    24  	case 'i':
    25  		return d.decodeInt()
    26  	case 'l':
    27  		d.cursor += 1
    28  		list := []interface{}{}
    29  		for {
    30  			if d.cursor == d.length {
    31  				return nil, errors.New("bencode: invalid list field")
    32  			}
    33  			if d.data[d.cursor] == 'e' {
    34  				d.cursor += 1
    35  				return list, nil
    36  			}
    37  			value, err := d.decode()
    38  			if err != nil {
    39  				return nil, err
    40  			}
    41  			list = append(list, value)
    42  		}
    43  	case 'd':
    44  		d.cursor += 1
    45  		dictionary := map[string]interface{}{}
    46  		for {
    47  			if d.cursor == d.length {
    48  				return nil, errors.New("bencode: invalid dictionary field")
    49  			}
    50  			if d.data[d.cursor] == 'e' {
    51  				d.cursor += 1
    52  				return dictionary, nil
    53  			}
    54  			key, err := d.decodeBytes()
    55  			if err != nil {
    56  				return nil, errors.New("bencode: non-string dictionary key")
    57  			}
    58  			value, err := d.decode()
    59  			if err != nil {
    60  				return nil, err
    61  			}
    62  			dictionary[crypto.BytesToString(key)] = value
    63  		}
    64  	case 'h':
    65  		d.cursor += 1
    66  		hashtable := map[int]interface{}{}
    67  		for {
    68  			if d.cursor == d.length {
    69  				return nil, errors.New("quantos decoding: invalid hashtable")
    70  			}
    71  			if d.data[d.cursor] == 'e' {
    72  				d.cursor += 1
    73  				return hashtable, nil
    74  			}
    75  			key, err := d.decodeBytes()
    76  			if err != nil {
    77  				return nil, errors.New("bencode: non-string dictionary key")
    78  			}
    79  			value, err := d.decode()
    80  			if err != nil {
    81  				return nil, err
    82  			}
    83  			hashtable[crypto.BytesToInt(key)] = value
    84  		}
    85  
    86  	default:
    87  		return d.decodeBytes()
    88  	}
    89  }
    90  
    91  func (d *Decoder) decodeBytes() ([]byte, error) {
    92  	if d.data[d.cursor] < '0' || d.data[d.cursor] > '9' {
    93  		return nil, errors.New("quantos bytes decoder: invalid string field")
    94  	}
    95  	index := bytes.IndexByte(d.data[d.cursor:], ':')
    96  	if index == -1 {
    97  		return nil, errors.New("quantos bytes decoder:  invalid string field")
    98  	}
    99  	index += d.cursor
   100  	stringLength, err := d.parseInt(d.data[d.cursor:index])
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  	index += 1
   105  	endIndex := index + int(stringLength)
   106  	if endIndex > d.length {
   107  		return nil, errors.New("quantos bytes decoder: not a valid string")
   108  	}
   109  	value := d.data[index:endIndex]
   110  	d.cursor = endIndex
   111  	return value, nil
   112  }
   113  
   114  var (
   115  	pow10i64 = [...]int64{
   116  		1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09,
   117  		1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18,
   118  	}
   119  	pow10i64Len = len(pow10i64)
   120  )
   121  
   122  func (d *Decoder) parseInt(data []byte) (int64, error) {
   123  	isNegative := false
   124  	if data[0] == '-' {
   125  		data = data[1:]
   126  		isNegative = true
   127  	}
   128  	maxDigit := len(data)
   129  	if maxDigit > pow10i64Len {
   130  		return 0, errors.New("quantos int parser: invalid length of number")
   131  	}
   132  	sum := int64(0)
   133  	for i, b := range data {
   134  		if b < '0' || b > '9' {
   135  			return 0, errors.New("quantos int parser: invalid integer byte: " + strconv.FormatUint(uint64(b), 10))
   136  		}
   137  		c := int64(b) - 48
   138  		digitValue := pow10i64[maxDigit-i-1]
   139  		sum += c * digitValue
   140  	}
   141  	if isNegative {
   142  		return -1 * sum, nil
   143  	}
   144  	return sum, nil
   145  }
   146  
   147  func (d *Decoder) decodeInt() (interface{}, error) {
   148  	d.cursor += 1
   149  	index := bytes.IndexByte(d.data[d.cursor:], 'e')
   150  	if index == -1 {
   151  		return nil, errors.New("quantos int decoder: invalid integer field")
   152  	}
   153  	index += d.cursor
   154  	integer, err := d.parseInt(d.data[d.cursor:index])
   155  	if err != nil {
   156  		return nil, err
   157  	}
   158  	d.cursor = index + 1
   159  	return integer, nil
   160  }