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 }