]> Sergey Matveev's repositories - btrtrc.git/blob - bencode/decode.go
Initial commit.
[btrtrc.git] / bencode / decode.go
1 package bencode
2
3 import "reflect"
4 import "runtime"
5 import "bufio"
6 import "bytes"
7 import "strconv"
8 import "strings"
9 import "io"
10
11 type decoder struct {
12         *bufio.Reader
13         offset int64
14         buf    bytes.Buffer
15         key    string
16 }
17
18 func (d *decoder) decode(v interface{}) (err error) {
19         var _ runtime.Error
20         /*
21                 defer func() {
22                         if e := recover(); e != nil {
23                                 if _, ok := e.(runtime.Error); ok {
24                                         panic(e)
25                                 }
26                                 err = e.(error)
27                         }
28                 }()
29         */
30
31         pv := reflect.ValueOf(v)
32         if pv.Kind() != reflect.Ptr || pv.IsNil() {
33                 return &UnmarshalInvalidArgError{reflect.TypeOf(v)}
34         }
35
36         d.parse_value(pv.Elem())
37         return nil
38 }
39
40 func check_for_unexpected_eof(err error, offset int64) {
41         if err == io.EOF {
42                 panic(&SyntaxError{
43                         Offset: offset,
44                         what:   "unexpected EOF",
45                 })
46         }
47 }
48
49 func (d *decoder) read_byte() byte {
50         b, err := d.ReadByte()
51         if err != nil {
52                 check_for_unexpected_eof(err, d.offset)
53                 panic(err)
54         }
55
56         d.offset++
57         return b
58 }
59
60 // reads data writing it to 'd.buf' until 'sep' byte is encountered, 'sep' byte
61 // is consumed, but not included into the 'd.buf'
62 func (d *decoder) read_until(sep byte) {
63         for {
64                 b := d.read_byte()
65                 if b == sep {
66                         return
67                 }
68                 d.buf.WriteByte(b)
69         }
70 }
71
72 func check_for_int_parse_error(err error, offset int64) {
73         if err != nil {
74                 panic(&SyntaxError{
75                         Offset: offset,
76                         what:   err.Error(),
77                 })
78         }
79 }
80
81 // called when 'i' was consumed
82 func (d *decoder) parse_int(v reflect.Value) {
83         start := d.offset - 1
84         d.read_until('e')
85         if d.buf.Len() == 0 {
86                 panic(&SyntaxError{
87                         Offset: start,
88                         what:   "empty integer value",
89                 })
90         }
91
92         switch v.Kind() {
93         case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
94                 n, err := strconv.ParseInt(d.buf.String(), 10, 64)
95                 check_for_int_parse_error(err, start)
96
97                 if v.OverflowInt(n) {
98                         panic(&UnmarshalTypeError{
99                                 Value: "integer " + d.buf.String(),
100                                 Type:  v.Type(),
101                         })
102                 }
103                 v.SetInt(n)
104         case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
105                 n, err := strconv.ParseUint(d.buf.String(), 10, 64)
106                 check_for_int_parse_error(err, start)
107
108                 if v.OverflowUint(n) {
109                         panic(&UnmarshalTypeError{
110                                 Value: "integer " + d.buf.String(),
111                                 Type:  v.Type(),
112                         })
113                 }
114                 v.SetUint(n)
115         case reflect.Bool:
116                 if d.buf.Len() == 1 && d.buf.Bytes()[0] == '0' {
117                         v.SetBool(false)
118                 }
119                 v.SetBool(true)
120         default:
121                 panic(&UnmarshalTypeError{
122                         Value: "integer " + d.buf.String(),
123                         Type:  v.Type(),
124                 })
125         }
126         d.buf.Reset()
127 }
128
129 func (d *decoder) parse_string(v reflect.Value) {
130         start := d.offset - 1
131
132         // read the string length first
133         d.read_until(':')
134         length, err := strconv.ParseInt(d.buf.String(), 10, 64)
135         check_for_int_parse_error(err, start)
136
137         d.buf.Reset()
138         n, err := io.CopyN(&d.buf, d, length)
139         d.offset += n
140         if err != nil {
141                 check_for_unexpected_eof(err, d.offset)
142                 panic(&SyntaxError{
143                         Offset: d.offset,
144                         what:   "unexpected I/O error: " + err.Error(),
145                 })
146         }
147
148         switch v.Kind() {
149         case reflect.String:
150                 v.SetString(d.buf.String())
151         case reflect.Slice:
152                 if v.Type().Elem().Kind() != reflect.Uint8 {
153                         panic(&UnmarshalTypeError{
154                                 Value: "string",
155                                 Type:  v.Type(),
156                         })
157                 }
158                 v.Set(reflect.ValueOf(d.buf.Bytes()))
159         default:
160                 panic(&UnmarshalTypeError{
161                         Value: "string",
162                         Type:  v.Type(),
163                 })
164         }
165
166         d.buf.Reset()
167 }
168
169 func (d *decoder) parse_dict(v reflect.Value) {
170         switch v.Kind() {
171         case reflect.Map:
172                 t := v.Type()
173                 if t.Key().Kind() != reflect.String {
174                         panic(&UnmarshalTypeError{
175                                 Value: "object",
176                                 Type:  t,
177                         })
178                 }
179                 if v.IsNil() {
180                         v.Set(reflect.MakeMap(t))
181                 }
182         case reflect.Struct:
183         default:
184                 panic(&UnmarshalTypeError{
185                         Value: "object",
186                         Type:  v.Type(),
187                 })
188         }
189
190         var map_elem reflect.Value
191
192         // so, at this point 'd' byte was consumed, let's just read key/value
193         // pairs one by one
194         for {
195                 var valuev reflect.Value
196                 keyv := reflect.ValueOf(&d.key).Elem()
197                 if !d.parse_value(keyv) {
198                         return
199                 }
200
201                 // get valuev as a map value or as a struct field
202                 switch v.Kind() {
203                 case reflect.Map:
204                         elem_type := v.Type().Elem()
205                         if !map_elem.IsValid() {
206                                 map_elem = reflect.New(elem_type).Elem()
207                         } else {
208                                 map_elem.Set(reflect.Zero(elem_type))
209                         }
210                         valuev = map_elem
211                 case reflect.Struct:
212                         var f reflect.StructField
213                         var ok bool
214
215                         t := v.Type()
216                         for i, n := 0, t.NumField(); i < n; i++ {
217                                 f = t.Field(i)
218                                 tag := f.Tag.Get("bencode")
219                                 if tag == "-" {
220                                         continue
221                                 }
222                                 if f.Anonymous {
223                                         continue
224                                 }
225
226                                 tag_name, _ := parse_tag(tag)
227                                 if tag_name == d.key {
228                                         ok = true
229                                         break
230                                 }
231
232                                 if f.Name == d.key {
233                                         ok = true
234                                         break
235                                 }
236
237                                 if strings.EqualFold(f.Name, d.key) {
238                                         ok = true
239                                         break
240                                 }
241                         }
242
243                         if ok {
244                                 if f.PkgPath != "" {
245                                         panic(&UnmarshalFieldError{
246                                                 Key:   d.key,
247                                                 Type:  v.Type(),
248                                                 Field: f,
249                                         })
250                                 } else {
251                                         valuev = v.FieldByIndex(f.Index)
252                                 }
253                         } else {
254                                 _, ok := d.parse_value_interface()
255                                 if !ok {
256                                         panic(&SyntaxError{
257                                                 Offset: d.offset,
258                                                 what:   "unexpected end of dict, no matching value for a given key",
259                                         })
260                                 }
261                                 continue
262                         }
263                 }
264
265                 // now we need to actually parse it
266                 if !d.parse_value(valuev) {
267                         panic(&SyntaxError{
268                                 Offset: d.offset,
269                                 what:   "unexpected end of dict, no matching value for a given key",
270                         })
271                 }
272
273                 if v.Kind() == reflect.Map {
274                         v.SetMapIndex(keyv, valuev)
275                 }
276         }
277 }
278
279 func (d *decoder) parse_list(v reflect.Value) {
280         switch v.Kind() {
281         case reflect.Array, reflect.Slice:
282         default:
283                 panic(&UnmarshalTypeError{
284                         Value: "array",
285                         Type:  v.Type(),
286                 })
287         }
288
289         i := 0
290         for {
291                 if v.Kind() == reflect.Slice && i >= v.Len() {
292                         v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem())))
293                 }
294
295                 ok := false
296                 if i < v.Len() {
297                         ok = d.parse_value(v.Index(i))
298                 } else {
299                         _, ok = d.parse_value_interface()
300                 }
301
302                 if !ok {
303                         break
304                 }
305
306                 i++
307         }
308
309         if i < v.Len() {
310                 if v.Kind() == reflect.Array {
311                         z := reflect.Zero(v.Type().Elem())
312                         for n := v.Len(); i < n; i++ {
313                                 v.Index(i).Set(z)
314                         }
315                 } else {
316                         v.SetLen(i)
317                 }
318         }
319
320         if i == 0 && v.Kind() == reflect.Slice {
321                 v.Set(reflect.MakeSlice(v.Type(), 0, 0))
322         }
323 }
324
325 // returns true if there was a value and it's now stored in 'v', otherwise there
326 // was an end symbol ("e") and no value was stored
327 func (d *decoder) parse_value(v reflect.Value) bool {
328         if pv := v; pv.Kind() == reflect.Ptr {
329                 // if the pointer is nil, allocate a new element of the type it
330                 // points to
331                 if pv.IsNil() {
332                         pv.Set(reflect.New(pv.Type().Elem()))
333                 }
334                 v = pv.Elem()
335         }
336
337         // common case
338         if v.Kind() == reflect.Interface {
339                 iface, _ := d.parse_value_interface()
340                 v.Set(reflect.ValueOf(iface))
341                 return true
342         }
343
344         b, err := d.ReadByte()
345         if err != nil {
346                 panic(err)
347         }
348         d.offset++
349
350         switch b {
351         case 'e':
352                 return false
353         case 'd':
354                 d.parse_dict(v)
355         case 'l':
356                 d.parse_list(v)
357         case 'i':
358                 d.parse_int(v)
359         default:
360                 if b >= '0' && b <= '9' {
361                         // string
362                         // append first digit of the length to the buffer
363                         d.buf.WriteByte(b)
364                         d.parse_string(v)
365                         break
366                 }
367
368                 // unknown value
369                 panic(&SyntaxError{
370                         Offset: d.offset - 1,
371                         what:   "unknown value type (invalid bencode?)",
372                 })
373         }
374
375         return true
376 }
377
378 func (d *decoder) parse_value_interface() (interface{}, bool) {
379         b, err := d.ReadByte()
380         if err != nil {
381                 panic(err)
382         }
383         d.offset++
384
385         switch b {
386         case 'e':
387                 return nil, false
388         case 'd':
389                 return d.parse_dict_interface(), true
390         case 'l':
391                 return d.parse_list_interface(), true
392         case 'i':
393                 return d.parse_int_interface(), true
394         default:
395                 if b >= '0' && b <= '9' {
396                         // string
397                         // append first digit of the length to the buffer
398                         d.buf.WriteByte(b)
399                         return d.parse_string_interface(), true
400                 }
401
402                 // unknown value
403                 panic(&SyntaxError{
404                         Offset: d.offset - 1,
405                         what:   "unknown value type (invalid bencode?)",
406                 })
407         }
408         panic("unreachable")
409 }
410
411 func (d *decoder) parse_int_interface() interface{} {
412         start := d.offset - 1
413         d.read_until('e')
414         if d.buf.Len() == 0 {
415                 panic(&SyntaxError{
416                         Offset: start,
417                         what:   "empty integer value",
418                 })
419         }
420
421         n, err := strconv.ParseInt(d.buf.String(), 10, 64)
422         check_for_int_parse_error(err, start)
423         d.buf.Reset()
424         return n
425 }
426
427 func (d *decoder) parse_string_interface() interface{} {
428         start := d.offset - 1
429
430         // read the string length first
431         d.read_until(':')
432         length, err := strconv.ParseInt(d.buf.String(), 10, 64)
433         check_for_int_parse_error(err, start)
434
435         d.buf.Reset()
436         n, err := io.CopyN(&d.buf, d, length)
437         d.offset += n
438         if err != nil {
439                 check_for_unexpected_eof(err, d.offset)
440                 panic(&SyntaxError{
441                         Offset: d.offset,
442                         what:   "unexpected I/O error: " + err.Error(),
443                 })
444         }
445
446         s := d.buf.String()
447         d.buf.Reset()
448         return s
449 }
450
451 func (d *decoder) parse_dict_interface() interface{} {
452         dict := make(map[string]interface{})
453         for {
454                 keyi, ok := d.parse_value_interface()
455                 if !ok {
456                         break
457                 }
458
459                 key, ok := keyi.(string)
460                 if !ok {
461                         panic(&SyntaxError{
462                                 Offset: d.offset,
463                                 what:   "non-string key in a dict",
464                         })
465                 }
466
467                 valuei, ok := d.parse_value_interface()
468                 if !ok {
469                         panic(&SyntaxError{
470                                 Offset: d.offset,
471                                 what:   "unexpected end of dict, no matching value for a given key",
472                         })
473                 }
474
475                 dict[key] = valuei
476         }
477         return dict
478 }
479
480 func (d *decoder) parse_list_interface() interface{} {
481         var list []interface{}
482         for {
483                 valuei, ok := d.parse_value_interface()
484                 if !ok {
485                         break
486                 }
487
488                 list = append(list, valuei)
489         }
490         return list
491 }