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  }