diff --git a/contrib/codecs/rdwr/client.go b/contrib/codecs/rdwr/client.go index 0cf77e5fb346bf786cbe8068e20c7b0ef671d10e..8943e8fe43e654a6ea208dfa4fbf703f695fa811 100644 --- a/contrib/codecs/rdwr/client.go +++ b/contrib/codecs/rdwr/client.go @@ -73,7 +73,7 @@ func (c *Client) listen() error { defer jx.PutDecoder(jd) jd.Reset(c.rd) for { - msg, err := jd.RawAppend(nil) + msg, err := jd.Raw() if err != nil { return err } diff --git a/pkg/clientutil/idreply.go b/pkg/clientutil/idreply.go index 167ce521046d656894ffcae672c926ddd5ab8cc0..d0cb60206b57398dd332a17b151562e7d0ee3af7 100644 --- a/pkg/clientutil/idreply.go +++ b/pkg/clientutil/idreply.go @@ -21,7 +21,7 @@ type IdReply struct { } type msgOrError struct { - msg io.ReadCloser + msg io.Reader err error } @@ -74,7 +74,7 @@ func (i *IdReply) remove(id []byte) { delete(i.chs, string(id)) } -func (i *IdReply) Resolve(id []byte, msg io.ReadCloser, err error) { +func (i *IdReply) Resolve(id []byte, msg io.Reader, err error) { ch := i.makeOrTake(id) if ch == nil { return @@ -92,7 +92,7 @@ func (i *IdReply) Resolve(id []byte, msg io.ReadCloser, err error) { } -func (i *IdReply) Ask(ctx context.Context, id []byte) (io.ReadCloser, error) { +func (i *IdReply) Ask(ctx context.Context, id []byte) (io.Reader, error) { select { case resp := <-i.makeOrTake(id): return resp.msg, resp.err diff --git a/pkg/jsonrpc/json.go b/pkg/jsonrpc/json.go index 30513769df698cf67dd7e731e714a2c499fd3fb7..b1b687347a478506a49aac30ad9865c1681c8643 100644 --- a/pkg/jsonrpc/json.go +++ b/pkg/jsonrpc/json.go @@ -89,7 +89,7 @@ func MarshalMessage(m *Message, enc *jx.Encoder) (err error) { return nil } -func UnmarshalMessage(m *Message, dec *jx.Decoder) error { +func UnmarshalMessage(m *Message, dec *jx.Decoder, doCopy bool) error { err := dec.Obj(func(d *jx.Decoder, key string) (err error) { switch key { default: @@ -97,6 +97,9 @@ func UnmarshalMessage(m *Message, dec *jx.Decoder) error { if err != nil { return err } + if doCopy { + raw = append([]byte(nil), raw...) + } if m.Extensions == nil { m.Extensions = make(map[string]json.RawMessage) } @@ -123,17 +126,22 @@ func UnmarshalMessage(m *Message, dec *jx.Decoder) error { case "method": m.Method, err = d.Str() case "params": - val, err := d.RawAppend(nil) + val, err := d.Raw() if err != nil { return err } + if doCopy { + val = append([]byte(nil), val...) + } m.Params = json.RawMessage(val) case "result": - // allocate full result :) - val, err := d.RawAppend(nil) + val, err := d.Raw() if err != nil { return err } + if doCopy { + val = append([]byte(nil), val...) + } m.Result = io.NopCloser(bytes.NewBuffer(val)) case "error": val, err := d.Raw() @@ -158,7 +166,7 @@ func (m *Message) UnmarshalJSON(xs []byte) error { dec := jx.GetDecoder() defer jx.PutDecoder(dec) dec.ResetBytes(xs) - return UnmarshalMessage(m, dec) + return UnmarshalMessage(m, dec, true) } func (m Message) MarshalJSON() ([]byte, error) { @@ -220,18 +228,22 @@ func IsBatchMessage(raw json.RawMessage) bool { // is called. Any non-JSON-RPC messages in the input return the zero value of // Message. func ParseMessage(in json.RawMessage) ([]*Message, bool) { - return ReadMessage(jx.DecodeBytes(in)) + return ReadMessage(jx.DecodeBytes(in), true) +} + +func ParseMessageCopyless(in json.RawMessage) ([]*Message, bool) { + return ReadMessage(jx.DecodeBytes(in), false) } // parseMessage parses raw bytes as a (batch of) JSON-RPC message(s). There are no error // checks in this function because the raw message has already been syntax-checked when it // is called. Any non-JSON-RPC messages in the input return the zero value of // Message. -func ReadMessage(dec *jx.Decoder) ([]*Message, bool) { +func ReadMessage(dec *jx.Decoder, doCopy bool) ([]*Message, bool) { msgs := []*Message{{}} switch dec.Next() { case jx.Object: - _ = UnmarshalMessage(msgs[0], dec) + _ = UnmarshalMessage(msgs[0], dec, doCopy) return msgs, false default: return msgs, false @@ -239,12 +251,7 @@ func ReadMessage(dec *jx.Decoder) ([]*Message, bool) { msgs = []*Message{} dec.Arr(func(d *jx.Decoder) error { msg := new(Message) - // err := UnmarshalMessage(msg, d) - raw, err := d.Raw() - if err != nil { - raw = []byte{} - } - err = json.Unmarshal(raw, msg) + err := UnmarshalMessage(msg, d, doCopy) if err != nil { msg = nil }