@cryptotaxi247 / kubo / commits / 3cebd2176

commands: Made Response implement io.Reader

Matt Bell committed Oct 22, 2014 at 17:46 UTC 3cebd2176e4beb4075e821904917f06780de955f
1 file changed +29
commands/response.go
+29
@@ -1,9 +1,11 @@
1 package commands
2
3 import (
4 + "bytes"
5 "encoding/json"
6 "encoding/xml"
7 "fmt"
8 + "io"
9 "strings"
10 )
11
@@ -49,6 +51,8 @@ var marshallers = map[EncodingType]Marshaller{
51 // Response is the result of a command request. Handlers write to the response,
52 // setting Error or Value. Response is returned to the client.
53 type Response interface {
54 + io.Reader
55 +
56 Request() Request
57
58 // Set/Return the response Error
@@ -68,6 +72,7 @@ type response struct {
72 req Request
73 err *Error
74 value interface{}
75 + out io.Reader
76 }
77
78 func (r *response) Request() Request {
@@ -112,6 +117,30 @@ func (r *response) Marshal() ([]byte, error) {
117 return marshaller(r.value)
118 }
119
120 +func (r *response) Read(p []byte) (int, error) {
121 + // if command set value to a io.Reader, set that as our output stream
122 + if r.out == nil {
123 + if out, ok := r.value.(io.Reader); ok {
124 + r.out = out
125 + }
126 + }
127 +
128 + // if there is an output stream set, read from it
129 + if r.out != nil {
130 + return r.out.Read(p)
131 + }
132 +
133 + // no stream set, so marshal the error or value
134 + output, err := r.Marshal()
135 + if err != nil {
136 + return 0, err
137 + }
138 +
139 + // then create a Reader from the marshalled data, and use it as our output stream
140 + r.out = bytes.NewReader(output)
141 + return r.out.Read(p)
142 +}
143 +
144 // NewResponse returns a response to match given Request
145 func NewResponse(req Request) Response {
146 return &response{req: req}