github.com/moreal/bencodex-go@v0.0.0-20231021172012-18277a477d15/internal/decoder/decoder.go (about) 1 package decoder 2 3 import ( 4 "errors" 5 bencodex "github.com/moreal/bencodex-go/internal" 6 ) 7 8 type Decoder struct { 9 data []byte 10 length int 11 cursor int 12 } 13 14 func (d *Decoder) Decode(data []byte) (interface{}, error) { 15 d.data = data 16 d.length = len(data) 17 return d.decode() 18 } 19 20 func (d *Decoder) decode() (interface{}, error) { 21 switch d.data[d.cursor] { 22 case 'i': 23 return d.decodeInt() 24 case 'n': 25 d.cursor += 1 26 return nil, nil 27 case 't': 28 d.cursor += 1 29 return true, nil 30 case 'f': 31 d.cursor += 1 32 return false, nil 33 case 'l': 34 d.cursor += 1 35 list := []interface{}{} 36 for { 37 if d.cursor == d.length { 38 return nil, errors.New("bencode: invalid list field") 39 } 40 if d.data[d.cursor] == 'e' { 41 d.cursor += 1 42 return list, nil 43 } 44 value, err := d.decode() 45 if err != nil { 46 return nil, err 47 } 48 list = append(list, value) 49 } 50 case 'd': 51 d.cursor += 1 52 dictionary := map[bencodex.BencodexBytesLike]interface{}{} 53 for { 54 if d.cursor == d.length { 55 return nil, errors.New("bencode: invalid dictionary field") 56 } 57 if d.data[d.cursor] == 'e' { 58 d.cursor += 1 59 return dictionary, nil 60 } 61 var ( 62 key bencodex.BencodexBytesLike 63 err error 64 ) 65 if '0' <= d.data[d.cursor] && d.data[d.cursor] <= '9' { 66 key, err = d.decodeBytes(false) 67 } 68 69 if d.data[d.cursor] == 'u' { 70 d.cursor += 1 71 key, err = d.decodeBytes(true) 72 } 73 74 if err != nil { 75 return nil, errors.New("bencode: non-string dictionary key") 76 } 77 value, err := d.decode() 78 if err != nil { 79 return nil, err 80 } 81 dictionary[key] = value 82 } 83 case 'u': 84 d.cursor += 1 85 unicode, err := d.decodeBytes(true) 86 if err != nil { 87 return nil, err 88 } 89 90 return unicode, nil 91 default: 92 return d.decodeBytes(false) 93 } 94 }