...
1
16
17 package groupcache
18
19 import (
20 "errors"
21
22 "github.com/golang/protobuf/proto"
23 )
24
25
26
27
28
29 type Sink interface {
30
31 SetString(s string) error
32
33
34
35 SetBytes(v []byte) error
36
37
38
39 SetProto(m proto.Message) error
40
41
42 view() (ByteView, error)
43 }
44
45 func cloneBytes(b []byte) []byte {
46 c := make([]byte, len(b))
47 copy(c, b)
48 return c
49 }
50
51 func setSinkView(s Sink, v ByteView) error {
52
53
54
55
56 type viewSetter interface {
57 setView(v ByteView) error
58 }
59 if vs, ok := s.(viewSetter); ok {
60 return vs.setView(v)
61 }
62 if v.b != nil {
63 return s.SetBytes(v.b)
64 }
65 return s.SetString(v.s)
66 }
67
68
69 func StringSink(sp *string) Sink {
70 return &stringSink{sp: sp}
71 }
72
73 type stringSink struct {
74 sp *string
75 v ByteView
76
77 }
78
79 func (s *stringSink) view() (ByteView, error) {
80
81 return s.v, nil
82 }
83
84 func (s *stringSink) SetString(v string) error {
85 s.v.b = nil
86 s.v.s = v
87 *s.sp = v
88 return nil
89 }
90
91 func (s *stringSink) SetBytes(v []byte) error {
92 return s.SetString(string(v))
93 }
94
95 func (s *stringSink) SetProto(m proto.Message) error {
96 b, err := proto.Marshal(m)
97 if err != nil {
98 return err
99 }
100 s.v.b = b
101 *s.sp = string(b)
102 return nil
103 }
104
105
106 func ByteViewSink(dst *ByteView) Sink {
107 if dst == nil {
108 panic("nil dst")
109 }
110 return &byteViewSink{dst: dst}
111 }
112
113 type byteViewSink struct {
114 dst *ByteView
115
116
117
118
119
120
121
122
123
124 }
125
126 func (s *byteViewSink) setView(v ByteView) error {
127 *s.dst = v
128 return nil
129 }
130
131 func (s *byteViewSink) view() (ByteView, error) {
132 return *s.dst, nil
133 }
134
135 func (s *byteViewSink) SetProto(m proto.Message) error {
136 b, err := proto.Marshal(m)
137 if err != nil {
138 return err
139 }
140 *s.dst = ByteView{b: b}
141 return nil
142 }
143
144 func (s *byteViewSink) SetBytes(b []byte) error {
145 *s.dst = ByteView{b: cloneBytes(b)}
146 return nil
147 }
148
149 func (s *byteViewSink) SetString(v string) error {
150 *s.dst = ByteView{s: v}
151 return nil
152 }
153
154
155 func ProtoSink(m proto.Message) Sink {
156 return &protoSink{
157 dst: m,
158 }
159 }
160
161 type protoSink struct {
162 dst proto.Message
163 typ string
164
165 v ByteView
166 }
167
168 func (s *protoSink) view() (ByteView, error) {
169 return s.v, nil
170 }
171
172 func (s *protoSink) SetBytes(b []byte) error {
173 err := proto.Unmarshal(b, s.dst)
174 if err != nil {
175 return err
176 }
177 s.v.b = cloneBytes(b)
178 s.v.s = ""
179 return nil
180 }
181
182 func (s *protoSink) SetString(v string) error {
183 b := []byte(v)
184 err := proto.Unmarshal(b, s.dst)
185 if err != nil {
186 return err
187 }
188 s.v.b = b
189 s.v.s = ""
190 return nil
191 }
192
193 func (s *protoSink) SetProto(m proto.Message) error {
194 b, err := proto.Marshal(m)
195 if err != nil {
196 return err
197 }
198
199
200
201
202 err = proto.Unmarshal(b, s.dst)
203 if err != nil {
204 return err
205 }
206 s.v.b = b
207 s.v.s = ""
208 return nil
209 }
210
211
212
213
214 func AllocatingByteSliceSink(dst *[]byte) Sink {
215 return &allocBytesSink{dst: dst}
216 }
217
218 type allocBytesSink struct {
219 dst *[]byte
220 v ByteView
221 }
222
223 func (s *allocBytesSink) view() (ByteView, error) {
224 return s.v, nil
225 }
226
227 func (s *allocBytesSink) setView(v ByteView) error {
228 if v.b != nil {
229 *s.dst = cloneBytes(v.b)
230 } else {
231 *s.dst = []byte(v.s)
232 }
233 s.v = v
234 return nil
235 }
236
237 func (s *allocBytesSink) SetProto(m proto.Message) error {
238 b, err := proto.Marshal(m)
239 if err != nil {
240 return err
241 }
242 return s.setBytesOwned(b)
243 }
244
245 func (s *allocBytesSink) SetBytes(b []byte) error {
246 return s.setBytesOwned(cloneBytes(b))
247 }
248
249 func (s *allocBytesSink) setBytesOwned(b []byte) error {
250 if s.dst == nil {
251 return errors.New("nil AllocatingByteSliceSink *[]byte dst")
252 }
253 *s.dst = cloneBytes(b)
254 s.v.b = b
255 s.v.s = ""
256 return nil
257 }
258
259 func (s *allocBytesSink) SetString(v string) error {
260 if s.dst == nil {
261 return errors.New("nil AllocatingByteSliceSink *[]byte dst")
262 }
263 *s.dst = []byte(v)
264 s.v.b = nil
265 s.v.s = v
266 return nil
267 }
268
269
270
271
272
273 func TruncatingByteSliceSink(dst *[]byte) Sink {
274 return &truncBytesSink{dst: dst}
275 }
276
277 type truncBytesSink struct {
278 dst *[]byte
279 v ByteView
280 }
281
282 func (s *truncBytesSink) view() (ByteView, error) {
283 return s.v, nil
284 }
285
286 func (s *truncBytesSink) SetProto(m proto.Message) error {
287 b, err := proto.Marshal(m)
288 if err != nil {
289 return err
290 }
291 return s.setBytesOwned(b)
292 }
293
294 func (s *truncBytesSink) SetBytes(b []byte) error {
295 return s.setBytesOwned(cloneBytes(b))
296 }
297
298 func (s *truncBytesSink) setBytesOwned(b []byte) error {
299 if s.dst == nil {
300 return errors.New("nil TruncatingByteSliceSink *[]byte dst")
301 }
302 n := copy(*s.dst, b)
303 if n < len(*s.dst) {
304 *s.dst = (*s.dst)[:n]
305 }
306 s.v.b = b
307 s.v.s = ""
308 return nil
309 }
310
311 func (s *truncBytesSink) SetString(v string) error {
312 if s.dst == nil {
313 return errors.New("nil TruncatingByteSliceSink *[]byte dst")
314 }
315 n := copy(*s.dst, v)
316 if n < len(*s.dst) {
317 *s.dst = (*s.dst)[:n]
318 }
319 s.v.b = nil
320 s.v.s = v
321 return nil
322 }
323
View as plain text