| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- package bencode
- import (
- "bytes"
- "fmt"
- "io"
- "reflect"
- "github.com/anacrolix/missinggo/expect"
- )
- //----------------------------------------------------------------------------
- // Errors
- //----------------------------------------------------------------------------
- // In case if marshaler cannot encode a type, it will return this error. Typical
- // example of such type is float32/float64 which has no bencode representation.
- type MarshalTypeError struct {
- Type reflect.Type
- }
- func (e *MarshalTypeError) Error() string {
- return "bencode: unsupported type: " + e.Type.String()
- }
- // Unmarshal argument must be a non-nil value of some pointer type.
- type UnmarshalInvalidArgError struct {
- Type reflect.Type
- }
- func (e *UnmarshalInvalidArgError) Error() string {
- if e.Type == nil {
- return "bencode: Unmarshal(nil)"
- }
- if e.Type.Kind() != reflect.Ptr {
- return "bencode: Unmarshal(non-pointer " + e.Type.String() + ")"
- }
- return "bencode: Unmarshal(nil " + e.Type.String() + ")"
- }
- // Unmarshaler spotted a value that was not appropriate for a given Go value.
- type UnmarshalTypeError struct {
- BencodeTypeName string
- UnmarshalTargetType reflect.Type
- }
- // This could probably be a value type, but we may already have users assuming
- // that it's passed by pointer.
- func (e *UnmarshalTypeError) Error() string {
- return fmt.Sprintf(
- "can't unmarshal a bencode %v into a %v",
- e.BencodeTypeName,
- e.UnmarshalTargetType,
- )
- }
- // Unmarshaler tried to write to an unexported (therefore unwritable) field.
- type UnmarshalFieldError struct {
- Key string
- Type reflect.Type
- Field reflect.StructField
- }
- func (e *UnmarshalFieldError) Error() string {
- return "bencode: key \"" + e.Key + "\" led to an unexported field \"" +
- e.Field.Name + "\" in type: " + e.Type.String()
- }
- // Malformed bencode input, unmarshaler failed to parse it.
- type SyntaxError struct {
- Offset int64 // location of the error
- What error // error description
- }
- func (e *SyntaxError) Error() string {
- return fmt.Sprintf("bencode: syntax error (offset: %d): %s", e.Offset, e.What)
- }
- // A non-nil error was returned after calling MarshalBencode on a type which
- // implements the Marshaler interface.
- type MarshalerError struct {
- Type reflect.Type
- Err error
- }
- func (e *MarshalerError) Error() string {
- return "bencode: error calling MarshalBencode for type " + e.Type.String() + ": " + e.Err.Error()
- }
- // A non-nil error was returned after calling UnmarshalBencode on a type which
- // implements the Unmarshaler interface.
- type UnmarshalerError struct {
- Type reflect.Type
- Err error
- }
- func (e *UnmarshalerError) Error() string {
- return "bencode: error calling UnmarshalBencode for type " + e.Type.String() + ": " + e.Err.Error()
- }
- //----------------------------------------------------------------------------
- // Interfaces
- //----------------------------------------------------------------------------
- // Any type which implements this interface, will be marshaled using the
- // specified method.
- type Marshaler interface {
- MarshalBencode() ([]byte, error)
- }
- // Any type which implements this interface, will be unmarshaled using the
- // specified method.
- type Unmarshaler interface {
- UnmarshalBencode([]byte) error
- }
- // Marshal the value 'v' to the bencode form, return the result as []byte and
- // an error if any.
- func Marshal(v interface{}) ([]byte, error) {
- var buf bytes.Buffer
- e := Encoder{w: &buf}
- err := e.Encode(v)
- if err != nil {
- return nil, err
- }
- return buf.Bytes(), nil
- }
- func MustMarshal(v interface{}) []byte {
- b, err := Marshal(v)
- expect.Nil(err)
- return b
- }
- // Unmarshal the bencode value in the 'data' to a value pointed by the 'v' pointer, return a non-nil
- // error if any. If there are trailing bytes, this results in ErrUnusedTrailingBytes, but the value
- // will be valid. It's probably more consistent to use Decoder.Decode if you want to rely on this
- // behaviour (inspired by Rust's serde here).
- func Unmarshal(data []byte, v interface{}) (err error) {
- buf := bytes.NewReader(data)
- dec := Decoder{r: buf}
- err = dec.Decode(v)
- if err != nil {
- return
- }
- if buf.Len() != 0 {
- return ErrUnusedTrailingBytes{buf.Len()}
- }
- return dec.ReadEOF()
- }
- type ErrUnusedTrailingBytes struct {
- NumUnusedBytes int
- }
- func (me ErrUnusedTrailingBytes) Error() string {
- return fmt.Sprintf("%d unused trailing bytes", me.NumUnusedBytes)
- }
- func NewDecoder(r io.Reader) *Decoder {
- return &Decoder{r: &scanner{r: r}}
- }
- func NewEncoder(w io.Writer) *Encoder {
- return &Encoder{w: w}
- }
|