aboutsummaryrefslogtreecommitdiff
path: root/bencode/bencode.go
diff options
context:
space:
mode:
Diffstat (limited to 'bencode/bencode.go')
-rw-r--r--bencode/bencode.go68
1 files changed, 67 insertions, 1 deletions
diff --git a/bencode/bencode.go b/bencode/bencode.go
index f1fce2f..532ac8a 100644
--- a/bencode/bencode.go
+++ b/bencode/bencode.go
@@ -1,5 +1,15 @@
package bencode
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "reflect"
+ "strings"
+)
+
// mapping / limitations
// dict -> struct
// list -> aray of same type
@@ -14,10 +24,66 @@ const (
itemString
)
+var ErrValue = errors.New("invalid value")
+
func Marshal(v interface{}) ([]byte, error) {
- return nil, nil
+ var out bytes.Buffer
+ val := reflect.ValueOf(v)
+ err := marshalField(&out, val)
+ return out.Bytes(), err
+}
+
+func marshalField(out io.Writer, v reflect.Value) error {
+ if !v.IsValid() {
+ return ErrValue
+ }
+ log.Println(v.Kind())
+ switch v.Kind() {
+ case reflect.String:
+ marshalString(out, v.String())
+ case reflect.Int:
+ marshalInt(out, v.Int())
+ case reflect.Slice:
+ fmt.Fprint(out, "l")
+ for i := 0; i < v.Len(); i++ {
+ marshalField(out, v.Index(i))
+ }
+ fmt.Fprint(out, "e")
+ case reflect.Struct:
+ t := v.Type()
+ fmt.Fprint(out, "d")
+ for i := 0; i < t.NumField(); i++ {
+ tag := t.Field(i).Tag.Get("bencode")
+ if tag == "-" {
+ continue
+ }
+ name, _ := parseTag(tag)
+ if name == "" {
+ name = t.Field(i).Name
+ }
+ marshalString(out, name)
+ marshalField(out, v.Field(i))
+ }
+ fmt.Fprint(out, "e")
+ }
+ return nil
+}
+
+func marshalString(out io.Writer, s string) {
+ fmt.Fprintf(out, "%d:%s", len(s), s)
+}
+
+func marshalInt(out io.Writer, i int64) {
+ fmt.Fprintf(out, "i%de", i)
}
func Unmarshal(data []byte, v interface{}) error {
return nil
}
+
+func parseTag(tag string) (string, string) {
+ if i := strings.Index(tag, ","); i != -1 {
+ return tag[:i], tag[i+1:]
+ }
+ return tag, ""
+}