From ac3b40ace3d42362fa4c48d59259b3347b5c2e56 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Wed, 15 Jun 2016 15:00:51 +1000 Subject: [PATCH] bencode: Remove private types encoder and decoder Instead the functionality is exposed directly on the public types. --- bencode/api.go | 40 ++++++---------------------------------- bencode/decode.go | 36 ++++++++++++++++++------------------ bencode/encode.go | 16 ++++++++-------- 3 files changed, 32 insertions(+), 60 deletions(-) diff --git a/bencode/api.go b/bencode/api.go index 89ac9d0e..08f0411f 100644 --- a/bencode/api.go +++ b/bencode/api.go @@ -109,16 +109,12 @@ type Unmarshaler interface { UnmarshalBencode([]byte) error } -//---------------------------------------------------------------------------- -// Stateless interface -//---------------------------------------------------------------------------- - // 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{Writer: bufio.NewWriter(&buf)} - err := e.encode(v) + e := Encoder{Writer: bufio.NewWriter(&buf)} + err := e.Encode(v) if err != nil { return nil, err } @@ -128,38 +124,14 @@ func Marshal(v interface{}) ([]byte, error) { // Unmarshal the bencode value in the 'data' to a value pointed by the 'v' // pointer, return a non-nil error if any. func Unmarshal(data []byte, v interface{}) error { - e := decoder{r: bytes.NewBuffer(data)} - return e.decode(v) -} - -//---------------------------------------------------------------------------- -// Stateful interface -//---------------------------------------------------------------------------- - -type Decoder struct { - d decoder + e := Decoder{r: bytes.NewBuffer(data)} + return e.Decode(v) } func NewDecoder(r io.Reader) *Decoder { - return &Decoder{decoder{r: bufio.NewReader(r)}} -} - -func (d *Decoder) Decode(v interface{}) error { - return d.d.decode(v) -} - -type Encoder struct { - e encoder + return &Decoder{r: bufio.NewReader(r)} } func NewEncoder(w io.Writer) *Encoder { - return &Encoder{encoder{Writer: bufio.NewWriter(w)}} -} - -func (e *Encoder) Encode(v interface{}) error { - err := e.e.encode(v) - if err != nil { - return err - } - return nil + return &Encoder{Writer: bufio.NewWriter(w)} } diff --git a/bencode/decode.go b/bencode/decode.go index ebd4684e..bdb978d7 100644 --- a/bencode/decode.go +++ b/bencode/decode.go @@ -12,7 +12,7 @@ import ( "strings" ) -type decoder struct { +type Decoder struct { r interface { io.ByteScanner io.Reader @@ -22,7 +22,7 @@ type decoder struct { key string } -func (d *decoder) decode(v interface{}) (err error) { +func (d *Decoder) Decode(v interface{}) (err error) { defer func() { if e := recover(); e != nil { if _, ok := e.(runtime.Error); ok { @@ -52,7 +52,7 @@ func check_for_unexpected_eof(err error, offset int64) { } } -func (d *decoder) read_byte() byte { +func (d *Decoder) read_byte() byte { b, err := d.r.ReadByte() if err != nil { check_for_unexpected_eof(err, d.offset) @@ -65,7 +65,7 @@ func (d *decoder) read_byte() byte { // reads data writing it to 'd.buf' until 'sep' byte is encountered, 'sep' byte // is consumed, but not included into the 'd.buf' -func (d *decoder) read_until(sep byte) { +func (d *Decoder) read_until(sep byte) { for { b := d.read_byte() if b == sep { @@ -84,7 +84,7 @@ func check_for_int_parse_error(err error, offset int64) { } } -func (d *decoder) throwSyntaxError(offset int64, err error) { +func (d *Decoder) throwSyntaxError(offset int64, err error) { panic(&SyntaxError{ Offset: offset, What: err, @@ -92,7 +92,7 @@ func (d *decoder) throwSyntaxError(offset int64, err error) { } // called when 'i' was consumed -func (d *decoder) parse_int(v reflect.Value) { +func (d *Decoder) parse_int(v reflect.Value) { start := d.offset - 1 d.read_until('e') if d.buf.Len() == 0 { @@ -138,7 +138,7 @@ func (d *decoder) parse_int(v reflect.Value) { d.buf.Reset() } -func (d *decoder) parse_string(v reflect.Value) { +func (d *Decoder) parse_string(v reflect.Value) { start := d.offset - 1 // read the string length first @@ -180,7 +180,7 @@ func (d *decoder) parse_string(v reflect.Value) { d.buf.Reset() } -func (d *decoder) parse_dict(v reflect.Value) { +func (d *Decoder) parse_dict(v reflect.Value) { switch v.Kind() { case reflect.Map: t := v.Type() @@ -284,7 +284,7 @@ func (d *decoder) parse_dict(v reflect.Value) { } } -func (d *decoder) parse_list(v reflect.Value) { +func (d *Decoder) parse_list(v reflect.Value) { switch v.Kind() { case reflect.Array, reflect.Slice: default: @@ -330,7 +330,7 @@ func (d *decoder) parse_list(v reflect.Value) { } } -func (d *decoder) read_one_value() bool { +func (d *Decoder) read_one_value() bool { b, err := d.r.ReadByte() if err != nil { panic(err) @@ -381,7 +381,7 @@ func (d *decoder) read_one_value() bool { } -func (d *decoder) parse_unmarshaler(v reflect.Value) bool { +func (d *Decoder) parse_unmarshaler(v reflect.Value) bool { m, ok := v.Interface().(Unmarshaler) if !ok { // T doesn't work, try *T @@ -409,7 +409,7 @@ func (d *decoder) parse_unmarshaler(v reflect.Value) bool { // Returns true if there was a value and it's now stored in 'v', otherwise // there was an end symbol ("e") and no value was stored. -func (d *decoder) parse_value(v reflect.Value) bool { +func (d *Decoder) parse_value(v reflect.Value) bool { // we support one level of indirection at the moment if v.Kind() == reflect.Ptr { // if the pointer is nil, allocate a new element of the type it @@ -462,14 +462,14 @@ func (d *decoder) parse_value(v reflect.Value) bool { } // An unknown bencode type character was encountered. -func (d *decoder) raiseUnknownValueType(b byte, offset int64) { +func (d *Decoder) raiseUnknownValueType(b byte, offset int64) { panic(&SyntaxError{ Offset: offset, What: fmt.Errorf("unknown value type %+q", b), }) } -func (d *decoder) parse_value_interface() (interface{}, bool) { +func (d *Decoder) parse_value_interface() (interface{}, bool) { b, err := d.r.ReadByte() if err != nil { panic(err) @@ -498,7 +498,7 @@ func (d *decoder) parse_value_interface() (interface{}, bool) { } } -func (d *decoder) parse_int_interface() (ret interface{}) { +func (d *Decoder) parse_int_interface() (ret interface{}) { start := d.offset - 1 d.read_until('e') if d.buf.Len() == 0 { @@ -528,7 +528,7 @@ func (d *decoder) parse_int_interface() (ret interface{}) { return } -func (d *decoder) parse_string_interface() interface{} { +func (d *Decoder) parse_string_interface() interface{} { start := d.offset - 1 // read the string length first @@ -552,7 +552,7 @@ func (d *decoder) parse_string_interface() interface{} { return s } -func (d *decoder) parse_dict_interface() interface{} { +func (d *Decoder) parse_dict_interface() interface{} { dict := make(map[string]interface{}) for { keyi, ok := d.parse_value_interface() @@ -578,7 +578,7 @@ func (d *decoder) parse_dict_interface() interface{} { return dict } -func (d *decoder) parse_list_interface() interface{} { +func (d *Decoder) parse_list_interface() interface{} { var list []interface{} for { valuei, ok := d.parse_value_interface() diff --git a/bencode/encode.go b/bencode/encode.go index 54250af3..bfe208df 100644 --- a/bencode/encode.go +++ b/bencode/encode.go @@ -15,12 +15,12 @@ func is_empty_value(v reflect.Value) bool { return missinggo.IsEmptyValue(v) } -type encoder struct { +type Encoder struct { *bufio.Writer scratch [64]byte } -func (e *encoder) encode(v interface{}) (err error) { +func (e *Encoder) Encode(v interface{}) (err error) { if v == nil { return } @@ -47,28 +47,28 @@ func (sv string_values) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } func (sv string_values) Less(i, j int) bool { return sv.get(i) < sv.get(j) } func (sv string_values) get(i int) string { return sv[i].String() } -func (e *encoder) write(s []byte) { +func (e *Encoder) write(s []byte) { _, err := e.Write(s) if err != nil { panic(err) } } -func (e *encoder) write_string(s string) { +func (e *Encoder) write_string(s string) { _, err := e.WriteString(s) if err != nil { panic(err) } } -func (e *encoder) reflect_string(s string) { +func (e *Encoder) reflect_string(s string) { b := strconv.AppendInt(e.scratch[:0], int64(len(s)), 10) e.write(b) e.write_string(":") e.write_string(s) } -func (e *encoder) reflect_byte_slice(s []byte) { +func (e *Encoder) reflect_byte_slice(s []byte) { b := strconv.AppendInt(e.scratch[:0], int64(len(s)), 10) e.write(b) e.write_string(":") @@ -77,7 +77,7 @@ func (e *encoder) reflect_byte_slice(s []byte) { // returns true if the value implements Marshaler interface and marshaling was // done successfully -func (e *encoder) reflect_marshaler(v reflect.Value) bool { +func (e *Encoder) reflect_marshaler(v reflect.Value) bool { m, ok := v.Interface().(Marshaler) if !ok { // T doesn't work, try *T @@ -100,7 +100,7 @@ func (e *encoder) reflect_marshaler(v reflect.Value) bool { return false } -func (e *encoder) reflect_value(v reflect.Value) { +func (e *Encoder) reflect_value(v reflect.Value) { if e.reflect_marshaler(v) { return -- 2.48.1