package rpc12// based on "github.com/gorilla/rpc/v2/json2"34// Copyright 2009 The Go Authors. All rights reserved.5// Copyright 2012 The Gorilla Authors. All rights reserved.6// Use of this source code is governed by a BSD-style7// license that can be found in the LICENSE file.89import (10"bytes"11"encoding/json"12"errors"13"io"14)1516// ----------------------------------------------------------------------------17// Request and Response18// ----------------------------------------------------------------------------1920// clientRequest represents a JSON-RPC request sent by a client.21type clientRequest struct {22// JSON-RPC protocol.23Version string `json:"jsonrpc"`2425// A String containing the name of the method to be invoked.26Method string `json:"method"`2728// Object to pass as request parameter to the method.29Params interface{} `json:"params"`3031// The request id. This can be of any type. It is used to match the32// response with the request that it is replying to.33Id uint64 `json:"id"`34}3536// clientResponse represents a JSON-RPC response returned to a client.37type clientResponse struct {38Version string `json:"jsonrpc"`39Result *json.RawMessage `json:"result"`40Error *json.RawMessage `json:"error"`41Id *uint64 `json:"id"`42}4344// EncodeClientRequest encodes parameters for a JSON-RPC client request.45func EncodeClientRequest(method string, args interface{}) (*bytes.Buffer, error) {46var buf bytes.Buffer47c := &clientRequest{48Version: "2.0",49Method: method,50Params: args,51Id: reqid(),52}53if err := json.NewEncoder(&buf).Encode(c); err != nil {54return nil, err55}56return &buf, nil57}5859func (c clientResponse) decode(reply interface{}) error {60if c.Error != nil {61jsonErr := &Error{}62if err := json.Unmarshal(*c.Error, jsonErr); err != nil {63return &Error{64Code: E_SERVER,65Message: string(*c.Error),66}67}68return jsonErr69}7071if c.Result == nil {72return ErrNullResult73}7475return json.Unmarshal(*c.Result, reply)76}7778// DecodeClientResponse decodes the response body of a client request into79// the interface reply.80func DecodeClientResponse(r io.Reader, reply interface{}) error {81var c clientResponse82if err := json.NewDecoder(r).Decode(&c); err != nil {83return err84}85return c.decode(reply)86}8788type ErrorCode int8990const (91E_PARSE ErrorCode = -3270092E_INVALID_REQ ErrorCode = -3260093E_NO_METHOD ErrorCode = -3260194E_BAD_PARAMS ErrorCode = -3260295E_INTERNAL ErrorCode = -3260396E_SERVER ErrorCode = -3200097)9899var ErrNullResult = errors.New("result is null")100101type Error struct {102// A Number that indicates the error type that occurred.103Code ErrorCode `json:"code"` /* required */104105// A String providing a short description of the error.106// The message SHOULD be limited to a concise single sentence.107Message string `json:"message"` /* required */108109// A Primitive or Structured value that contains additional information about the error.110Data interface{} `json:"data"` /* optional */111}112113func (e *Error) Error() string {114return e.Message115}116117118