public void TestArray() { var tests = new[] { (float)0, (float)50505, Single.NaN, Single.MaxValue, Single.MinValue, Single.PositiveInfinity, Single.NegativeInfinity, Single.Epsilon, }.Select(f => MPack.From(f)) .ToArray(); var arr = new MPackArray(tests); var bytes = arr.EncodeToBytes(); var round = MPack.ParseFromBytes(bytes) as MPackArray; Assert.IsTrue(round != null); Assert.IsTrue(arr.Count == round.Count); for (int i = 0; i < arr.Count; i++) { Assert.AreEqual(arr[i], round[i]); } Assert.AreEqual(arr, round); }
public void TestMap() { MPackMap dictionary = new MPackMap { { "array1", MPack.From(new[] { MPack.From("array1_value1"), MPack.From("array1_value2"), MPack.From("array1_value3"), }) }, { "bool1", MPack.From(true) }, { "double1", MPack.From(50.5) }, { "double2", MPack.From(15.2) }, { "int1", MPack.From(50505) }, { "int2", MPack.From(50) }, { 3.14, MPack.From(3.14) }, { 42, MPack.From(42) } }; var bytes = dictionary.EncodeToBytes(); var result = MPack.ParseFromBytes(bytes) as MPackMap; Assert.AreEqual(dictionary, result); }
public void TestBoolean() { var tru = MPack.ParseFromBytes(MPack.From(true).EncodeToBytes()).To <bool>(); var fal = MPack.ParseFromBytes(MPack.From(false).EncodeToBytes()).To <bool>(); Assert.IsTrue(tru); Assert.IsFalse(fal); }
public void TestUInt64() { var tests = new[] { UInt64.MaxValue, UInt64.MinValue, }; foreach (var value in tests) { Assert.AreEqual(value, MPack.ParseFromBytes(MPack.From(value).EncodeToBytes()).To <ulong>()); } }
public void TestString() { var tests = new string[] { Helpers.GetString(2), Helpers.GetString(8), Helpers.GetString(16), Helpers.GetString(32), Helpers.GetString(257), Helpers.GetString(65537) }; foreach (var value in tests) { Assert.AreEqual(value, MPack.ParseFromBytes(MPack.From(value).EncodeToBytes()).To <string>()); } }
public void TestBinary() { var tests = new[] { Helpers.GetBytes(8), Helpers.GetBytes(16), Helpers.GetBytes(32), Helpers.GetBytes(257), Helpers.GetBytes(65537) }; foreach (var value in tests) { var result = MPack.ParseFromBytes(MPack.From(value).EncodeToBytes()).To <byte[]>(); Assert.IsTrue(Enumerable.SequenceEqual(value, result)); } }
public void TestSingle() { var tests = new[] { (float)0, (float)50505, Single.NaN, Single.MaxValue, Single.MinValue, Single.PositiveInfinity, Single.NegativeInfinity, Single.Epsilon, }; foreach (var value in tests) { Assert.AreEqual(value, MPack.ParseFromBytes(MPack.From(value).EncodeToBytes()).To <float>()); } }
public static DBUpdateMessage Decode(byte[] bytes) { try { var message = new DBUpdateMessage(); var decoded = MPack.ParseFromBytes(bytes); message.Command = decoded["command"].To <string>(); message.Key = decoded["key"].To <string>(); message.Value = (message.Command == "remove") ? null : decoded["value"].To <string>(); message.Version = decoded["version"].To <int>(); message.ServerId = decoded["serverId"].To <int>(); return(message); } catch { return(null); } }
public static void EncodeToStream(Stream ms, MPack m) { switch (m.ValueType) { case MPackType.Null: WriteNull(ms); break; case MPackType.String: WriteString(ms, Convert.ToString(m.Value)); break; case MPackType.SInt: WriteInteger(ms, Convert.ToInt64(m.Value)); break; case MPackType.UInt: WriteInteger(ms, Convert.ToUInt64(m.Value)); break; case MPackType.Bool: WriteBoolean(ms, Convert.ToBoolean(m.Value)); break; case MPackType.Single: WriteSingle(ms, Convert.ToSingle(m.Value)); break; case MPackType.Double: WriteDouble(ms, Convert.ToDouble(m.Value)); break; case MPackType.Binary: WriteBinary(ms, (byte[])m.Value); break; case MPackType.Map: WriteMap(ms, m); break; case MPackType.Array: WirteArray(ms, m); break; default: WriteNull(ms); break; } }
public void TestInteger() { var tests = new[] { 0, 1, -1, sbyte.MinValue, sbyte.MaxValue, byte.MaxValue, short.MinValue, short.MaxValue, int.MinValue, int.MaxValue, long.MaxValue, long.MinValue, }; foreach (var value in tests) { Assert.AreEqual(value, MPack.ParseFromBytes(MPack.From(value).EncodeToBytes()).To <long>()); } }
public void TestDouble() { var tests = new[] { 0d, 1d, -1d, 224d, 256d, 65530d, 65540d, Double.NaN, Double.MaxValue, Double.MinValue, Double.PositiveInfinity, Double.NegativeInfinity }; foreach (var value in tests) { Assert.AreEqual(value, MPack.ParseFromBytes(MPack.From(value).EncodeToBytes()).To <double>()); } }
private static void WriteMap(Stream stream, MPack mpack) { MPackMap map = mpack as MPackMap; if (map == null) throw new InvalidOperationException("A call to WriteMap can not occur unless type is of MsgPackMap"); byte b; byte[] lenBytes; int len = map.Count; if (len <= 15) { b = (byte)(0x80 + (byte)len); stream.WriteByte(b); } else if (len <= 65535) { b = 0xDE; stream.WriteByte(b); lenBytes = _convert.GetBytes((UInt16)len); stream.Write(lenBytes, 0, lenBytes.Length); } else { b = 0xDF; stream.WriteByte(b); lenBytes = _convert.GetBytes((UInt32)len); stream.Write(lenBytes, 0, lenBytes.Length); } foreach (KeyValuePair<string, MPack> child in map) { WriteString(stream, child.Key); EncodeToStream(stream, child.Value); } }
private void LogRead(MPack pack) { LogTo.Trace(() => "[Remoter] Recieving: " + pack.ToString().SubstringSafe(0, 1000)); }
public void TestNumRepr() { Assert.IsTrue(Enumerable.SequenceEqual(MPack.From(127).EncodeToBytes(), new byte[] { 0b01111111 }), "127");
public void TestNull() { Assert.AreEqual(null, MPack.ParseFromBytes(MPack.Null().EncodeToBytes()).To <object>()); }
//private void Error(object sender, ClientEventArgs<Exception> e) //{ // _buffer.OnError(e.Value); //} //private void Disconnected(object sender, EventArgs e) //{ // _buffer.OnCompleted(); //} //private void Recieve(object sender, ClientEventArgs<byte[]> e) //{ // try // { // var mpack = MPack.ParseFromBytes(e.Value); // LogRead(mpack); // _buffer.OnNext(mpack); // } // catch (Exception ex) // { // _buffer.OnError(ex); // } //} public void Write(MPack packet) { LogWrite(packet); var bytes = packet.EncodeToBytes(); Client.Write(bytes); }
public static object ParamaterToObject(Type type, MPack param) { if (param.ValueType == MPackType.Binary && type == typeof(byte[])) return (byte[])param.Value; var tcode = (int)Type.GetTypeCode(type); if (tcode > 2) return param.To(type); if (type.IsByRef) type = type.GetElementType(); return ClassifyMPack.Deserialize(type, param); }
private MPack Execute(MPack p) { var map = (MPackMap)p; //var responseBody = new RResponseBody(); RSession sesh = null; DateTime start = DateTime.Now; string method = null; MPackMap result = new MPackMap(); if (map.ContainsKey(CONST.HDR_ID)) result[CONST.HDR_ID] = map[CONST.HDR_ID]; try { // parse client input packet var token = map[CONST.HDR_TOKEN].To<string>(); var sig = map[CONST.HDR_METHOD].To<string>(); var parsedSig = RemoteCallHelper.ParseMethodName(sig); method = parsedSig.Name; sesh = _parent.Sessions.Get(token); if (sesh == null) throw new ArgumentException("Specified token is invalid"); result[CONST.HDR_TOKEN] = MPack.From(token); // get method details, parameters, return type, etc //sesh = _parent._sessions[token]; var methodInfo = sesh.Endpoint.Methods.Single(mth => mth.Name == method); var methodParams = methodInfo.Parameters; var serverArgTypes = methodParams .Select(x => x.ParameterType) .ToArray(); var serverRetType = methodInfo.ReturnType; if (!RemoteCallHelper.CheckMethodSignature(methodInfo.Method, parsedSig)) throw new InvalidOperationException("Method signature does not match that of the server's implementation"); // check if user is authorized to execute this method //if (methodInfo.Attributes.FirstOrDefault(a => a is RRequireAuth) != null) // if (!_authenticated && _parent.CredentialValidator != null) // throw new MethodAccessException("This method requires authentication"); //var role = methodInfo.Attributes.FirstOrDefault(a => a is RRequireRole) as RRequireRole; //if (role != null && _parent.CredentialValidator != null) //{ // if (!_authenticated || !_parent.CredentialValidator.IsInRole(_user, role.RequiredRole)) // throw new MethodAccessException( // $"User must be in {role.RequiredRole} role to access this method."); //} // deserialize the request body //var requestBody = ClassifyJson.Deserialize<RRequestBody>(JsonValue.Parse(p.Payload)); var mpackArgs = map[CONST.HDR_ARGS]; object[] reconArgs = new object[serverArgTypes.Length]; List<int> refParams = new List<int>(); for (int i = 0; i < reconArgs.Length; i++) { var mpk = mpackArgs[i]; var type = serverArgTypes[i]; var byref = methodParams[i].IsOut || type.IsByRef; var streamed = serverArgTypes[i].IsAssignableFrom(typeof(Stream)); if (streamed) { reconArgs[i] = new MessageConsumerStream(mpk.To<string>(), _protocol.Buffer, _cancelSource.Token, WritePacket); } else { if (byref) refParams.Add(i); reconArgs[i] = RemoteCallHelper.ParamaterToObject(type, mpk); } } // validate that we have all the required parameters for (int i = 0; i < reconArgs.Length; i++) { //if (reconArgs[i] == null && !methodParams[i].IsOptional && !methodParams[i].IsOut) // throw new ArgumentException("A required method parameter is missing."); if (reconArgs[i] == null && methodParams[i].IsOptional) reconArgs[i] = Type.Missing; } //var returnValue = methodInfo.Delegate(sesh.Instance, reconArgs); var returnValue = methodInfo.Method.Invoke(sesh.Instance, reconArgs); if (returnValue != null && !serverRetType.IsInstanceOfType(returnValue)) throw new InvalidOperationException("Return value type mismatch"); // populate ref / out parameters to the response body if (refParams.Any()) { var refoutParams = new MPackArray(Enumerable.Range(0, reconArgs.Length).Select(v => MPack.Null())); for (int i = 0; i < refParams.Count; i++) { var paramIndex = refParams[i]; refoutParams[paramIndex] = RemoteCallHelper.ObjectToParamater(reconArgs[paramIndex]); } result[CONST.HDR_ARGS] = refoutParams; } // set the return value of response body if (typeof(Stream).IsAssignableFrom(serverRetType)) { bool writable = methodInfo.Method.ReturnParameter.GetCustomAttributes(typeof(RWritable)).Any(); string tkn = Guid.NewGuid().ToString(); var wrappedStream = new MessageProviderStream(tkn, (Stream)returnValue, _protocol.Buffer, WritePacket, _cancelSource.Token, writable); result[CONST.HDR_STATUS] = MPack.From(CONST.STA_STREAM); result[CONST.HDR_VALUE] = MPack.From(tkn); } else if (serverRetType == typeof(void)) { result[CONST.HDR_STATUS] = MPack.From(CONST.STA_VOID); } else if (Attribute.IsDefined(serverRetType ?? typeof(object), typeof(RContractProvider))) { result[CONST.HDR_STATUS] = MPack.From(CONST.STA_SERVICE); REndpoint endpoint = _parent.Endpoints.SingleOrDefault(ed => ed.Interface == serverRetType); if (endpoint == null) endpoint = new REndpoint(RandomEx.GetString(20), serverRetType, context => null); // create new session var ses = new RSession(endpoint, returnValue); var policy = new CacheItemPolicy() { SlidingExpiration = _parent.SessionTimeout }; _parent.Sessions.Add(ses.Token, ses, policy); if (returnValue is IDisposable) { policy.RemovedCallback = args => ((IDisposable)args.CacheItem.Value).Dispose(); } result[CONST.HDR_VALUE] = MPack.From(ses.Token); } else { result[CONST.HDR_STATUS] = MPack.From(CONST.STA_NORMAL); result[CONST.HDR_VALUE] = RemoteCallHelper.ObjectToParamater(returnValue); } } catch (Exception ex) { string message; string type; if (ex is TargetInvocationException || ex is AggregateException) { type = ex.InnerException.GetType().Name; message = ex.InnerException.Message; } else { type = ex.GetType().Name; message = ex.Message; } result[CONST.HDR_STATUS] = MPack.From(CONST.STA_ERROR); result[CONST.HDR_VALUE] = MPack.From($"({type}){message}"); result[CONST.HDR_LOCATION] = MPack.From($"{sesh?.Endpoint.Path ?? "[invalid]"}/{method ?? "[invalid]"}()"); } DateTime end = DateTime.Now; var time = end - start; result[CONST.HDR_TIME] = MPack.From(time.TotalMilliseconds); return result; }
private void WritePacket(MPack p) { var map = p as MPackMap; if (map == null) return; int id = -1; string cmd = "null"; if (map?.ContainsKey(CONST.HDR_ID) == true) id = map[CONST.HDR_ID].To<int>(); if (map?.ContainsKey(CONST.HDR_CMD) == true) cmd = map[CONST.HDR_CMD].To<string>(); _protocol.Write(p); }
public Task WriteAsync(MPack packet) { LogWrite(packet); var bytes = packet.EncodeToBytes(); return Client.WriteAsync(bytes); }
private static void WirteArray(Stream ms, MPack mpack) { MPackArray list = mpack as MPackArray; if (list == null) throw new InvalidOperationException("A call to WirteArray can not occur unless type is of MsgPackArray"); byte b; byte[] lenBytes; int len = list.Count; if (len <= 15) { b = (byte)(0x90 + (byte)len); ms.WriteByte(b); } else if (len <= 65535) { b = 0xDC; ms.WriteByte(b); lenBytes = _convert.GetBytes((UInt16)len); ms.Write(lenBytes, 0, lenBytes.Length); } else { b = 0xDD; ms.WriteByte(b); lenBytes = _convert.GetBytes((UInt32)len); ms.Write(lenBytes, 0, lenBytes.Length); } for (int i = 0; i < len; i++) { EncodeToStream(ms, list[i]); } }
private MPack Close(MPack p) { var map = (MPackMap)p; MPackMap result = new MPackMap(); if (map.ContainsKey(CONST.HDR_ID)) result[CONST.HDR_ID] = map[CONST.HDR_ID]; if (!map.ContainsKey(CONST.HDR_TOKEN)) { result[CONST.HDR_STATUS] = MPack.From(CONST.STA_ERROR); result[CONST.HDR_VALUE] = MPack.From("Parameter missing: " + nameof(CONST.HDR_TOKEN)); return result; } var token = map[CONST.HDR_TOKEN].To<string>(); CloseSession(token); result[CONST.HDR_STATUS] = MPack.From(CONST.STA_VOID); return result; }
private void LogWrite(MPack pack) { LogTo.Trace(() => "[Remoter] Sending: " + pack.ToString().SubstringSafe(0, 1000)); }
private MPack Open(MPack p) { var map = (MPackMap)p; REndpoint endpoint = null; string clToken = null; if (map.ContainsKey(CONST.HDR_LOCATION)) endpoint = _parent.Endpoints.SingleOrDefault(end => end.Path.EqualsNoCase(map[CONST.HDR_LOCATION].To<string>())); if (map.ContainsKey(CONST.HDR_TOKEN)) clToken = map[CONST.HDR_TOKEN].To<string>(); RSession session = null; MPackMap result = new MPackMap(); if (map.ContainsKey(CONST.HDR_ID)) result[CONST.HDR_ID] = map[CONST.HDR_ID]; if (clToken != null) { session = _parent.Sessions.Get(clToken); LogTo.Debug($"Session opened (existing). {_parent.Sessions.Count} in cache."); if (session != null && _sessions.Contains(clToken)) { result[CONST.HDR_STATUS] = MPack.From(CONST.STA_NORMAL); result[CONST.HDR_VALUE] = MPack.From(clToken); return result; } } else if (endpoint != null) { object service = endpoint.GenerateService(new RContext(_client.RemoteEndpoint)); clToken = Guid.NewGuid().ToString(); session = new RSession(endpoint, service, clToken); var policy = new CacheItemPolicy() { SlidingExpiration = _parent.SessionTimeout }; if (service is IDisposable) { policy.RemovedCallback = args => { ((IDisposable)args.CacheItem.Value).Dispose(); LogTo.Debug($"[{args.CacheItem.Key}] Session object timed out and destroyed"); }; } _parent.Sessions.Set(clToken, session, policy); LogTo.Debug($"Session opened (new). {_parent.Sessions.Count} in cache."); //_parent._sessions.Add(clToken, session); } if (session == null) { result[CONST.HDR_STATUS] = MPack.From(CONST.STA_ERROR); result[CONST.HDR_VALUE] = MPack.From("No valid path or token was provided."); return result; } else { _sessions.Add(clToken); } foreach (var evt in session.Endpoint.Events) { _events.Add(clToken, new EventPropegator(session.Instance, evt, (o, args) => { MPackMap evtP = new MPackMap { {CONST.HDR_CMD, MPack.From(CONST.CMD_EVENT)}, {CONST.HDR_TOKEN, MPack.From(clToken)}, {CONST.HDR_METHOD, MPack.From(evt.Name)}, {CONST.HDR_VALUE, ClassifyMPack.Serialize(args)} }; WritePacket(evtP); })); } result[CONST.HDR_STATUS] = MPack.From(CONST.STA_NORMAL); result[CONST.HDR_VALUE] = MPack.From(clToken); return result; }