@@ -2,162 +2,118 @@ package encoder
2
2
3
3
import (
4
4
"fmt"
5
+ "unsafe"
5
6
6
7
"github.com/IncSW/go-bencode/internal"
7
8
)
8
9
9
- func prepareBuffer (result * []byte , offset int , length int , neededLength int ) int {
10
- availableLength := length - offset
10
+ //go:linkname memmove runtime.memmove
11
+ //go:noescape
12
+ func memmove (to unsafe.Pointer , from unsafe.Pointer , n uintptr )
13
+
14
+ type sliceHeader struct {
15
+ data unsafe.Pointer
16
+ len int
17
+ cap int
18
+ }
19
+
20
+ type Encoder struct {
21
+ buffer []byte
22
+ length int
23
+ offset int
24
+ }
25
+
26
+ //go:nosplit
27
+ func (e * Encoder ) grow (neededLength int ) {
28
+ availableLength := e .length - e .offset
11
29
if availableLength >= neededLength {
12
- return length
30
+ return
13
31
}
14
-
15
- rate := 1
16
- for availableLength < neededLength {
17
- rate ++
18
- availableLength = length * rate - offset
32
+ if e .length == 0 {
33
+ if neededLength < 16 {
34
+ neededLength = 16
35
+ }
36
+ e .length = neededLength
37
+ availableLength = neededLength
38
+ } else {
39
+ for availableLength < neededLength {
40
+ e .length += e .length
41
+ availableLength = e .length - e .offset
42
+ }
19
43
}
44
+ buffer := make ([]byte , e .length )
45
+ memmove (
46
+ unsafe .Pointer (uintptr ((* sliceHeader )(unsafe .Pointer (& buffer )).data )),
47
+ (* sliceHeader )(unsafe .Pointer (& e .buffer )).data ,
48
+ uintptr (e .offset ),
49
+ )
50
+ e .buffer = buffer
51
+ }
20
52
21
- newResult := make ([]byte , length * rate )
22
- copy (newResult , (* result )[:length ])
23
- length *= rate
24
- * result = newResult
53
+ //go:nosplit
54
+ func (e * Encoder ) write (data []byte ) {
55
+ length := len (data )
56
+ memmove (
57
+ unsafe .Pointer (uintptr ((* sliceHeader )(unsafe .Pointer (& e .buffer )).data )+ uintptr (e .offset )),
58
+ (* sliceHeader )(unsafe .Pointer (& data )).data ,
59
+ uintptr (length ),
60
+ )
61
+ e .offset += length
62
+ }
25
63
26
- return length
64
+ //go:nosplit
65
+ func (e * Encoder ) writeByte (data byte ) {
66
+ * (* byte )(unsafe .Pointer (uintptr ((* sliceHeader )(unsafe .Pointer (& e .buffer )).data ) + uintptr (e .offset ))) = data
67
+ e .offset ++
27
68
}
28
69
29
- func MarshalTo (dst []byte , data interface {}) ([]byte , error ) {
70
+ func ( e * Encoder ) EncodeTo (dst []byte , data interface {}) ([]byte , error ) {
30
71
if cap (dst ) > len (dst ) {
31
72
dst = dst [:cap (dst )]
32
73
} else if len (dst ) == 0 {
33
74
dst = make ([]byte , 512 )
34
75
}
35
- length , _ , err := marshal (data , & dst , 0 , len (dst ))
76
+ e .buffer = dst
77
+ e .length = cap (dst )
78
+ err := e .encode (data )
36
79
if err != nil {
37
80
return nil , err
38
81
}
39
- return dst [: length ], nil
82
+ return e . buffer [: e . offset ], nil
40
83
}
41
84
42
- func marshal ( data interface {}, result * [] byte , offset int , length int ) ( int , int , error ) {
85
+ func ( e * Encoder ) encode ( data interface {}) error {
43
86
switch value := data .(type ) {
44
87
case int64 :
45
- offset , length = marshalInt (value , result , offset , length )
46
- return offset , length , nil
47
-
88
+ e .encodeInt (value )
48
89
case int32 :
49
- offset , length = marshalInt (int64 (value ), result , offset , length )
50
- return offset , length , nil
51
-
90
+ e .encodeInt (int64 (value ))
52
91
case int16 :
53
- offset , length = marshalInt (int64 (value ), result , offset , length )
54
- return offset , length , nil
55
-
92
+ e .encodeInt (int64 (value ))
56
93
case int8 :
57
- offset , length = marshalInt (int64 (value ), result , offset , length )
58
- return offset , length , nil
59
-
94
+ e .encodeInt (int64 (value ))
60
95
case int :
61
- offset , length = marshalInt (int64 (value ), result , offset , length )
62
- return offset , length , nil
63
-
96
+ e .encodeInt (int64 (value ))
64
97
case uint64 :
65
- offset , length = marshalInt (int64 (value ), result , offset , length )
66
- return offset , length , nil
67
-
98
+ e .encodeInt (int64 (value ))
68
99
case uint32 :
69
- offset , length = marshalInt (int64 (value ), result , offset , length )
70
- return offset , length , nil
71
-
100
+ e .encodeInt (int64 (value ))
72
101
case uint16 :
73
- offset , length = marshalInt (int64 (value ), result , offset , length )
74
- return offset , length , nil
75
-
102
+ e .encodeInt (int64 (value ))
76
103
case uint8 :
77
- offset , length = marshalInt (int64 (value ), result , offset , length )
78
- return offset , length , nil
79
-
104
+ e .encodeInt (int64 (value ))
80
105
case uint :
81
- offset , length = marshalInt (int64 (value ), result , offset , length )
82
- return offset , length , nil
83
-
106
+ e .encodeInt (int64 (value ))
84
107
case []byte :
85
- offset , length = marshalBytes (value , result , offset , length )
86
- return offset , length , nil
87
-
108
+ e .encodeBytes (value )
88
109
case string :
89
- offset , length = marshalBytes (internal .S2B (value ), result , offset , length )
90
- return offset , length , nil
91
-
110
+ e .encodeBytes (internal .S2B (value ))
92
111
case []interface {}:
93
- return marshalList (value , result , offset , length )
94
-
112
+ return e .encodeList (value )
95
113
case map [string ]interface {}:
96
- return marshalDictionary (value , result , offset , length )
97
-
114
+ return e .encodeDictionary (value )
98
115
default :
99
- return 0 , 0 , fmt .Errorf ("bencode: unsupported type: %T" , value )
100
- }
101
- }
102
-
103
- func marshalBytes (data []byte , result * []byte , offset int , length int ) (int , int ) {
104
- dataLength := len (data )
105
- offset , length = writeInt (int64 (dataLength ), result , offset , length )
106
- length = prepareBuffer (result , offset , length , dataLength + 1 )
107
- (* result )[offset ] = ':'
108
- offset ++
109
- copy ((* result )[offset :], data )
110
- offset += dataLength
111
- return offset , length
112
- }
113
-
114
- func marshalList (data []interface {}, result * []byte , offset int , length int ) (int , int , error ) {
115
- length = prepareBuffer (result , offset , length , 1 )
116
-
117
- (* result )[offset ] = 'l'
118
- offset ++
119
-
120
- for _ , data := range data {
121
- var err error
122
- offset , length , err = marshal (data , result , offset , length )
123
- if err != nil {
124
- return 0 , 0 , err
125
- }
116
+ return fmt .Errorf ("bencode: unsupported type: %T" , value )
126
117
}
127
-
128
- length = prepareBuffer (result , offset , length , 1 )
129
-
130
- (* result )[offset ] = 'e'
131
- offset ++
132
-
133
- return offset , length , nil
134
- }
135
-
136
- func marshalDictionary (data map [string ]interface {}, result * []byte , offset int , length int ) (int , int , error ) {
137
- length = prepareBuffer (result , offset , length , 1 )
138
-
139
- (* result )[offset ] = 'd'
140
- offset ++
141
-
142
- keys := make ([]string , 0 , len (data ))
143
- for key , _ := range data {
144
- keys = append (keys , key )
145
- }
146
- internal .SortStrings (keys )
147
-
148
- for _ , key := range keys {
149
- offset , length = marshalBytes (internal .S2B (key ), result , offset , length )
150
- var err error
151
- offset , length , err = marshal (data [key ], result , offset , length )
152
- if err != nil {
153
- return 0 , 0 , err
154
- }
155
- }
156
-
157
- length = prepareBuffer (result , offset , length , 1 )
158
-
159
- (* result )[offset ] = 'e'
160
- offset ++
161
-
162
- return offset , length , nil
118
+ return nil
163
119
}
0 commit comments