/// <summary> /// Write to stream. /// </summary> public void Write(Stream to) { using (MemoryStream ms = new MemoryStream()) { var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); try { formatter.Serialize(ms, map); } catch (Exception e) { throw new InvalidDataException("Bad message: Could not serialise.", e); } ms.Position = 0; writeSize(to, ms.Length); ms.CopyTo(to); } List <LongStream> l_l = new List <LongStream>(); List <ArbitraryDataContainer> l_a = new List <ArbitraryDataContainer>(); foreach (var val in map.Hashtable) { if (val.Value is LongStream) { l_l.Add(val.Value as LongStream); } else if (val.Value is ArbitraryDataContainer) { l_a.Add(val.Value as ArbitraryDataContainer); } } foreach (var adc in l_a) { var template = new ArbitraryDataContainer.Template(adc); template.WriteStream(to); adc.WriteStream(to); } foreach (var ls in l_l) { ls.WriteStream(to); OnLongStreamWriteComplete(ls); } }
/// <summary> /// Read (blocking) from stream. /// </summary> public void Read(Stream from) { var size = readSize(from); if (size <= 0 || size > MaxSize) { throw new InvalidDataException("Bad length."); } else { lock (from) { byte[] buffer = new byte[size]; from.BlockingRead(buffer, 0, buffer.Length); using (MemoryStream ms = new MemoryStream(buffer)) { ms.Position = 0; var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); try { map = formatter.Deserialize(ms) as Internal; } catch (Exception e) { throw new InvalidDataException("Deserialisation failed.", e); } if (map == null) { throw new InvalidDataException("Data received is of invalid type."); } } } } // File.WriteAllText("fuck2", this.ToString()); List <LongStream> templates = new List <LongStream>(); List <string> keys = new List <string>(); Dictionary <Guid, LongStream> reads = new Dictionary <Guid, LongStream>(); List <ArbitraryDataContainer> c_templates = new List <ArbitraryDataContainer>(); List <string> c_keys = new List <string>(); foreach (var vl in map.Hashtable) { if (vl.Value is LongStream) { templates.Add(vl.Value as LongStream); keys.Add(vl.Key); } if (vl.Value is ArbitraryDataContainer) { c_templates.Add(vl.Value as ArbitraryDataContainer); c_keys.Add(vl.Key); } } //ADC if (c_templates.Count > 0) { for (int i = 0; i < c_templates.Count; i++) { var template = new ArbitraryDataContainer.Template(); template.ReadStream(from); int j = 0; for (; j < c_templates.Count; j++) { var adc = c_templates[j]; if (adc.UUID.Equals(template.UUID)) { //Match, adc is correct type var ty = template.InvokeFrom(adc.GetType()); ty.ReadStream(from); map.Hashtable[c_keys[j]] = ty; break; } } if (j >= c_templates.Count) { throw new InvalidDataException("Unexpected ADC UUID received."); } } } //LongStream if (templates.Count > 0) { //expected for (int i = 0; i < templates.Count; i++) { var ls = OnCreateLongStream(); ls.StreamReadCreate = LongStreamReadCreate; ls.ReadStream(from); OnLongStreamReadComplete(ls); reads.Add(ls.UUID, ls); } //match them up //foreach (var l in templates) for (int i = 0; i < templates.Count; i++) { var l = templates[i]; if (reads.ContainsKey(l.UUID)) { var match = reads[l.UUID]; if (match.StreamLength != l.StreamLength) { throw new InvalidDataException("LongStream metadata incongruence."); } //l.Backing = match.Backing; map.Hashtable[keys[i]] = match; } else { throw new InvalidDataException("Expected LongStream UUID not received."); } } } }