Пример #1
0
        /// <summary>
        /// Parse a structure
        /// </summary>
        /// <param name="data">Bytes array</param>
        /// <param name="offset">Zero-indexed offset.</param>
        /// <param name="length">Number of bytes to parse.</param>
        /// <param name="connection">DistributedConnection is required in case a structure in the array holds items at the other end.</param>
        /// <param name="parsedKeys">Array to store keys in.</param>
        /// <param name="parsedTypes">Array to store DataTypes in.</param>
        /// <param name="keys">Array of keys, in case the data doesn't include keys</param>
        /// <param name="types">Array of DataTypes, in case the data doesn't include DataTypes</param>
        /// <returns>Structure</returns>
        public static AsyncReply <Structure> ParseStructure(byte[] data, uint offset, uint length, DistributedConnection connection, out Structure.StructureMetadata metadata, string[] keys = null, DataType[] types = null)// out string[] parsedKeys, out DataType[] parsedTypes, string[] keys = null, DataType[] types = null)
        {
            var reply    = new AsyncReply <Structure>();
            var bag      = new AsyncBag <object>();
            var keylist  = new List <string>();
            var typelist = new List <DataType>();

            if (keys == null)
            {
                while (length > 0)
                {
                    var len = data[offset++];
                    keylist.Add(data.GetString(offset, len));
                    offset += len;

                    typelist.Add((DataType)data[offset]);

                    uint rt;
                    bag.Add(Codec.Parse(data, offset, out rt, connection));
                    length -= rt + len + 1;
                    offset += rt;
                }
            }
            else if (types == null)
            {
                keylist.AddRange(keys);

                while (length > 0)
                {
                    typelist.Add((DataType)data[offset]);

                    uint rt;
                    bag.Add(Codec.Parse(data, offset, out rt, connection));
                    length -= rt;
                    offset += rt;
                }
            }
            else
            {
                keylist.AddRange(keys);
                typelist.AddRange(types);

                var i = 0;
                while (length > 0)
                {
                    uint rt;
                    bag.Add(Codec.Parse(data, offset, out rt, connection, types[i]));
                    length -= rt;
                    offset += rt;
                    i++;
                }
            }

            bag.Seal();

            bag.Then((res) =>
            {
                // compose the list
                var s = new Structure();
                for (var i = 0; i < keylist.Count; i++)
                {
                    s[keylist[i]] = res[i];
                }
                reply.Trigger(s);
            });

            metadata = new Structure.StructureMetadata()
            {
                Keys = keylist.ToArray(), Types = typelist.ToArray()
            };

            return(reply);
        }
Пример #2
0
        /// <summary>
        /// Parse an array of structures
        /// </summary>
        /// <param name="data">Bytes array</param>
        /// <param name="offset">Zero-indexed offset</param>
        /// <param name="length">Number of bytes to parse</param>
        /// <param name="connection">DistributedConnection is required in case a structure in the array holds items at the other end</param>
        /// <returns>Array of structures</returns>
        public static AsyncBag <Structure> ParseStructureArray(byte[] data, uint offset, uint length, DistributedConnection connection)
        {
            var reply = new AsyncBag <Structure>();

            if (length == 0)
            {
                reply.Seal();
                return(reply);
            }

            var end = offset + length;

            var result = (StructureComparisonResult)data[offset++];

            AsyncReply previous = null;

            // string[] previousKeys = null;
            // DataType[] previousTypes = null;

            Structure.StructureMetadata metadata = new Structure.StructureMetadata();


            if (result == StructureComparisonResult.Null)
            {
                previous = new AsyncReply <Structure>(null);
            }
            else if (result == StructureComparisonResult.Structure)
            {
                uint cs = data.GetUInt32(offset);
                offset  += 4;
                previous = ParseStructure(data, offset, cs, connection, out metadata);
                offset  += cs;
            }

            reply.Add(previous);


            while (offset < end)
            {
                result = (StructureComparisonResult)data[offset++];

                if (result == StructureComparisonResult.Null)
                {
                    previous = new AsyncReply <Structure>(null);
                }
                else if (result == StructureComparisonResult.Structure)
                {
                    uint cs = data.GetUInt32(offset);
                    offset  += 4;
                    previous = ParseStructure(data, offset, cs, connection, out metadata);// out previousKeys, out previousTypes);
                    offset  += cs;
                }
                else if (result == StructureComparisonResult.StructureSameKeys)
                {
                    uint cs = data.GetUInt32(offset);
                    offset  += 4;
                    previous = ParseStructure(data, offset, cs, connection, out metadata, metadata.Keys);
                    offset  += cs;
                }
                else if (result == StructureComparisonResult.StructureSameTypes)
                {
                    uint cs = data.GetUInt32(offset);
                    offset  += 4;
                    previous = ParseStructure(data, offset, cs, connection, out metadata, metadata.Keys, metadata.Types);
                    offset  += cs;
                }

                reply.Add(previous);
            }

            reply.Seal();
            return(reply);
        }