/// <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); }
/// <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); }