]> Sergey Matveev's repositories - btrtrc.git/blob - bencode/api.go
vgo get -u
[btrtrc.git] / bencode / api.go
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         Value string
45         Type  reflect.Type
46 }
47
48 func (e *UnmarshalTypeError) Error() string {
49         return "bencode: value (" + e.Value + ") is not appropriate for type: " +
50                 e.Type.String()
51 }
52
53 // Unmarshaler tried to write to an unexported (therefore unwritable) field.
54 type UnmarshalFieldError struct {
55         Key   string
56         Type  reflect.Type
57         Field reflect.StructField
58 }
59
60 func (e *UnmarshalFieldError) Error() string {
61         return "bencode: key \"" + e.Key + "\" led to an unexported field \"" +
62                 e.Field.Name + "\" in type: " + e.Type.String()
63 }
64
65 // Malformed bencode input, unmarshaler failed to parse it.
66 type SyntaxError struct {
67         Offset int64 // location of the error
68         What   error // error description
69 }
70
71 func (e *SyntaxError) Error() string {
72         return fmt.Sprintf("bencode: syntax error (offset: %d): %s", e.Offset, e.What)
73 }
74
75 // A non-nil error was returned after calling MarshalBencode on a type which
76 // implements the Marshaler interface.
77 type MarshalerError struct {
78         Type reflect.Type
79         Err  error
80 }
81
82 func (e *MarshalerError) Error() string {
83         return "bencode: error calling MarshalBencode for type " + e.Type.String() + ": " + e.Err.Error()
84 }
85
86 // A non-nil error was returned after calling UnmarshalBencode on a type which
87 // implements the Unmarshaler interface.
88 type UnmarshalerError struct {
89         Type reflect.Type
90         Err  error
91 }
92
93 func (e *UnmarshalerError) Error() string {
94         return "bencode: error calling UnmarshalBencode for type " + e.Type.String() + ": " + e.Err.Error()
95 }
96
97 //----------------------------------------------------------------------------
98 // Interfaces
99 //----------------------------------------------------------------------------
100
101 // Any type which implements this interface, will be marshaled using the
102 // specified method.
103 type Marshaler interface {
104         MarshalBencode() ([]byte, error)
105 }
106
107 // Any type which implements this interface, will be unmarshaled using the
108 // specified method.
109 type Unmarshaler interface {
110         UnmarshalBencode([]byte) error
111 }
112
113 // Marshal the value 'v' to the bencode form, return the result as []byte and
114 // an error if any.
115 func Marshal(v interface{}) ([]byte, error) {
116         var buf bytes.Buffer
117         e := Encoder{w: &buf}
118         err := e.Encode(v)
119         if err != nil {
120                 return nil, err
121         }
122         return buf.Bytes(), nil
123 }
124
125 func MustMarshal(v interface{}) []byte {
126         b, err := Marshal(v)
127         expect.Nil(err)
128         return b
129 }
130
131 // Unmarshal the bencode value in the 'data' to a value pointed by the 'v'
132 // pointer, return a non-nil error if any.
133 func Unmarshal(data []byte, v interface{}) (err error) {
134         buf := bytes.NewBuffer(data)
135         e := Decoder{r: buf}
136         err = e.Decode(v)
137         if err == nil && buf.Len() != 0 {
138                 err = ErrUnusedTrailingBytes{buf.Len()}
139         }
140         return
141 }
142
143 type ErrUnusedTrailingBytes struct {
144         NumUnusedBytes int
145 }
146
147 func (me ErrUnusedTrailingBytes) Error() string {
148         return fmt.Sprintf("%d unused trailing bytes", me.NumUnusedBytes)
149 }
150
151 func NewDecoder(r io.Reader) *Decoder {
152         return &Decoder{r: &scanner{r: r}}
153 }
154
155 func NewEncoder(w io.Writer) *Encoder {
156         return &Encoder{w: w}
157 }