github.com/anacrolix/torrent@v1.61.0/bencode/api.go (about)

     1  package bencode
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"reflect"
     8  
     9  	"github.com/anacrolix/missinggo/expect"
    10  )
    11  
    12  //----------------------------------------------------------------------------
    13  // Errors
    14  //----------------------------------------------------------------------------
    15  
    16  // In case if marshaler cannot encode a type, it will return this error. Typical
    17  // example of such type is float32/float64 which has no bencode representation.
    18  type MarshalTypeError struct {
    19  	Type reflect.Type
    20  }
    21  
    22  func (e *MarshalTypeError) Error() string {
    23  	return "bencode: unsupported type: " + e.Type.String()
    24  }
    25  
    26  // Unmarshal argument must be a non-nil value of some pointer type.
    27  type UnmarshalInvalidArgError struct {
    28  	Type reflect.Type
    29  }
    30  
    31  func (e *UnmarshalInvalidArgError) Error() string {
    32  	if e.Type == nil {
    33  		return "bencode: Unmarshal(nil)"
    34  	}
    35  
    36  	if e.Type.Kind() != reflect.Ptr {
    37  		return "bencode: Unmarshal(non-pointer " + e.Type.String() + ")"
    38  	}
    39  	return "bencode: Unmarshal(nil " + e.Type.String() + ")"
    40  }
    41  
    42  // Unmarshaler spotted a value that was not appropriate for a given Go value.
    43  type UnmarshalTypeError struct {
    44  	BencodeTypeName     string
    45  	UnmarshalTargetType reflect.Type
    46  }
    47  
    48  // This could probably be a value type, but we may already have users assuming
    49  // that it's passed by pointer.
    50  func (e *UnmarshalTypeError) Error() string {
    51  	return fmt.Sprintf(
    52  		"can't unmarshal a bencode %v into a %v",
    53  		e.BencodeTypeName,
    54  		e.UnmarshalTargetType,
    55  	)
    56  }
    57  
    58  // Unmarshaler tried to write to an unexported (therefore unwritable) field.
    59  type UnmarshalFieldError struct {
    60  	Key   string
    61  	Type  reflect.Type
    62  	Field reflect.StructField
    63  }
    64  
    65  func (e *UnmarshalFieldError) Error() string {
    66  	return "bencode: key \"" + e.Key + "\" led to an unexported field \"" +
    67  		e.Field.Name + "\" in type: " + e.Type.String()
    68  }
    69  
    70  // Malformed bencode input, unmarshaler failed to parse it.
    71  type SyntaxError struct {
    72  	Offset int64 // location of the error
    73  	What   error // error description
    74  }
    75  
    76  func (e *SyntaxError) Error() string {
    77  	return fmt.Sprintf("bencode: syntax error (offset: %d): %s", e.Offset, e.What)
    78  }
    79  
    80  // A non-nil error was returned after calling MarshalBencode on a type which
    81  // implements the Marshaler interface.
    82  type MarshalerError struct {
    83  	Type reflect.Type
    84  	Err  error
    85  }
    86  
    87  func (e *MarshalerError) Error() string {
    88  	return "bencode: error calling MarshalBencode for type " + e.Type.String() + ": " + e.Err.Error()
    89  }
    90  
    91  // A non-nil error was returned after calling UnmarshalBencode on a type which
    92  // implements the Unmarshaler interface.
    93  type UnmarshalerError struct {
    94  	Type reflect.Type
    95  	Err  error
    96  }
    97  
    98  func (e *UnmarshalerError) Error() string {
    99  	return "bencode: error calling UnmarshalBencode for type " + e.Type.String() + ": " + e.Err.Error()
   100  }
   101  
   102  //----------------------------------------------------------------------------
   103  // Interfaces
   104  //----------------------------------------------------------------------------
   105  
   106  // Any type which implements this interface, will be marshaled using the
   107  // specified method.
   108  type Marshaler interface {
   109  	MarshalBencode() ([]byte, error)
   110  }
   111  
   112  // Any type which implements this interface, will be unmarshaled using the
   113  // specified method.
   114  type Unmarshaler interface {
   115  	UnmarshalBencode([]byte) error
   116  }
   117  
   118  // Marshal the value 'v' to the bencode form, return the result as []byte and
   119  // an error if any.
   120  func Marshal(v interface{}) ([]byte, error) {
   121  	var buf bytes.Buffer
   122  	e := Encoder{w: &buf}
   123  	err := e.Encode(v)
   124  	if err != nil {
   125  		return nil, err
   126  	}
   127  	return buf.Bytes(), nil
   128  }
   129  
   130  func MustMarshal(v interface{}) []byte {
   131  	b, err := Marshal(v)
   132  	expect.Nil(err)
   133  	return b
   134  }
   135  
   136  // Unmarshal the bencode value in the 'data' to a value pointed by the 'v' pointer, return a non-nil
   137  // error if any. If there are trailing bytes, this results in ErrUnusedTrailingBytes, but the value
   138  // will be valid. It's probably more consistent to use Decoder.Decode if you want to rely on this
   139  // behaviour (inspired by Rust's serde here).
   140  func Unmarshal(data []byte, v interface{}) (err error) {
   141  	buf := bytes.NewReader(data)
   142  	dec := Decoder{r: buf}
   143  	err = dec.Decode(v)
   144  	if err != nil {
   145  		return
   146  	}
   147  	if buf.Len() != 0 {
   148  		return ErrUnusedTrailingBytes{buf.Len()}
   149  	}
   150  	return dec.ReadEOF()
   151  }
   152  
   153  type ErrUnusedTrailingBytes struct {
   154  	NumUnusedBytes int
   155  }
   156  
   157  func (me ErrUnusedTrailingBytes) Error() string {
   158  	return fmt.Sprintf("%d unused trailing bytes", me.NumUnusedBytes)
   159  }
   160  
   161  func NewDecoder(r io.Reader) *Decoder {
   162  	return &Decoder{r: &scanner{r: r}}
   163  }
   164  
   165  func NewEncoder(w io.Writer) *Encoder {
   166  	return &Encoder{w: w}
   167  }