// MarshalJSON returns a JSON representation of a data dictionary. // If any of the dictionary's embedded values is a cborrpc.PythonTuple // or a uuid.UUID, returns a base64-encoded CBOR string; otherwise // returns a normal JSON object. func (d DataDict) MarshalJSON() (out []byte, err error) { var v interface{} if needsCBOREncoding(reflect.ValueOf(d)) { // Do CBOR encoding to a byte array var intermediate []byte cborHandle := &codec.CborHandle{} err = cborrpc.SetExts(cborHandle) if err != nil { return nil, err } encoder := codec.NewEncoderBytes(&intermediate, cborHandle) err = encoder.Encode(map[string]interface{}(d)) if err != nil { return nil, err } // base64 encode that byte array s := base64.StdEncoding.EncodeToString(intermediate) // Then we will JSON encode that string v = s } else { // We will JSON encode the base object v = map[string]interface{}(d) } codecHandle := &codec.JsonHandle{} encoder := codec.NewEncoderBytes(&out, codecHandle) err = encoder.Encode(v) return }
func bytesToMap(in []byte) (out map[string]interface{}, err error) { cbor := new(codec.CborHandle) err = cborrpc.SetExts(cbor) if err != nil { return } decoder := codec.NewDecoderBytes(in, cbor) err = decoder.Decode(&out) return }
func mapToBytes(in map[string]interface{}) (out []byte, err error) { cbor := new(codec.CborHandle) err = cborrpc.SetExts(cbor) if err != nil { return } encoder := codec.NewEncoderBytes(&out, cbor) err = encoder.Encode(in) return }
// ServeCBORRPC runs a CBOR-RPC server on the specified local address. // This serves connections forever, and probably wants to be run in a // goroutine. Panics on any error in the initial setup or in accepting // connections. func ServeCBORRPC( coord coordinate.Coordinate, gConfig map[string]interface{}, network, laddr string, reqLogger *logrus.Logger, ) { var ( cbor *codec.CborHandle err error namespace coordinate.Namespace ln net.Listener conn net.Conn jobd *jobserver.JobServer ) cbor = new(codec.CborHandle) if err == nil { err = cborrpc.SetExts(cbor) } if err == nil { namespace, err = coord.Namespace("") } if err == nil { jobd = &jobserver.JobServer{ Namespace: namespace, GlobalConfig: gConfig, Clock: clock.New(), } ln, err = net.Listen(network, laddr) } for err == nil { conn, err = ln.Accept() if err == nil { go handleConnection(conn, jobd, cbor, reqLogger) } } panic(err) }
// UnmarshalJSON converts a byte array back into a data dictionary. // If it is a string, it should be base64-encoded CBOR. If it is // an object it is decoded normally. func (d *DataDict) UnmarshalJSON(in []byte) error { jsonHandle := &codec.JsonHandle{} var h codec.Handle var b []byte if len(in) > 0 && in[0] == '"' { // This is a string. Decode it from JSON... var s string decoder := codec.NewDecoderBytes(in, jsonHandle) err := decoder.Decode(&s) if err != nil { return err } // ...base64 decode it... b, err = base64.StdEncoding.DecodeString(s) if err != nil { return err } // ...and having gotten that byte string back, we will go // on to decode it as CBOR. cborHandle := codec.CborHandle{} err = cborrpc.SetExts(&cborHandle) if err != nil { return err } h = &cborHandle } else { // This is not a string and we will decode it as straight // JSON. h = jsonHandle b = in } decoder := codec.NewDecoderBytes(b, h) return decoder.Decode((*map[string]interface{})(d)) }