OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [net/] [rpc/] [jsonrpc/] [server.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2010 The Go Authors.  All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
package jsonrpc
6
 
7
import (
8
        "encoding/json"
9
        "errors"
10
        "io"
11
        "net/rpc"
12
        "sync"
13
)
14
 
15
type serverCodec struct {
16
        dec *json.Decoder // for reading JSON values
17
        enc *json.Encoder // for writing JSON values
18
        c   io.Closer
19
 
20
        // temporary work space
21
        req  serverRequest
22
        resp serverResponse
23
 
24
        // JSON-RPC clients can use arbitrary json values as request IDs.
25
        // Package rpc expects uint64 request IDs.
26
        // We assign uint64 sequence numbers to incoming requests
27
        // but save the original request ID in the pending map.
28
        // When rpc responds, we use the sequence number in
29
        // the response to find the original request ID.
30
        mutex   sync.Mutex // protects seq, pending
31
        seq     uint64
32
        pending map[uint64]*json.RawMessage
33
}
34
 
35
// NewServerCodec returns a new rpc.ServerCodec using JSON-RPC on conn.
36
func NewServerCodec(conn io.ReadWriteCloser) rpc.ServerCodec {
37
        return &serverCodec{
38
                dec:     json.NewDecoder(conn),
39
                enc:     json.NewEncoder(conn),
40
                c:       conn,
41
                pending: make(map[uint64]*json.RawMessage),
42
        }
43
}
44
 
45
type serverRequest struct {
46
        Method string           `json:"method"`
47
        Params *json.RawMessage `json:"params"`
48
        Id     *json.RawMessage `json:"id"`
49
}
50
 
51
func (r *serverRequest) reset() {
52
        r.Method = ""
53
        if r.Params != nil {
54
                *r.Params = (*r.Params)[0:0]
55
        }
56
        if r.Id != nil {
57
                *r.Id = (*r.Id)[0:0]
58
        }
59
}
60
 
61
type serverResponse struct {
62
        Id     *json.RawMessage `json:"id"`
63
        Result interface{}      `json:"result"`
64
        Error  interface{}      `json:"error"`
65
}
66
 
67
func (c *serverCodec) ReadRequestHeader(r *rpc.Request) error {
68
        c.req.reset()
69
        if err := c.dec.Decode(&c.req); err != nil {
70
                return err
71
        }
72
        r.ServiceMethod = c.req.Method
73
 
74
        // JSON request id can be any JSON value;
75
        // RPC package expects uint64.  Translate to
76
        // internal uint64 and save JSON on the side.
77
        c.mutex.Lock()
78
        c.seq++
79
        c.pending[c.seq] = c.req.Id
80
        c.req.Id = nil
81
        r.Seq = c.seq
82
        c.mutex.Unlock()
83
 
84
        return nil
85
}
86
 
87
func (c *serverCodec) ReadRequestBody(x interface{}) error {
88
        if x == nil {
89
                return nil
90
        }
91
        // JSON params is array value.
92
        // RPC params is struct.
93
        // Unmarshal into array containing struct for now.
94
        // Should think about making RPC more general.
95
        var params [1]interface{}
96
        params[0] = x
97
        return json.Unmarshal(*c.req.Params, ¶ms)
98
}
99
 
100
var null = json.RawMessage([]byte("null"))
101
 
102
func (c *serverCodec) WriteResponse(r *rpc.Response, x interface{}) error {
103
        var resp serverResponse
104
        c.mutex.Lock()
105
        b, ok := c.pending[r.Seq]
106
        if !ok {
107
                c.mutex.Unlock()
108
                return errors.New("invalid sequence number in response")
109
        }
110
        delete(c.pending, r.Seq)
111
        c.mutex.Unlock()
112
 
113
        if b == nil {
114
                // Invalid request so no id.  Use JSON null.
115
                b = &null
116
        }
117
        resp.Id = b
118
        resp.Result = x
119
        if r.Error == "" {
120
                resp.Error = nil
121
        } else {
122
                resp.Error = r.Error
123
        }
124
        return c.enc.Encode(resp)
125
}
126
 
127
func (c *serverCodec) Close() error {
128
        return c.c.Close()
129
}
130
 
131
// ServeConn runs the JSON-RPC server on a single connection.
132
// ServeConn blocks, serving the connection until the client hangs up.
133
// The caller typically invokes ServeConn in a go statement.
134
func ServeConn(conn io.ReadWriteCloser) {
135
        rpc.ServeCodec(NewServerCodec(conn))
136
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.