-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgopatch
103 lines (98 loc) · 3 KB
/
gopatch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
diff -r d1b75410b793 src/pkg/encoding/binary/binary.go
--- a/src/pkg/encoding/binary/binary.go Tue Nov 17 18:21:47 2009 -0800
+++ b/src/pkg/encoding/binary/binary.go Fri Dec 04 12:32:48 2009 +0300
@@ -120,8 +120,15 @@
// r are decoded using the specified byte order and written
// to successive fields of the data.
func Read(r io.Reader, order ByteOrder, data interface{}) os.Error {
- v := reflect.NewValue(data).(*reflect.PtrValue).Elem();
- size := sizeof(v.Type());
+ var ptr *reflect.PtrValue;
+ var v reflect.Value;
+ ptr, ok := reflect.NewValue(data).(*reflect.PtrValue);
+ if ok {
+ v = ptr.Elem();
+ } else {
+ v = reflect.NewValue(data).(*reflect.SliceValue);
+ }
+ size := TotalSize(v);
if size < 0 {
return os.NewError("binary.Read: invalid type " + v.Type().String())
}
@@ -143,7 +150,7 @@
// from successive fields of the data.
func Write(w io.Writer, order ByteOrder, data interface{}) os.Error {
v := reflect.Indirect(reflect.NewValue(data));
- size := sizeof(v.Type());
+ size := TotalSize(v);
if size < 0 {
return os.NewError("binary.Write: invalid type " + v.Type().String())
}
@@ -154,8 +161,16 @@
return err;
}
-func sizeof(t reflect.Type) int {
- switch t := t.(type) {
+func TotalSize(v reflect.Value) int {
+ if slicevalue, ok := v.(*reflect.SliceValue); ok {
+ elem := sizeof(v.Type().(*reflect.SliceType).Elem());
+ return slicevalue.Len() * elem;
+ }
+ return sizeof(v.Type());
+}
+
+func sizeof(v reflect.Type) int {
+ switch t := v.(type) {
case *reflect.ArrayType:
n := sizeof(t.Elem());
if n < 0 {
@@ -281,6 +296,12 @@
d.value(v.Field(i))
}
+ case *reflect.SliceValue:
+ l := v.Len();
+ for i := 0; i < l; i++ {
+ d.value(v.Elem(i));
+ }
+
case *reflect.Uint8Value:
v.Set(d.uint8())
case *reflect.Uint16Value:
@@ -316,6 +337,11 @@
for i := 0; i < l; i++ {
e.value(v.Field(i))
}
+ case *reflect.SliceValue:
+ l := v.Len();
+ for i := 0; i < l; i++ {
+ e.value(v.Elem(i))
+ }
case *reflect.Uint8Value:
e.uint8(v.Get())
diff -r d1b75410b793 src/pkg/encoding/binary/binary_test.go
--- a/src/pkg/encoding/binary/binary_test.go Tue Nov 17 18:21:47 2009 -0800
+++ b/src/pkg/encoding/binary/binary_test.go Fri Dec 04 12:32:48 2009 +0300
@@ -64,6 +64,9 @@
39, 40, 41, 42,
}
+var src = []byte{ 1, 2, 3, 4, 5, 6, 7, 8 };
+var res = []int32 { 0x01020304, 0x05060708 };
+
func checkResult(t *testing.T, dir string, order, err os.Error, have, want interface{}) {
if err != nil {
t.Errorf("%v %v: %v", dir, order, err);
@@ -97,3 +100,15 @@
func TestBigEndianPtrWrite(t *testing.T) { testWrite(t, BigEndian, big, &s) }
func TestLittleEndianPtrWrite(t *testing.T) { testWrite(t, LittleEndian, little, &s) }
+
+func TestReadSlice(t *testing.T) {
+ slice := make([]int32, 2);
+ err := Read(bytes.NewBuffer(src), BigEndian, slice);
+ checkResult(t, "ReadSlice", BigEndian, err, slice, res);
+}
+
+func TestWriteSlice(t *testing.T) {
+ buf := new(bytes.Buffer);
+ err := Write(buf, BigEndian, res);
+ checkResult(t, "WriteSlice", BigEndian, err, buf.Bytes(), src);
+}