Ejemplo n.º 1
0
    public static AsyncReply TupleParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
    {
        var results = new AsyncBag <object>();
        var rt      = new AsyncReply();

        var tupleSize = data[offset++];

        length--;

        var types = new List <Type>();

        for (var i = 0; i < tupleSize; i++)
        {
            var(cs, rep) = RepresentationType.Parse(data, offset);
            types.Add(rep.GetRuntimeType());
            offset += cs;
            length -= cs;
        }

        while (length > 0)
        {
            var(cs, reply) = Codec.Parse(data, offset, connection, requestSequence);

            results.Add(reply);

            if (cs > 0)
            {
                offset += (uint)cs;
                length -= (uint)cs;
            }
            else
            {
                throw new Exception("Error while parsing structured data");
            }
        }

        results.Seal();


        results.Then(ar =>
        {
            if (ar.Length == 2)
            {
                var type = typeof(ValueTuple <,>).MakeGenericType(types.ToArray());
                rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1]));
            }
            else if (ar.Length == 3)
            {
                var type = typeof(ValueTuple <, ,>).MakeGenericType(types.ToArray());
                rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2]));
            }
            else if (ar.Length == 4)
            {
                var type = typeof(ValueTuple <, , ,>).MakeGenericType(types.ToArray());
                rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3]));
            }
        });

        return(rt);
    }
Ejemplo n.º 2
0
    public static (TransmissionTypeIdentifier, byte[]) EnumComposer(object value, DistributedConnection connection)
    {
        if (value == null)
        {
            return(TransmissionTypeIdentifier.Null, new byte[0]);
        }

        var template = Warehouse.GetTemplateByType(value.GetType());

        var intVal = Convert.ChangeType(value, (value as Enum).GetTypeCode());

        var ct = template.Constants.FirstOrDefault(x => x.Value.Equals(intVal));

        if (ct == null)
        {
            return(TransmissionTypeIdentifier.Null, new byte[0]);
        }


        var rt = new List <byte>();

        rt.AddRange(template.ClassId.ToByteArray());
        rt.Add(ct.Index);

        return(TransmissionTypeIdentifier.Enum, rt.ToArray());
    }
Ejemplo n.º 3
0
        /// <summary>
        /// Compose a structure into an array of bytes
        /// </summary>
        /// <param name="value">Structure to compose</param>
        /// <param name="connection">DistributedConnection is required in case an item in the structure is at the other end</param>
        /// <param name="includeKeys">Whether to include the structure keys</param>
        /// <param name="includeTypes">Whether to include each item DataType</param>
        /// <param name="prependLength">If true, prepend the length as UInt32 at the beginning of the returned bytes array</param>
        /// <returns>Array of bytes in the network byte order</returns>
        public static byte[] ComposeStructure(Structure value, DistributedConnection connection, bool includeKeys = true, bool includeTypes = true, bool prependLength = false)
        {
            var rt = new BinaryList();

            if (includeKeys)
            {
                foreach (var i in value)
                {
                    var key = DC.ToBytes(i.Key);
                    rt.Append((byte)key.Length, key, Compose(i.Value, connection));
                }
            }
            else
            {
                foreach (var i in value)
                {
                    rt.Append(Compose(i.Value, connection, includeTypes));
                }
            }

            if (prependLength)
            {
                rt.Insert(0, rt.Length);
            }

            return(rt.ToArray());
        }
Ejemplo n.º 4
0
    public static (TransmissionTypeIdentifier, byte[]) TupleComposer(object value, DistributedConnection connection)
    {
        if (value == null)
        {
            return(TransmissionTypeIdentifier.Null, new byte[0]);
        }

        var rt = new List <byte>();

        var fields = value.GetType().GetFields();
        var list   = fields.Select(x => x.GetValue(value)).ToArray();
        var types  = fields.Select(x => RepresentationType.FromType(x.FieldType).Compose()).ToArray();

        rt.Add((byte)list.Length);

        foreach (var t in types)
        {
            rt.AddRange(t);
        }

        var composed = ArrayComposer(list, connection);

        if (composed == null)
        {
            return(TransmissionTypeIdentifier.Null, new byte[0]);
        }
        else
        {
            rt.AddRange(composed);
            return(TransmissionTypeIdentifier.Tuple, rt.ToArray());
        }
    }
Ejemplo n.º 5
0
    public static AsyncReply TypedListParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
    {
        var rt = new AsyncBag <object>();

        // get the type
        var(hdrCs, rep) = RepresentationType.Parse(data, offset);

        offset += hdrCs;
        length -= hdrCs;

        var runtimeType = rep.GetRuntimeType();

        rt.ArrayType = runtimeType;

        while (length > 0)
        {
            var(cs, reply) = Codec.Parse(data, offset, connection, requestSequence);

            rt.Add(reply);

            if (cs > 0)
            {
                offset += (uint)cs;
                length -= (uint)cs;
            }
            else
            {
                throw new Exception("Error while parsing structured data");
            }
        }

        rt.Seal();
        return(rt);
    }
Ejemplo n.º 6
0
 /// <summary>
 /// Compose a property value.
 /// </summary>
 /// <param name="propertyValue">Property value</param>
 /// <param name="connection">DistributedConnection is required to check locality.</param>
 /// <returns>Array of bytes in the network byte order.</returns>
 public static byte[] ComposePropertyValue(PropertyValue propertyValue, DistributedConnection connection)//, bool includeAge = true)
 {
     // age, date, value
     //if (includeAge)
     return(BinaryList.ToBytes(propertyValue.Age, propertyValue.Date, Compose(propertyValue.Value, connection)));
     //else
     //  return BinaryList.ToBytes(propertyValue.Date, Compose(propertyValue.Value, connection));
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Compose a resource
 /// </summary>
 /// <param name="resource">Resource to compose.</param>
 /// <param name="connection">DistributedConnection is required to check locality.</param>
 /// <returns>Array of bytes in the network byte order.</returns>
 public static byte[] ComposeResource(IResource resource, DistributedConnection connection)
 {
     if (IsLocalResource(resource, connection))
     {
         return(DC.ToBytes((resource as DistributedResource).Id));
     }
     else
     {
         return(BinaryList.ToBytes(resource.Instance.Template.ClassId, resource.Instance.Id));
     }
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Get DataType array of a given Structure
        /// </summary>
        /// <param name="structure">Structure to get its DataTypes</param>
        /// <param name="connection">Distributed connection is required in case a type is at the other end</param>
        private static DataType[] GetStructureDateTypes(Structure structure, DistributedConnection connection)
        {
            var keys  = structure.GetKeys();
            var types = new DataType[keys.Length];

            for (var i = 0; i < keys.Length; i++)
            {
                types[i] = Codec.GetDataType(structure[keys[i]], connection);
            }
            return(types);
        }
Ejemplo n.º 9
0
    // public DistributedResourceStack Stack
    //{
    //     get { return stack; }
    //}

    /// <summary>
    /// Create a new distributed resource.
    /// </summary>
    /// <param name="connection">Connection responsible for the distributed resource.</param>
    /// <param name="template">Resource template.</param>
    /// <param name="instanceId">Instance Id given by the other end.</param>
    /// <param name="age">Resource age.</param>
    public DistributedResource(DistributedConnection connection, uint instanceId, ulong age, string link)
    {
        this.link       = link;
        this.connection = connection;
        this.instanceId = instanceId;

        //this.Instance.Template = template;
        //this.Instance.Age = age;
        //this.template = template;
        //this.age = age;
    }
Ejemplo n.º 10
0
        /// <summary>
        /// Check if a resource is local to a given connection.
        /// </summary>
        /// <param name="resource">Resource to check.</param>
        /// <param name="connection">DistributedConnection to check if the resource is local to it.</param>
        /// <returns>True, if the resource owner is the given connection, otherwise False.</returns>
        static bool IsLocalResource(IResource resource, DistributedConnection connection)
        {
            if (resource is DistributedResource)
            {
                if ((resource as DistributedResource).Connection == connection)
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Compose an array of property values.
        /// </summary>
        /// <param name="array">PropertyValue array.</param>
        /// <param name="connection">DistributedConnection is required to check locality.</param>
        /// <param name="prependLength">If True, prepend the length as UInt32 at the beginning of the output.</param>
        /// <returns>Array of bytes in the network byte order.</returns>
        /// //, bool includeAge = true
        public static byte[] ComposePropertyValueArray(PropertyValue[] array, DistributedConnection connection, bool prependLength = false)
        {
            var rt = new List <byte>();

            for (var i = 0; i < array.Length; i++)
            {
                rt.AddRange(ComposePropertyValue(array[i], connection));
            }
            if (prependLength)
            {
                rt.InsertRange(0, DC.ToBytes(rt.Count));
            }
            return(rt.ToArray());
        }
Ejemplo n.º 12
0
    public static AsyncReply TypedMapParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
    {
        // get key type
        var(keyCs, keyRepType) = RepresentationType.Parse(data, offset);
        offset += keyCs;
        length -= keyCs;

        var(valueCs, valueRepType) = RepresentationType.Parse(data, offset);
        offset += valueCs;
        length -= valueCs;

        var map = (IMap)Activator.CreateInstance(typeof(Map <,>).MakeGenericType(keyRepType.GetRuntimeType(), valueRepType.GetRuntimeType()));

        var rt = new AsyncReply();

        var results = new AsyncBag <object>();

        while (length > 0)
        {
            var(cs, reply) = Codec.Parse(data, offset, connection, requestSequence);


            results.Add(reply);

            if (cs > 0)
            {
                offset += (uint)cs;
                length -= (uint)cs;
            }
            else
            {
                throw new Exception("Error while parsing structured data");
            }
        }

        results.Seal();

        results.Then(ar =>
        {
            for (var i = 0; i < ar.Length; i += 2)
            {
                map.Add(ar[i], ar[i + 1]);
            }

            rt.Trigger(map);
        });


        return(rt);
    }
Ejemplo n.º 13
0
    public static byte[] ArrayComposer(IEnumerable value, DistributedConnection connection)
    {
        if (value == null)
        {
            return(null);
        }

        var rt = new List <byte>();

        foreach (var i in value)
        {
            rt.AddRange(Codec.Compose(i, connection));
        }

        return(rt.ToArray());
    }
Ejemplo n.º 14
0
    public static byte[] HistoryComposer(KeyList <PropertyTemplate, PropertyValue[]> history,
                                         DistributedConnection connection, bool prependLength = false)
    {
        //@TODO:Test
        var rt = new BinaryList();

        for (var i = 0; i < history.Count; i++)
        {
            rt.AddUInt8(history.Keys.ElementAt(i).Index)
            .AddUInt8Array(Codec.Compose(history.Values.ElementAt(i), connection));
        }

        if (prependLength)
        {
            rt.InsertInt32(0, rt.Length);
        }

        return(rt.ToArray());
    }
Ejemplo n.º 15
0
        /// <summary>
        /// Compose an array of resources
        /// </summary>
        /// <param name="resources">Array of resources.</param>
        /// <param name="connection">DistributedConnection is required to check locality.</param>
        /// <param name="prependLength">If True, prepend the length of the output at the beginning.</param>
        /// <returns>Array of bytes in the network byte order.</returns>

        public static byte[] ComposeResourceArray(IResource[] resources, DistributedConnection connection, bool prependLength = false)
        {
            if (resources == null || resources?.Length == 0)
            {
                return prependLength ? new byte[] { 0, 0, 0, 0 }
            }
            : new byte[0];

            var rt         = new BinaryList();
            var comparsion = Compare(null, resources[0], connection);

            rt.Append((byte)comparsion);

            if (comparsion == ResourceComparisonResult.Local)
            {
                rt.Append((resources[0] as DistributedResource).Id);
            }
            else if (comparsion == ResourceComparisonResult.Distributed)
            {
                rt.Append(resources[0].Instance.Id);
            }

            for (var i = 1; i < resources.Length; i++)
            {
                comparsion = Compare(resources[i - 1], resources[i], connection);
                rt.Append((byte)comparsion);
                if (comparsion == ResourceComparisonResult.Local)
                {
                    rt.Append((resources[i] as DistributedResource).Id);
                }
                else if (comparsion == ResourceComparisonResult.Distributed)
                {
                    rt.Append(resources[i].Instance.Id);
                }
            }

            if (prependLength)
            {
                rt.Insert(0, rt.Length);
            }

            return(rt.ToArray());
        }
Ejemplo n.º 16
0
    /// <summary>
    /// Parse a value
    /// </summary>
    /// <param name="data">Bytes array</param>
    /// <param name="offset">Zero-indexed offset.</param>
    /// <param name="size">Output the number of bytes parsed</param>
    /// <param name="connection">DistributedConnection is required in case a structure in the array holds items at the other end.</param>
    /// <param name="dataType">DataType, in case the data is not prepended with DataType</param>
    /// <returns>Value</returns>
    public static (uint, AsyncReply) Parse(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence, TransmissionType?dataType = null)
    {
        uint len = 0;

        if (dataType == null)
        {
            (var longLen, dataType) = TransmissionType.Parse(data, offset, (uint)data.Length);
            len    = (uint)longLen;
            offset = dataType.Value.Offset;
        }
        else
        {
            len = (uint)dataType.Value.ContentLength;
        }

        var tt = dataType.Value;

        if (tt.Class == TransmissionTypeClass.Fixed)
        {
            return(len, FixedParsers[tt.Exponent][tt.Index](data, dataType.Value.Offset, (uint)tt.ContentLength, connection, requestSequence));
Ejemplo n.º 17
0
        /// <summary>
        /// Compose an array of structures into an array of bytes
        /// </summary>
        /// <param name="structures">Array of Structure to compose</param>
        /// <param name="connection">DistributedConnection is required in case a structure in the array holds items at the other end</param>
        /// <param name="prependLength">If true, prepend the length as UInt32 at the beginning of the returned bytes array</param>
        /// <returns>Array of bytes in the network byte order</returns>
        public static byte[] ComposeStructureArray(Structure[] structures, DistributedConnection connection, bool prependLength = false)
        {
            if (structures == null || structures?.Length == 0)
            {
                return prependLength ? new byte[] { 0, 0, 0, 0 }
            }
            : new byte[0];

            var rt         = new BinaryList();
            var comparsion = StructureComparisonResult.Structure;

            rt.Append((byte)comparsion);
            rt.Append(ComposeStructure(structures[0], connection, true, true, true));

            for (var i = 1; i < structures.Length; i++)
            {
                comparsion = Compare(structures[i - 1], structures[i], connection);
                rt.Append((byte)comparsion);

                if (comparsion == StructureComparisonResult.Structure)
                {
                    rt.Append(ComposeStructure(structures[i], connection, true, true, true));
                }
                else if (comparsion == StructureComparisonResult.StructureSameKeys)
                {
                    rt.Append(ComposeStructure(structures[i], connection, false, true, true));
                }
                else if (comparsion == StructureComparisonResult.StructureSameTypes)
                {
                    rt.Append(ComposeStructure(structures[i], connection, false, false, true));
                }
            }

            if (prependLength)
            {
                rt.Insert(0, rt.Length);
            }

            return(rt.ToArray());
        }
Ejemplo n.º 18
0
        public override bool Execute(HTTPConnection sender)
        {
            if (sender.Request.Filename.StartsWith("/iip/"))
            {
                // find the service
                var path = sender.Request.Filename.Substring(5);// sender.Request.Query["path"];


                Warehouse.Get(path).Then((r) =>
                {
                    if (r is DistributedServer)
                    {
                        var httpServer = sender.Parent;
                        var iipServer  = r as DistributedServer;
                        var tcpSocket  = sender.Unassign();
                        if (tcpSocket == null)
                        {
                            return;
                        }

                        var wsSocket = new WSSocket(tcpSocket);
                        httpServer.RemoveConnection(sender);

                        //httpServer.Connections.Remove(sender);
                        var iipConnection = new DistributedConnection();
                        //                      iipConnection.OnReady += IipConnection_OnReady;
//                        iipConnection.Server = iipServer;
                        //                    iipConnection.Assign(wsSocket);

                        iipServer.AddConnection(iipConnection);
                        iipConnection.Assign(wsSocket);
                        wsSocket.Begin();
                    }
                });

                return(true);
            }

            return(false);
        }
Ejemplo n.º 19
0
    //public static (TransmissionTypeIdentifier, byte[]) ListComposerFromArray(dynamic value, DistributedConnection connection)
    //{
    //    var rt = new List<byte>();
    //    var array = (object[])value;

    //    for (var i = 0; i < array.Length; i++)
    //        rt.AddRange(Codec.Compose(array[i], connection));

    //    return (TransmissionTypeIdentifier.List, rt.ToArray());
    //}

    public static (TransmissionTypeIdentifier, byte[]) ListComposer(object value, DistributedConnection connection)
    {
        var rt = ArrayComposer((IEnumerable)value, connection);

        if (rt == null)
        {
            return(TransmissionTypeIdentifier.Null, new byte[0]);
        }
        else
        {
            return(TransmissionTypeIdentifier.List, rt);
        }


        //var rt = new List<byte>();
        //var list = (IEnumerable)value;// ((List<object>)value);

        //foreach (var o in list)
        //    rt.AddRange(Codec.Compose(o, connection));

        //return (TransmissionTypeIdentifier.List, rt.ToArray());
    }
Ejemplo n.º 20
0
    public static AsyncReply RecordListParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
    {
        var rt = new AsyncBag <IRecord>();

        while (length > 0)
        {
            var(cs, reply) = Codec.Parse(data, offset, connection, requestSequence);

            rt.Add(reply);

            if (cs > 0)
            {
                offset += (uint)cs;
                length -= (uint)cs;
            }
            else
            {
                throw new Exception("Error while parsing structured data");
            }
        }

        rt.Seal();
        return(rt);
    }
Ejemplo n.º 21
0
    public override AsyncReply <bool> Execute(HTTPConnection sender)
    {
        if (sender.IsWebsocketRequest())
        {
            if (Server == null)
            {
                return(new AsyncReply <bool>(false));
            }

            var tcpSocket = sender.Unassign();

            if (tcpSocket == null)
            {
                return(new AsyncReply <bool>(false));
            }

            var httpServer = sender.Parent;
            var wsSocket   = new WSocket(tcpSocket);
            httpServer.Remove(sender);

            var iipConnection = new DistributedConnection();

            Server.Add(iipConnection);
            iipConnection.Assign(wsSocket);
            wsSocket.Begin();

            return(new AsyncReply <bool>(true));
        }

        return(new AsyncReply <bool>(false));

        /*
         * if (sender.Request.Filename.StartsWith("/iip/"))
         * {
         *  // find the service
         *  var path = sender.Request.Filename.Substring(5);// sender.Request.Query["path"];
         *
         *
         *  Warehouse.Get(path).Then((r) =>
         *  {
         *      if (r is DistributedServer)
         *      {
         *          var httpServer = sender.Parent;
         *          var iipServer = r as DistributedServer;
         *          var tcpSocket = sender.Unassign();
         *          if (tcpSocket == null)
         *              return;
         *
         *          var wsSocket = new WSSocket(tcpSocket);
         *          httpServer.RemoveConnection(sender);
         *
         *          //httpServer.Connections.Remove(sender);
         *          var iipConnection = new DistributedConnection();
         * //                      iipConnection.OnReady += IipConnection_OnReady;
         * //                        iipConnection.Server = iipServer;
         * //                    iipConnection.Assign(wsSocket);
         *
         *          iipServer.AddConnection(iipConnection);
         *          iipConnection.Assign(wsSocket);
         *          wsSocket.Begin();
         *      }
         *  });
         *
         *  return true;
         * }
         *
         * return false;
         */
    }
Ejemplo n.º 22
0
 private void IipConnection_OnReady(DistributedConnection sender)
 {
     Warehouse.Put(sender.RemoteUsername, sender, null, sender.Server).Wait();
 }
Ejemplo n.º 23
0
 public static unsafe AsyncReply Int128Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
 {
     fixed(byte *ptr = &data[offset])
     return(new AsyncReply <decimal>(*(decimal *)ptr));
 }
Ejemplo n.º 24
0
 public static unsafe AsyncReply UInt16Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
 {
     fixed(byte *ptr = &data[offset])
     return(new AsyncReply <ushort>(*(ushort *)ptr));
 }
Ejemplo n.º 25
0
    public static AsyncReply <KeyList <PropertyTemplate, PropertyValue[]> > HistoryParser(byte[] data, uint offset, uint length, IResource resource, DistributedConnection connection, uint[] requestSequence)
    {
        //var count = (int)toAge - (int)fromAge;

        var list = new KeyList <PropertyTemplate, PropertyValue[]>();

        var reply = new AsyncReply <KeyList <PropertyTemplate, PropertyValue[]> >();

        var bagOfBags = new AsyncBag <PropertyValue[]>();

        var ends = offset + length;

        while (offset < ends)
        {
            var index = data[offset++];
            var pt    = resource.Instance.Template.GetPropertyTemplateByIndex(index);
            list.Add(pt, null);
            var cs = data.GetUInt32(offset, Endian.Little);
            offset += 4;

            var(len, pv) = PropertyValueParser(data, offset, connection, requestSequence);

            bagOfBags.Add(pv);// ParsePropertyValueArray(data, offset, cs, connection));
            offset += len;
        }

        bagOfBags.Seal();

        bagOfBags.Then(x =>
        {
            for (var i = 0; i < list.Count; i++)
            {
                list[list.Keys.ElementAt(i)] = x[i];
            }

            reply.Trigger(list);
        });

        return(reply);
    }
Ejemplo n.º 26
0
    public static (uint, AsyncReply <PropertyValue>) PropertyValueParser(byte[] data, uint offset, DistributedConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
    {
        var reply = new AsyncReply <PropertyValue>();

        var age = data.GetUInt64(offset, Endian.Little);

        offset += 8;

        DateTime date = data.GetDateTime(offset, Endian.Little);

        offset += 8;


        var(valueSize, results) = Codec.Parse(data, offset, connection, requestSequence);

        results.Then(value =>
        {
            reply.Trigger(new PropertyValue(value, age, date));
        });

        return(16 + valueSize, reply);
    }
Ejemplo n.º 27
0
 public static AsyncReply Char8Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
 {
     return(new AsyncReply <char>((char)data[offset]));
 }
Ejemplo n.º 28
0
 public abstract AsyncReply <IResource[]> Query(string path, DistributedConnection sender);
 public MyChildResource(DistributedConnection connection, uint instanceId, ulong age, string link) : base(connection, instanceId, age, link)
 {
 }
Ejemplo n.º 30
0
 public static unsafe AsyncReply Float64Parser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence)
 {
     fixed(byte *ptr = &data[offset])
     return(new AsyncReply <double>(*(double *)ptr));
 }