func (s *messageReceiver) call(name, method string, value []byte, inParamsType mojom_types.MojomStruct, outParamsType *mojom_types.MojomStruct) ([]byte, error) { s.ctx.Infof("server: %s.%s: %#v", name, method, inParamsType) inVType, err := transcoder.MojomStructToVDLType(inParamsType, s.header.desc) if err != nil { return nil, err } // Decode the vom.RawBytes from the mojom bytes and mojom type. target := util.StructSplitTarget() if err := transcoder.FromMojo(target, value, inVType); err != nil { return nil, fmt.Errorf("transcoder.FromMojo failed: %v", err) } // inVdlValue is a struct, but we need to send []interface. inargs := target.Fields() inargsIfc := make([]interface{}, len(inargs)) for i := range inargs { inargsIfc[i] = inargs[i] } // We know that the v23serverproxy will give us back a bunch of // data in []interface{}. so we'll want to decode them into *vom.RawBytes. s.ctx.Infof("%s %v", method, outParamsType) var numParams int if outParamsType != nil { numParams = len(outParamsType.Fields) } outargs := make([]*vom.RawBytes, numParams) outptrs := make([]interface{}, len(outargs)) for i := range outargs { outptrs[i] = &outargs[i] } // Now, run the call without any authorization. if err := v23.GetClient(s.ctx).Call(s.ctx, name, method, inargsIfc, outptrs, options.ServerAuthorizer{security.AllowEveryone()}); err != nil { return nil, err } if outParamsType == nil { return nil, nil } outVType, err := transcoder.MojomStructToVDLType(*outParamsType, s.header.desc) if err != nil { return nil, err } toMojoTarget := transcoder.ToMojomTarget() if err := util.JoinRawBytesAsStruct(toMojoTarget, outVType, outargs); err != nil { return nil, err } return toMojoTarget.Bytes(), nil }
// callRemoteMethod calls the method remotely in a generic way. // Produces []*vom.RawBytes at the end for the invoker to return. func (fs fakeService) callRemoteMethod(ctx *context.T, method string, mi mojom_types.MojomInterface, desc map[string]mojom_types.UserDefinedType, argptrs []interface{}) ([]*vom.RawBytes, error) { // We need to parse the signature result to get the method relevant info out. found := false var ordinal uint32 for ord, mm := range mi.Methods { if *mm.DeclData.ShortName == method { ordinal = ord found = true break } } if !found { return nil, fmt.Errorf("callRemoteMethod: method %s does not exist", method) } mm := mi.Methods[ordinal] // A void function must have request id of 0, whereas one with response params // should have a unique request id. header := bindings.MessageHeader{ Type: ordinal, Flags: bindings.MessageExpectsResponseFlag, RequestId: fs.ids.Count(), } // Now produce the *bindings.Message that we will send to the other side. inType, err := transcoder.MojomStructToVDLType(mm.Parameters, desc) if err != nil { return nil, err } message, err := encodeMessageFromVom(header, argptrs, inType) if err != nil { return nil, err } // Otherwise, make a generic call with the message. outMessage, err := fs.callRemoteWithResponse(ctx, message) if err != nil { return nil, err } // Decode the *vom.RawBytes from the mojom bytes and mojom type. outType, err := transcoder.MojomStructToVDLType(*mm.ResponseParams, desc) if err != nil { return nil, err } target := util.StructSplitTarget() if err := transcoder.FromMojo(target, outMessage.Payload, outType); err != nil { return nil, fmt.Errorf("transcoder.FromMojo failed: %v", err) } return target.Fields(), nil }
func TestSplitRawBytesStruct(t *testing.T) { inputStruct := TestStructA{ 1, 2, "3", } expectedFieldsRaw := []*vom.RawBytes{ vom.RawBytesOf(int8(1)), vom.RawBytesOf(uint64(2)), vom.RawBytesOf("3"), } target := util.StructSplitTarget() if err := vdl.FromReflect(target, reflect.ValueOf(inputStruct)); err != nil { t.Fatalf("error splitting target: %v", err) } if got, want := target.Fields(), expectedFieldsRaw; !reflect.DeepEqual(got, want) { t.Errorf("got %v, want %v", got, want) } }