static object UnpackExt8(byte a, BinaryReader reader) { var length = reader.ReadByte(); var extType = reader.ReadByte(); if (extType != 10) { throw new InvalidOperationException("Only extension type 10 (Citizen funcref) is handled by this class."); } var funcRefData = reader.ReadBytes(length); var remoteFunctionReference = new RemoteFunctionReference(funcRefData); return(new CallbackDelegate(delegate(object[] args) { var byteData = MsgPackSerializer.Serialize(args); var returnByteData = remoteFunctionReference.InvokeNative(byteData); var returnData = Deserialize(returnByteData) as List <object>; if (returnData == null || returnData.Count == 0) { return null; } return (returnData)[0]; })); }
protected override void PackToCore(MsgPack.Packer packer, Delegate objectTree) { if (objectTree is CallbackDelegate) { var funcRef = objectTree.Method.DeclaringType?.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static).FirstOrDefault(a => a.FieldType == typeof(RemoteFunctionReference)); if (funcRef == null) { throw new ArgumentException("The CallbackDelegate does not contain a RemoteFunctionReference capture."); } RemoteFunctionReference fr = (RemoteFunctionReference)funcRef.GetValue(objectTree.Target); packer.PackExtendedTypeValue(10, fr.Duplicate()); } else { var funcRefDetails = FunctionReference.Create(objectTree); string refType = InternalManager.CanonicalizeRef(funcRefDetails.Identifier); packer.PackExtendedTypeValue(10, Encoding.UTF8.GetBytes(refType)); } }
static object CreateRemoteFunctionReference(byte[] funcRefData) { var remoteFunctionReference = new RemoteFunctionReference(funcRefData); return(new CallbackDelegate(delegate(object[] args) { var byteData = MsgPackSerializer.Serialize(args); var returnByteData = remoteFunctionReference.InvokeNative(byteData); var returnData = Deserialize(returnByteData) as List <object>; if (returnData == null || returnData.Count == 0) { return null; } if (returnData[0] is IDictionary <string, object> obj) { if (obj.TryGetValue("__cfx_async_retval", out dynamic asyncRef)) { var tcs = new TaskCompletionSource <object>(); asyncRef(new Action <dynamic, dynamic>((res, err) => { if (err != null && err != false) { tcs.SetException(new Exception(err.ToString())); } else { tcs.SetResult(res[0]); } })); return tcs.Task; } } return (returnData)[0]; })); }
static object UnpackExt8(byte a, BinaryReader reader) { var length = reader.ReadByte(); var extType = reader.ReadByte(); if (extType != 1) { throw new InvalidOperationException("Only extension type 1 (Citizen callback) is handled by this class."); } // read the local reference ID var tmpBytes = reader.ReadBytes(4); var reference = BitConverter.ToUInt32(new byte[] { tmpBytes[3], tmpBytes[2], tmpBytes[1], tmpBytes[0] }, 0); // read the environment instance ID tmpBytes = reader.ReadBytes(4); var instance = BitConverter.ToUInt32(new byte[] { tmpBytes[3], tmpBytes[2], tmpBytes[1], tmpBytes[0] }, 0); // read the resource name tmpBytes = reader.ReadBytes(length - 8); var resource = Encoding.UTF8.GetString(tmpBytes, 0, tmpBytes.Length); var remoteFunctionReference = new RemoteFunctionReference(resource, instance, reference); return(new CallbackDelegate(delegate(object[] args) { var byteData = MsgPackSerializer.Serialize(args); var returnByteData = remoteFunctionReference.InvokeNative(byteData); var returnData = Deserialize(returnByteData) as List <object>; if (returnData == null || returnData.Count == 0) { return null; } return (returnData)[0]; })); }