aboutsummaryrefslogtreecommitdiff
path: root/bencode
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2016-06-11 01:46:33 +0200
committerDimitri Sokolyuk <demon@dim13.org>2016-06-11 01:46:33 +0200
commita75f52e481d787bd57530114852696bb59a62b82 (patch)
treeed4bd6df9069868a117c57d13a0ccc688f66aca5 /bencode
parent9e26bb7935e283cd2efb6ce3956e193f3a908412 (diff)
marshal
Diffstat (limited to 'bencode')
-rw-r--r--bencode/bencode.go68
-rw-r--r--bencode/bencode_test.go20
2 files changed, 87 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, ""
+}
diff --git a/bencode/bencode_test.go b/bencode/bencode_test.go
index c69aa05..f9018b2 100644
--- a/bencode/bencode_test.go
+++ b/bencode/bencode_test.go
@@ -1 +1,21 @@
package bencode
+
+import (
+ "testing"
+
+ "dim13.org/btr/torrent"
+)
+
+func TestMarshal(t *testing.T) {
+ v := torrent.Torrent{
+ Announce: "test",
+ AnnounceList: []string{"test1", "test2", "test3"},
+ Comment: "comment",
+ CreationDate: 123,
+ }
+ out, err := Marshal(v)
+ if err != nil {
+ t.Error(err)
+ }
+ t.Logf("%q\n", string(out))
+}