using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Tango.Transport.Adapters { /// /// Represents an in-memory transport adapter. /// /// public class MemoryTransportAdapter : TransportAdapterBase { #region Memory Transport Manager internal static class MemoryTransportManager { private static List _adapters; static MemoryTransportManager() { _adapters = new List(); } internal static void Connect(MemoryTransportAdapter adapter) { if (adapter == null) { throw new NullReferenceException("Cannot connect null adapter."); } if (String.IsNullOrWhiteSpace(adapter.Address)) { throw new InvalidOperationException("Cannot register a memory adapter with null address."); } if (_adapters.Where(x => x.Address == adapter.Address).Count() > 1) { throw new InvalidOperationException("Cannot register more than two memory adapters with the same address."); } if (_adapters.Contains(adapter)) { throw new InvalidOperationException("The specified memory adapter is already registered."); } _adapters.Add(adapter); } internal static void Disconnect(MemoryTransportAdapter adapter) { if (adapter == null) { throw new NullReferenceException("Cannot disconnect null adapter."); } _adapters.Remove(adapter); } internal static void Write(MemoryTransportAdapter adapter, byte[] data) { Task.Factory.StartNew(() => { var other_adapter = _adapters.ToList().SingleOrDefault(x => x.Address == adapter.Address && x != adapter); if (other_adapter != null) { other_adapter.EmulateDataAvailable(data); } }); } } #endregion /// /// Initializes a new instance of the class. /// /// The address. public MemoryTransportAdapter(String address) { ComponentName = $"In-Memory Adapter {_component_counter++}"; Address = address; } /// /// Emulates in coming data. /// /// The data. internal void EmulateDataAvailable(byte[] data) { OnDataAvailable(data); } /// /// Writes the specified data to the stream. /// /// The data. public override void Write(byte[] data, bool immidiate = false) { ThrowIfDisposed(); try { TotalBytesSent += data.Length; _totalBytes += data.Length; MemoryTransportManager.Write(this, data); } catch (Exception ex) { OnFailed(LogManager.Log(ex)); } } /// /// Connects the transport component. /// /// public override Task Connect() { MemoryTransportManager.Connect(this); State = TransportComponentState.Connected; return Task.FromResult(new object()); } /// /// Disconnects the transport component. /// /// public override Task Disconnect() { MemoryTransportManager.Disconnect(this); State = TransportComponentState.Disconnected; return Task.FromResult(new object()); } } }