diff options
Diffstat (limited to 'Software/Visual_Studio/Tango.Transport')
59 files changed, 513 insertions, 6630 deletions
diff --git a/Software/Visual_Studio/Tango.Transport/Adapters/MemoryTransportAdapter.cs b/Software/Visual_Studio/Tango.Transport/Adapters/MemoryTransportAdapter.cs index fa365f805..09b98527a 100644 --- a/Software/Visual_Studio/Tango.Transport/Adapters/MemoryTransportAdapter.cs +++ b/Software/Visual_Studio/Tango.Transport/Adapters/MemoryTransportAdapter.cs @@ -81,7 +81,6 @@ namespace Tango.Transport.Adapters /// <param name="address">The address.</param> public MemoryTransportAdapter(String address) { - ComponentName = $"In-Memory Adapter {_component_counter++}"; Address = address; } @@ -98,7 +97,7 @@ namespace Tango.Transport.Adapters /// Writes the specified data to the stream. /// </summary> /// <param name="data">The data.</param> - public override void Write(byte[] data, bool immidiate = false) + public override void Write(byte[] data) { ThrowIfDisposed(); diff --git a/Software/Visual_Studio/Tango.Transport/Adapters/MultiTransportAdapter.cs b/Software/Visual_Studio/Tango.Transport/Adapters/MultiTransportAdapter.cs deleted file mode 100644 index f4f7eb9cf..000000000 --- a/Software/Visual_Studio/Tango.Transport/Adapters/MultiTransportAdapter.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Tango.Transport.Adapters -{ - /// <summary> - /// Experimental... - /// </summary> - /// <seealso cref="Tango.Transport.TransportAdapterBase" /> - public class MultiTransportAdapter : TransportAdapterBase - { - public class MultiTransportAdapterDataAvailableEventArgs : EventArgs - { - public ITransportAdapter Adapter { get; set; } - public byte[] Data { get; set; } - } - - public class MultiTransportAdapterStateChangedEventArgs : EventArgs - { - public ITransportAdapter Adapter { get; set; } - public TransportComponentState State { get; set; } - } - - public event EventHandler<MultiTransportAdapterDataAvailableEventArgs> AdapterDataAvailable; - public event EventHandler<MultiTransportAdapterStateChangedEventArgs> AdapterStateChangedAvailable; - - public ReadOnlyCollection<ITransportAdapter> Adapters { get; private set; } - - public MultiTransportAdapter() - { - Adapters = new ReadOnlyCollection<ITransportAdapter>(new List<ITransportAdapter>()); - ComponentName = "Multi Transport Adapter"; - } - - public override void Write(byte[] data, bool immidiate = false) - { - Adapters.ToList().ForEach(x => x.Write(data)); - } - - public void Write(byte[] data, ITransportAdapter adapter) - { - adapter.Write(data); - } - - public override async Task Connect() - { - foreach (var adapter in Adapters.ToList().Where(x => x.State != TransportComponentState.Connected)) - { - await adapter.Connect(); - } - } - - public override async Task Disconnect() - { - foreach (var adapter in Adapters.ToList()) - { - await adapter.Disconnect(); - } - } - - public override void Dispose() - { - foreach (var adapter in Adapters.ToList()) - { - adapter.Dispose(); - } - } - - public void AddAdapter(ITransportAdapter adapter) - { - List<ITransportAdapter> list = Adapters.ToList(); - list.Add(adapter); - Adapters = new ReadOnlyCollection<ITransportAdapter>(list); - - adapter.DataAvailable += Adapter_DataAvailable; - adapter.StateChanged += Adapter_StateChanged; - } - - public void RemoveAdapter(ITransportAdapter adapter) - { - List<ITransportAdapter> list = Adapters.ToList(); - list.Remove(adapter); - Adapters = new ReadOnlyCollection<ITransportAdapter>(list); - - adapter.DataAvailable -= Adapter_DataAvailable; - adapter.StateChanged -= Adapter_StateChanged; - } - - public void ClearAdapters() - { - foreach (var adapter in Adapters.ToList()) - { - adapter.DataAvailable -= Adapter_DataAvailable; - adapter.StateChanged -= Adapter_StateChanged; - } - - Adapters = new ReadOnlyCollection<ITransportAdapter>(new List<ITransportAdapter>()); - } - - private void Adapter_StateChanged(object sender, TransportComponentState state) - { - AdapterStateChangedAvailable?.Invoke(this, new MultiTransportAdapterStateChangedEventArgs() - { - Adapter = sender as ITransportAdapter, - State = state, - }); - } - - private void Adapter_DataAvailable(object sender, byte[] data) - { - OnDataAvailable(data); - - AdapterDataAvailable?.Invoke(this, new MultiTransportAdapterDataAvailableEventArgs() - { - Adapter = sender as ITransportAdapter, - Data = data, - }); - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Adapters/SignalRTransportAdapter.cs b/Software/Visual_Studio/Tango.Transport/Adapters/SignalRTransportAdapter.cs deleted file mode 100644 index c9a2453f0..000000000 --- a/Software/Visual_Studio/Tango.Transport/Adapters/SignalRTransportAdapter.cs +++ /dev/null @@ -1,380 +0,0 @@ -using Microsoft.AspNet.SignalR.Client; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Tango.Core; - -namespace Tango.Transport.Adapters -{ - /// <summary> - /// Represents an adapter for communicating via SignalR protocol. - /// </summary> - /// <seealso cref="Tango.Transport.TransportAdapterBase" /> - public class SignalRTransportAdapter : TransportAdapterBase - { - private IHubProxy _proxy; - private HubConnection _connection; - private Thread _pushThread; - private ProducerConsumerQueue<byte[]> _pushQueue; - private object _writeSyncObject = new object(); - - /// <summary> - /// Gets or sets the URL of the SignalR service. - /// </summary> - public String Url { get; set; } - - /// <summary> - /// Gets or sets the SignalR hub name. - /// </summary> - public String Hub { get; set; } - - /// <summary> - /// Gets or sets the serial number of the remote machine (Use only for <see cref="SignalRTransportAdapterMode.CreateSession"/>) mode. - /// </summary> - public String SerialNumber { get; set; } - - /// <summary> - /// Gets or sets the remote session identifier. - /// </summary> - public String SessionID { get; private set; } - - /// <summary> - /// Gets or sets the interval of write operation. - /// Unlike other adapters, the SignalR adapter accumulates multiple write operations into one chunk. - /// </summary> - public TimeSpan WriteInterval { get; set; } - - /// <summary> - /// Gets or sets the adapter mode. - /// </summary> - public SignalRTransportAdapterMode Mode { get; set; } - - /// <summary> - /// Gets or sets the adapter connection timeout. - /// </summary> - public TimeSpan ConnectionTimeout { get; set; } - - /// <summary> - /// Initializes a new instance of the <see cref="SignalRTransportAdapter"/> class. - /// </summary> - public SignalRTransportAdapter() : base() - { - ConnectionTimeout = TimeSpan.FromSeconds(30); - WriteInterval = TimeSpan.FromMilliseconds(1); - ComponentName = $"SignalR Adapter {_component_counter++}"; - } - - /// <summary> - /// Initializes a new instance of the <see cref="SignalRTransportAdapter"/> class. - /// </summary> - /// <param name="url">The service address.</param> - /// <param name="hub">The hub name.</param> - /// <param name="mode">The adapter mode.</param> - /// <param name="serialNumber">The machine serial number (when creating session).</param> - /// <param name="sessionID">The session identifier (when joining session).</param> - public SignalRTransportAdapter(String url, String hub, SignalRTransportAdapterMode mode, String serialNumber = null, String sessionID = null, String ipAddress = null) : this() - { - Url = url; - Hub = hub; - Mode = mode; - SerialNumber = serialNumber; - SessionID = sessionID; - Address = sessionID; - - if (!String.IsNullOrWhiteSpace(ipAddress)) - { - Address = ipAddress; - } - } - - /// <summary> - /// Writes the specified data to the stream. - /// </summary> - /// <param name="data">The data.</param> - /// <param name="immidiate">Writes the data as soon as possible while ignoring any message queuing and batching.</param> - public override void Write(byte[] data, bool immidiate = false) - { - TotalBytesSent += data.Length; - _totalBytes += data.Length; - - AppendTransferRateBytes(data.Length); - - if (!immidiate) - { - _pushQueue.BlockEnqueue(data); - } - else - { - try - { - lock (_writeSyncObject) - { - _proxy.Invoke("Write", new List<byte[]>() { data }).GetAwaiter().GetResult(); - } - } - catch (Exception ex) - { - OnFailed(LogManager.Log(ex, $"{ComponentName}: Error writing to SignalR adapter ({Address}).")); - return; - } - } - } - - /// <summary> - /// Connects the transport component. - /// </summary> - /// <returns></returns> - public override Task Connect() - { - if (State != TransportComponentState.Connected) - { - LogManager.Log($"{ComponentName}: Connecting SignalR adapter..."); - - bool completed = false; - - TaskCompletionSource<object> completionSource = new TaskCompletionSource<object>(); - - _connection = new HubConnection(Url); - _proxy = _connection.CreateHubProxy(Hub); - - Core.Threading.TimeoutTask.StartNew(() => - { - if (!completed) - { - completed = true; - completionSource.SetException(new TimeoutException("Could not reach the remote machine after the given timeout.")); - } - - }, ConnectionTimeout); - - if (Mode == SignalRTransportAdapterMode.CreateSession) - { - _proxy.On("SessionCreated", () => - { - try - { - if (!completed) - { - completed = true; - - LogManager.Log($"{ComponentName}: SignalR adapter session created ({SessionID})..."); - LogManager.Log($"{ComponentName}: SingalR adapter connected."); - State = TransportComponentState.Connected; - - StartPushThread(); - - completionSource.SetResult(true); - } - } - catch (Exception ex) - { - if (!completed) - { - LogManager.Log(ex, $"{ComponentName}: Error occurred after session created."); - completed = true; - completionSource.SetException(ex); - } - } - }); - } - - _connection.StateChanged += async (x) => - { - try - { - if (x.NewState == ConnectionState.Connected) - { - if (Mode == SignalRTransportAdapterMode.CreateSession) - { - LogManager.Log($"{ComponentName}: Creating SignalR adapter Session..."); - SessionID = await _proxy.Invoke<String>("CreateSession", SerialNumber); - } - else - { - LogManager.Log($"{ComponentName}: Joining SignalR adapter session ({SessionID})..."); - await _proxy.Invoke("JoinSession", SessionID); - LogManager.Log($"{ComponentName}: SingalR adapter connected."); - } - - if (Mode == SignalRTransportAdapterMode.JoinSession) - { - if (!completed) - { - completed = true; - State = TransportComponentState.Connected; - StartPushThread(); - completionSource.SetResult(true); - } - } - } - } - catch (Exception ex) - { - if (!completed) - { - completed = true; - LogManager.Log(ex, $"{ComponentName}: Error occurred on connection state changed event."); - completionSource.SetException(ex); - } - } - }; - - _proxy.On<List<byte[]>>("DataAvailable", (dataCollection) => { OnDataAvailable(dataCollection); }); - _connection.Start(); - - return completionSource.Task; - } - - return Task.FromResult(true); - } - - /// <summary> - /// Disconnects the transport component. - /// </summary> - /// <returns></returns> - public override Task Disconnect() - { - return Task.Factory.StartNew(() => - { - if (State == TransportComponentState.Connected) - { - LogManager.Log($"{ComponentName}: Disconnecting SignalR adapter..."); - Core.Threading.TimeoutTask.StartNew(() => - { - try - { - _connection.Stop(); - _connection.Dispose(); - - try - { - if (_pushThread != null) - { - _pushThread.Abort(); - } - } - catch { } - } - catch (Exception ex) - { - LogManager.Log(ex, $"{ComponentName}: Error disposing SignalR adapter connection."); - } - }, TimeSpan.FromSeconds(5)); - - LogManager.Log($"{ComponentName}: SignalR adapter disconnected."); - State = TransportComponentState.Disconnected; - } - }); - } - - /// <summary> - /// Handles the write operation. - /// </summary> - private void PushThreadMethod() - { - try - { - while (State == TransportComponentState.Connected) - { - List<byte[]> dataCollection = new List<byte[]>(); - - var data = _pushQueue.BlockDequeue(); - var first = true; - - while (_pushQueue.Count > 0 || first) - { - if (!first) - { - data = _pushQueue.BlockDequeue(); - } - else - { - first = false; - } - - if (EnableCompression) - { - var compressed = Compression.GZipHelper.Compress(data); - dataCollection.Add(compressed); - } - else - { - dataCollection.Add(data); - } - } - - if (dataCollection.Count > 0) - { - try - { - lock (_writeSyncObject) - { - _proxy.Invoke("Write", dataCollection).GetAwaiter().GetResult(); - } - } - catch (Exception ex) - { - OnFailed(LogManager.Log(ex, $"{ComponentName}: Error writing to SignalR adapter ({Address}).")); - return; - } - } - - Thread.Sleep(WriteInterval); - } - } - catch (ThreadAbortException) { } - } - - /// <summary> - /// Called when new data is available. - /// </summary> - /// <param name="dataCollection">The data collection.</param> - private void OnDataAvailable(List<byte[]> dataCollection) - { - try - { - foreach (var data in dataCollection) - { - if (EnableCompression) - { - try - { - var decompressed = Compression.GZipHelper.Decompress(data); - OnDataAvailable(decompressed); - } - catch (Exception ex) - { - if (ex.Message.Contains("GZip")) - { - //Temporarily ignore, probably switching protocol definitions... - OnDataAvailable(data); - } - else - { - throw ex; - } - } - } - else - { - OnDataAvailable(data); - } - } - } - catch (Exception ex) - { - OnFailed(ex); - } - } - - private void StartPushThread() - { - _pushQueue = new ProducerConsumerQueue<byte[]>(); - _pushThread = new Thread(PushThreadMethod); - _pushThread.IsBackground = true; - _pushThread.Name = $"{ComponentName} Push Thread"; - _pushThread.Start(); - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Adapters/SignalRTransportAdapterMode.cs b/Software/Visual_Studio/Tango.Transport/Adapters/SignalRTransportAdapterMode.cs deleted file mode 100644 index d2335b60b..000000000 --- a/Software/Visual_Studio/Tango.Transport/Adapters/SignalRTransportAdapterMode.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Tango.Transport.Adapters -{ - /// <summary> - /// Represents a <see cref="SignalRTransportAdapter"/> mode. - /// </summary> - public enum SignalRTransportAdapterMode - { - /// <summary> - /// The adapter should initiate a session with a remote adapter. - /// </summary> - CreateSession, - /// <summary> - /// The adapter should join an existing session. - /// </summary> - JoinSession - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Adapters/TcpTransportAdapter.cs b/Software/Visual_Studio/Tango.Transport/Adapters/TcpTransportAdapter.cs index 427c335ff..af2a5201b 100644 --- a/Software/Visual_Studio/Tango.Transport/Adapters/TcpTransportAdapter.cs +++ b/Software/Visual_Studio/Tango.Transport/Adapters/TcpTransportAdapter.cs @@ -10,9 +10,7 @@ using System.Reactive.Subjects; using System.Text; using System.Threading; using System.Threading.Tasks; -using Tango.Core; using Tango.Logging; -using Tango.Transport.Compression; namespace Tango.Transport.Adapters { @@ -25,10 +23,7 @@ namespace Tango.Transport.Adapters private TcpClient _socket; private Thread _pullThread; private bool _initializedFromConstructor; - private Thread _pushThread; - private ProducerConsumerQueue<byte[]> _pushQueue; private byte[] _size_buffer; - private object _writeSyncObject = new object(); #region Properties @@ -37,16 +32,6 @@ namespace Tango.Transport.Adapters /// </summary> public int Port { get; set; } - /// <summary> - /// Gets or sets the adapter write mode. - /// </summary> - public TcpTransportAdapterWriteMode WriteMode { get; set; } - - /// <summary> - /// Gets or sets the write interval when using <see cref="TcpTransportAdapterWriteMode.Interval"/> mode. - /// </summary> - public TimeSpan WriteInterval { get; set; } - #endregion #region Constructors @@ -56,11 +41,8 @@ namespace Tango.Transport.Adapters /// </summary> public TcpTransportAdapter() { - ComponentName = $"TCP Adapter {_component_counter++}"; Address = "127.0.0.1"; Port = 9999; - WriteMode = TcpTransportAdapterWriteMode.Interval; - WriteInterval = TimeSpan.FromMilliseconds(10); } /// <summary> @@ -110,27 +92,16 @@ namespace Tango.Transport.Adapters SetSocketProperties(); } - LogManager.Log($"TCP adapter ({Address}) Connected..."); - State = TransportComponentState.Connected; _pullThread = new Thread(PullThreadMethod); - _pullThread.Name = $"{ComponentName} Pull Thread"; _pullThread.IsBackground = true; _pullThread.Start(); - - if (WriteMode == TcpTransportAdapterWriteMode.Interval) - { - _pushThread = new Thread(PushThreadMethod); - _pushThread.IsBackground = true; - _pushThread.Name = $"{ComponentName} Push Thread"; - _pushQueue = new ProducerConsumerQueue<byte[]>(); - _pushThread.Start(); - } + LogManager.Log("TCP adapter Connected..."); } } catch (Exception ex) { - throw LogManager.Log(ex, $"Could not connect the TCP adapter ({Address})."); + throw LogManager.Log(ex, "Could not connect the TCP adapter."); } }); } @@ -149,19 +120,12 @@ namespace Tango.Transport.Adapters { State = TransportComponentState.Disconnected; _socket.Close(); - - try - { - _pushThread.Abort(); - } - catch { } - - LogManager.Log($"TCP adapter ({Address}) disconnected."); + LogManager.Log("TCP adapter disconnected."); } } catch (Exception ex) { - LogManager.Log(ex, $"Could not disconnect the TCP adapter ({Address})."); + LogManager.Log(ex, "Could not disconnect the TCP adapter."); } })); } @@ -170,35 +134,18 @@ namespace Tango.Transport.Adapters /// Writes the specified data to the stream. /// </summary> /// <param name="data">The data.</param> - /// <param name="immidiate">Writes the data as soon as possible while ignoring any message queuing and batching.</param> - public override void Write(byte[] data, bool immidiate = false) + public override void Write(byte[] data) { ThrowIfDisposed(); try { - if (EnableCompression) - { - data = GZipHelper.Compress(data); - } - data = PostProcessBuffer(data); - - if (WriteMode == TcpTransportAdapterWriteMode.Direct || immidiate) - { - lock (_writeSyncObject) - { - _socket.GetStream().Write(data, 0, data.Length); - } - } - else - { - _pushQueue.BlockEnqueue(data); - } + _socket.GetStream().Write(data, 0, data.Length); } catch (Exception ex) { - OnFailed(LogManager.Log(ex, $"Error writing to TCP adapter ({Address}).")); + OnFailed(LogManager.Log(ex)); } } @@ -247,25 +194,6 @@ namespace Tango.Transport.Adapters } } - if (EnableCompression) - { - try - { - data = GZipHelper.Decompress(data); - } - catch (Exception ex) - { - if (ex.Message.Contains("GZip")) - { - //Temporarily ignore, probably switching protocol definitions... - } - else - { - throw ex; - } - } - } - OnDataAvailable(data); } else @@ -284,59 +212,6 @@ namespace Tango.Transport.Adapters #endregion - #region Push Thread - - private void PushThreadMethod() - { - try - { - while (State == TransportComponentState.Connected) - { - List<byte[]> dataCollection = new List<byte[]>(); - - var data = _pushQueue.BlockDequeue(); - var first = true; - - while (_pushQueue.Count > 0 || first) - { - if (!first) - { - data = _pushQueue.BlockDequeue(); - } - else - { - first = false; - } - - dataCollection.Add(data); - } - - if (dataCollection.Count > 0) - { - try - { - byte[] allData = dataCollection.SelectMany(a => a).ToArray(); - - lock (_writeSyncObject) - { - _socket.GetStream().Write(allData, 0, allData.Length); - } - } - catch (Exception ex) - { - OnFailed(LogManager.Log(ex, $"Error writing to TCP adapter ({Address}).")); - return; - } - } - - Thread.Sleep(WriteInterval); - } - } - catch (ThreadAbortException) { } - } - - #endregion - #region Private Methods private void SetSocketProperties() diff --git a/Software/Visual_Studio/Tango.Transport/Adapters/TcpTransportAdapterWriteMode.cs b/Software/Visual_Studio/Tango.Transport/Adapters/TcpTransportAdapterWriteMode.cs deleted file mode 100644 index 89665e2d2..000000000 --- a/Software/Visual_Studio/Tango.Transport/Adapters/TcpTransportAdapterWriteMode.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Tango.Transport.Adapters -{ - /// <summary> - /// Represents a <see cref="TcpTransportAdapter"/> write mode. - /// </summary> - public enum TcpTransportAdapterWriteMode - { - /// <summary> - /// Writes the data directly from the Write(); method (default). - /// </summary> - Direct, - - /// <summary> - /// Accumulates the data being written from the Write(); method and writes a block of messages on intervals. - /// </summary> - Interval - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Adapters/UsbTransportAdapter.cs b/Software/Visual_Studio/Tango.Transport/Adapters/UsbTransportAdapter.cs index 4785e11c8..3b9ca7b55 100644 --- a/Software/Visual_Studio/Tango.Transport/Adapters/UsbTransportAdapter.cs +++ b/Software/Visual_Studio/Tango.Transport/Adapters/UsbTransportAdapter.cs @@ -19,7 +19,6 @@ namespace Tango.Transport.Adapters public class UsbTransportAdapter : TransportAdapterBase { private SerialPort _serialPort; //Serial port instance used to communicate over the serial port. - private const int MAX_EXPECTED_SIZE = 50000; /// <summary> /// Gets or sets the baud rate. @@ -33,7 +32,6 @@ namespace Tango.Transport.Adapters { BaudRate = UsbSerialBaudRates.BR_9600; Address = "COM1"; - ComponentName = $"USB Adapter {_component_counter++}"; } /// <summary> @@ -67,7 +65,7 @@ namespace Tango.Transport.Adapters if (State != TransportComponentState.Connected) { - ThreadFactory.StartNew(() => + Task.Factory.StartNew(() => { try { @@ -80,6 +78,7 @@ namespace Tango.Transport.Adapters _serialPort = new SerialPort(); _serialPort.BaudRate = BaudRate.ToInt32(); + _serialPort.DataReceived += OnSerialPortDataReceived; _serialPort.PortName = Address; _serialPort.ReadBufferSize = MAX_BUFFER_SIZE; _serialPort.WriteBufferSize = MAX_BUFFER_SIZE; @@ -87,11 +86,6 @@ namespace Tango.Transport.Adapters _serialPort.DiscardInBuffer(); _serialPort.DiscardOutBuffer(); - - _serialPort.DataReceived += OnSerialPortDataReceived; - - LogManager.Log($"USB adapter ({Address}) Connected..."); - State = TransportComponentState.Connected; if (!source.Task.IsCompleted) @@ -138,7 +132,7 @@ namespace Tango.Transport.Adapters if (State == TransportComponentState.Connected) { - ThreadFactory.StartNew(() => + Task.Factory.StartNew(() => { try { @@ -155,11 +149,9 @@ namespace Tango.Transport.Adapters //_serialPort.DiscardInBuffer(); _serialPort.Close(); _serialPort.Dispose(); - _serialPort.DataReceived -= OnSerialPortDataReceived; - - LogManager.Log("USB adapter disconnected."); State = TransportComponentState.Disconnected; + LogManager.Log("USB adapter disconnected."); } catch (Exception ex) { @@ -202,8 +194,7 @@ namespace Tango.Transport.Adapters /// Writes the specified data to the stream. /// </summary> /// <param name="data">The data.</param> - /// <param name="immidiate">Writes the data as soon as possible while ignoring any message queuing and batching.</param> - public override void Write(byte[] data, bool immidiate = false) + public override void Write(byte[] data) { ThrowIfDisposed(); @@ -214,7 +205,7 @@ namespace Tango.Transport.Adapters } catch (Exception ex) { - OnFailed(LogManager.Log(ex, $"Error writing to USB adapter ({Address}).")); + OnFailed(LogManager.Log(ex, "Error writing to the serial port.")); } } @@ -227,10 +218,7 @@ namespace Tango.Transport.Adapters { try { - if (e.EventType == SerialData.Eof) - { - return; - } + if (e.EventType == SerialData.Eof) return; if (_serialPort.BytesToRead > 4) { @@ -238,22 +226,6 @@ namespace Tango.Transport.Adapters _serialPort.Read(size, 0, size.Length); int expectedSize = BitConverter.ToInt32(size, 0); - if (expectedSize > MAX_EXPECTED_SIZE || expectedSize < 1) - { - LogManager.Log($"Invalid expected size received on USB adapter ({expectedSize} bytes). Discarding buffers...", LogCategory.Warning); - - byte[] falseData = new byte[_serialPort.BytesToRead]; - _serialPort.Read(falseData, 0, falseData.Length); - - try - { - _serialPort.DiscardInBuffer(); - _serialPort.DiscardOutBuffer(); - } - catch { } - return; - } - byte[] data = new byte[expectedSize]; int read = 0; @@ -261,13 +233,11 @@ namespace Tango.Transport.Adapters { read += _serialPort.Read(data, read, Math.Min(_serialPort.BytesToRead, expectedSize - read)); + //Thread.Sleep(2); + if (State != TransportComponentState.Connected) { - if (_serialPort != null) - { - _serialPort.DataReceived -= OnSerialPortDataReceived; - } - return; + break; } } @@ -277,7 +247,7 @@ namespace Tango.Transport.Adapters } catch (Exception ex) { - LogManager.Log(ex, $"Error occurred while trying to read from the serial port ({Address})."); + LogManager.Log(ex, "Error occurred while trying to read from the serial port."); } } @@ -290,6 +260,7 @@ namespace Tango.Transport.Adapters { try { + LogManager.Log("Finalizing USB transport adapter."); _serialPort.Close(); _serialPort.Dispose(); } diff --git a/Software/Visual_Studio/Tango.Transport/AutoProtobuf.cs b/Software/Visual_Studio/Tango.Transport/AutoProtobuf.cs deleted file mode 100644 index d028860b8..000000000 --- a/Software/Visual_Studio/Tango.Transport/AutoProtobuf.cs +++ /dev/null @@ -1,138 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using ProtoBuf.Meta; - -namespace Tango.Transport -{ - public static class AutoProtobuf - { - private const BindingFlags Flags = BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; - private static readonly Dictionary<Type, HashSet<Type>> SubTypes = new Dictionary<Type, HashSet<Type>>(); - private static readonly ConcurrentBag<Type> BuiltTypes = new ConcurrentBag<Type>(); - private static readonly Type ObjectType = typeof(object); - - /// <summary> - /// Build the ProtoBuf serializer from the generic <see cref="Type">type</see>. - /// </summary> - /// <typeparam name="T">The type of build the serializer for.</typeparam> - public static void Build<T>() - { - var type = typeof(T); - Build(type); - } - - /// <summary> - /// Build the ProtoBuf serializer from the data's <see cref="Type">type</see>. - /// </summary> - /// <typeparam name="T">The type of build the serializer for.</typeparam> - /// <param name="data">The data who's type a serializer will be made.</param> - // ReSharper disable once UnusedParameter.Global - public static void Build<T>(T data) - { - Build<T>(); - } - - /// <summary> - /// Build the ProtoBuf serializer for the <see cref="Type">type</see>. - /// </summary> - /// <param name="type">The type of build the serializer for.</param> - public static void Build(Type type) - { - if (BuiltTypes.Contains(type)) - { - return; - } - - lock (type) - { - if (RuntimeTypeModel.Default.CanSerialize(type)) - { - if (type.IsGenericType) - { - BuildGenerics(type); - } - - return; - } - - var meta = RuntimeTypeModel.Default.Add(type, false); - var fields = GetFields(type); - - meta.Add(fields.Select(m => m.Name).ToArray()); - meta.UseConstructor = false; - - BuildBaseClasses(type); - BuildGenerics(type); - - foreach (var memberType in fields.Select(f => f.FieldType).Where(t => !t.IsPrimitive)) - { - Build(memberType); - } - - BuiltTypes.Add(type); - } - } - - /// <summary> - /// Gets the fields for a type. - /// </summary> - /// <param name="type">The type.</param> - /// <returns></returns> - private static FieldInfo[] GetFields(Type type) - { - return type.GetFields(Flags); - } - - /// <summary> - /// Builds the base class serializers for a type. - /// </summary> - /// <param name="type">The type.</param> - private static void BuildBaseClasses(Type type) - { - var baseType = type.BaseType; - var inheritingType = type; - - - while (baseType != null && baseType != ObjectType) - { - HashSet<Type> baseTypeEntry; - - if (!SubTypes.TryGetValue(baseType, out baseTypeEntry)) - { - baseTypeEntry = new HashSet<Type>(); - SubTypes.Add(baseType, baseTypeEntry); - } - - if (!baseTypeEntry.Contains(inheritingType)) - { - Build(baseType); - RuntimeTypeModel.Default[baseType].AddSubType(baseTypeEntry.Count + 500, inheritingType); - baseTypeEntry.Add(inheritingType); - } - - inheritingType = baseType; - baseType = baseType.BaseType; - } - } - - /// <summary> - /// Builds the serializers for the generic parameters for a given type. - /// </summary> - /// <param name="type">The type.</param> - private static void BuildGenerics(Type type) - { - if (type.IsGenericType || (type.BaseType != null && type.BaseType.IsGenericType)) - { - var generics = type.IsGenericType ? type.GetGenericArguments() : type.BaseType.GetGenericArguments(); - - foreach (var generic in generics) - { - Build(generic); - } - } - } - } -}
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.Transport/Compression/Common/CRC.cs b/Software/Visual_Studio/Tango.Transport/Compression/Common/CRC.cs deleted file mode 100644 index 59fd06bde..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/Common/CRC.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Common/CRC.cs - -namespace Tango.Transport.Compression -{ - class CRC - { - public static readonly uint[] Table; - - static CRC() - { - Table = new uint[256]; - const uint kPoly = 0xEDB88320; - for (uint i = 0; i < 256; i++) - { - uint r = i; - for (int j = 0; j < 8; j++) - if ((r & 1) != 0) - r = (r >> 1) ^ kPoly; - else - r >>= 1; - Table[i] = r; - } - } - - uint _value = 0xFFFFFFFF; - - public void Init() { _value = 0xFFFFFFFF; } - - public void UpdateByte(byte b) - { - _value = Table[(((byte)(_value)) ^ b)] ^ (_value >> 8); - } - - public void Update(byte[] data, uint offset, uint size) - { - for (uint i = 0; i < size; i++) - _value = Table[(((byte)(_value)) ^ data[offset + i])] ^ (_value >> 8); - } - - public uint GetDigest() { return _value ^ 0xFFFFFFFF; } - - static uint CalculateDigest(byte[] data, uint offset, uint size) - { - CRC crc = new CRC(); - // crc.Init(); - crc.Update(data, offset, size); - return crc.GetDigest(); - } - - static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size) - { - return (CalculateDigest(data, offset, size) == digest); - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/Common/CommandLineParser.cs b/Software/Visual_Studio/Tango.Transport/Compression/Common/CommandLineParser.cs deleted file mode 100644 index dd0cb45d1..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/Common/CommandLineParser.cs +++ /dev/null @@ -1,274 +0,0 @@ -// CommandLineParser.cs - -using System; -using System.Collections; - -namespace Tango.Transport.Compression.CommandLineParser -{ - public enum SwitchType - { - Simple, - PostMinus, - LimitedPostString, - UnLimitedPostString, - PostChar - } - - public class SwitchForm - { - public string IDString; - public SwitchType Type; - public bool Multi; - public int MinLen; - public int MaxLen; - public string PostCharSet; - - public SwitchForm(string idString, SwitchType type, bool multi, - int minLen, int maxLen, string postCharSet) - { - IDString = idString; - Type = type; - Multi = multi; - MinLen = minLen; - MaxLen = maxLen; - PostCharSet = postCharSet; - } - public SwitchForm(string idString, SwitchType type, bool multi, int minLen): - this(idString, type, multi, minLen, 0, "") - { - } - public SwitchForm(string idString, SwitchType type, bool multi): - this(idString, type, multi, 0) - { - } - } - - public class SwitchResult - { - public bool ThereIs; - public bool WithMinus; - public ArrayList PostStrings = new ArrayList(); - public int PostCharIndex; - public SwitchResult() - { - ThereIs = false; - } - } - - public class Parser - { - public ArrayList NonSwitchStrings = new ArrayList(); - SwitchResult[] _switches; - - public Parser(int numSwitches) - { - _switches = new SwitchResult[numSwitches]; - for (int i = 0; i < numSwitches; i++) - _switches[i] = new SwitchResult(); - } - - bool ParseString(string srcString, SwitchForm[] switchForms) - { - int len = srcString.Length; - if (len == 0) - return false; - int pos = 0; - if (!IsItSwitchChar(srcString[pos])) - return false; - while (pos < len) - { - if (IsItSwitchChar(srcString[pos])) - pos++; - const int kNoLen = -1; - int matchedSwitchIndex = 0; - int maxLen = kNoLen; - for (int switchIndex = 0; switchIndex < _switches.Length; switchIndex++) - { - int switchLen = switchForms[switchIndex].IDString.Length; - if (switchLen <= maxLen || pos + switchLen > len) - continue; - if (String.Compare(switchForms[switchIndex].IDString, 0, - srcString, pos, switchLen, true) == 0) - { - matchedSwitchIndex = switchIndex; - maxLen = switchLen; - } - } - if (maxLen == kNoLen) - throw new Exception("maxLen == kNoLen"); - SwitchResult matchedSwitch = _switches[matchedSwitchIndex]; - SwitchForm switchForm = switchForms[matchedSwitchIndex]; - if ((!switchForm.Multi) && matchedSwitch.ThereIs) - throw new Exception("switch must be single"); - matchedSwitch.ThereIs = true; - pos += maxLen; - int tailSize = len - pos; - SwitchType type = switchForm.Type; - switch (type) - { - case SwitchType.PostMinus: - { - if (tailSize == 0) - matchedSwitch.WithMinus = false; - else - { - matchedSwitch.WithMinus = (srcString[pos] == kSwitchMinus); - if (matchedSwitch.WithMinus) - pos++; - } - break; - } - case SwitchType.PostChar: - { - if (tailSize < switchForm.MinLen) - throw new Exception("switch is not full"); - string charSet = switchForm.PostCharSet; - const int kEmptyCharValue = -1; - if (tailSize == 0) - matchedSwitch.PostCharIndex = kEmptyCharValue; - else - { - int index = charSet.IndexOf(srcString[pos]); - if (index < 0) - matchedSwitch.PostCharIndex = kEmptyCharValue; - else - { - matchedSwitch.PostCharIndex = index; - pos++; - } - } - break; - } - case SwitchType.LimitedPostString: - case SwitchType.UnLimitedPostString: - { - int minLen = switchForm.MinLen; - if (tailSize < minLen) - throw new Exception("switch is not full"); - if (type == SwitchType.UnLimitedPostString) - { - matchedSwitch.PostStrings.Add(srcString.Substring(pos)); - return true; - } - String stringSwitch = srcString.Substring(pos, minLen); - pos += minLen; - for (int i = minLen; i < switchForm.MaxLen && pos < len; i++, pos++) - { - char c = srcString[pos]; - if (IsItSwitchChar(c)) - break; - stringSwitch += c; - } - matchedSwitch.PostStrings.Add(stringSwitch); - break; - } - } - } - return true; - - } - - public void ParseStrings(SwitchForm[] switchForms, string[] commandStrings) - { - int numCommandStrings = commandStrings.Length; - bool stopSwitch = false; - for (int i = 0; i < numCommandStrings; i++) - { - string s = commandStrings[i]; - if (stopSwitch) - NonSwitchStrings.Add(s); - else - if (s == kStopSwitchParsing) - stopSwitch = true; - else - if (!ParseString(s, switchForms)) - NonSwitchStrings.Add(s); - } - } - - public SwitchResult this[int index] { get { return _switches[index]; } } - - public static int ParseCommand(CommandForm[] commandForms, string commandString, - out string postString) - { - for (int i = 0; i < commandForms.Length; i++) - { - string id = commandForms[i].IDString; - if (commandForms[i].PostStringMode) - { - if (commandString.IndexOf(id) == 0) - { - postString = commandString.Substring(id.Length); - return i; - } - } - else - if (commandString == id) - { - postString = ""; - return i; - } - } - postString = ""; - return -1; - } - - static bool ParseSubCharsCommand(int numForms, CommandSubCharsSet[] forms, - string commandString, ArrayList indices) - { - indices.Clear(); - int numUsedChars = 0; - for (int i = 0; i < numForms; i++) - { - CommandSubCharsSet charsSet = forms[i]; - int currentIndex = -1; - int len = charsSet.Chars.Length; - for (int j = 0; j < len; j++) - { - char c = charsSet.Chars[j]; - int newIndex = commandString.IndexOf(c); - if (newIndex >= 0) - { - if (currentIndex >= 0) - return false; - if (commandString.IndexOf(c, newIndex + 1) >= 0) - return false; - currentIndex = j; - numUsedChars++; - } - } - if (currentIndex == -1 && !charsSet.EmptyAllowed) - return false; - indices.Add(currentIndex); - } - return (numUsedChars == commandString.Length); - } - const char kSwitchID1 = '-'; - const char kSwitchID2 = '/'; - - const char kSwitchMinus = '-'; - const string kStopSwitchParsing = "--"; - - static bool IsItSwitchChar(char c) - { - return (c == kSwitchID1 || c == kSwitchID2); - } - } - - public class CommandForm - { - public string IDString = ""; - public bool PostStringMode = false; - public CommandForm(string idString, bool postStringMode) - { - IDString = idString; - PostStringMode = postStringMode; - } - } - - class CommandSubCharsSet - { - public string Chars = ""; - public bool EmptyAllowed = false; - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/Common/InBuffer.cs b/Software/Visual_Studio/Tango.Transport/Compression/Common/InBuffer.cs deleted file mode 100644 index 012954dfa..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/Common/InBuffer.cs +++ /dev/null @@ -1,72 +0,0 @@ -// InBuffer.cs - -namespace Tango.Transport.Compression -{ - public class InBuffer - { - byte[] m_Buffer; - uint m_Pos; - uint m_Limit; - uint m_BufferSize; - System.IO.Stream m_Stream; - bool m_StreamWasExhausted; - ulong m_ProcessedSize; - - public InBuffer(uint bufferSize) - { - m_Buffer = new byte[bufferSize]; - m_BufferSize = bufferSize; - } - - public void Init(System.IO.Stream stream) - { - m_Stream = stream; - m_ProcessedSize = 0; - m_Limit = 0; - m_Pos = 0; - m_StreamWasExhausted = false; - } - - public bool ReadBlock() - { - if (m_StreamWasExhausted) - return false; - m_ProcessedSize += m_Pos; - int aNumProcessedBytes = m_Stream.Read(m_Buffer, 0, (int)m_BufferSize); - m_Pos = 0; - m_Limit = (uint)aNumProcessedBytes; - m_StreamWasExhausted = (aNumProcessedBytes == 0); - return (!m_StreamWasExhausted); - } - - - public void ReleaseStream() - { - // m_Stream.Close(); - m_Stream = null; - } - - public bool ReadByte(byte b) // check it - { - if (m_Pos >= m_Limit) - if (!ReadBlock()) - return false; - b = m_Buffer[m_Pos++]; - return true; - } - - public byte ReadByte() - { - // return (byte)m_Stream.ReadByte(); - if (m_Pos >= m_Limit) - if (!ReadBlock()) - return 0xFF; - return m_Buffer[m_Pos++]; - } - - public ulong GetProcessedSize() - { - return m_ProcessedSize + m_Pos; - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/Common/OutBuffer.cs b/Software/Visual_Studio/Tango.Transport/Compression/Common/OutBuffer.cs deleted file mode 100644 index 624ecf937..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/Common/OutBuffer.cs +++ /dev/null @@ -1,47 +0,0 @@ -// OutBuffer.cs - -namespace Tango.Transport.Compression -{ - public class OutBuffer - { - byte[] m_Buffer; - uint m_Pos; - uint m_BufferSize; - System.IO.Stream m_Stream; - ulong m_ProcessedSize; - - public OutBuffer(uint bufferSize) - { - m_Buffer = new byte[bufferSize]; - m_BufferSize = bufferSize; - } - - public void SetStream(System.IO.Stream stream) { m_Stream = stream; } - public void FlushStream() { m_Stream.Flush(); } - public void CloseStream() { m_Stream.Close(); } - public void ReleaseStream() { m_Stream = null; } - - public void Init() - { - m_ProcessedSize = 0; - m_Pos = 0; - } - - public void WriteByte(byte b) - { - m_Buffer[m_Pos++] = b; - if (m_Pos >= m_BufferSize) - FlushData(); - } - - public void FlushData() - { - if (m_Pos == 0) - return; - m_Stream.Write(m_Buffer, 0, (int)m_Pos); - m_Pos = 0; - } - - public ulong GetProcessedSize() { return m_ProcessedSize + m_Pos; } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/Compress/.DS_Store b/Software/Visual_Studio/Tango.Transport/Compression/Compress/.DS_Store Binary files differdeleted file mode 100644 index c6fa379b8..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/Compress/.DS_Store +++ /dev/null diff --git a/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZ/IMatchFinder.cs b/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZ/IMatchFinder.cs deleted file mode 100644 index 6f68bee3a..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZ/IMatchFinder.cs +++ /dev/null @@ -1,24 +0,0 @@ -// IMatchFinder.cs - -using System; - -namespace Tango.Transport.Compression.LZ -{ - interface IInWindowStream - { - void SetStream(System.IO.Stream inStream); - void Init(); - void ReleaseStream(); - Byte GetIndexByte(Int32 index); - UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit); - UInt32 GetNumAvailableBytes(); - } - - interface IMatchFinder : IInWindowStream - { - void Create(UInt32 historySize, UInt32 keepAddBufferBefore, - UInt32 matchMaxLen, UInt32 keepAddBufferAfter); - UInt32 GetMatches(UInt32[] distances); - void Skip(UInt32 num); - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZ/LzBinTree.cs b/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZ/LzBinTree.cs deleted file mode 100644 index b09701788..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZ/LzBinTree.cs +++ /dev/null @@ -1,367 +0,0 @@ -// LzBinTree.cs - -using System; - -namespace Tango.Transport.Compression.LZ -{ - public class BinTree : InWindow, IMatchFinder - { - UInt32 _cyclicBufferPos; - UInt32 _cyclicBufferSize = 0; - UInt32 _matchMaxLen; - - UInt32[] _son; - UInt32[] _hash; - - UInt32 _cutValue = 0xFF; - UInt32 _hashMask; - UInt32 _hashSizeSum = 0; - - bool HASH_ARRAY = true; - - const UInt32 kHash2Size = 1 << 10; - const UInt32 kHash3Size = 1 << 16; - const UInt32 kBT2HashSize = 1 << 16; - const UInt32 kStartMaxLen = 1; - const UInt32 kHash3Offset = kHash2Size; - const UInt32 kEmptyHashValue = 0; - const UInt32 kMaxValForNormalize = ((UInt32)1 << 31) - 1; - - UInt32 kNumHashDirectBytes = 0; - UInt32 kMinMatchCheck = 4; - UInt32 kFixHashSize = kHash2Size + kHash3Size; - - public void SetType(int numHashBytes) - { - HASH_ARRAY = (numHashBytes > 2); - if (HASH_ARRAY) - { - kNumHashDirectBytes = 0; - kMinMatchCheck = 4; - kFixHashSize = kHash2Size + kHash3Size; - } - else - { - kNumHashDirectBytes = 2; - kMinMatchCheck = 2 + 1; - kFixHashSize = 0; - } - } - - public new void SetStream(System.IO.Stream stream) { base.SetStream(stream); } - public new void ReleaseStream() { base.ReleaseStream(); } - - public new void Init() - { - base.Init(); - for (UInt32 i = 0; i < _hashSizeSum; i++) - _hash[i] = kEmptyHashValue; - _cyclicBufferPos = 0; - ReduceOffsets(-1); - } - - public new void MovePos() - { - if (++_cyclicBufferPos >= _cyclicBufferSize) - _cyclicBufferPos = 0; - base.MovePos(); - if (_pos == kMaxValForNormalize) - Normalize(); - } - - public new Byte GetIndexByte(Int32 index) { return base.GetIndexByte(index); } - - public new UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) - { return base.GetMatchLen(index, distance, limit); } - - public new UInt32 GetNumAvailableBytes() { return base.GetNumAvailableBytes(); } - - public void Create(UInt32 historySize, UInt32 keepAddBufferBefore, - UInt32 matchMaxLen, UInt32 keepAddBufferAfter) - { - if (historySize > kMaxValForNormalize - 256) - throw new Exception(); - _cutValue = 16 + (matchMaxLen >> 1); - - UInt32 windowReservSize = (historySize + keepAddBufferBefore + - matchMaxLen + keepAddBufferAfter) / 2 + 256; - - base.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize); - - _matchMaxLen = matchMaxLen; - - UInt32 cyclicBufferSize = historySize + 1; - if (_cyclicBufferSize != cyclicBufferSize) - _son = new UInt32[(_cyclicBufferSize = cyclicBufferSize) * 2]; - - UInt32 hs = kBT2HashSize; - - if (HASH_ARRAY) - { - hs = historySize - 1; - hs |= (hs >> 1); - hs |= (hs >> 2); - hs |= (hs >> 4); - hs |= (hs >> 8); - hs >>= 1; - hs |= 0xFFFF; - if (hs > (1 << 24)) - hs >>= 1; - _hashMask = hs; - hs++; - hs += kFixHashSize; - } - if (hs != _hashSizeSum) - _hash = new UInt32[_hashSizeSum = hs]; - } - - public UInt32 GetMatches(UInt32[] distances) - { - UInt32 lenLimit; - if (_pos + _matchMaxLen <= _streamPos) - lenLimit = _matchMaxLen; - else - { - lenLimit = _streamPos - _pos; - if (lenLimit < kMinMatchCheck) - { - MovePos(); - return 0; - } - } - - UInt32 offset = 0; - UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; - UInt32 cur = _bufferOffset + _pos; - UInt32 maxLen = kStartMaxLen; // to avoid items for len < hashSize; - UInt32 hashValue, hash2Value = 0, hash3Value = 0; - - if (HASH_ARRAY) - { - UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1]; - hash2Value = temp & (kHash2Size - 1); - temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8); - hash3Value = temp & (kHash3Size - 1); - hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask; - } - else - hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8); - - UInt32 curMatch = _hash[kFixHashSize + hashValue]; - if (HASH_ARRAY) - { - UInt32 curMatch2 = _hash[hash2Value]; - UInt32 curMatch3 = _hash[kHash3Offset + hash3Value]; - _hash[hash2Value] = _pos; - _hash[kHash3Offset + hash3Value] = _pos; - if (curMatch2 > matchMinPos) - if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur]) - { - distances[offset++] = maxLen = 2; - distances[offset++] = _pos - curMatch2 - 1; - } - if (curMatch3 > matchMinPos) - if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur]) - { - if (curMatch3 == curMatch2) - offset -= 2; - distances[offset++] = maxLen = 3; - distances[offset++] = _pos - curMatch3 - 1; - curMatch2 = curMatch3; - } - if (offset != 0 && curMatch2 == curMatch) - { - offset -= 2; - maxLen = kStartMaxLen; - } - } - - _hash[kFixHashSize + hashValue] = _pos; - - UInt32 ptr0 = (_cyclicBufferPos << 1) + 1; - UInt32 ptr1 = (_cyclicBufferPos << 1); - - UInt32 len0, len1; - len0 = len1 = kNumHashDirectBytes; - - if (kNumHashDirectBytes != 0) - { - if (curMatch > matchMinPos) - { - if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] != - _bufferBase[cur + kNumHashDirectBytes]) - { - distances[offset++] = maxLen = kNumHashDirectBytes; - distances[offset++] = _pos - curMatch - 1; - } - } - } - - UInt32 count = _cutValue; - - while(true) - { - if(curMatch <= matchMinPos || count-- == 0) - { - _son[ptr0] = _son[ptr1] = kEmptyHashValue; - break; - } - UInt32 delta = _pos - curMatch; - UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ? - (_cyclicBufferPos - delta) : - (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1; - - UInt32 pby1 = _bufferOffset + curMatch; - UInt32 len = Math.Min(len0, len1); - if (_bufferBase[pby1 + len] == _bufferBase[cur + len]) - { - while(++len != lenLimit) - if (_bufferBase[pby1 + len] != _bufferBase[cur + len]) - break; - if (maxLen < len) - { - distances[offset++] = maxLen = len; - distances[offset++] = delta - 1; - if (len == lenLimit) - { - _son[ptr1] = _son[cyclicPos]; - _son[ptr0] = _son[cyclicPos + 1]; - break; - } - } - } - if (_bufferBase[pby1 + len] < _bufferBase[cur + len]) - { - _son[ptr1] = curMatch; - ptr1 = cyclicPos + 1; - curMatch = _son[ptr1]; - len1 = len; - } - else - { - _son[ptr0] = curMatch; - ptr0 = cyclicPos; - curMatch = _son[ptr0]; - len0 = len; - } - } - MovePos(); - return offset; - } - - public void Skip(UInt32 num) - { - do - { - UInt32 lenLimit; - if (_pos + _matchMaxLen <= _streamPos) - lenLimit = _matchMaxLen; - else - { - lenLimit = _streamPos - _pos; - if (lenLimit < kMinMatchCheck) - { - MovePos(); - continue; - } - } - - UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; - UInt32 cur = _bufferOffset + _pos; - - UInt32 hashValue; - - if (HASH_ARRAY) - { - UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1]; - UInt32 hash2Value = temp & (kHash2Size - 1); - _hash[hash2Value] = _pos; - temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8); - UInt32 hash3Value = temp & (kHash3Size - 1); - _hash[kHash3Offset + hash3Value] = _pos; - hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask; - } - else - hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8); - - UInt32 curMatch = _hash[kFixHashSize + hashValue]; - _hash[kFixHashSize + hashValue] = _pos; - - UInt32 ptr0 = (_cyclicBufferPos << 1) + 1; - UInt32 ptr1 = (_cyclicBufferPos << 1); - - UInt32 len0, len1; - len0 = len1 = kNumHashDirectBytes; - - UInt32 count = _cutValue; - while (true) - { - if (curMatch <= matchMinPos || count-- == 0) - { - _son[ptr0] = _son[ptr1] = kEmptyHashValue; - break; - } - - UInt32 delta = _pos - curMatch; - UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ? - (_cyclicBufferPos - delta) : - (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1; - - UInt32 pby1 = _bufferOffset + curMatch; - UInt32 len = Math.Min(len0, len1); - if (_bufferBase[pby1 + len] == _bufferBase[cur + len]) - { - while (++len != lenLimit) - if (_bufferBase[pby1 + len] != _bufferBase[cur + len]) - break; - if (len == lenLimit) - { - _son[ptr1] = _son[cyclicPos]; - _son[ptr0] = _son[cyclicPos + 1]; - break; - } - } - if (_bufferBase[pby1 + len] < _bufferBase[cur + len]) - { - _son[ptr1] = curMatch; - ptr1 = cyclicPos + 1; - curMatch = _son[ptr1]; - len1 = len; - } - else - { - _son[ptr0] = curMatch; - ptr0 = cyclicPos; - curMatch = _son[ptr0]; - len0 = len; - } - } - MovePos(); - } - while (--num != 0); - } - - void NormalizeLinks(UInt32[] items, UInt32 numItems, UInt32 subValue) - { - for (UInt32 i = 0; i < numItems; i++) - { - UInt32 value = items[i]; - if (value <= subValue) - value = kEmptyHashValue; - else - value -= subValue; - items[i] = value; - } - } - - void Normalize() - { - UInt32 subValue = _pos - _cyclicBufferSize; - NormalizeLinks(_son, _cyclicBufferSize * 2, subValue); - NormalizeLinks(_hash, _hashSizeSum, subValue); - ReduceOffsets((Int32)subValue); - } - - public void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZ/LzInWindow.cs b/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZ/LzInWindow.cs deleted file mode 100644 index fd8f6fc9a..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZ/LzInWindow.cs +++ /dev/null @@ -1,132 +0,0 @@ -// LzInWindow.cs - -using System; - -namespace Tango.Transport.Compression.LZ -{ - public class InWindow - { - public Byte[] _bufferBase = null; // pointer to buffer with data - System.IO.Stream _stream; - UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done - bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream - - UInt32 _pointerToLastSafePosition; - - public UInt32 _bufferOffset; - - public UInt32 _blockSize; // Size of Allocated memory block - public UInt32 _pos; // offset (from _buffer) of curent byte - UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos - UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos - public UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream - - public void MoveBlock() - { - UInt32 offset = (UInt32)(_bufferOffset) + _pos - _keepSizeBefore; - // we need one additional byte, since MovePos moves on 1 byte. - if (offset > 0) - offset--; - - UInt32 numBytes = (UInt32)(_bufferOffset) + _streamPos - offset; - - // check negative offset ???? - for (UInt32 i = 0; i < numBytes; i++) - _bufferBase[i] = _bufferBase[offset + i]; - _bufferOffset -= offset; - } - - public virtual void ReadBlock() - { - if (_streamEndWasReached) - return; - while (true) - { - int size = (int)((0 - _bufferOffset) + _blockSize - _streamPos); - if (size == 0) - return; - int numReadBytes = _stream.Read(_bufferBase, (int)(_bufferOffset + _streamPos), size); - if (numReadBytes == 0) - { - _posLimit = _streamPos; - UInt32 pointerToPostion = _bufferOffset + _posLimit; - if (pointerToPostion > _pointerToLastSafePosition) - _posLimit = (UInt32)(_pointerToLastSafePosition - _bufferOffset); - - _streamEndWasReached = true; - return; - } - _streamPos += (UInt32)numReadBytes; - if (_streamPos >= _pos + _keepSizeAfter) - _posLimit = _streamPos - _keepSizeAfter; - } - } - - void Free() { _bufferBase = null; } - - public void Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv) - { - _keepSizeBefore = keepSizeBefore; - _keepSizeAfter = keepSizeAfter; - UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv; - if (_bufferBase == null || _blockSize != blockSize) - { - Free(); - _blockSize = blockSize; - _bufferBase = new Byte[_blockSize]; - } - _pointerToLastSafePosition = _blockSize - keepSizeAfter; - } - - public void SetStream(System.IO.Stream stream) { _stream = stream; } - public void ReleaseStream() { _stream = null; } - - public void Init() - { - _bufferOffset = 0; - _pos = 0; - _streamPos = 0; - _streamEndWasReached = false; - ReadBlock(); - } - - public void MovePos() - { - _pos++; - if (_pos > _posLimit) - { - UInt32 pointerToPostion = _bufferOffset + _pos; - if (pointerToPostion > _pointerToLastSafePosition) - MoveBlock(); - ReadBlock(); - } - } - - public Byte GetIndexByte(Int32 index) { return _bufferBase[_bufferOffset + _pos + index]; } - - // index + limit have not to exceed _keepSizeAfter; - public UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) - { - if (_streamEndWasReached) - if ((_pos + index) + limit > _streamPos) - limit = _streamPos - (UInt32)(_pos + index); - distance++; - // Byte *pby = _buffer + (size_t)_pos + index; - UInt32 pby = _bufferOffset + _pos + (UInt32)index; - - UInt32 i; - for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++); - return i; - } - - public UInt32 GetNumAvailableBytes() { return _streamPos - _pos; } - - public void ReduceOffsets(Int32 subValue) - { - _bufferOffset += (UInt32)subValue; - _posLimit -= (UInt32)subValue; - _pos -= (UInt32)subValue; - _streamPos -= (UInt32)subValue; - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZ/LzOutWindow.cs b/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZ/LzOutWindow.cs deleted file mode 100644 index 611e6b35e..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZ/LzOutWindow.cs +++ /dev/null @@ -1,110 +0,0 @@ -// LzOutWindow.cs - -namespace Tango.Transport.Compression.LZ -{ - public class OutWindow - { - byte[] _buffer = null; - uint _pos; - uint _windowSize = 0; - uint _streamPos; - System.IO.Stream _stream; - - public uint TrainSize = 0; - - public void Create(uint windowSize) - { - if (_windowSize != windowSize) - { - // System.GC.Collect(); - _buffer = new byte[windowSize]; - } - _windowSize = windowSize; - _pos = 0; - _streamPos = 0; - } - - public void Init(System.IO.Stream stream, bool solid) - { - ReleaseStream(); - _stream = stream; - if (!solid) - { - _streamPos = 0; - _pos = 0; - TrainSize = 0; - } - } - - public bool Train(System.IO.Stream stream) - { - long len = stream.Length; - uint size = (len < _windowSize) ? (uint)len : _windowSize; - TrainSize = size; - stream.Position = len - size; - _streamPos = _pos = 0; - while (size > 0) - { - uint curSize = _windowSize - _pos; - if (size < curSize) - curSize = size; - int numReadBytes = stream.Read(_buffer, (int)_pos, (int)curSize); - if (numReadBytes == 0) - return false; - size -= (uint)numReadBytes; - _pos += (uint)numReadBytes; - _streamPos += (uint)numReadBytes; - if (_pos == _windowSize) - _streamPos = _pos = 0; - } - return true; - } - - public void ReleaseStream() - { - Flush(); - _stream = null; - } - - public void Flush() - { - uint size = _pos - _streamPos; - if (size == 0) - return; - _stream.Write(_buffer, (int)_streamPos, (int)size); - if (_pos >= _windowSize) - _pos = 0; - _streamPos = _pos; - } - - public void CopyBlock(uint distance, uint len) - { - uint pos = _pos - distance - 1; - if (pos >= _windowSize) - pos += _windowSize; - for (; len > 0; len--) - { - if (pos >= _windowSize) - pos = 0; - _buffer[_pos++] = _buffer[pos++]; - if (_pos >= _windowSize) - Flush(); - } - } - - public void PutByte(byte b) - { - _buffer[_pos++] = b; - if (_pos >= _windowSize) - Flush(); - } - - public byte GetByte(uint distance) - { - uint pos = _pos - distance - 1; - if (pos >= _windowSize) - pos += _windowSize; - return _buffer[pos]; - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZMA/LzmaBase.cs b/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZMA/LzmaBase.cs deleted file mode 100644 index b2b898673..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZMA/LzmaBase.cs +++ /dev/null @@ -1,76 +0,0 @@ -// LzmaBase.cs - -namespace Tango.Transport.Compression.LZMA -{ - internal abstract class Base - { - public const uint kNumRepDistances = 4; - public const uint kNumStates = 12; - - // static byte []kLiteralNextStates = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; - // static byte []kMatchNextStates = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; - // static byte []kRepNextStates = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; - // static byte []kShortRepNextStates = {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; - - public struct State - { - public uint Index; - public void Init() { Index = 0; } - public void UpdateChar() - { - if (Index < 4) Index = 0; - else if (Index < 10) Index -= 3; - else Index -= 6; - } - public void UpdateMatch() { Index = (uint)(Index < 7 ? 7 : 10); } - public void UpdateRep() { Index = (uint)(Index < 7 ? 8 : 11); } - public void UpdateShortRep() { Index = (uint)(Index < 7 ? 9 : 11); } - public bool IsCharState() { return Index < 7; } - } - - public const int kNumPosSlotBits = 6; - public const int kDicLogSizeMin = 0; - // public const int kDicLogSizeMax = 30; - // public const uint kDistTableSizeMax = kDicLogSizeMax * 2; - - public const int kNumLenToPosStatesBits = 2; // it's for speed optimization - public const uint kNumLenToPosStates = 1 << kNumLenToPosStatesBits; - - public const uint kMatchMinLen = 2; - - public static uint GetLenToPosState(uint len) - { - len -= kMatchMinLen; - if (len < kNumLenToPosStates) - return len; - return (uint)(kNumLenToPosStates - 1); - } - - public const int kNumAlignBits = 4; - public const uint kAlignTableSize = 1 << kNumAlignBits; - public const uint kAlignMask = (kAlignTableSize - 1); - - public const uint kStartPosModelIndex = 4; - public const uint kEndPosModelIndex = 14; - public const uint kNumPosModels = kEndPosModelIndex - kStartPosModelIndex; - - public const uint kNumFullDistances = 1 << ((int)kEndPosModelIndex / 2); - - public const uint kNumLitPosStatesBitsEncodingMax = 4; - public const uint kNumLitContextBitsMax = 8; - - public const int kNumPosStatesBitsMax = 4; - public const uint kNumPosStatesMax = (1 << kNumPosStatesBitsMax); - public const int kNumPosStatesBitsEncodingMax = 4; - public const uint kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax); - - public const int kNumLowLenBits = 3; - public const int kNumMidLenBits = 3; - public const int kNumHighLenBits = 8; - public const uint kNumLowLenSymbols = 1 << kNumLowLenBits; - public const uint kNumMidLenSymbols = 1 << kNumMidLenBits; - public const uint kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols + - (1 << kNumHighLenBits); - public const uint kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1; - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZMA/LzmaDecoder.cs b/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZMA/LzmaDecoder.cs deleted file mode 100644 index d6314be7b..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZMA/LzmaDecoder.cs +++ /dev/null @@ -1,398 +0,0 @@ -// LzmaDecoder.cs - -using System; - -namespace Tango.Transport.Compression.LZMA -{ - using RangeCoder; - - public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream - { - class LenDecoder - { - BitDecoder m_Choice = new BitDecoder(); - BitDecoder m_Choice2 = new BitDecoder(); - BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax]; - BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax]; - BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits); - uint m_NumPosStates = 0; - - public void Create(uint numPosStates) - { - for (uint posState = m_NumPosStates; posState < numPosStates; posState++) - { - m_LowCoder[posState] = new BitTreeDecoder(Base.kNumLowLenBits); - m_MidCoder[posState] = new BitTreeDecoder(Base.kNumMidLenBits); - } - m_NumPosStates = numPosStates; - } - - public void Init() - { - m_Choice.Init(); - for (uint posState = 0; posState < m_NumPosStates; posState++) - { - m_LowCoder[posState].Init(); - m_MidCoder[posState].Init(); - } - m_Choice2.Init(); - m_HighCoder.Init(); - } - - public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState) - { - if (m_Choice.Decode(rangeDecoder) == 0) - return m_LowCoder[posState].Decode(rangeDecoder); - else - { - uint symbol = Base.kNumLowLenSymbols; - if (m_Choice2.Decode(rangeDecoder) == 0) - symbol += m_MidCoder[posState].Decode(rangeDecoder); - else - { - symbol += Base.kNumMidLenSymbols; - symbol += m_HighCoder.Decode(rangeDecoder); - } - return symbol; - } - } - } - - class LiteralDecoder - { - struct Decoder2 - { - BitDecoder[] m_Decoders; - public void Create() { m_Decoders = new BitDecoder[0x300]; } - public void Init() { for (int i = 0; i < 0x300; i++) m_Decoders[i].Init(); } - - public byte DecodeNormal(RangeCoder.Decoder rangeDecoder) - { - uint symbol = 1; - do - symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder); - while (symbol < 0x100); - return (byte)symbol; - } - - public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte) - { - uint symbol = 1; - do - { - uint matchBit = (uint)(matchByte >> 7) & 1; - matchByte <<= 1; - uint bit = m_Decoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder); - symbol = (symbol << 1) | bit; - if (matchBit != bit) - { - while (symbol < 0x100) - symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder); - break; - } - } - while (symbol < 0x100); - return (byte)symbol; - } - } - - Decoder2[] m_Coders; - int m_NumPrevBits; - int m_NumPosBits; - uint m_PosMask; - - public void Create(int numPosBits, int numPrevBits) - { - if (m_Coders != null && m_NumPrevBits == numPrevBits && - m_NumPosBits == numPosBits) - return; - m_NumPosBits = numPosBits; - m_PosMask = ((uint)1 << numPosBits) - 1; - m_NumPrevBits = numPrevBits; - uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits); - m_Coders = new Decoder2[numStates]; - for (uint i = 0; i < numStates; i++) - m_Coders[i].Create(); - } - - public void Init() - { - uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits); - for (uint i = 0; i < numStates; i++) - m_Coders[i].Init(); - } - - uint GetState(uint pos, byte prevByte) - { return ((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits)); } - - public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte) - { return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); } - - public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte) - { return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); } - }; - - LZ.OutWindow m_OutWindow = new LZ.OutWindow(); - RangeCoder.Decoder m_RangeDecoder = new RangeCoder.Decoder(); - - BitDecoder[] m_IsMatchDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax]; - BitDecoder[] m_IsRepDecoders = new BitDecoder[Base.kNumStates]; - BitDecoder[] m_IsRepG0Decoders = new BitDecoder[Base.kNumStates]; - BitDecoder[] m_IsRepG1Decoders = new BitDecoder[Base.kNumStates]; - BitDecoder[] m_IsRepG2Decoders = new BitDecoder[Base.kNumStates]; - BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax]; - - BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates]; - BitDecoder[] m_PosDecoders = new BitDecoder[Base.kNumFullDistances - Base.kEndPosModelIndex]; - - BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits); - - LenDecoder m_LenDecoder = new LenDecoder(); - LenDecoder m_RepLenDecoder = new LenDecoder(); - - LiteralDecoder m_LiteralDecoder = new LiteralDecoder(); - - uint m_DictionarySize; - uint m_DictionarySizeCheck; - - uint m_PosStateMask; - - public Decoder() - { - m_DictionarySize = 0xFFFFFFFF; - for (int i = 0; i < Base.kNumLenToPosStates; i++) - m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits); - } - - void SetDictionarySize(uint dictionarySize) - { - if (m_DictionarySize != dictionarySize) - { - m_DictionarySize = dictionarySize; - m_DictionarySizeCheck = Math.Max(m_DictionarySize, 1); - uint blockSize = Math.Max(m_DictionarySizeCheck, (1 << 12)); - m_OutWindow.Create(blockSize); - } - } - - void SetLiteralProperties(int lp, int lc) - { - if (lp > 8) - throw new InvalidParamException(); - if (lc > 8) - throw new InvalidParamException(); - m_LiteralDecoder.Create(lp, lc); - } - - void SetPosBitsProperties(int pb) - { - if (pb > Base.kNumPosStatesBitsMax) - throw new InvalidParamException(); - uint numPosStates = (uint)1 << pb; - m_LenDecoder.Create(numPosStates); - m_RepLenDecoder.Create(numPosStates); - m_PosStateMask = numPosStates - 1; - } - - bool _solid = false; - void Init(System.IO.Stream inStream, System.IO.Stream outStream) - { - m_RangeDecoder.Init(inStream); - m_OutWindow.Init(outStream, _solid); - - uint i; - for (i = 0; i < Base.kNumStates; i++) - { - for (uint j = 0; j <= m_PosStateMask; j++) - { - uint index = (i << Base.kNumPosStatesBitsMax) + j; - m_IsMatchDecoders[index].Init(); - m_IsRep0LongDecoders[index].Init(); - } - m_IsRepDecoders[i].Init(); - m_IsRepG0Decoders[i].Init(); - m_IsRepG1Decoders[i].Init(); - m_IsRepG2Decoders[i].Init(); - } - - m_LiteralDecoder.Init(); - for (i = 0; i < Base.kNumLenToPosStates; i++) - m_PosSlotDecoder[i].Init(); - // m_PosSpecDecoder.Init(); - for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++) - m_PosDecoders[i].Init(); - - m_LenDecoder.Init(); - m_RepLenDecoder.Init(); - m_PosAlignDecoder.Init(); - } - - public void Code(System.IO.Stream inStream, System.IO.Stream outStream, - Int64 inSize, Int64 outSize, ICodeProgress progress) - { - Init(inStream, outStream); - - Base.State state = new Base.State(); - state.Init(); - uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0; - - UInt64 nowPos64 = 0; - UInt64 outSize64 = (UInt64)outSize; - if (nowPos64 < outSize64) - { - if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0) - throw new DataErrorException(); - state.UpdateChar(); - byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0); - m_OutWindow.PutByte(b); - nowPos64++; - } - while (nowPos64 < outSize64) - { - // UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64); - // while(nowPos64 < next) - { - uint posState = (uint)nowPos64 & m_PosStateMask; - if (m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0) - { - byte b; - byte prevByte = m_OutWindow.GetByte(0); - if (!state.IsCharState()) - b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder, - (uint)nowPos64, prevByte, m_OutWindow.GetByte(rep0)); - else - b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)nowPos64, prevByte); - m_OutWindow.PutByte(b); - state.UpdateChar(); - nowPos64++; - } - else - { - uint len; - if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1) - { - if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0) - { - if (m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0) - { - state.UpdateShortRep(); - m_OutWindow.PutByte(m_OutWindow.GetByte(rep0)); - nowPos64++; - continue; - } - } - else - { - UInt32 distance; - if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0) - { - distance = rep1; - } - else - { - if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0) - distance = rep2; - else - { - distance = rep3; - rep3 = rep2; - } - rep2 = rep1; - } - rep1 = rep0; - rep0 = distance; - } - len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen; - state.UpdateRep(); - } - else - { - rep3 = rep2; - rep2 = rep1; - rep1 = rep0; - len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState); - state.UpdateMatch(); - uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder); - if (posSlot >= Base.kStartPosModelIndex) - { - int numDirectBits = (int)((posSlot >> 1) - 1); - rep0 = ((2 | (posSlot & 1)) << numDirectBits); - if (posSlot < Base.kEndPosModelIndex) - rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders, - rep0 - posSlot - 1, m_RangeDecoder, numDirectBits); - else - { - rep0 += (m_RangeDecoder.DecodeDirectBits( - numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits); - rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder); - } - } - else - rep0 = posSlot; - } - if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck) - { - if (rep0 == 0xFFFFFFFF) - break; - throw new DataErrorException(); - } - m_OutWindow.CopyBlock(rep0, len); - nowPos64 += len; - } - } - } - m_OutWindow.Flush(); - m_OutWindow.ReleaseStream(); - m_RangeDecoder.ReleaseStream(); - } - - public void SetDecoderProperties(byte[] properties) - { - if (properties.Length < 5) - throw new InvalidParamException(); - int lc = properties[0] % 9; - int remainder = properties[0] / 9; - int lp = remainder % 5; - int pb = remainder / 5; - if (pb > Base.kNumPosStatesBitsMax) - throw new InvalidParamException(); - UInt32 dictionarySize = 0; - for (int i = 0; i < 4; i++) - dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8); - SetDictionarySize(dictionarySize); - SetLiteralProperties(lp, lc); - SetPosBitsProperties(pb); - } - - public bool Train(System.IO.Stream stream) - { - _solid = true; - return m_OutWindow.Train(stream); - } - - /* - public override bool CanRead { get { return true; }} - public override bool CanWrite { get { return true; }} - public override bool CanSeek { get { return true; }} - public override long Length { get { return 0; }} - public override long Position - { - get { return 0; } - set { } - } - public override void Flush() { } - public override int Read(byte[] buffer, int offset, int count) - { - return 0; - } - public override void Write(byte[] buffer, int offset, int count) - { - } - public override long Seek(long offset, System.IO.SeekOrigin origin) - { - return 0; - } - public override void SetLength(long value) {} - */ - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZMA/LzmaEncoder.cs b/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZMA/LzmaEncoder.cs deleted file mode 100644 index 3341be17a..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/Compress/LZMA/LzmaEncoder.cs +++ /dev/null @@ -1,1480 +0,0 @@ -// LzmaEncoder.cs - -using System; - -namespace Tango.Transport.Compression.LZMA -{ - using RangeCoder; - - public class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties - { - enum EMatchFinderType - { - BT2, - BT4, - }; - - const UInt32 kIfinityPrice = 0xFFFFFFF; - - static Byte[] g_FastPos = new Byte[1 << 11]; - - static Encoder() - { - const Byte kFastSlots = 22; - int c = 2; - g_FastPos[0] = 0; - g_FastPos[1] = 1; - for (Byte slotFast = 2; slotFast < kFastSlots; slotFast++) - { - UInt32 k = ((UInt32)1 << ((slotFast >> 1) - 1)); - for (UInt32 j = 0; j < k; j++, c++) - g_FastPos[c] = slotFast; - } - } - - static UInt32 GetPosSlot(UInt32 pos) - { - if (pos < (1 << 11)) - return g_FastPos[pos]; - if (pos < (1 << 21)) - return (UInt32)(g_FastPos[pos >> 10] + 20); - return (UInt32)(g_FastPos[pos >> 20] + 40); - } - - static UInt32 GetPosSlot2(UInt32 pos) - { - if (pos < (1 << 17)) - return (UInt32)(g_FastPos[pos >> 6] + 12); - if (pos < (1 << 27)) - return (UInt32)(g_FastPos[pos >> 16] + 32); - return (UInt32)(g_FastPos[pos >> 26] + 52); - } - - Base.State _state = new Base.State(); - Byte _previousByte; - UInt32[] _repDistances = new UInt32[Base.kNumRepDistances]; - - void BaseInit() - { - _state.Init(); - _previousByte = 0; - for (UInt32 i = 0; i < Base.kNumRepDistances; i++) - _repDistances[i] = 0; - } - - const int kDefaultDictionaryLogSize = 22; - const UInt32 kNumFastBytesDefault = 0x20; - - class LiteralEncoder - { - public struct Encoder2 - { - BitEncoder[] m_Encoders; - - public void Create() { m_Encoders = new BitEncoder[0x300]; } - - public void Init() { for (int i = 0; i < 0x300; i++) m_Encoders[i].Init(); } - - public void Encode(RangeCoder.Encoder rangeEncoder, byte symbol) - { - uint context = 1; - for (int i = 7; i >= 0; i--) - { - uint bit = (uint)((symbol >> i) & 1); - m_Encoders[context].Encode(rangeEncoder, bit); - context = (context << 1) | bit; - } - } - - public void EncodeMatched(RangeCoder.Encoder rangeEncoder, byte matchByte, byte symbol) - { - uint context = 1; - bool same = true; - for (int i = 7; i >= 0; i--) - { - uint bit = (uint)((symbol >> i) & 1); - uint state = context; - if (same) - { - uint matchBit = (uint)((matchByte >> i) & 1); - state += ((1 + matchBit) << 8); - same = (matchBit == bit); - } - m_Encoders[state].Encode(rangeEncoder, bit); - context = (context << 1) | bit; - } - } - - public uint GetPrice(bool matchMode, byte matchByte, byte symbol) - { - uint price = 0; - uint context = 1; - int i = 7; - if (matchMode) - { - for (; i >= 0; i--) - { - uint matchBit = (uint)(matchByte >> i) & 1; - uint bit = (uint)(symbol >> i) & 1; - price += m_Encoders[((1 + matchBit) << 8) + context].GetPrice(bit); - context = (context << 1) | bit; - if (matchBit != bit) - { - i--; - break; - } - } - } - for (; i >= 0; i--) - { - uint bit = (uint)(symbol >> i) & 1; - price += m_Encoders[context].GetPrice(bit); - context = (context << 1) | bit; - } - return price; - } - } - - Encoder2[] m_Coders; - int m_NumPrevBits; - int m_NumPosBits; - uint m_PosMask; - - public void Create(int numPosBits, int numPrevBits) - { - if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits) - return; - m_NumPosBits = numPosBits; - m_PosMask = ((uint)1 << numPosBits) - 1; - m_NumPrevBits = numPrevBits; - uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits); - m_Coders = new Encoder2[numStates]; - for (uint i = 0; i < numStates; i++) - m_Coders[i].Create(); - } - - public void Init() - { - uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits); - for (uint i = 0; i < numStates; i++) - m_Coders[i].Init(); - } - - public Encoder2 GetSubCoder(UInt32 pos, Byte prevByte) - { return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits))]; } - } - - class LenEncoder - { - RangeCoder.BitEncoder _choice = new RangeCoder.BitEncoder(); - RangeCoder.BitEncoder _choice2 = new RangeCoder.BitEncoder(); - RangeCoder.BitTreeEncoder[] _lowCoder = new RangeCoder.BitTreeEncoder[Base.kNumPosStatesEncodingMax]; - RangeCoder.BitTreeEncoder[] _midCoder = new RangeCoder.BitTreeEncoder[Base.kNumPosStatesEncodingMax]; - RangeCoder.BitTreeEncoder _highCoder = new RangeCoder.BitTreeEncoder(Base.kNumHighLenBits); - - public LenEncoder() - { - for (UInt32 posState = 0; posState < Base.kNumPosStatesEncodingMax; posState++) - { - _lowCoder[posState] = new RangeCoder.BitTreeEncoder(Base.kNumLowLenBits); - _midCoder[posState] = new RangeCoder.BitTreeEncoder(Base.kNumMidLenBits); - } - } - - public void Init(UInt32 numPosStates) - { - _choice.Init(); - _choice2.Init(); - for (UInt32 posState = 0; posState < numPosStates; posState++) - { - _lowCoder[posState].Init(); - _midCoder[posState].Init(); - } - _highCoder.Init(); - } - - public void Encode(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState) - { - if (symbol < Base.kNumLowLenSymbols) - { - _choice.Encode(rangeEncoder, 0); - _lowCoder[posState].Encode(rangeEncoder, symbol); - } - else - { - symbol -= Base.kNumLowLenSymbols; - _choice.Encode(rangeEncoder, 1); - if (symbol < Base.kNumMidLenSymbols) - { - _choice2.Encode(rangeEncoder, 0); - _midCoder[posState].Encode(rangeEncoder, symbol); - } - else - { - _choice2.Encode(rangeEncoder, 1); - _highCoder.Encode(rangeEncoder, symbol - Base.kNumMidLenSymbols); - } - } - } - - public void SetPrices(UInt32 posState, UInt32 numSymbols, UInt32[] prices, UInt32 st) - { - UInt32 a0 = _choice.GetPrice0(); - UInt32 a1 = _choice.GetPrice1(); - UInt32 b0 = a1 + _choice2.GetPrice0(); - UInt32 b1 = a1 + _choice2.GetPrice1(); - UInt32 i = 0; - for (i = 0; i < Base.kNumLowLenSymbols; i++) - { - if (i >= numSymbols) - return; - prices[st + i] = a0 + _lowCoder[posState].GetPrice(i); - } - for (; i < Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; i++) - { - if (i >= numSymbols) - return; - prices[st + i] = b0 + _midCoder[posState].GetPrice(i - Base.kNumLowLenSymbols); - } - for (; i < numSymbols; i++) - prices[st + i] = b1 + _highCoder.GetPrice(i - Base.kNumLowLenSymbols - Base.kNumMidLenSymbols); - } - }; - - const UInt32 kNumLenSpecSymbols = Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; - - class LenPriceTableEncoder : LenEncoder - { - UInt32[] _prices = new UInt32[Base.kNumLenSymbols << Base.kNumPosStatesBitsEncodingMax]; - UInt32 _tableSize; - UInt32[] _counters = new UInt32[Base.kNumPosStatesEncodingMax]; - - public void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; } - - public UInt32 GetPrice(UInt32 symbol, UInt32 posState) - { - return _prices[posState * Base.kNumLenSymbols + symbol]; - } - - void UpdateTable(UInt32 posState) - { - SetPrices(posState, _tableSize, _prices, posState * Base.kNumLenSymbols); - _counters[posState] = _tableSize; - } - - public void UpdateTables(UInt32 numPosStates) - { - for (UInt32 posState = 0; posState < numPosStates; posState++) - UpdateTable(posState); - } - - public new void Encode(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState) - { - base.Encode(rangeEncoder, symbol, posState); - if (--_counters[posState] == 0) - UpdateTable(posState); - } - } - - const UInt32 kNumOpts = 1 << 12; - class Optimal - { - public Base.State State; - - public bool Prev1IsChar; - public bool Prev2; - - public UInt32 PosPrev2; - public UInt32 BackPrev2; - - public UInt32 Price; - public UInt32 PosPrev; - public UInt32 BackPrev; - - public UInt32 Backs0; - public UInt32 Backs1; - public UInt32 Backs2; - public UInt32 Backs3; - - public void MakeAsChar() { BackPrev = 0xFFFFFFFF; Prev1IsChar = false; } - public void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; } - public bool IsShortRep() { return (BackPrev == 0); } - }; - Optimal[] _optimum = new Optimal[kNumOpts]; - LZ.IMatchFinder _matchFinder = null; - RangeCoder.Encoder _rangeEncoder = new RangeCoder.Encoder(); - - RangeCoder.BitEncoder[] _isMatch = new RangeCoder.BitEncoder[Base.kNumStates << Base.kNumPosStatesBitsMax]; - RangeCoder.BitEncoder[] _isRep = new RangeCoder.BitEncoder[Base.kNumStates]; - RangeCoder.BitEncoder[] _isRepG0 = new RangeCoder.BitEncoder[Base.kNumStates]; - RangeCoder.BitEncoder[] _isRepG1 = new RangeCoder.BitEncoder[Base.kNumStates]; - RangeCoder.BitEncoder[] _isRepG2 = new RangeCoder.BitEncoder[Base.kNumStates]; - RangeCoder.BitEncoder[] _isRep0Long = new RangeCoder.BitEncoder[Base.kNumStates << Base.kNumPosStatesBitsMax]; - - RangeCoder.BitTreeEncoder[] _posSlotEncoder = new RangeCoder.BitTreeEncoder[Base.kNumLenToPosStates]; - - RangeCoder.BitEncoder[] _posEncoders = new RangeCoder.BitEncoder[Base.kNumFullDistances - Base.kEndPosModelIndex]; - RangeCoder.BitTreeEncoder _posAlignEncoder = new RangeCoder.BitTreeEncoder(Base.kNumAlignBits); - - LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder(); - LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEncoder(); - - LiteralEncoder _literalEncoder = new LiteralEncoder(); - - UInt32[] _matchDistances = new UInt32[Base.kMatchMaxLen * 2 + 2]; - - UInt32 _numFastBytes = kNumFastBytesDefault; - UInt32 _longestMatchLength; - UInt32 _numDistancePairs; - - UInt32 _additionalOffset; - - UInt32 _optimumEndIndex; - UInt32 _optimumCurrentIndex; - - bool _longestMatchWasFound; - - UInt32[] _posSlotPrices = new UInt32[1 << (Base.kNumPosSlotBits + Base.kNumLenToPosStatesBits)]; - UInt32[] _distancesPrices = new UInt32[Base.kNumFullDistances << Base.kNumLenToPosStatesBits]; - UInt32[] _alignPrices = new UInt32[Base.kAlignTableSize]; - UInt32 _alignPriceCount; - - UInt32 _distTableSize = (kDefaultDictionaryLogSize * 2); - - int _posStateBits = 2; - UInt32 _posStateMask = (4 - 1); - int _numLiteralPosStateBits = 0; - int _numLiteralContextBits = 3; - - UInt32 _dictionarySize = (1 << kDefaultDictionaryLogSize); - UInt32 _dictionarySizePrev = 0xFFFFFFFF; - UInt32 _numFastBytesPrev = 0xFFFFFFFF; - - Int64 nowPos64; - bool _finished; - System.IO.Stream _inStream; - - EMatchFinderType _matchFinderType = EMatchFinderType.BT4; - bool _writeEndMark = false; - - bool _needReleaseMFStream; - - void Create() - { - if (_matchFinder == null) - { - LZ.BinTree bt = new LZ.BinTree(); - int numHashBytes = 4; - if (_matchFinderType == EMatchFinderType.BT2) - numHashBytes = 2; - bt.SetType(numHashBytes); - _matchFinder = bt; - } - _literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits); - - if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes) - return; - _matchFinder.Create(_dictionarySize, kNumOpts, _numFastBytes, Base.kMatchMaxLen + 1); - _dictionarySizePrev = _dictionarySize; - _numFastBytesPrev = _numFastBytes; - } - - public Encoder() - { - for (int i = 0; i < kNumOpts; i++) - _optimum[i] = new Optimal(); - for (int i = 0; i < Base.kNumLenToPosStates; i++) - _posSlotEncoder[i] = new RangeCoder.BitTreeEncoder(Base.kNumPosSlotBits); - } - - void SetWriteEndMarkerMode(bool writeEndMarker) - { - _writeEndMark = writeEndMarker; - } - - void Init() - { - BaseInit(); - _rangeEncoder.Init(); - - uint i; - for (i = 0; i < Base.kNumStates; i++) - { - for (uint j = 0; j <= _posStateMask; j++) - { - uint complexState = (i << Base.kNumPosStatesBitsMax) + j; - _isMatch[complexState].Init(); - _isRep0Long[complexState].Init(); - } - _isRep[i].Init(); - _isRepG0[i].Init(); - _isRepG1[i].Init(); - _isRepG2[i].Init(); - } - _literalEncoder.Init(); - for (i = 0; i < Base.kNumLenToPosStates; i++) - _posSlotEncoder[i].Init(); - for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++) - _posEncoders[i].Init(); - - _lenEncoder.Init((UInt32)1 << _posStateBits); - _repMatchLenEncoder.Init((UInt32)1 << _posStateBits); - - _posAlignEncoder.Init(); - - _longestMatchWasFound = false; - _optimumEndIndex = 0; - _optimumCurrentIndex = 0; - _additionalOffset = 0; - } - - void ReadMatchDistances(out UInt32 lenRes, out UInt32 numDistancePairs) - { - lenRes = 0; - numDistancePairs = _matchFinder.GetMatches(_matchDistances); - if (numDistancePairs > 0) - { - lenRes = _matchDistances[numDistancePairs - 2]; - if (lenRes == _numFastBytes) - lenRes += _matchFinder.GetMatchLen((int)lenRes - 1, _matchDistances[numDistancePairs - 1], - Base.kMatchMaxLen - lenRes); - } - _additionalOffset++; - } - - - void MovePos(UInt32 num) - { - if (num > 0) - { - _matchFinder.Skip(num); - _additionalOffset += num; - } - } - - UInt32 GetRepLen1Price(Base.State state, UInt32 posState) - { - return _isRepG0[state.Index].GetPrice0() + - _isRep0Long[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0(); - } - - UInt32 GetPureRepPrice(UInt32 repIndex, Base.State state, UInt32 posState) - { - UInt32 price; - if (repIndex == 0) - { - price = _isRepG0[state.Index].GetPrice0(); - price += _isRep0Long[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1(); - } - else - { - price = _isRepG0[state.Index].GetPrice1(); - if (repIndex == 1) - price += _isRepG1[state.Index].GetPrice0(); - else - { - price += _isRepG1[state.Index].GetPrice1(); - price += _isRepG2[state.Index].GetPrice(repIndex - 2); - } - } - return price; - } - - UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, Base.State state, UInt32 posState) - { - UInt32 price = _repMatchLenEncoder.GetPrice(len - Base.kMatchMinLen, posState); - return price + GetPureRepPrice(repIndex, state, posState); - } - - UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) - { - UInt32 price; - UInt32 lenToPosState = Base.GetLenToPosState(len); - if (pos < Base.kNumFullDistances) - price = _distancesPrices[(lenToPosState * Base.kNumFullDistances) + pos]; - else - price = _posSlotPrices[(lenToPosState << Base.kNumPosSlotBits) + GetPosSlot2(pos)] + - _alignPrices[pos & Base.kAlignMask]; - return price + _lenEncoder.GetPrice(len - Base.kMatchMinLen, posState); - } - - UInt32 Backward(out UInt32 backRes, UInt32 cur) - { - _optimumEndIndex = cur; - UInt32 posMem = _optimum[cur].PosPrev; - UInt32 backMem = _optimum[cur].BackPrev; - do - { - if (_optimum[cur].Prev1IsChar) - { - _optimum[posMem].MakeAsChar(); - _optimum[posMem].PosPrev = posMem - 1; - if (_optimum[cur].Prev2) - { - _optimum[posMem - 1].Prev1IsChar = false; - _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2; - _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2; - } - } - UInt32 posPrev = posMem; - UInt32 backCur = backMem; - - backMem = _optimum[posPrev].BackPrev; - posMem = _optimum[posPrev].PosPrev; - - _optimum[posPrev].BackPrev = backCur; - _optimum[posPrev].PosPrev = cur; - cur = posPrev; - } - while (cur > 0); - backRes = _optimum[0].BackPrev; - _optimumCurrentIndex = _optimum[0].PosPrev; - return _optimumCurrentIndex; - } - - UInt32[] reps = new UInt32[Base.kNumRepDistances]; - UInt32[] repLens = new UInt32[Base.kNumRepDistances]; - - - UInt32 GetOptimum(UInt32 position, out UInt32 backRes) - { - if (_optimumEndIndex != _optimumCurrentIndex) - { - UInt32 lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex; - backRes = _optimum[_optimumCurrentIndex].BackPrev; - _optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev; - return lenRes; - } - _optimumCurrentIndex = _optimumEndIndex = 0; - - UInt32 lenMain, numDistancePairs; - if (!_longestMatchWasFound) - { - ReadMatchDistances(out lenMain, out numDistancePairs); - } - else - { - lenMain = _longestMatchLength; - numDistancePairs = _numDistancePairs; - _longestMatchWasFound = false; - } - - UInt32 numAvailableBytes = _matchFinder.GetNumAvailableBytes() + 1; - if (numAvailableBytes < 2) - { - backRes = 0xFFFFFFFF; - return 1; - } - if (numAvailableBytes > Base.kMatchMaxLen) - numAvailableBytes = Base.kMatchMaxLen; - - UInt32 repMaxIndex = 0; - UInt32 i; - for (i = 0; i < Base.kNumRepDistances; i++) - { - reps[i] = _repDistances[i]; - repLens[i] = _matchFinder.GetMatchLen(0 - 1, reps[i], Base.kMatchMaxLen); - if (repLens[i] > repLens[repMaxIndex]) - repMaxIndex = i; - } - if (repLens[repMaxIndex] >= _numFastBytes) - { - backRes = repMaxIndex; - UInt32 lenRes = repLens[repMaxIndex]; - MovePos(lenRes - 1); - return lenRes; - } - - if (lenMain >= _numFastBytes) - { - backRes = _matchDistances[numDistancePairs - 1] + Base.kNumRepDistances; - MovePos(lenMain - 1); - return lenMain; - } - - Byte currentByte = _matchFinder.GetIndexByte(0 - 1); - Byte matchByte = _matchFinder.GetIndexByte((Int32)(0 - _repDistances[0] - 1 - 1)); - - if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2) - { - backRes = (UInt32)0xFFFFFFFF; - return 1; - } - - _optimum[0].State = _state; - - UInt32 posState = (position & _posStateMask); - - _optimum[1].Price = _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0() + - _literalEncoder.GetSubCoder(position, _previousByte).GetPrice(!_state.IsCharState(), matchByte, currentByte); - _optimum[1].MakeAsChar(); - - UInt32 matchPrice = _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1(); - UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1(); - - if (matchByte == currentByte) - { - UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState); - if (shortRepPrice < _optimum[1].Price) - { - _optimum[1].Price = shortRepPrice; - _optimum[1].MakeAsShortRep(); - } - } - - UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]); - - if(lenEnd < 2) - { - backRes = _optimum[1].BackPrev; - return 1; - } - - _optimum[1].PosPrev = 0; - - _optimum[0].Backs0 = reps[0]; - _optimum[0].Backs1 = reps[1]; - _optimum[0].Backs2 = reps[2]; - _optimum[0].Backs3 = reps[3]; - - UInt32 len = lenEnd; - do - _optimum[len--].Price = kIfinityPrice; - while (len >= 2); - - for (i = 0; i < Base.kNumRepDistances; i++) - { - UInt32 repLen = repLens[i]; - if (repLen < 2) - continue; - UInt32 price = repMatchPrice + GetPureRepPrice(i, _state, posState); - do - { - UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState); - Optimal optimum = _optimum[repLen]; - if (curAndLenPrice < optimum.Price) - { - optimum.Price = curAndLenPrice; - optimum.PosPrev = 0; - optimum.BackPrev = i; - optimum.Prev1IsChar = false; - } - } - while (--repLen >= 2); - } - - UInt32 normalMatchPrice = matchPrice + _isRep[_state.Index].GetPrice0(); - - len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); - if (len <= lenMain) - { - UInt32 offs = 0; - while (len > _matchDistances[offs]) - offs += 2; - for (; ; len++) - { - UInt32 distance = _matchDistances[offs + 1]; - UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState); - Optimal optimum = _optimum[len]; - if (curAndLenPrice < optimum.Price) - { - optimum.Price = curAndLenPrice; - optimum.PosPrev = 0; - optimum.BackPrev = distance + Base.kNumRepDistances; - optimum.Prev1IsChar = false; - } - if (len == _matchDistances[offs]) - { - offs += 2; - if (offs == numDistancePairs) - break; - } - } - } - - UInt32 cur = 0; - - while (true) - { - cur++; - if (cur == lenEnd) - return Backward(out backRes, cur); - UInt32 newLen; - ReadMatchDistances(out newLen, out numDistancePairs); - if (newLen >= _numFastBytes) - { - _numDistancePairs = numDistancePairs; - _longestMatchLength = newLen; - _longestMatchWasFound = true; - return Backward(out backRes, cur); - } - position++; - UInt32 posPrev = _optimum[cur].PosPrev; - Base.State state; - if (_optimum[cur].Prev1IsChar) - { - posPrev--; - if (_optimum[cur].Prev2) - { - state = _optimum[_optimum[cur].PosPrev2].State; - if (_optimum[cur].BackPrev2 < Base.kNumRepDistances) - state.UpdateRep(); - else - state.UpdateMatch(); - } - else - state = _optimum[posPrev].State; - state.UpdateChar(); - } - else - state = _optimum[posPrev].State; - if (posPrev == cur - 1) - { - if (_optimum[cur].IsShortRep()) - state.UpdateShortRep(); - else - state.UpdateChar(); - } - else - { - UInt32 pos; - if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2) - { - posPrev = _optimum[cur].PosPrev2; - pos = _optimum[cur].BackPrev2; - state.UpdateRep(); - } - else - { - pos = _optimum[cur].BackPrev; - if (pos < Base.kNumRepDistances) - state.UpdateRep(); - else - state.UpdateMatch(); - } - Optimal opt = _optimum[posPrev]; - if (pos < Base.kNumRepDistances) - { - if (pos == 0) - { - reps[0] = opt.Backs0; - reps[1] = opt.Backs1; - reps[2] = opt.Backs2; - reps[3] = opt.Backs3; - } - else if (pos == 1) - { - reps[0] = opt.Backs1; - reps[1] = opt.Backs0; - reps[2] = opt.Backs2; - reps[3] = opt.Backs3; - } - else if (pos == 2) - { - reps[0] = opt.Backs2; - reps[1] = opt.Backs0; - reps[2] = opt.Backs1; - reps[3] = opt.Backs3; - } - else - { - reps[0] = opt.Backs3; - reps[1] = opt.Backs0; - reps[2] = opt.Backs1; - reps[3] = opt.Backs2; - } - } - else - { - reps[0] = (pos - Base.kNumRepDistances); - reps[1] = opt.Backs0; - reps[2] = opt.Backs1; - reps[3] = opt.Backs2; - } - } - _optimum[cur].State = state; - _optimum[cur].Backs0 = reps[0]; - _optimum[cur].Backs1 = reps[1]; - _optimum[cur].Backs2 = reps[2]; - _optimum[cur].Backs3 = reps[3]; - UInt32 curPrice = _optimum[cur].Price; - - currentByte = _matchFinder.GetIndexByte(0 - 1); - matchByte = _matchFinder.GetIndexByte((Int32)(0 - reps[0] - 1 - 1)); - - posState = (position & _posStateMask); - - UInt32 curAnd1Price = curPrice + - _isMatch[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0() + - _literalEncoder.GetSubCoder(position, _matchFinder.GetIndexByte(0 - 2)). - GetPrice(!state.IsCharState(), matchByte, currentByte); - - Optimal nextOptimum = _optimum[cur + 1]; - - bool nextIsChar = false; - if (curAnd1Price < nextOptimum.Price) - { - nextOptimum.Price = curAnd1Price; - nextOptimum.PosPrev = cur; - nextOptimum.MakeAsChar(); - nextIsChar = true; - } - - matchPrice = curPrice + _isMatch[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1(); - repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1(); - - if (matchByte == currentByte && - !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0)) - { - UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState); - if (shortRepPrice <= nextOptimum.Price) - { - nextOptimum.Price = shortRepPrice; - nextOptimum.PosPrev = cur; - nextOptimum.MakeAsShortRep(); - nextIsChar = true; - } - } - - UInt32 numAvailableBytesFull = _matchFinder.GetNumAvailableBytes() + 1; - numAvailableBytesFull = Math.Min(kNumOpts - 1 - cur, numAvailableBytesFull); - numAvailableBytes = numAvailableBytesFull; - - if (numAvailableBytes < 2) - continue; - if (numAvailableBytes > _numFastBytes) - numAvailableBytes = _numFastBytes; - if (!nextIsChar && matchByte != currentByte) - { - // try Literal + rep0 - UInt32 t = Math.Min(numAvailableBytesFull - 1, _numFastBytes); - UInt32 lenTest2 = _matchFinder.GetMatchLen(0, reps[0], t); - if (lenTest2 >= 2) - { - Base.State state2 = state; - state2.UpdateChar(); - UInt32 posStateNext = (position + 1) & _posStateMask; - UInt32 nextRepMatchPrice = curAnd1Price + - _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1() + - _isRep[state2.Index].GetPrice1(); - { - UInt32 offset = cur + 1 + lenTest2; - while (lenEnd < offset) - _optimum[++lenEnd].Price = kIfinityPrice; - UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice( - 0, lenTest2, state2, posStateNext); - Optimal optimum = _optimum[offset]; - if (curAndLenPrice < optimum.Price) - { - optimum.Price = curAndLenPrice; - optimum.PosPrev = cur + 1; - optimum.BackPrev = 0; - optimum.Prev1IsChar = true; - optimum.Prev2 = false; - } - } - } - } - - UInt32 startLen = 2; // speed optimization - - for (UInt32 repIndex = 0; repIndex < Base.kNumRepDistances; repIndex++) - { - UInt32 lenTest = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], numAvailableBytes); - if (lenTest < 2) - continue; - UInt32 lenTestTemp = lenTest; - do - { - while (lenEnd < cur + lenTest) - _optimum[++lenEnd].Price = kIfinityPrice; - UInt32 curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState); - Optimal optimum = _optimum[cur + lenTest]; - if (curAndLenPrice < optimum.Price) - { - optimum.Price = curAndLenPrice; - optimum.PosPrev = cur; - optimum.BackPrev = repIndex; - optimum.Prev1IsChar = false; - } - } - while(--lenTest >= 2); - lenTest = lenTestTemp; - - if (repIndex == 0) - startLen = lenTest + 1; - - // if (_maxMode) - if (lenTest < numAvailableBytesFull) - { - UInt32 t = Math.Min(numAvailableBytesFull - 1 - lenTest, _numFastBytes); - UInt32 lenTest2 = _matchFinder.GetMatchLen((Int32)lenTest, reps[repIndex], t); - if (lenTest2 >= 2) - { - Base.State state2 = state; - state2.UpdateRep(); - UInt32 posStateNext = (position + lenTest) & _posStateMask; - UInt32 curAndLenCharPrice = - repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState) + - _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice0() + - _literalEncoder.GetSubCoder(position + lenTest, - _matchFinder.GetIndexByte((Int32)lenTest - 1 - 1)).GetPrice(true, - _matchFinder.GetIndexByte((Int32)((Int32)lenTest - 1 - (Int32)(reps[repIndex] + 1))), - _matchFinder.GetIndexByte((Int32)lenTest - 1)); - state2.UpdateChar(); - posStateNext = (position + lenTest + 1) & _posStateMask; - UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1(); - UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1(); - - // for(; lenTest2 >= 2; lenTest2--) - { - UInt32 offset = lenTest + 1 + lenTest2; - while(lenEnd < cur + offset) - _optimum[++lenEnd].Price = kIfinityPrice; - UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext); - Optimal optimum = _optimum[cur + offset]; - if (curAndLenPrice < optimum.Price) - { - optimum.Price = curAndLenPrice; - optimum.PosPrev = cur + lenTest + 1; - optimum.BackPrev = 0; - optimum.Prev1IsChar = true; - optimum.Prev2 = true; - optimum.PosPrev2 = cur; - optimum.BackPrev2 = repIndex; - } - } - } - } - } - - if (newLen > numAvailableBytes) - { - newLen = numAvailableBytes; - for (numDistancePairs = 0; newLen > _matchDistances[numDistancePairs]; numDistancePairs += 2) ; - _matchDistances[numDistancePairs] = newLen; - numDistancePairs += 2; - } - if (newLen >= startLen) - { - normalMatchPrice = matchPrice + _isRep[state.Index].GetPrice0(); - while (lenEnd < cur + newLen) - _optimum[++lenEnd].Price = kIfinityPrice; - - UInt32 offs = 0; - while (startLen > _matchDistances[offs]) - offs += 2; - - for (UInt32 lenTest = startLen; ; lenTest++) - { - UInt32 curBack = _matchDistances[offs + 1]; - UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState); - Optimal optimum = _optimum[cur + lenTest]; - if (curAndLenPrice < optimum.Price) - { - optimum.Price = curAndLenPrice; - optimum.PosPrev = cur; - optimum.BackPrev = curBack + Base.kNumRepDistances; - optimum.Prev1IsChar = false; - } - - if (lenTest == _matchDistances[offs]) - { - if (lenTest < numAvailableBytesFull) - { - UInt32 t = Math.Min(numAvailableBytesFull - 1 - lenTest, _numFastBytes); - UInt32 lenTest2 = _matchFinder.GetMatchLen((Int32)lenTest, curBack, t); - if (lenTest2 >= 2) - { - Base.State state2 = state; - state2.UpdateMatch(); - UInt32 posStateNext = (position + lenTest) & _posStateMask; - UInt32 curAndLenCharPrice = curAndLenPrice + - _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice0() + - _literalEncoder.GetSubCoder(position + lenTest, - _matchFinder.GetIndexByte((Int32)lenTest - 1 - 1)). - GetPrice(true, - _matchFinder.GetIndexByte((Int32)lenTest - (Int32)(curBack + 1) - 1), - _matchFinder.GetIndexByte((Int32)lenTest - 1)); - state2.UpdateChar(); - posStateNext = (position + lenTest + 1) & _posStateMask; - UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1(); - UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1(); - - UInt32 offset = lenTest + 1 + lenTest2; - while (lenEnd < cur + offset) - _optimum[++lenEnd].Price = kIfinityPrice; - curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext); - optimum = _optimum[cur + offset]; - if (curAndLenPrice < optimum.Price) - { - optimum.Price = curAndLenPrice; - optimum.PosPrev = cur + lenTest + 1; - optimum.BackPrev = 0; - optimum.Prev1IsChar = true; - optimum.Prev2 = true; - optimum.PosPrev2 = cur; - optimum.BackPrev2 = curBack + Base.kNumRepDistances; - } - } - } - offs += 2; - if (offs == numDistancePairs) - break; - } - } - } - } - } - - bool ChangePair(UInt32 smallDist, UInt32 bigDist) - { - const int kDif = 7; - return (smallDist < ((UInt32)(1) << (32 - kDif)) && bigDist >= (smallDist << kDif)); - } - - void WriteEndMarker(UInt32 posState) - { - if (!_writeEndMark) - return; - - _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].Encode(_rangeEncoder, 1); - _isRep[_state.Index].Encode(_rangeEncoder, 0); - _state.UpdateMatch(); - UInt32 len = Base.kMatchMinLen; - _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState); - UInt32 posSlot = (1 << Base.kNumPosSlotBits) - 1; - UInt32 lenToPosState = Base.GetLenToPosState(len); - _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot); - int footerBits = 30; - UInt32 posReduced = (((UInt32)1) << footerBits) - 1; - _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits); - _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask); - } - - void Flush(UInt32 nowPos) - { - ReleaseMFStream(); - WriteEndMarker(nowPos & _posStateMask); - _rangeEncoder.FlushData(); - _rangeEncoder.FlushStream(); - } - - public void CodeOneBlock(out Int64 inSize, out Int64 outSize, out bool finished) - { - inSize = 0; - outSize = 0; - finished = true; - - if (_inStream != null) - { - _matchFinder.SetStream(_inStream); - _matchFinder.Init(); - _needReleaseMFStream = true; - _inStream = null; - if (_trainSize > 0) - _matchFinder.Skip(_trainSize); - } - - if (_finished) - return; - _finished = true; - - - Int64 progressPosValuePrev = nowPos64; - if (nowPos64 == 0) - { - if (_matchFinder.GetNumAvailableBytes() == 0) - { - Flush((UInt32)nowPos64); - return; - } - UInt32 len, numDistancePairs; // it's not used - ReadMatchDistances(out len, out numDistancePairs); - UInt32 posState = (UInt32)(nowPos64) & _posStateMask; - _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].Encode(_rangeEncoder, 0); - _state.UpdateChar(); - Byte curByte = _matchFinder.GetIndexByte((Int32)(0 - _additionalOffset)); - _literalEncoder.GetSubCoder((UInt32)(nowPos64), _previousByte).Encode(_rangeEncoder, curByte); - _previousByte = curByte; - _additionalOffset--; - nowPos64++; - } - if (_matchFinder.GetNumAvailableBytes() == 0) - { - Flush((UInt32)nowPos64); - return; - } - while (true) - { - UInt32 pos; - UInt32 len = GetOptimum((UInt32)nowPos64, out pos); - - UInt32 posState = ((UInt32)nowPos64) & _posStateMask; - UInt32 complexState = (_state.Index << Base.kNumPosStatesBitsMax) + posState; - if (len == 1 && pos == 0xFFFFFFFF) - { - _isMatch[complexState].Encode(_rangeEncoder, 0); - Byte curByte = _matchFinder.GetIndexByte((Int32)(0 - _additionalOffset)); - LiteralEncoder.Encoder2 subCoder = _literalEncoder.GetSubCoder((UInt32)nowPos64, _previousByte); - if (!_state.IsCharState()) - { - Byte matchByte = _matchFinder.GetIndexByte((Int32)(0 - _repDistances[0] - 1 - _additionalOffset)); - subCoder.EncodeMatched(_rangeEncoder, matchByte, curByte); - } - else - subCoder.Encode(_rangeEncoder, curByte); - _previousByte = curByte; - _state.UpdateChar(); - } - else - { - _isMatch[complexState].Encode(_rangeEncoder, 1); - if (pos < Base.kNumRepDistances) - { - _isRep[_state.Index].Encode(_rangeEncoder, 1); - if (pos == 0) - { - _isRepG0[_state.Index].Encode(_rangeEncoder, 0); - if (len == 1) - _isRep0Long[complexState].Encode(_rangeEncoder, 0); - else - _isRep0Long[complexState].Encode(_rangeEncoder, 1); - } - else - { - _isRepG0[_state.Index].Encode(_rangeEncoder, 1); - if (pos == 1) - _isRepG1[_state.Index].Encode(_rangeEncoder, 0); - else - { - _isRepG1[_state.Index].Encode(_rangeEncoder, 1); - _isRepG2[_state.Index].Encode(_rangeEncoder, pos - 2); - } - } - if (len == 1) - _state.UpdateShortRep(); - else - { - _repMatchLenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState); - _state.UpdateRep(); - } - UInt32 distance = _repDistances[pos]; - if (pos != 0) - { - for (UInt32 i = pos; i >= 1; i--) - _repDistances[i] = _repDistances[i - 1]; - _repDistances[0] = distance; - } - } - else - { - _isRep[_state.Index].Encode(_rangeEncoder, 0); - _state.UpdateMatch(); - _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState); - pos -= Base.kNumRepDistances; - UInt32 posSlot = GetPosSlot(pos); - UInt32 lenToPosState = Base.GetLenToPosState(len); - _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot); - - if (posSlot >= Base.kStartPosModelIndex) - { - int footerBits = (int)((posSlot >> 1) - 1); - UInt32 baseVal = ((2 | (posSlot & 1)) << footerBits); - UInt32 posReduced = pos - baseVal; - - if (posSlot < Base.kEndPosModelIndex) - RangeCoder.BitTreeEncoder.ReverseEncode(_posEncoders, - baseVal - posSlot - 1, _rangeEncoder, footerBits, posReduced); - else - { - _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits); - _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask); - _alignPriceCount++; - } - } - UInt32 distance = pos; - for (UInt32 i = Base.kNumRepDistances - 1; i >= 1; i--) - _repDistances[i] = _repDistances[i - 1]; - _repDistances[0] = distance; - _matchPriceCount++; - } - _previousByte = _matchFinder.GetIndexByte((Int32)(len - 1 - _additionalOffset)); - } - _additionalOffset -= len; - nowPos64 += len; - if (_additionalOffset == 0) - { - // if (!_fastMode) - if (_matchPriceCount >= (1 << 7)) - FillDistancesPrices(); - if (_alignPriceCount >= Base.kAlignTableSize) - FillAlignPrices(); - inSize = nowPos64; - outSize = _rangeEncoder.GetProcessedSizeAdd(); - if (_matchFinder.GetNumAvailableBytes() == 0) - { - Flush((UInt32)nowPos64); - return; - } - - if (nowPos64 - progressPosValuePrev >= (1 << 12)) - { - _finished = false; - finished = false; - return; - } - } - } - } - - void ReleaseMFStream() - { - if (_matchFinder != null && _needReleaseMFStream) - { - _matchFinder.ReleaseStream(); - _needReleaseMFStream = false; - } - } - - void SetOutStream(System.IO.Stream outStream) { _rangeEncoder.SetStream(outStream); } - void ReleaseOutStream() { _rangeEncoder.ReleaseStream(); } - - void ReleaseStreams() - { - ReleaseMFStream(); - ReleaseOutStream(); - } - - void SetStreams(System.IO.Stream inStream, System.IO.Stream outStream, - Int64 inSize, Int64 outSize) - { - _inStream = inStream; - _finished = false; - Create(); - SetOutStream(outStream); - Init(); - - // if (!_fastMode) - { - FillDistancesPrices(); - FillAlignPrices(); - } - - _lenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen); - _lenEncoder.UpdateTables((UInt32)1 << _posStateBits); - _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen); - _repMatchLenEncoder.UpdateTables((UInt32)1 << _posStateBits); - - nowPos64 = 0; - } - - - public void Code(System.IO.Stream inStream, System.IO.Stream outStream, - Int64 inSize, Int64 outSize, ICodeProgress progress) - { - _needReleaseMFStream = false; - try - { - SetStreams(inStream, outStream, inSize, outSize); - while (true) - { - Int64 processedInSize; - Int64 processedOutSize; - bool finished; - CodeOneBlock(out processedInSize, out processedOutSize, out finished); - if (finished) - return; - if (progress != null) - { - progress.SetProgress(processedInSize, processedOutSize); - } - } - } - finally - { - ReleaseStreams(); - } - } - - const int kPropSize = 5; - Byte[] properties = new Byte[kPropSize]; - - public void WriteCoderProperties(System.IO.Stream outStream) - { - properties[0] = (Byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits); - for (int i = 0; i < 4; i++) - properties[1 + i] = (Byte)(_dictionarySize >> (8 * i)); - outStream.Write(properties, 0, kPropSize); - } - - UInt32[] tempPrices = new UInt32[Base.kNumFullDistances]; - UInt32 _matchPriceCount; - - void FillDistancesPrices() - { - for (UInt32 i = Base.kStartPosModelIndex; i < Base.kNumFullDistances; i++) - { - UInt32 posSlot = GetPosSlot(i); - int footerBits = (int)((posSlot >> 1) - 1); - UInt32 baseVal = ((2 | (posSlot & 1)) << footerBits); - tempPrices[i] = BitTreeEncoder.ReverseGetPrice(_posEncoders, - baseVal - posSlot - 1, footerBits, i - baseVal); - } - - for (UInt32 lenToPosState = 0; lenToPosState < Base.kNumLenToPosStates; lenToPosState++) - { - UInt32 posSlot; - RangeCoder.BitTreeEncoder encoder = _posSlotEncoder[lenToPosState]; - - UInt32 st = (lenToPosState << Base.kNumPosSlotBits); - for (posSlot = 0; posSlot < _distTableSize; posSlot++) - _posSlotPrices[st + posSlot] = encoder.GetPrice(posSlot); - for (posSlot = Base.kEndPosModelIndex; posSlot < _distTableSize; posSlot++) - _posSlotPrices[st + posSlot] += ((((posSlot >> 1) - 1) - Base.kNumAlignBits) << RangeCoder.BitEncoder.kNumBitPriceShiftBits); - - UInt32 st2 = lenToPosState * Base.kNumFullDistances; - UInt32 i; - for (i = 0; i < Base.kStartPosModelIndex; i++) - _distancesPrices[st2 + i] = _posSlotPrices[st + i]; - for (; i < Base.kNumFullDistances; i++) - _distancesPrices[st2 + i] = _posSlotPrices[st + GetPosSlot(i)] + tempPrices[i]; - } - _matchPriceCount = 0; - } - - void FillAlignPrices() - { - for (UInt32 i = 0; i < Base.kAlignTableSize; i++) - _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i); - _alignPriceCount = 0; - } - - - static string[] kMatchFinderIDs = - { - "BT2", - "BT4", - }; - - static int FindMatchFinder(string s) - { - for (int m = 0; m < kMatchFinderIDs.Length; m++) - if (s == kMatchFinderIDs[m]) - return m; - return -1; - } - - public void SetCoderProperties(CoderPropID[] propIDs, object[] properties) - { - for (UInt32 i = 0; i < properties.Length; i++) - { - object prop = properties[i]; - switch (propIDs[i]) - { - case CoderPropID.NumFastBytes: - { - if (!(prop is Int32)) - throw new InvalidParamException(); - Int32 numFastBytes = (Int32)prop; - if (numFastBytes < 5 || numFastBytes > Base.kMatchMaxLen) - throw new InvalidParamException(); - _numFastBytes = (UInt32)numFastBytes; - break; - } - case CoderPropID.Algorithm: - { - /* - if (!(prop is Int32)) - throw new InvalidParamException(); - Int32 maximize = (Int32)prop; - _fastMode = (maximize == 0); - _maxMode = (maximize >= 2); - */ - break; - } - case CoderPropID.MatchFinder: - { - if (!(prop is String)) - throw new InvalidParamException(); - EMatchFinderType matchFinderIndexPrev = _matchFinderType; - int m = FindMatchFinder(((string)prop).ToUpper()); - if (m < 0) - throw new InvalidParamException(); - _matchFinderType = (EMatchFinderType)m; - if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType) - { - _dictionarySizePrev = 0xFFFFFFFF; - _matchFinder = null; - } - break; - } - case CoderPropID.DictionarySize: - { - const int kDicLogSizeMaxCompress = 30; - if (!(prop is Int32)) - throw new InvalidParamException(); ; - Int32 dictionarySize = (Int32)prop; - if (dictionarySize < (UInt32)(1 << Base.kDicLogSizeMin) || - dictionarySize > (UInt32)(1 << kDicLogSizeMaxCompress)) - throw new InvalidParamException(); - _dictionarySize = (UInt32)dictionarySize; - int dicLogSize; - for (dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++) - if (dictionarySize <= ((UInt32)(1) << dicLogSize)) - break; - _distTableSize = (UInt32)dicLogSize * 2; - break; - } - case CoderPropID.PosStateBits: - { - if (!(prop is Int32)) - throw new InvalidParamException(); - Int32 v = (Int32)prop; - if (v < 0 || v > (UInt32)Base.kNumPosStatesBitsEncodingMax) - throw new InvalidParamException(); - _posStateBits = (int)v; - _posStateMask = (((UInt32)1) << (int)_posStateBits) - 1; - break; - } - case CoderPropID.LitPosBits: - { - if (!(prop is Int32)) - throw new InvalidParamException(); - Int32 v = (Int32)prop; - if (v < 0 || v > (UInt32)Base.kNumLitPosStatesBitsEncodingMax) - throw new InvalidParamException(); - _numLiteralPosStateBits = (int)v; - break; - } - case CoderPropID.LitContextBits: - { - if (!(prop is Int32)) - throw new InvalidParamException(); - Int32 v = (Int32)prop; - if (v < 0 || v > (UInt32)Base.kNumLitContextBitsMax) - throw new InvalidParamException(); ; - _numLiteralContextBits = (int)v; - break; - } - case CoderPropID.EndMarker: - { - if (!(prop is Boolean)) - throw new InvalidParamException(); - SetWriteEndMarkerMode((Boolean)prop); - break; - } - default: - throw new InvalidParamException(); - } - } - } - - uint _trainSize = 0; - public void SetTrainSize(uint trainSize) - { - _trainSize = trainSize; - } - - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/Compress/RangeCoder/RangeCoder.cs b/Software/Visual_Studio/Tango.Transport/Compression/Compress/RangeCoder/RangeCoder.cs deleted file mode 100644 index 0ce6d5a56..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/Compress/RangeCoder/RangeCoder.cs +++ /dev/null @@ -1,234 +0,0 @@ -using System; - -namespace Tango.Transport.Compression.RangeCoder -{ - class Encoder - { - public const uint kTopValue = (1 << 24); - - System.IO.Stream Stream; - - public UInt64 Low; - public uint Range; - uint _cacheSize; - byte _cache; - - long StartPosition; - - public void SetStream(System.IO.Stream stream) - { - Stream = stream; - } - - public void ReleaseStream() - { - Stream = null; - } - - public void Init() - { - StartPosition = Stream.Position; - - Low = 0; - Range = 0xFFFFFFFF; - _cacheSize = 1; - _cache = 0; - } - - public void FlushData() - { - for (int i = 0; i < 5; i++) - ShiftLow(); - } - - public void FlushStream() - { - Stream.Flush(); - } - - public void CloseStream() - { - Stream.Close(); - } - - public void Encode(uint start, uint size, uint total) - { - Low += start * (Range /= total); - Range *= size; - while (Range < kTopValue) - { - Range <<= 8; - ShiftLow(); - } - } - - public void ShiftLow() - { - if ((uint)Low < (uint)0xFF000000 || (uint)(Low >> 32) == 1) - { - byte temp = _cache; - do - { - Stream.WriteByte((byte)(temp + (Low >> 32))); - temp = 0xFF; - } - while (--_cacheSize != 0); - _cache = (byte)(((uint)Low) >> 24); - } - _cacheSize++; - Low = ((uint)Low) << 8; - } - - public void EncodeDirectBits(uint v, int numTotalBits) - { - for (int i = numTotalBits - 1; i >= 0; i--) - { - Range >>= 1; - if (((v >> i) & 1) == 1) - Low += Range; - if (Range < kTopValue) - { - Range <<= 8; - ShiftLow(); - } - } - } - - public void EncodeBit(uint size0, int numTotalBits, uint symbol) - { - uint newBound = (Range >> numTotalBits) * size0; - if (symbol == 0) - Range = newBound; - else - { - Low += newBound; - Range -= newBound; - } - while (Range < kTopValue) - { - Range <<= 8; - ShiftLow(); - } - } - - public long GetProcessedSizeAdd() - { - return _cacheSize + - Stream.Position - StartPosition + 4; - // (long)Stream.GetProcessedSize(); - } - } - - class Decoder - { - public const uint kTopValue = (1 << 24); - public uint Range; - public uint Code; - // public Buffer.InBuffer Stream = new Buffer.InBuffer(1 << 16); - public System.IO.Stream Stream; - - public void Init(System.IO.Stream stream) - { - // Stream.Init(stream); - Stream = stream; - - Code = 0; - Range = 0xFFFFFFFF; - for (int i = 0; i < 5; i++) - Code = (Code << 8) | (byte)Stream.ReadByte(); - } - - public void ReleaseStream() - { - // Stream.ReleaseStream(); - Stream = null; - } - - public void CloseStream() - { - Stream.Close(); - } - - public void Normalize() - { - while (Range < kTopValue) - { - Code = (Code << 8) | (byte)Stream.ReadByte(); - Range <<= 8; - } - } - - public void Normalize2() - { - if (Range < kTopValue) - { - Code = (Code << 8) | (byte)Stream.ReadByte(); - Range <<= 8; - } - } - - public uint GetThreshold(uint total) - { - return Code / (Range /= total); - } - - public void Decode(uint start, uint size, uint total) - { - Code -= start * Range; - Range *= size; - Normalize(); - } - - public uint DecodeDirectBits(int numTotalBits) - { - uint range = Range; - uint code = Code; - uint result = 0; - for (int i = numTotalBits; i > 0; i--) - { - range >>= 1; - /* - result <<= 1; - if (code >= range) - { - code -= range; - result |= 1; - } - */ - uint t = (code - range) >> 31; - code -= range & (t - 1); - result = (result << 1) | (1 - t); - - if (range < kTopValue) - { - code = (code << 8) | (byte)Stream.ReadByte(); - range <<= 8; - } - } - Range = range; - Code = code; - return result; - } - - public uint DecodeBit(uint size0, int numTotalBits) - { - uint newBound = (Range >> numTotalBits) * size0; - uint symbol; - if (Code < newBound) - { - symbol = 0; - Range = newBound; - } - else - { - symbol = 1; - Code -= newBound; - Range -= newBound; - } - Normalize(); - return symbol; - } - - // ulong GetProcessedSize() {return Stream.GetProcessedSize(); } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/Compress/RangeCoder/RangeCoderBit.cs b/Software/Visual_Studio/Tango.Transport/Compression/Compress/RangeCoder/RangeCoderBit.cs deleted file mode 100644 index 72b22da7a..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/Compress/RangeCoder/RangeCoderBit.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; - -namespace Tango.Transport.Compression.RangeCoder -{ - struct BitEncoder - { - public const int kNumBitModelTotalBits = 11; - public const uint kBitModelTotal = (1 << kNumBitModelTotalBits); - const int kNumMoveBits = 5; - const int kNumMoveReducingBits = 2; - public const int kNumBitPriceShiftBits = 6; - - uint Prob; - - public void Init() { Prob = kBitModelTotal >> 1; } - - public void UpdateModel(uint symbol) - { - if (symbol == 0) - Prob += (kBitModelTotal - Prob) >> kNumMoveBits; - else - Prob -= (Prob) >> kNumMoveBits; - } - - public void Encode(Encoder encoder, uint symbol) - { - // encoder.EncodeBit(Prob, kNumBitModelTotalBits, symbol); - // UpdateModel(symbol); - uint newBound = (encoder.Range >> kNumBitModelTotalBits) * Prob; - if (symbol == 0) - { - encoder.Range = newBound; - Prob += (kBitModelTotal - Prob) >> kNumMoveBits; - } - else - { - encoder.Low += newBound; - encoder.Range -= newBound; - Prob -= (Prob) >> kNumMoveBits; - } - if (encoder.Range < Encoder.kTopValue) - { - encoder.Range <<= 8; - encoder.ShiftLow(); - } - } - - private static UInt32[] ProbPrices = new UInt32[kBitModelTotal >> kNumMoveReducingBits]; - - static BitEncoder() - { - const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits); - for (int i = kNumBits - 1; i >= 0; i--) - { - UInt32 start = (UInt32)1 << (kNumBits - i - 1); - UInt32 end = (UInt32)1 << (kNumBits - i); - for (UInt32 j = start; j < end; j++) - ProbPrices[j] = ((UInt32)i << kNumBitPriceShiftBits) + - (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1)); - } - } - - public uint GetPrice(uint symbol) - { - return ProbPrices[(((Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits]; - } - public uint GetPrice0() { return ProbPrices[Prob >> kNumMoveReducingBits]; } - public uint GetPrice1() { return ProbPrices[(kBitModelTotal - Prob) >> kNumMoveReducingBits]; } - } - - struct BitDecoder - { - public const int kNumBitModelTotalBits = 11; - public const uint kBitModelTotal = (1 << kNumBitModelTotalBits); - const int kNumMoveBits = 5; - - uint Prob; - - public void UpdateModel(int numMoveBits, uint symbol) - { - if (symbol == 0) - Prob += (kBitModelTotal - Prob) >> numMoveBits; - else - Prob -= (Prob) >> numMoveBits; - } - - public void Init() { Prob = kBitModelTotal >> 1; } - - public uint Decode(RangeCoder.Decoder rangeDecoder) - { - uint newBound = (uint)(rangeDecoder.Range >> kNumBitModelTotalBits) * (uint)Prob; - if (rangeDecoder.Code < newBound) - { - rangeDecoder.Range = newBound; - Prob += (kBitModelTotal - Prob) >> kNumMoveBits; - if (rangeDecoder.Range < Decoder.kTopValue) - { - rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte(); - rangeDecoder.Range <<= 8; - } - return 0; - } - else - { - rangeDecoder.Range -= newBound; - rangeDecoder.Code -= newBound; - Prob -= (Prob) >> kNumMoveBits; - if (rangeDecoder.Range < Decoder.kTopValue) - { - rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte(); - rangeDecoder.Range <<= 8; - } - return 1; - } - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/Compress/RangeCoder/RangeCoderBitTree.cs b/Software/Visual_Studio/Tango.Transport/Compression/Compress/RangeCoder/RangeCoderBitTree.cs deleted file mode 100644 index de2376d02..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/Compress/RangeCoder/RangeCoderBitTree.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System; - -namespace Tango.Transport.Compression.RangeCoder -{ - struct BitTreeEncoder - { - BitEncoder[] Models; - int NumBitLevels; - - public BitTreeEncoder(int numBitLevels) - { - NumBitLevels = numBitLevels; - Models = new BitEncoder[1 << numBitLevels]; - } - - public void Init() - { - for (uint i = 1; i < (1 << NumBitLevels); i++) - Models[i].Init(); - } - - public void Encode(Encoder rangeEncoder, UInt32 symbol) - { - UInt32 m = 1; - for (int bitIndex = NumBitLevels; bitIndex > 0; ) - { - bitIndex--; - UInt32 bit = (symbol >> bitIndex) & 1; - Models[m].Encode(rangeEncoder, bit); - m = (m << 1) | bit; - } - } - - public void ReverseEncode(Encoder rangeEncoder, UInt32 symbol) - { - UInt32 m = 1; - for (UInt32 i = 0; i < NumBitLevels; i++) - { - UInt32 bit = symbol & 1; - Models[m].Encode(rangeEncoder, bit); - m = (m << 1) | bit; - symbol >>= 1; - } - } - - public UInt32 GetPrice(UInt32 symbol) - { - UInt32 price = 0; - UInt32 m = 1; - for (int bitIndex = NumBitLevels; bitIndex > 0; ) - { - bitIndex--; - UInt32 bit = (symbol >> bitIndex) & 1; - price += Models[m].GetPrice(bit); - m = (m << 1) + bit; - } - return price; - } - - public UInt32 ReverseGetPrice(UInt32 symbol) - { - UInt32 price = 0; - UInt32 m = 1; - for (int i = NumBitLevels; i > 0; i--) - { - UInt32 bit = symbol & 1; - symbol >>= 1; - price += Models[m].GetPrice(bit); - m = (m << 1) | bit; - } - return price; - } - - public static UInt32 ReverseGetPrice(BitEncoder[] Models, UInt32 startIndex, - int NumBitLevels, UInt32 symbol) - { - UInt32 price = 0; - UInt32 m = 1; - for (int i = NumBitLevels; i > 0; i--) - { - UInt32 bit = symbol & 1; - symbol >>= 1; - price += Models[startIndex + m].GetPrice(bit); - m = (m << 1) | bit; - } - return price; - } - - public static void ReverseEncode(BitEncoder[] Models, UInt32 startIndex, - Encoder rangeEncoder, int NumBitLevels, UInt32 symbol) - { - UInt32 m = 1; - for (int i = 0; i < NumBitLevels; i++) - { - UInt32 bit = symbol & 1; - Models[startIndex + m].Encode(rangeEncoder, bit); - m = (m << 1) | bit; - symbol >>= 1; - } - } - } - - struct BitTreeDecoder - { - BitDecoder[] Models; - int NumBitLevels; - - public BitTreeDecoder(int numBitLevels) - { - NumBitLevels = numBitLevels; - Models = new BitDecoder[1 << numBitLevels]; - } - - public void Init() - { - for (uint i = 1; i < (1 << NumBitLevels); i++) - Models[i].Init(); - } - - public uint Decode(RangeCoder.Decoder rangeDecoder) - { - uint m = 1; - for (int bitIndex = NumBitLevels; bitIndex > 0; bitIndex--) - m = (m << 1) + Models[m].Decode(rangeDecoder); - return m - ((uint)1 << NumBitLevels); - } - - public uint ReverseDecode(RangeCoder.Decoder rangeDecoder) - { - uint m = 1; - uint symbol = 0; - for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) - { - uint bit = Models[m].Decode(rangeDecoder); - m <<= 1; - m += bit; - symbol |= (bit << bitIndex); - } - return symbol; - } - - public static uint ReverseDecode(BitDecoder[] Models, UInt32 startIndex, - RangeCoder.Decoder rangeDecoder, int NumBitLevels) - { - uint m = 1; - uint symbol = 0; - for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) - { - uint bit = Models[startIndex + m].Decode(rangeDecoder); - m <<= 1; - m += bit; - symbol |= (bit << bitIndex); - } - return symbol; - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/GZipHelper.cs b/Software/Visual_Studio/Tango.Transport/Compression/GZipHelper.cs deleted file mode 100644 index 5ec17a35f..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/GZipHelper.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.IO.Compression; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Tango.Transport.Compression -{ - public static class GZipHelper - { - public static byte[] Compress(byte[] buffer) - { - using (MemoryStream ms = new MemoryStream()) - { - using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true)) - { - zip.Write(buffer, 0, buffer.Length); - } - - return ms.ToArray(); - } - } - - public static byte[] Decompress(byte[] gzBuffer) - { - using (MemoryStream msOut = new MemoryStream()) - { - using (MemoryStream ms = new MemoryStream(gzBuffer)) - { - using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress)) - { - zip.CopyTo(msOut); - } - } - - return msOut.ToArray(); - } - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/ICoder.cs b/Software/Visual_Studio/Tango.Transport/Compression/ICoder.cs deleted file mode 100644 index de7804504..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/ICoder.cs +++ /dev/null @@ -1,145 +0,0 @@ -// ICoder.h - -using System; - -namespace Tango.Transport.Compression -{ - /// <summary> - /// The exception that is thrown when an error in input stream occurs during decoding. - /// </summary> - class DataErrorException : ApplicationException - { - public DataErrorException(): base("Data Error") { } - } - - /// <summary> - /// The exception that is thrown when the value of an argument is outside the allowable range. - /// </summary> - class InvalidParamException : ApplicationException - { - public InvalidParamException(): base("Invalid Parameter") { } - } - - public interface ICodeProgress - { - /// <summary> - /// Callback progress. - /// </summary> - /// <param name="inSize"> - /// input size. -1 if unknown. - /// </param> - /// <param name="outSize"> - /// output size. -1 if unknown. - /// </param> - void SetProgress(Int64 inSize, Int64 outSize); - }; - - public interface ICoder - { - /// <summary> - /// Codes streams. - /// </summary> - /// <param name="inStream"> - /// input Stream. - /// </param> - /// <param name="outStream"> - /// output Stream. - /// </param> - /// <param name="inSize"> - /// input Size. -1 if unknown. - /// </param> - /// <param name="outSize"> - /// output Size. -1 if unknown. - /// </param> - /// <param name="progress"> - /// callback progress reference. - /// </param> - /// <exception cref="SevenZip.DataErrorException"> - /// if input stream is not valid - /// </exception> - void Code(System.IO.Stream inStream, System.IO.Stream outStream, - Int64 inSize, Int64 outSize, ICodeProgress progress); - }; - - /* - public interface ICoder2 - { - void Code(ISequentialInStream []inStreams, - const UInt64 []inSizes, - ISequentialOutStream []outStreams, - UInt64 []outSizes, - ICodeProgress progress); - }; - */ - - /// <summary> - /// Provides the fields that represent properties idenitifiers for compressing. - /// </summary> - public enum CoderPropID - { - /// <summary> - /// Specifies size of dictionary. - /// </summary> - DictionarySize = 0x400, - /// <summary> - /// Specifies size of memory for PPM*. - /// </summary> - UsedMemorySize, - /// <summary> - /// Specifies order for PPM methods. - /// </summary> - Order, - /// <summary> - /// Specifies number of postion state bits for LZMA (0 <= x <= 4). - /// </summary> - PosStateBits = 0x440, - /// <summary> - /// Specifies number of literal context bits for LZMA (0 <= x <= 8). - /// </summary> - LitContextBits, - /// <summary> - /// Specifies number of literal position bits for LZMA (0 <= x <= 4). - /// </summary> - LitPosBits, - /// <summary> - /// Specifies number of fast bytes for LZ*. - /// </summary> - NumFastBytes = 0x450, - /// <summary> - /// Specifies match finder. LZMA: "BT2", "BT4" or "BT4B". - /// </summary> - MatchFinder, - /// <summary> - /// Specifies number of passes. - /// </summary> - NumPasses = 0x460, - /// <summary> - /// Specifies number of algorithm. - /// </summary> - Algorithm = 0x470, - /// <summary> - /// Specifies multithread mode. - /// </summary> - MultiThread = 0x480, - /// <summary> - /// Specifies mode with end marker. - /// </summary> - EndMarker = 0x490 - }; - - - public interface ISetCoderProperties - { - void SetCoderProperties(CoderPropID[] propIDs, object[] properties); - }; - - public interface IWriteCoderProperties - { - void WriteCoderProperties(System.IO.Stream outStream); - } - - public interface ISetDecoderProperties - { - void SetDecoderProperties(byte[] properties); - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Compression/SevenZipHelper.cs b/Software/Visual_Studio/Tango.Transport/Compression/SevenZipHelper.cs deleted file mode 100644 index e23648aa9..000000000 --- a/Software/Visual_Studio/Tango.Transport/Compression/SevenZipHelper.cs +++ /dev/null @@ -1,105 +0,0 @@ -// 7Zip helper code by Peter Bromberg -// http://www.eggheadcafe.com/tutorials/aspnet/064b41e4-60bc-4d35-9136-368603bcc27a/7zip-lzma-inmemory-com.aspx - -using System; -using System.IO; - - -namespace Tango.Transport.Compression -{ - public static class SevenZipHelper - { - - static int dictionary = 1 << 23; - - // static Int32 posStateBits = 2; - // static Int32 litContextBits = 3; // for normal files - // UInt32 litContextBits = 0; // for 32-bit data - // static Int32 litPosBits = 0; - // UInt32 litPosBits = 2; // for 32-bit data - // static Int32 algorithm = 2; - // static Int32 numFastBytes = 128; - - static bool eos = false; - - - - - - static CoderPropID[] propIDs = - { - CoderPropID.DictionarySize, - CoderPropID.PosStateBits, - CoderPropID.LitContextBits, - CoderPropID.LitPosBits, - CoderPropID.Algorithm, - CoderPropID.NumFastBytes, - CoderPropID.MatchFinder, - CoderPropID.EndMarker - }; - - // these are the default properties, keeping it simple for now: - static object[] properties = - { - (Int32)(dictionary), - (Int32)(2), - (Int32)(3), - (Int32)(0), - (Int32)(2), - (Int32)(128), - "bt4", - eos - }; - - - public static byte[] Compress(byte[] inputBytes) - { - - MemoryStream inStream = new MemoryStream(inputBytes); - MemoryStream outStream = new MemoryStream(); - LZMA.Encoder encoder = new LZMA.Encoder(); - encoder.SetCoderProperties(propIDs, properties); - encoder.WriteCoderProperties(outStream); - long fileSize = inStream.Length; - for (int i = 0; i < 8; i++) - outStream.WriteByte((Byte)(fileSize >> (8 * i))); - encoder.Code(inStream, outStream, -1, -1, null); - return outStream.ToArray(); - } - - public static byte[] Decompress(byte[] inputBytes) - { - MemoryStream newInStream = new MemoryStream(inputBytes); - - LZMA.Decoder decoder = new LZMA.Decoder(); - - newInStream.Seek(0, 0); - MemoryStream newOutStream = new MemoryStream(); - - byte[] properties2 = new byte[5]; - if (newInStream.Read(properties2, 0, 5) != 5) - throw (new Exception("input .lzma is too short")); - long outSize = 0; - for (int i = 0; i < 8; i++) - { - int v = newInStream.ReadByte(); - if (v < 0) - throw (new Exception("Can't Read 1")); - outSize |= ((long)(byte)v) << (8 * i); - } - decoder.SetDecoderProperties(properties2); - - long compressedSize = newInStream.Length - newInStream.Position; - decoder.Code(newInStream, newOutStream, compressedSize, outSize, null); - - byte[] b = newOutStream.ToArray(); - - return b; - - - - } - - - } -} diff --git a/Software/Visual_Studio/Tango.Transport/ContinuousResponseAbortedException.cs b/Software/Visual_Studio/Tango.Transport/ContinuousResponseAbortedException.cs index 94bb39af0..2a34ba248 100644 --- a/Software/Visual_Studio/Tango.Transport/ContinuousResponseAbortedException.cs +++ b/Software/Visual_Studio/Tango.Transport/ContinuousResponseAbortedException.cs @@ -3,22 +3,19 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using Tango.PMR.Common; namespace Tango.Transport { public class ContinuousResponseAbortedException : Exception { - public MessageContainer Container { get; set; } - - public ContinuousResponseAbortedException(String message) : base(message) + public ContinuousResponseAbortedException() { } - public ContinuousResponseAbortedException(MessageContainer container, String message) : this(message) + public ContinuousResponseAbortedException(String message) : base(message) { - Container = container; + } } } diff --git a/Software/Visual_Studio/Tango.Transport/Discovery/UsbCommunicationScanner.cs b/Software/Visual_Studio/Tango.Transport/Discovery/UsbCommunicationScanner.cs index 7606de4fc..10628da27 100644 --- a/Software/Visual_Studio/Tango.Transport/Discovery/UsbCommunicationScanner.cs +++ b/Software/Visual_Studio/Tango.Transport/Discovery/UsbCommunicationScanner.cs @@ -144,7 +144,7 @@ namespace Tango.Transport.Discovery logManager.Log("Connecting transporter..."); await transporter.Connect(); logManager.Log("Sending scanning request..."); - var response = await transporter.SendRequest(request, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(2) }); + var response = await transporter.SendRequest(request, TimeSpan.FromSeconds(2)); if (response is TResponse) { diff --git a/Software/Visual_Studio/Tango.Transport/GenericMessageSerializer.cs b/Software/Visual_Studio/Tango.Transport/GenericMessageSerializer.cs deleted file mode 100644 index 6368a7754..000000000 --- a/Software/Visual_Studio/Tango.Transport/GenericMessageSerializer.cs +++ /dev/null @@ -1,193 +0,0 @@ -using Google.Protobuf; -using Newtonsoft.Json; -using Newtonsoft.Json.Bson; -using Newtonsoft.Json.Serialization; -using ProtoBuf; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Tango.Core.Bson; -using Tango.PMR; -using Tango.PMR.Common; -using Tango.PMR.Integration; - -namespace Tango.Transport -{ - public static class GenericMessageSerializer - { - private static JsonSerializer _serializer; - - static GenericMessageSerializer() - { - _serializer = new BsonUtcSerializer(); - - ProtoBuf.Meta.RuntimeTypeModel.Default.AutoAddMissingTypes = true; - ProtoBuf.Meta.RuntimeTypeModel.Default.AutoAddProtoContractTypesOnly = false; - ProtoBuf.Meta.RuntimeTypeModel.Default.InferTagFromNameDefault = true; - ProtoBuf.Meta.RuntimeTypeModel.Default.UseImplicitZeroDefaults = true; - } - - public static object Deserialize(Type type, byte[] array, GenericMessageProtocol mode) - { - if (mode == GenericMessageProtocol.Json) - { - return JsonConvert.DeserializeObject(Encoding.UTF8.GetString(array), type); - } - else if (mode == GenericMessageProtocol.Bson) - { - return DeserializeFromBson(array, type); - } - else - { - AutoProtobuf.Build(type); - - using (MemoryStream ms = new MemoryStream(array)) - { - return Serializer.Deserialize(type, ms); - } - } - } - - public static object DeserializeFromByteString(Type type, ByteString byteString, GenericMessageProtocol mode) - { - if (mode == GenericMessageProtocol.Json) - { - return JsonConvert.DeserializeObject(byteString.ToStringUtf8(), type); - } - else if (mode == GenericMessageProtocol.Bson) - { - return DeserializeFromBson(byteString.ToByteArray(), type); - } - else - { - AutoProtobuf.Build(type); - return Deserialize(type, byteString.ToByteArray(), mode); - } - } - - //--------------------------------------------------------------------- - - public static byte[] Serialize<T>(T message, GenericMessageProtocol mode) - { - if (mode == GenericMessageProtocol.Json) - { - return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message)); - } - else if (mode == GenericMessageProtocol.Bson) - { - return SerializeToBson(message); - } - else - { - AutoProtobuf.Build<T>(); - - using (MemoryStream ms = new MemoryStream()) - { - Serializer.Serialize<T>(ms, message); - return ms.ToArray(); - } - } - } - - public static T Deserialize<T>(byte[] array, GenericMessageProtocol mode) - { - if (mode == GenericMessageProtocol.Json) - { - return (T)Deserialize(typeof(T), array, mode); - } - else if (mode == GenericMessageProtocol.Bson) - { - return DeserializeFromBson<T>(array); - } - else - { - AutoProtobuf.Build<T>(); - - using (MemoryStream ms = new MemoryStream(array)) - { - return Serializer.Deserialize<T>(ms); - } - } - } - - public static ByteString SerializeToByteString<T>(T message, GenericMessageProtocol mode) - { - if (mode == GenericMessageProtocol.Json) - { - var byteString = ByteString.CopyFromUtf8(JsonConvert.SerializeObject(message)); - return byteString; - } - else if (mode == GenericMessageProtocol.Bson) - { - var byteString = ByteString.CopyFrom(SerializeToBson(message)); - return byteString; - } - else - { - AutoProtobuf.Build<T>(); - - return ByteString.CopyFrom(Serialize<T>(message, mode)); - } - } - - public static T DeserializeFromByteString<T>(ByteString byteString, GenericMessageProtocol mode) - { - if (mode == GenericMessageProtocol.Json) - { - return JsonConvert.DeserializeObject<T>(byteString.ToStringUtf8()); - } - else if (mode == GenericMessageProtocol.Bson) - { - return DeserializeFromBson<T>(byteString.ToByteArray()); - } - else - { - AutoProtobuf.Build<T>(); - - return Deserialize<T>(byteString.ToByteArray(), mode); - } - } - - public static T ExtractGenericRequestFromContainer<T>(MessageContainer container, GenericMessageProtocol mode) where T : class - { - var message = MessageFactory.ExtractMessageFromContainer(container); - var genericType = Type.GetType((message as GenericRequest).Type); - var innerMessage = DeserializeFromByteString(genericType, (message as GenericRequest).Data, mode); - return innerMessage as T; - } - - private static byte[] SerializeToBson(Object obj) - { - MemoryStream ms = new MemoryStream(); - using (BsonWriter writer = new BsonWriter(ms)) - { - _serializer.Serialize(writer, obj); - return ms.ToArray(); - } - } - - private static Object DeserializeFromBson(byte[] data, Type type) - { - MemoryStream ms = new MemoryStream(data); - using (BsonReader reader = new BsonReader(ms)) - { - Object obj = _serializer.Deserialize(reader, type); - return obj; - } - } - - private static T DeserializeFromBson<T>(byte[] data) - { - MemoryStream ms = new MemoryStream(data); - using (BsonReader reader = new BsonReader(ms)) - { - T obj = _serializer.Deserialize<T>(reader); - return obj; - } - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/ITransportAdapter.cs b/Software/Visual_Studio/Tango.Transport/ITransportAdapter.cs index 3c5bed9d0..5e6b528c2 100644 --- a/Software/Visual_Studio/Tango.Transport/ITransportAdapter.cs +++ b/Software/Visual_Studio/Tango.Transport/ITransportAdapter.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.Linq; using System.Reactive; using System.Reactive.Linq; @@ -13,14 +12,9 @@ namespace Tango.Transport /// Represents a transport adapter capable of connecting, writing and receiving data from a stream. /// </summary> /// <seealso cref="Tango.Transport.ITransportComponent" /> - public interface ITransportAdapter : ITransportComponent, INotifyPropertyChanged + public interface ITransportAdapter : ITransportComponent { /// <summary> - /// Gets the last failed state exception/reason. - /// </summary> - Exception FailedStateException { get; } - - /// <summary> /// Gets the total bytes received. /// </summary> long TotalBytesReceived { get; } @@ -36,16 +30,10 @@ namespace Tango.Transport long TransferRate { get; } /// <summary> - /// Gets or sets a value indicating whether to enable compression/decompression of data. - /// </summary> - bool EnableCompression { get; set; } - - /// <summary> /// Writes the specified data to the stream. /// </summary> /// <param name="data">The data.</param> - /// <param name="immidiate">Writes the data as soon as possible while ignoring any message queuing and batching.</param> - void Write(byte[] data, bool immidiate = false); + void Write(byte[] data); /// <summary> /// Occurs when new data is available. diff --git a/Software/Visual_Studio/Tango.Transport/ITransportComponent.cs b/Software/Visual_Studio/Tango.Transport/ITransportComponent.cs index 7972f8551..5266e0217 100644 --- a/Software/Visual_Studio/Tango.Transport/ITransportComponent.cs +++ b/Software/Visual_Studio/Tango.Transport/ITransportComponent.cs @@ -12,11 +12,6 @@ namespace Tango.Transport public interface ITransportComponent : IDisposable { /// <summary> - /// Gets or sets the name of the transport component. - /// </summary> - String ComponentName { get; set; } - - /// <summary> /// Connects the transport component. /// </summary> /// <returns></returns> diff --git a/Software/Visual_Studio/Tango.Transport/ITransporter.cs b/Software/Visual_Studio/Tango.Transport/ITransporter.cs index 777b97e19..1f7039df7 100644 --- a/Software/Visual_Studio/Tango.Transport/ITransporter.cs +++ b/Software/Visual_Studio/Tango.Transport/ITransporter.cs @@ -10,12 +10,9 @@ using Tango.Transport.Adapters; using Tango.PMR; using Tango.PMR.Common; using System.Collections.ObjectModel; -using Tango.PMR.Integration; namespace Tango.Transport { - public delegate void RequestHandlerCallbackDelegate<Request>(ITransporter transporter, Request request, String token); - /// <summary> /// Represents a transportation engine which can send and receive <see cref="TangoMessage{T}"/> message using a <see cref="ITransportAdapter">Transport adapter</see>. /// </summary> @@ -38,122 +35,70 @@ namespace Tango.Transport Exception FailedStateException { get; } /// <summary> - /// Gets or sets the generic protocol used to serialize/deserialize generic messages. - /// </summary> - GenericMessageProtocol GenericProtocol { get; set; } - - /// <summary> - /// Registers a custom request handler. - /// </summary> - /// <typeparam name="Request">The type of the request.</typeparam> - /// <param name="callback">The callback.</param> - void RegisterRequestHandler<Request>(RequestHandlerCallbackDelegate<Request> callback) where Request : class; - - /// <summary> - /// Unregisters a custom request handler. - /// </summary> - /// <typeparam name="Request">The type of the request.</typeparam> - /// <param name="callback">The callback.</param> - void UnregisterRequestHandler<Request>(RequestHandlerCallbackDelegate<Request> callback) where Request : class; - - /// <summary> - /// Copies this instance request handlers to the specified instance. - /// </summary> - /// <param name="transporter">The transporter to copy the handlers to.</param> - void CopyRequestHandlers(ITransporter transporter); - - /// <summary> /// Sends a request. /// </summary> /// <param name="request">The request.</param> - /// <param name="config">Request configuration.</param> + /// <param name="timeout">Optional timeout. If not specified will use the <see cref="RequestTimeout"/>.</param> /// <returns></returns> - Task<IMessage> SendRequest(IMessage request, TransportRequestConfig config = null); + Task<IMessage> SendRequest(IMessage request, TimeSpan? timeout = null); /// <summary> /// Sends the request. /// </summary> - /// <param name="config">Request configuration.</param> + /// <param name="container">The container.</param> /// <returns></returns> - Task<MessageContainer> SendRequest(MessageContainer container, TransportRequestConfig config = null); + Task<MessageContainer> SendRequest(MessageContainer container); /// <summary> - /// Sends a request. + /// Sends a continuous request. /// </summary> - /// <typeparam name="Request">The type of the request.</typeparam> - /// <typeparam name="Response">The type of the response.</typeparam> - /// <param name="request">The request.</param> - /// <param name="config">Request configuration.</param> + /// <param name="container">The container.</param> /// <returns></returns> - Task<TangoMessage<Response>> SendRequest<Request, Response>(TangoMessage<Request> request, TransportRequestConfig config = null) where Request : IMessage<Request> where Response : IMessage<Response>; + IObservable<MessageContainer> SendContinuousRequest(MessageContainer container); /// <summary> - /// Sends a continuous request. + /// Sends the response. /// </summary> /// <param name="container">The container.</param> - /// <param name="config">Request configuration.</param> /// <returns></returns> - IObservable<MessageContainer> SendContinuousRequest(MessageContainer container, TransportContinuousRequestConfig config = null); + Task SendResponse(MessageContainer container); /// <summary> - /// Sends a request and expecting multiple response messages. + /// Sends the response. /// </summary> - /// <param name="config">Request configuration.</param> + /// <param name="response">The response.</param> + /// <param name="token">The token.</param> + /// <param name="completed">The completed.</param> + /// <param name="errorCode">The error code.</param> + /// <param name="errorMessage">The error message.</param> /// <returns></returns> - IObservable<IMessage> SendContinuousRequest(IMessage request, TransportContinuousRequestConfig config = null); + Task SendResponse(IMessage response, String token, bool? completed = null, ErrorCode? errorCode = null, String errorMessage = null); /// <summary> /// Sends a request and expecting multiple response messages. /// </summary> - /// <typeparam name="Request">The type of the request.</typeparam> - /// <typeparam name="Response">The type of the response.</typeparam> - /// <param name="config">Request configuration.</param> + /// <param name="request">The request.</param> /// <returns></returns> - IObservable<TangoMessage<Response>> SendContinuousRequest<Request, Response>(TangoMessage<Request> request, TransportContinuousRequestConfig config = null) where Request : IMessage<Request> where Response : IMessage<Response>; + IObservable<IMessage> SendContinuousRequest(IMessage request, TimeSpan? timeout = null); /// <summary> - /// Sends a generic request of any type. + /// Sends a request. /// </summary> /// <typeparam name="Request">The type of the request.</typeparam> /// <typeparam name="Response">The type of the response.</typeparam> /// <param name="request">The request.</param> - /// <param name="config">The configuration.</param> - /// <returns></returns> - Task<Response> SendGenericRequest<Request, Response>(Request request, TransportRequestConfig config = null) where Request : class where Response : class; - - /// <summary> - /// Sends a generic response. - /// </summary> - /// <typeparam name="Response">The type of the response.</typeparam> - /// <param name="response">The response.</param> - /// <param name="token">The request token.</param> - /// <param name="config">The response configuration.</param> + /// <param name="timeout">Optional timeout. If not specified will use the <see cref="RequestTimeout"/>.</param> /// <returns></returns> - Task SendGenericResponse<Response>(Response response, String token, TransportResponseConfig config = null) where Response : class; + Task<TangoMessage<Response>> SendRequest<Request, Response>(TangoMessage<Request> request, TimeSpan? timeout = null) where Request : IMessage<Request> where Response : IMessage<Response>; /// <summary> - /// Sends a generic request and expecting multiple generic response messages. + /// Sends a request and expecting multiple response messages. /// </summary> /// <typeparam name="Request">The type of the request.</typeparam> /// <typeparam name="Response">The type of the response.</typeparam> - /// <param name="config">Request configuration.</param> - /// <returns></returns> - IObservable<Response> SendGenericContinuousRequest<Request, Response>(Request request, TransportContinuousRequestConfig config = null) where Request : class where Response : class; - - /// <summary> - /// Sends the response. - /// </summary> - /// <param name="container">The container.</param> - /// <returns></returns> - Task SendResponse(MessageContainer container, TransportResponseConfig config = null); - - /// <summary> - /// Sends the response. - /// </summary> - /// <param name="response">Request token.</param> - /// <param name="config">Response configuration.</param> + /// <param name="request">The request.</param> /// <returns></returns> - Task SendResponse(IMessage response, String token, TransportResponseConfig config = null); + IObservable<TangoMessage<Response>> SendContinuousRequest<Request, Response>(TangoMessage<Request> request, TimeSpan? firstTimeout = null, TimeSpan? continousTimeout = null) where Request : IMessage<Request> where Response : IMessage<Response>; /// <summary> /// Sends a response. @@ -164,20 +109,22 @@ namespace Tango.Transport Task SendResponse<Response>(TangoMessage<Response> response) where Response : IMessage<Response>; /// <summary> - /// Sends a response. + /// Sends a response for the specified token. /// </summary> /// <typeparam name="Response">The type of the response.</typeparam> /// <param name="response">The response.</param> - /// <param name="token">Request token.</param> - /// <param name="config">Response configuration.</param> + /// <param name="token">The token.</param> + /// <param name="completed">The completed.</param> + /// <param name="errorCode">The error code.</param> + /// <param name="errorMessage">The error message.</param> /// <returns></returns> - Task SendResponse<Response>(TangoMessage<Response> response, String token, TransportResponseConfig config = null) where Response : IMessage<Response>; + Task SendResponse<Response>(TangoMessage<Response> response, String token, bool? completed = null, ErrorCode? errorCode = null, String errorMessage = null) where Response : IMessage<Response>; /// <summary> /// Sends a general error response agnostic to the type of request. /// </summary> /// <param name="exception">The exception.</param> - /// <param name="token">Request token.</param> + /// <param name="token">The token.</param> /// <returns></returns> Task SendErrorResponse(Exception exception, String token); @@ -189,7 +136,7 @@ namespace Tango.Transport /// <summary> /// Occurs when a new request message has been received. /// </summary> - event EventHandler<RequestReceivedEventArgs> RequestReceived; + event EventHandler<MessageContainer> RequestReceived; /// <summary> /// Occurs when a new response message has been received. @@ -197,21 +144,6 @@ namespace Tango.Transport event EventHandler<MessageContainer> PendingResponseReceived; /// <summary> - /// Occurs when a request has been sent. - /// </summary> - event EventHandler<IMessage> RequestSent; - - /// <summary> - /// Occurs when a request response has been received. - /// </summary> - event EventHandler<IMessage> ResponseReceived; - - /// <summary> - /// Occurs when a request has failed. - /// </summary> - event EventHandler<RequestFailedEventArgs> RequestFailed; - - /// <summary> /// Gets or sets the default request timeout. /// </summary> TimeSpan RequestTimeout { get; set; } diff --git a/Software/Visual_Studio/Tango.Transport/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.Transport/Properties/AssemblyInfo.cs index 7ea5cd212..e762707fe 100644 --- a/Software/Visual_Studio/Tango.Transport/Properties/AssemblyInfo.cs +++ b/Software/Visual_Studio/Tango.Transport/Properties/AssemblyInfo.cs @@ -3,5 +3,5 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; [assembly: AssemblyTitle("Tango - Transport Components")] -[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyVersion("2.0.31.1608")] [assembly: ComVisible(false)]
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango.Transport/RequestFailedEventArgs.cs b/Software/Visual_Studio/Tango.Transport/RequestFailedEventArgs.cs deleted file mode 100644 index dfbb24a6f..000000000 --- a/Software/Visual_Studio/Tango.Transport/RequestFailedEventArgs.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Google.Protobuf; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Tango.Transport -{ - public class RequestFailedEventArgs : EventArgs - { - public IMessage Message { get; set; } - - public Exception Exception { get; set; } - - public RequestFailedEventArgs(IMessage message, Exception exception) - { - Message = message; - Exception = exception; - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/RequestReceivedEventArgs.cs b/Software/Visual_Studio/Tango.Transport/RequestReceivedEventArgs.cs deleted file mode 100644 index b7a406fd6..000000000 --- a/Software/Visual_Studio/Tango.Transport/RequestReceivedEventArgs.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Tango.PMR.Common; - -namespace Tango.Transport -{ - public class RequestReceivedEventArgs - { - public MessageContainer Container { get; set; } - public bool Handled { get; set; } - - public RequestReceivedEventArgs() - { - - } - - public RequestReceivedEventArgs(MessageContainer container) : this() - { - Container = container; - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/ResponseErrorException.cs b/Software/Visual_Studio/Tango.Transport/ResponseErrorException.cs index d55b622cb..3bb5023ca 100644 --- a/Software/Visual_Studio/Tango.Transport/ResponseErrorException.cs +++ b/Software/Visual_Studio/Tango.Transport/ResponseErrorException.cs @@ -24,11 +24,7 @@ namespace Tango.Transport /// Initializes a new instance of the <see cref="ResponseErrorException{T}"/> class. /// </summary> /// <param name="error">The error.</param> - public ResponseErrorException(MessageContainer container, String requestName) : base( - container.Error != ErrorCode.GeneralError || String.IsNullOrEmpty(container.ErrorMessage) ? - $"{requestName} has returned with an error ({container.Error})\n{container.ErrorMessage}" - : - $"{requestName} failed.\n{container.ErrorMessage}") + public ResponseErrorException(MessageContainer container) : base(String.Format("{0} has returned with an error ({1}).{2}{3}", container.Type.ToString(), container.Error.ToString(), Environment.NewLine, container.ErrorMessage)) { Container = container; } diff --git a/Software/Visual_Studio/Tango.Transport/Routing/SimpleTransportRouter.cs b/Software/Visual_Studio/Tango.Transport/Routing/SimpleTransportRouter.cs index a05ad7b00..6be334d95 100644 --- a/Software/Visual_Studio/Tango.Transport/Routing/SimpleTransportRouter.cs +++ b/Software/Visual_Studio/Tango.Transport/Routing/SimpleTransportRouter.cs @@ -14,11 +14,6 @@ namespace Tango.Transport.Routing public class SimpleTransportRouter : ITransportRouter { /// <summary> - /// Gets or sets the name of the transport component. - /// </summary> - public String ComponentName { get; set; } - - /// <summary> /// Occurs when component state changes. /// </summary> public event EventHandler<TransportComponentState> StateChanged; @@ -45,7 +40,6 @@ namespace Tango.Transport.Routing { Channels = new ObservableCollection<TransportRoutingChannel>(); Channels.CollectionChanged += OnChannelsCollectionChanged; - ComponentName = "Router"; } /// <summary> diff --git a/Software/Visual_Studio/Tango.Transport/Routing/TransportRoutingChannel.cs b/Software/Visual_Studio/Tango.Transport/Routing/TransportRoutingChannel.cs index 01b957975..aeb83fd48 100644 --- a/Software/Visual_Studio/Tango.Transport/Routing/TransportRoutingChannel.cs +++ b/Software/Visual_Studio/Tango.Transport/Routing/TransportRoutingChannel.cs @@ -13,11 +13,6 @@ namespace Tango.Transport.Routing public class TransportRoutingChannel : ITransportComponent { /// <summary> - /// Gets or sets the name of the transport component. - /// </summary> - public String ComponentName { get; set; } - - /// <summary> /// Occurs when component state changes. /// </summary> public event EventHandler<TransportComponentState> StateChanged; @@ -50,8 +45,6 @@ namespace Tango.Transport.Routing /// <param name="adapter2">The second adapter.</param> public TransportRoutingChannel(ITransportAdapter adapter1, ITransportAdapter adapter2) { - ComponentName = "Routing Channel"; - Adapter1 = adapter1; Adapter2 = adapter2; diff --git a/Software/Visual_Studio/Tango.Transport/Servers/TcpServer.cs b/Software/Visual_Studio/Tango.Transport/Servers/TcpServer.cs index 54e9b6a32..29cc3c7e8 100644 --- a/Software/Visual_Studio/Tango.Transport/Servers/TcpServer.cs +++ b/Software/Visual_Studio/Tango.Transport/Servers/TcpServer.cs @@ -58,11 +58,9 @@ namespace Tango.Transport.Servers if (!IsStarted) { Listener = new TcpListener(System.Net.IPAddress.Any, Port); - Listener.ExclusiveAddressUse = false; - Listener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); Listener.Start(); IsStarted = true; - LogManager.Log($"TCP server started on port {Port}."); + LogManager.Log($"TCP started on port {Port}."); WaitForConnection(); } } @@ -75,7 +73,7 @@ namespace Tango.Transport.Servers { Listener.Stop(); IsStarted = false; - LogManager.Log($"TCP server stopped on port {Port}."); + LogManager.Log($"TCP stopped on port {Port}."); } } diff --git a/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj b/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj index bbe0b3780..87af709e0 100644 --- a/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj +++ b/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj @@ -34,20 +34,13 @@ <Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL"> <HintPath>..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath> </Reference> - <Reference Include="Microsoft.AspNet.SignalR.Client, Version=2.4.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> - <HintPath>..\packages\Microsoft.AspNet.SignalR.Client.2.4.1\lib\net45\Microsoft.AspNet.SignalR.Client.dll</HintPath> - </Reference> <Reference Include="Microsoft.WindowsAzure.Storage, Version=4.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" /> <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> </Reference> - <Reference Include="protobuf-net"> - <HintPath>..\Referenced Assemblies\Protobuf-net\protobuf-net.dll</HintPath> - </Reference> <Reference Include="System" /> <Reference Include="System.Core" /> <Reference Include="System.Management" /> - <Reference Include="System.Net.Http.WebRequest" /> <Reference Include="System.Reactive.Core, Version=3.0.3000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> <HintPath>..\packages\System.Reactive.Core.3.1.1\lib\net46\System.Reactive.Core.dll</HintPath> </Reference> @@ -80,31 +73,9 @@ <Link>GlobalVersionInfo.cs</Link> </Compile> <Compile Include="Adapters\MemoryTransportAdapter.cs" /> - <Compile Include="Adapters\MultiTransportAdapter.cs" /> - <Compile Include="Adapters\SignalRTransportAdapter.cs" /> - <Compile Include="Adapters\SignalRTransportAdapterMode.cs" /> - <Compile Include="Adapters\TcpTransportAdapterWriteMode.cs" /> <Compile Include="Adapters\UsbSerialBaudRates.cs" /> <Compile Include="Adapters\UsbTransportAdapter.cs" /> - <Compile Include="AutoProtobuf.cs" /> <Compile Include="Components\ComPortEnumerator.cs" /> - <Compile Include="Compression\Common\CommandLineParser.cs" /> - <Compile Include="Compression\Common\CRC.cs" /> - <Compile Include="Compression\Common\InBuffer.cs" /> - <Compile Include="Compression\Common\OutBuffer.cs" /> - <Compile Include="Compression\Compress\LZMA\LzmaBase.cs" /> - <Compile Include="Compression\Compress\LZMA\LzmaDecoder.cs" /> - <Compile Include="Compression\Compress\LZMA\LzmaEncoder.cs" /> - <Compile Include="Compression\Compress\LZ\IMatchFinder.cs" /> - <Compile Include="Compression\Compress\LZ\LzBinTree.cs" /> - <Compile Include="Compression\Compress\LZ\LzInWindow.cs" /> - <Compile Include="Compression\Compress\LZ\LzOutWindow.cs" /> - <Compile Include="Compression\Compress\RangeCoder\RangeCoder.cs" /> - <Compile Include="Compression\Compress\RangeCoder\RangeCoderBit.cs" /> - <Compile Include="Compression\Compress\RangeCoder\RangeCoderBitTree.cs" /> - <Compile Include="Compression\GZipHelper.cs" /> - <Compile Include="Compression\ICoder.cs" /> - <Compile Include="Compression\SevenZipHelper.cs" /> <Compile Include="ContinuousResponseAbortedException.cs" /> <Compile Include="Discovery\CommunicationScannerResult.cs" /> <Compile Include="Discovery\ICommunicationScanner.cs" /> @@ -126,38 +97,26 @@ <Compile Include="PendingResponse.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="ITransporter.cs" /> - <Compile Include="GenericMessageSerializer.cs" /> - <Compile Include="RequestFailedEventArgs.cs" /> - <Compile Include="RequestReceivedEventArgs.cs" /> <Compile Include="ResponseErrorException.cs" /> <Compile Include="Routing\SimpleTransportRouter.cs" /> <Compile Include="Servers\ClientConnectedEventArgs.cs" /> <Compile Include="Servers\TcpServer.cs" /> <Compile Include="TransportAdapterBase.cs" /> <Compile Include="TransportComponentState.cs" /> - <Compile Include="TransportContinuousRequestConfig.cs" /> <Compile Include="TransporterBase.cs" /> - <Compile Include="TransporterDisconnectedException.cs" /> <Compile Include="Transporters\BasicTransporter.cs" /> <Compile Include="TransportMessage.cs" /> <Compile Include="TransportMessageBase.cs" /> - <Compile Include="TransportRequestConfig.cs" /> <Compile Include="TransportMessageDirection.cs" /> <Compile Include="Routing\TransportRoutingChannel.cs" /> - <Compile Include="TransportResponseConfig.cs" /> - <Compile Include="TransportThreadingMode.cs" /> - <Compile Include="Web\AutoFileDownloader.cs" /> <Compile Include="Web\InvalidTokenException.cs" /> - <Compile Include="Web\IWebFileDownloader.cs" /> <Compile Include="Web\IWebTransportClient.cs" /> <Compile Include="Web\IWebRequestMessage.cs" /> <Compile Include="Web\IWebResponseMessage.cs" /> <Compile Include="Web\IWebTransportMessage.cs" /> - <Compile Include="Web\StandardFileDownloader.cs" /> - <Compile Include="Web\StorageBlobStream.cs" /> <Compile Include="Web\TokenExpiredException.cs" /> <Compile Include="Web\StorageBlobDownloader.cs" /> - <Compile Include="Web\WebFileDownloaderProgressEventArgs.cs" /> + <Compile Include="Web\StorageBlobProgressEventArgs.cs" /> <Compile Include="Web\StorageBlobUploader.cs" /> <Compile Include="Web\WebRequestMessage.cs" /> <Compile Include="Web\WebResponseMessage.cs" /> @@ -184,7 +143,6 @@ </ItemGroup> <ItemGroup> <None Include="app.config" /> - <None Include="Compression\Compress\.DS_Store" /> <None Include="packages.config" /> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> diff --git a/Software/Visual_Studio/Tango.Transport/TransportAdapterBase.cs b/Software/Visual_Studio/Tango.Transport/TransportAdapterBase.cs index 065b9dc41..d100628ac 100644 --- a/Software/Visual_Studio/Tango.Transport/TransportAdapterBase.cs +++ b/Software/Visual_Studio/Tango.Transport/TransportAdapterBase.cs @@ -17,7 +17,6 @@ namespace Tango.Transport public abstract class TransportAdapterBase : ExtendedObject, ITransportAdapter { protected long _totalBytes; - protected static long _component_counter = 1; private long _transferRateTotalBytes; private Timer _transferRateTimer; @@ -39,11 +38,6 @@ namespace Tango.Transport #region Properties - /// <summary> - /// Gets or sets the name of the transport component. - /// </summary> - public String ComponentName { get; set; } = "Not Set"; - private long _totalBytesReceived; /// <summary> /// Gets the total bytes received. @@ -77,20 +71,10 @@ namespace Tango.Transport protected set { _transferRate = value; RaisePropertyChanged(nameof(TransferRate)); } } - private String _address; /// <summary> /// Gets or sets the channel address. /// </summary> - public String Address - { - get { return _address; } - set { _address = value; RaisePropertyChangedAuto(); } - } - - /// <summary> - /// Gets the last failed state exception/reason. - /// </summary> - public Exception FailedStateException { get; private set; } + public String Address { get; set; } private TransportComponentState _state; /// <summary> @@ -101,24 +85,11 @@ namespace Tango.Transport get { return _state; } protected set { - if (_state != value) - { - _state = value; - OnStateChanged(_state); - } + _state = value; + OnStateChanged(_state); } } - private bool _enableCompression; - /// <summary> - /// Gets or sets a value indicating whether to enable compression/decompression of data. - /// </summary> - public bool EnableCompression - { - get { return _enableCompression; } - set { _enableCompression = value; RaisePropertyChangedAuto(); } - } - #endregion #region Virtual Methods @@ -129,10 +100,9 @@ namespace Tango.Transport /// <param name="ex">The ex.</param> protected virtual void OnFailed(Exception ex) { - FailedStateException = ex; - LogManager.Log(ex, $"{ComponentName}: Adapter failed."); Disconnect().Wait(); State = TransportComponentState.Failed; + LogManager.Log(ex, "Adapter failed."); } /// <summary> @@ -187,7 +157,7 @@ namespace Tango.Transport { if (State == TransportComponentState.Disposed) { - throw LogManager.Log(new ObjectDisposedException($"{ComponentName}: The adapter is in a " + State + " state.")); + throw LogManager.Log(new ObjectDisposedException("The adapter is in a " + State + " state.")); } } @@ -214,7 +184,7 @@ namespace Tango.Transport #region Private Methods - protected void AppendTransferRateBytes(long dataLength) + private void AppendTransferRateBytes(long dataLength) { _transferRateTotalBytes += dataLength; } @@ -240,8 +210,7 @@ namespace Tango.Transport /// Writes the specified data to the stream. /// </summary> /// <param name="data">The data.</param> - /// <param name="immidiate">Writes the data as soon as possible while ignoring any message queuing and batching.</param> - public abstract void Write(byte[] data, bool immidiate = false); + public abstract void Write(byte[] data); /// <summary> /// Connects the transport component. diff --git a/Software/Visual_Studio/Tango.Transport/TransportContinuousRequestConfig.cs b/Software/Visual_Studio/Tango.Transport/TransportContinuousRequestConfig.cs deleted file mode 100644 index 999522c9a..000000000 --- a/Software/Visual_Studio/Tango.Transport/TransportContinuousRequestConfig.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Tango.Transport -{ - public class TransportContinuousRequestConfig : TransportRequestConfig - { - public TimeSpan? ContinuousTimeout { get; set; } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/TransportMessage.cs b/Software/Visual_Studio/Tango.Transport/TransportMessage.cs index 245619e5e..73bf3b1e0 100644 --- a/Software/Visual_Studio/Tango.Transport/TransportMessage.cs +++ b/Software/Visual_Studio/Tango.Transport/TransportMessage.cs @@ -5,12 +5,9 @@ using System.Linq; using System.Reactive.Subjects; using System.Text; using System.Threading.Tasks; -using Tango.Core.ExtensionMethods; -using Tango.Core.Threading; using Tango.Logging; using Tango.PMR; using Tango.PMR.Common; -using Tango.PMR.Integration; namespace Tango.Transport { @@ -21,13 +18,12 @@ namespace Tango.Transport /// <seealso cref="Tango.Transport.TransportMessageBase" /> internal class TransportMessage<T> : TransportMessageBase { - private bool exceptionRaised; - private TaskCompletionSource<T> _completionSource; - private bool taskCompleted; public Subject<T> ContinuesResponseSubject { get; set; } + public bool AtLeastOneResponseReceived { get; set; } + public DateTime LastResponseTime { get; set; } public bool Completed { get; set; } @@ -53,16 +49,14 @@ namespace Tango.Transport { Completed = completed; - Action setResultAction = () => + Task.Factory.StartNew(() => { try { if (!IsContinuous) { - if (!taskCompleted) + if (!_completionSource.Task.IsCompleted) { - taskCompleted = true; - if (_completionSource.GetType() == typeof(TaskCompletionSource<IMessage>)) { _completionSource.SetResult((T)result.GetType().GetProperty("Message").GetValue(result)); @@ -113,22 +107,7 @@ namespace Tango.Transport LogManager.Log(e, $"Error while settings exception for message."); } } - }; - - if (ThreadingMode == TransportThreadingMode.NewThread) - { - ThreadFactory.StartNew(() => - { - setResultAction(); - }); - } - else - { - Task.Factory.StartNew(() => - { - setResultAction(); - }); - } + }); } /// <summary> @@ -137,81 +116,23 @@ namespace Tango.Transport /// <param name="ex">The ex.</param> public override void SetException(Exception ex) { - if (exceptionRaised || taskCompleted) - { - return; - } - Completed = true; - exceptionRaised = true; - Action setExceptionAction = () => + Task.Factory.StartNew(() => { if (!IsContinuous) { - if (!taskCompleted) + if (!_completionSource.Task.IsCompleted) { - taskCompleted = true; - - if (!(ex is ContinuousResponseAbortedException) && !(ex is TransporterDisconnectedException)) - { - LogManager.Log($"{TransportComponentName}: Request failed '{GetActualMessageTypeName()}'...\n{ex.FlattenException()}", LogCategory.Error); - } _completionSource.SetException(ex); } } else { - if (!(ex is ContinuousResponseAbortedException) && !(ex is TransporterDisconnectedException)) - { - LogManager.Log($"{TransportComponentName}: Request failed '{GetActualMessageTypeName()}'...\n{ex.FlattenException()}", LogCategory.Error); - } - AtLeastOneResponseReceived = true; ContinuesResponseSubject.OnError(ex); } - }; - - if (ThreadingMode == TransportThreadingMode.NewThread) - { - ThreadFactory.StartNew(() => - { - setExceptionAction(); - }); - } - else - { - Task.Factory.StartNew(() => - { - setExceptionAction(); - }); - } - } - - public override string GetActualMessageTypeName() - { - return GetActualMessageTypeName(Message); - } - - public override object GetActualMessage() - { - object obj = null; - - if (Message is ITangoMessage) - { - obj = Message.GetType().GetProperty("Message").GetValue(Message); - } - else if (Message is MessageContainer) - { - obj = Message; - } - else - { - obj = Message; - } - - return obj; + }); } - } } diff --git a/Software/Visual_Studio/Tango.Transport/TransportMessageBase.cs b/Software/Visual_Studio/Tango.Transport/TransportMessageBase.cs index 0d2ba6c36..7736a2752 100644 --- a/Software/Visual_Studio/Tango.Transport/TransportMessageBase.cs +++ b/Software/Visual_Studio/Tango.Transport/TransportMessageBase.cs @@ -5,9 +5,6 @@ using System.Reactive.Subjects; using System.Text; using System.Threading.Tasks; using Tango.Core; -using Tango.PMR; -using Tango.PMR.Common; -using Tango.PMR.Integration; namespace Tango.Transport { @@ -16,14 +13,6 @@ namespace Tango.Transport /// </summary> internal abstract class TransportMessageBase : ExtendedObject { - public bool AtLeastOneResponseReceived { get; set; } - - public String TransportComponentName { get; set; } - - public QueuePriority Priority { get; set; } - - public TransportThreadingMode ThreadingMode { get; set; } - /// <summary> /// Gets or sets a value indicating whether this instance is multi response. /// </summary> @@ -55,13 +44,6 @@ namespace Tango.Transport public Object Message { get; set; } /// <summary> - /// Gets or sets a value indicating whether log the message before sending. - /// </summary> - public bool ShouldLog { get; set; } - - public bool Immidiate { get; set; } - - /// <summary> /// Notifies the message observer of the new result. /// </summary> /// <param name="result">The result.</param> @@ -73,10 +55,6 @@ namespace Tango.Transport /// <param name="ex">The ex.</param> public abstract void SetException(Exception ex); - public abstract String GetActualMessageTypeName(); - - public abstract Object GetActualMessage(); - /// <summary> /// Initializes a new instance of the <see cref="TransportMessageBase"/> class. /// </summary> @@ -91,52 +69,5 @@ namespace Tango.Transport Direction = direction; Serialize = toBytes; } - - public static String GetActualMessageTypeName(Object obj) - { - String name = String.Empty; - - if (obj is ITangoMessage) - { - var message = obj.GetType().GetProperty("Message").GetValue(obj); - - if (message.GetType() == typeof(GenericRequest)) - { - try - { - name = (message as GenericRequest).GetTypeName(); - } - catch - { - name = message.GetType().Name; - } - } - else if (message.GetType() == typeof(GenericResponse)) - { - try - { - name = (message as GenericResponse).GetTypeName(); - } - catch - { - name = message.GetType().Name; - } - } - else - { - name = message.GetType().Name; - } - } - else if (obj is MessageContainer) - { - name = (obj as MessageContainer).Type.ToString(); - } - else - { - name = obj.GetType().Name; - } - - return name; - } } } diff --git a/Software/Visual_Studio/Tango.Transport/TransportRequestConfig.cs b/Software/Visual_Studio/Tango.Transport/TransportRequestConfig.cs deleted file mode 100644 index 7c4df474d..000000000 --- a/Software/Visual_Studio/Tango.Transport/TransportRequestConfig.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Tango.Core; - -namespace Tango.Transport -{ - public class TransportRequestConfig - { - public TimeSpan? Timeout { get; set; } - public bool ShouldLog { get; set; } - public bool Immediate { get; set; } - public QueuePriority Priority { get; set; } - public TransportThreadingMode ThreadingMode { get; set; } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/TransportResponseConfig.cs b/Software/Visual_Studio/Tango.Transport/TransportResponseConfig.cs deleted file mode 100644 index 79940757d..000000000 --- a/Software/Visual_Studio/Tango.Transport/TransportResponseConfig.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Tango.Core; -using Tango.PMR.Common; - -namespace Tango.Transport -{ - public class TransportResponseConfig - { - public bool Completed { get; set; } - public ErrorCode? ErrorCode { get; set; } - public String ErrorMessage { get; set; } - public bool ShouldLog { get; set; } - public bool Immediate { get; set; } - public QueuePriority Priority { get; set; } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/TransportThreadingMode.cs b/Software/Visual_Studio/Tango.Transport/TransportThreadingMode.cs deleted file mode 100644 index 7678fced4..000000000 --- a/Software/Visual_Studio/Tango.Transport/TransportThreadingMode.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Tango.Transport -{ - /// <summary> - /// Represents a request message response execution mode. - /// Including it's timeout procedure execution. - /// </summary> - public enum TransportThreadingMode - { - /// <summary> - /// The request response will be executed on a new thread and so its timeout procedure. - /// </summary> - NewThread, - - /// <summary> - /// The request response will be executed on the thread pool and so its timeout procedure. - /// </summary> - ThreadPool, - } -} diff --git a/Software/Visual_Studio/Tango.Transport/TransporterBase.cs b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs index 4c88a0158..2824ed26a 100644 --- a/Software/Visual_Studio/Tango.Transport/TransporterBase.cs +++ b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs @@ -17,12 +17,6 @@ using System.ServiceModel; using Tango.Transport.Encoders; using Tango.PMR.Connection; using Tango.Core.Threading; -using System.IO; -using Tango.Core.ExtensionMethods; -using Tango.PMR.Integration; -using Newtonsoft.Json; -using System.Diagnostics; -using System.Reactive.Concurrency; namespace Tango.Transport { @@ -32,17 +26,8 @@ namespace Tango.Transport /// <seealso cref="Tango.Transport.ITransporter" /> public abstract class TransporterBase : ExtendedObject, ITransporter { - protected static long _component_counter = 1; - - private class RequestHandler - { - public Type RequestType { get; set; } - public Action<ITransporter, Object, String> Callback { get; set; } - public object RegisteredCallback { get; set; } - } - private const int MESSAGE_TOKEN_LENGTH = 36; - private PriorityProducerConsumerQueue<TransportMessageBase> _sendingQueue; + private ProducerConsumerQueue<TransportMessageBase> _sendingQueue; private ConcurrentList<TransportMessageBase> _pendingRequests; private ProducerConsumerQueue<byte[]> _arrivedResponses; private Thread _pushThread; @@ -51,18 +36,13 @@ namespace Tango.Transport private ITransportAdapter _adapter; private Dictionary<String, PendingResponse> _pendingResponses; private DateTime _lastKeepAliveTime; - private List<RequestHandler> _requestHandlers; - private static JsonSerializerSettings _genericMessageSettings = new JsonSerializerSettings() - { - TypeNameHandling = TypeNameHandling.All, - }; #region Events /// <summary> /// Occurs when a new request message has been received. /// </summary> - public event EventHandler<RequestReceivedEventArgs> RequestReceived; + public event EventHandler<MessageContainer> RequestReceived; /// <summary> /// Occurs when a new response message has been received. @@ -74,31 +54,11 @@ namespace Tango.Transport /// </summary> public event EventHandler<TransportComponentState> StateChanged; - /// <summary> - /// Occurs when a request has been sent. - /// </summary> - public event EventHandler<IMessage> RequestSent; - - /// <summary> - /// Occurs when a request response has been received. - /// </summary> - public event EventHandler<IMessage> ResponseReceived; - - /// <summary> - /// Occurs when a request has failed. - /// </summary> - public event EventHandler<RequestFailedEventArgs> RequestFailed; - #endregion #region Properties /// <summary> - /// Gets or sets the name of the transport component. - /// </summary> - public String ComponentName { get; set; } - - /// <summary> /// Gets or sets the <see cref="ITransportAdapter" /> used to read and write raw data. /// </summary> public ITransportAdapter Adapter @@ -154,11 +114,11 @@ namespace Tango.Transport if (_useKeepAlive) { - LogManager.Log($"{GetExtendedComponentName()}: KeepAlive is activated..."); + LogManager.Log("KeepAlive is activated..."); } else { - LogManager.Log($"{GetExtendedComponentName()}: KeepAlive is deactivated."); + LogManager.Log("KeepAlive is deactivated."); } } } @@ -188,16 +148,6 @@ namespace Tango.Transport /// </summary> public Exception FailedStateException { get; private set; } - private GenericMessageProtocol _genericProtocol; - /// <summary> - /// Gets or sets the generic protocol used to serialize/deserialize generic messages. - /// </summary> - public GenericMessageProtocol GenericProtocol - { - get { return _genericProtocol; } - set { _genericProtocol = value; RaisePropertyChangedAuto(); } - } - #endregion #region Virtual Methods @@ -213,7 +163,7 @@ namespace Tango.Transport _pendingRequests.Clear(); _pendingResponses.Clear(); _arrivedResponses = new ProducerConsumerQueue<byte[]>(); - _sendingQueue = new PriorityProducerConsumerQueue<TransportMessageBase>(); + _sendingQueue = new ProducerConsumerQueue<TransportMessageBase>(); } if (oldAdapter != null) @@ -224,7 +174,7 @@ namespace Tango.Transport if (newAdapter != null) { - LogManager.Log($"{GetExtendedComponentName()}: Adapter Changed: Type = {newAdapter.GetType().Name}, Address = {newAdapter.Address}, State = {newAdapter.State}"); + LogManager.Log(String.Format("Adapter Changed: Type = {0}, Address = {1}, State = {2}", newAdapter.GetType().Name, newAdapter.Address, newAdapter.State)); newAdapter.StateChanged -= OnAdapterStateChanged; newAdapter.DataAvailable -= OnAdapterDataAvailable; @@ -238,7 +188,7 @@ namespace Tango.Transport } else { - LogManager.Log($"{GetExtendedComponentName()}: Adapter Changed: null"); + LogManager.Log("Adapter Changed: null"); } } @@ -251,7 +201,7 @@ namespace Tango.Transport { if (e == TransportComponentState.Failed && FailsWithAdapter) { - OnFailed(new CommunicationException($"The adapter has failed with exception '{Adapter.FailedStateException.Message}' and the transporter is configured to fail with the adapter.")); + OnFailed(new CommunicationException("The adapter has failed. Going into a failed state...")); } } @@ -270,104 +220,21 @@ namespace Tango.Transport /// Called when the component has failed. /// </summary> /// <param name="ex">The ex.</param> - protected virtual async void OnFailed(Exception ex) - { - if (State != TransportComponentState.Failed) - { - FailedStateException = ex; - LogManager.Log(ex, $"{GetExtendedComponentName()}: Transporter failed."); - State = TransportComponentState.Failed; - - await OnPostDisconnection(); - } - else - { - LogManager.Log(ex, LogCategory.Warning, $"{GetExtendedComponentName()}: OnFailed called while state is already failed!"); - } - } - - protected virtual async Task OnPostDisconnection() + protected virtual void OnFailed(Exception ex) { - try - { - if (_pullThread != null) - { - _pullThread.Abort(); - _pushThread.Abort(); - _keepAliveThread.Abort(); - } - } - catch { } - - if (Adapter != null) - { - await Adapter.Disconnect(); - } - - NotifyContinuousRequestMessagesDisconnection(); + FailedStateException = ex; + State = TransportComponentState.Failed; + LogManager.Log(ex, "Transporter failed."); + Disconnect().Wait(); } /// <summary> /// Called when a new request has been received. /// </summary> /// <param name="container">The request.</param> - protected virtual void OnRequestReceived(RequestReceivedEventArgs e) + protected virtual void OnRequestReceived(MessageContainer container) { - var container = e.Container; - - if (_requestHandlers.Count > 0) - { - if (container.Type != MessageType.GenericRequest) - { - var handlers = _requestHandlers.Where(x => x.RequestType.Name == container.Type.ToOriginalName()).ToList(); - - if (handlers.Count > 0) //Handle - { - e.Handled = true; - - var request = MessageFactory.ExtractMessageFromContainer(container); - - foreach (var handler in handlers) - { - try - { - handler.Callback.Invoke(this, request, container.Token); - } - catch - { - //Ignore any exception on the client side. - } - } - } - } - else - { - var genericRequest = MessageFactory.ExtractMessageFromContainer<GenericRequest>(container); - - var handlers = _requestHandlers.Where(x => x.RequestType.AssemblyQualifiedName == genericRequest.Type).ToList(); - - if (handlers.Count > 0) - { - e.Handled = true; - - var innerRequest = GenericMessageSerializer.DeserializeFromByteString(handlers[0].RequestType, genericRequest.Data, GenericProtocol); - - foreach (var handler in handlers) - { - try - { - handler.Callback.Invoke(this, innerRequest, container.Token); - } - catch - { - //Ignore any exception on the client side. - } - } - } - } - } - - RequestReceived?.Invoke(this, e); + RequestReceived?.Invoke(this, container); } /// <summary> @@ -388,80 +255,6 @@ namespace Tango.Transport StateChanged?.Invoke(this, state); } - /// <summary> - /// Returns a string representing the component name. If an adapter is attached it will be part of the string. - /// </summary> - /// <returns></returns> - protected virtual String GetExtendedComponentName() - { - return Adapter != null ? $"{ComponentName} ({Adapter.Address})" : ComponentName; - } - - /// <summary> - /// Notifies all the continuous request messages about disconnection. - /// </summary> - protected virtual void NotifyContinuousRequestMessagesDisconnection() - { - LogManager.Log("Notifying all continuous request messages about disconnection..."); - foreach (var request in _pendingRequests.ToList().Where(x => x.Direction == TransportMessageDirection.Request && x.IsContinuous)) - { - try - { - _pendingRequests.Remove(request); - LogManager.Log($"Notifying continuous request '{(request.Message as ITangoMessage).Type}'..."); - OnRequestFailed(request, new TransporterDisconnectedException("Transporter disconnected.")); - request.SetException(new TransporterDisconnectedException("Transporter disconnected.")); - } - catch (Exception e) - { - System.Diagnostics.Debug.WriteLine(e.ToString()); - } - } - } - - /// <summary> - /// Called when the request has been sent - /// </summary> - /// <param name="response">The request.</param> - private void OnRequestSent(TransportMessageBase request) - { - if (request.ShouldLog) - { - IMessage message = request.GetActualMessage() as IMessage; - - if (message != null) - { - RequestSent?.Invoke(this, message); - } - } - } - - /// <summary> - /// Called when the response has been received - /// </summary> - /// <param name="response">The response.</param> - private void OnResponseReceived(IMessage response) - { - if (response != null) - { - ResponseReceived?.Invoke(this, response); - } - } - - /// <summary> - /// Called when the request has been failed - /// </summary> - /// <param name="request">The request.</param> - private void OnRequestFailed(TransportMessageBase request, Exception exception) - { - IMessage message = request.GetActualMessage() as IMessage; - - if (message != null) - { - RequestFailed?.Invoke(this, new RequestFailedEventArgs(message, exception)); - } - } - #endregion #region Constructors @@ -471,13 +264,11 @@ namespace Tango.Transport /// </summary> public TransporterBase() { - ComponentName = "Not Set"; Encoder = new ProtoEncoder(); _pendingResponses = new Dictionary<string, PendingResponse>(); - _sendingQueue = new PriorityProducerConsumerQueue<TransportMessageBase>(); + _sendingQueue = new ProducerConsumerQueue<TransportMessageBase>(); _pendingRequests = new ConcurrentList<TransportMessageBase>(); _arrivedResponses = new ProducerConsumerQueue<byte[]>(); - _requestHandlers = new List<RequestHandler>(); RequestTimeout = TimeSpan.FromSeconds(5); EnableKeepAliveAutoResponse = true; KeepAliveTimeout = TimeSpan.FromSeconds(2); @@ -502,7 +293,7 @@ namespace Tango.Transport /// </summary> public void ClearQueues() { - _sendingQueue = new PriorityProducerConsumerQueue<TransportMessageBase>(); + _sendingQueue = new ProducerConsumerQueue<TransportMessageBase>(); _pendingRequests = new ConcurrentList<TransportMessageBase>(); _arrivedResponses = new ProducerConsumerQueue<byte[]>(); } @@ -521,7 +312,7 @@ namespace Tango.Transport State = TransportComponentState.Connected; StartThreads(); - LogManager.Log($"{GetExtendedComponentName()}: Transporter Connected..."); + LogManager.Log("Transporter Connected..."); } /// <summary> @@ -530,323 +321,255 @@ namespace Tango.Transport /// <returns></returns> public virtual async Task Disconnect() { - if (State == TransportComponentState.Connected) - { - State = TransportComponentState.Disconnected; + State = TransportComponentState.Disconnected; - await OnPostDisconnection(); + try + { + if (_pullThread != null) + { + _pullThread.Abort(); + _pushThread.Abort(); + _keepAliveThread.Abort(); + } + } + catch { } - LogManager.Log($"{GetExtendedComponentName()}: Transporter Disconnected..."); + if (Adapter != null) + { + await Adapter.Disconnect(); } + LogManager.Log("Transporter Disconnected..."); } - #endregion - - #region Public Request Methods - /// <summary> /// Sends a request. /// </summary> /// <param name="request">The request.</param> - /// <param name="config">Request configuration.</param> + /// <param name="timeout">Optional timeout. If not specified will use the <see cref="RequestTimeout" />.</param> /// <returns></returns> - /// <exception cref="InvalidOperationException"></exception> - public Task<IMessage> SendRequest(IMessage request, TransportRequestConfig config = null) + public Task<IMessage> SendRequest(IMessage request, TimeSpan? timeout = null) { + String requestName = request.GetType().Name; + String responseName = requestName.Replace("Request", "Response"); + MessageContainer container = new MessageContainer(); container.Token = Guid.NewGuid().ToString(); container.Data = request.ToByteString(); - container.Timeout = config.Timeout.HasValue ? (UInt32)config.Timeout.Value.TotalMilliseconds : (UInt32)RequestTimeout.TotalMilliseconds; - container.Type = MessageFactory.ParseMessageType(request.GetType().Name); + container.Timeout = timeout.HasValue ? (UInt32)timeout.Value.TotalMilliseconds : (UInt32)RequestTimeout.TotalMilliseconds; + container.Type = MessageFactory.ParseMessageType(requestName); - return SendRequestInternal<IMessage>(container.Token, container, config).Task; - } + LogManager.Log("Queuing request message: " + requestName + " Token: " + container.Token, LogCategory.Debug); + LogManager.Log("Expected response: " + responseName, LogCategory.Debug); - /// <summary> - /// Sends the request. - /// </summary> - /// <param name="container"></param> - /// <param name="config">Request configuration.</param> - /// <returns></returns> - /// <exception cref="InvalidOperationException"></exception> - public Task<MessageContainer> SendRequest(MessageContainer container, TransportRequestConfig config = null) - { - return SendRequestInternal<MessageContainer>(container.Token, container, config).Task; - } + if (State != TransportComponentState.Connected) + { + throw LogManager.Log(new InvalidOperationException($"Could not send the request while transporter state is {State}.")); + } - /// <summary> - /// Sends a request. - /// </summary> - /// <typeparam name="Request">The type of the request.</typeparam> - /// <typeparam name="Response">The type of the response.</typeparam> - /// <param name="request">The request.</param> - /// <param name="config">Request configuration.</param> - /// <returns></returns> - /// <exception cref="InvalidOperationException"></exception> - public Task<TangoMessage<Response>> SendRequest<Request, Response>(TangoMessage<Request> request, TransportRequestConfig config = null) where Request : IMessage<Request> where Response : IMessage<Response> - { - return SendRequestInternal<TangoMessage<Response>>(request.Container.Token, request, config).Task; - } + TaskCompletionSource<IMessage> source = new TaskCompletionSource<IMessage>(); + TransportMessage<IMessage> message = new TransportMessage<IMessage>(container.Token, request, TransportMessageDirection.Request, () => container.ToByteArray(), source); - private TaskCompletionSource<T> SendRequestInternal<T>(String token, Object request, TransportRequestConfig config = null) - { - config = config ?? new TransportRequestConfig(); + message.ActivateTimeout = () => + { + TimeoutTask.StartNew(() => + { - TaskCompletionSource<T> source = new TaskCompletionSource<T>(); + if (!source.Task.IsCompleted) + { + TimeoutException ex = new TimeoutException("Request message: " + requestName + " had timed out after " + (timeout != null ? timeout.Value.TotalSeconds : RequestTimeout.TotalSeconds) + " seconds."); + LogManager.Log(ex); + LogManager.Log("Setting request task exception...", LogCategory.Debug); + source.SetException(ex); + } - String requestName = TransportMessageBase.GetActualMessageTypeName(request); + }, timeout != null ? timeout.Value : RequestTimeout); + }; - Func<byte[]> toBytes = null; + EnqueueMessageOut(message); - if (request is ITangoMessage tangoMessage) - { - toBytes = () => Encoder.Encode(tangoMessage); - } - else if (request is IMessage protoMessage) - { - toBytes = () => protoMessage.ToByteArray(); - } + return source.Task; + } - TransportMessage<T> message = new TransportMessage<T>(token, request, TransportMessageDirection.Request, toBytes, source); - message.ShouldLog = config.ShouldLog; - message.Immidiate = config.Immediate; - message.Priority = config.Priority; - message.TransportComponentName = GetExtendedComponentName(); - message.ThreadingMode = config.ThreadingMode; + /// <summary> + /// Sends the response. + /// </summary> + /// <param name="response">The response.</param> + /// <param name="token">The token.</param> + /// <param name="completed">The completed.</param> + /// <param name="errorCode">The error code.</param> + /// <param name="errorMessage">The error message.</param> + /// <returns></returns> + /// <exception cref="System.InvalidOperationException">Matching request token was not found!</exception> + public Task SendResponse(IMessage response, string token, bool? completed = default(bool?), ErrorCode? errorCode = default(ErrorCode?), string errorMessage = null) + { + String responseName = response.GetType().Name; - TimeSpan? timeout = config.Timeout; + MessageContainer container = new MessageContainer(); + container.Token = token; + container.Data = response.ToByteString(); + container.Type = MessageFactory.ParseMessageType(responseName); - if (request is MessageContainer container) + if (errorCode.HasValue) { - timeout = GetContainerTimeoutOrDefault(container); + container.Error = errorCode.Value; } - if (timeout == null) + if (errorMessage != null) { - timeout = RequestTimeout; + container.ErrorMessage = errorMessage; } - if (request is ITangoMessage tanMessage) + if (completed.HasValue) { - tanMessage.Container.Timeout = (uint)timeout.Value.TotalMilliseconds; + container.Completed = completed.Value; } - String responseName = requestName.Replace("Request", "Response"); + return SendResponse(container); + } - LogManager.Log($"{GetExtendedComponentName()}: Queuing request message: {requestName} Token: {token}", LogCategory.Debug); - LogManager.Log($"{GetExtendedComponentName()}: Expected response: {responseName}", LogCategory.Debug); + /// <summary> + /// Sends the request. + /// </summary> + /// <param name="container">The container.</param> + /// <returns></returns> + public Task<MessageContainer> SendRequest(MessageContainer container) + { + String responseName = container.Type.ToString().Replace("Request", "Response"); + TimeSpan? timeout = GetContainerTimeoutOrDefault(container); + + LogManager.Log("Queuing request message: " + container.Type + " Token: " + container.Token, LogCategory.Debug); + LogManager.Log("Expected response: " + responseName, LogCategory.Debug); if (State != TransportComponentState.Connected) { - throw LogManager.Log(new InvalidOperationException($"{GetExtendedComponentName()}: Could not send the request while transporter state is {State}.")); + throw LogManager.Log(new InvalidOperationException($"Could not send the request while transporter state is {State}.")); } + TaskCompletionSource<MessageContainer> source = new TaskCompletionSource<MessageContainer>(); + TransportMessage<MessageContainer> message = new TransportMessage<MessageContainer>(container.Token, container, TransportMessageDirection.Request, () => container.ToByteArray(), source); - Action timeoutAction = () => + message.ActivateTimeout = () => { - if (!source.Task.IsCompleted) + TimeoutTask.StartNew(() => { - TimeoutException ex = new TimeoutException($"{GetExtendedComponentName()}: Request message '{requestName}' had timed out after {timeout.Value.TotalSeconds} seconds."); - OnRequestFailed(message, ex); - message.SetException(ex); - } - }; - if (config.ThreadingMode == TransportThreadingMode.NewThread) - { - message.ActivateTimeout = () => - { - TimeoutTask.StartNew(() => + if (!source.Task.IsCompleted) { - timeoutAction(); - }, timeout.Value); - }; - } - else - { - message.ActivateTimeout = () => - { - Task.Delay(timeout.Value).ContinueWith((x) => - { - timeoutAction(); - }); - }; - } - - EnqueueMessageOut(message); - - return source; - } - - /// <summary> - /// Sends a request and expecting multiple response messages. - /// </summary> - /// <param name="request"></param> - /// <param name="config">Request configuration.</param> - /// <returns></returns> - /// <exception cref="InvalidOperationException"></exception> - public IObservable<IMessage> SendContinuousRequest(IMessage request, TransportContinuousRequestConfig config = null) - { - MessageContainer container = new MessageContainer(); - container.Token = Guid.NewGuid().ToString(); - container.Data = request.ToByteString(); - container.Type = MessageFactory.ParseMessageType(request.GetType().Name); + TimeoutException ex = new TimeoutException("Request message: " + container.Type + " had timed out after " + (timeout != null ? timeout.Value.TotalSeconds : RequestTimeout.TotalSeconds) + " seconds."); + LogManager.Log(ex); + LogManager.Log("Setting request task exception...", LogCategory.Debug); + source.SetException(ex); + } - //We need to assign this timeout because when the internal method detects a MessageContainer it will bypass the container continuous timeout assignment. - container.ContinuousTimeout = config.ContinuousTimeout != null ? (UInt32)config.ContinuousTimeout.Value.TotalMilliseconds : 0; + }, timeout != null ? timeout.Value : RequestTimeout); - container.Continuous = true; + }; - return SendContinuousRequestInternal<IMessage>(container.Token, container, config); - } + EnqueueMessageOut(message); - /// <summary> - /// Sends a request and expecting multiple response messages. - /// </summary> - /// <typeparam name="Request">The type of the request.</typeparam> - /// <typeparam name="Response">The type of the response.</typeparam> - /// <param name="request"></param> - /// <param name="config">Request configuration.</param> - /// <returns></returns> - /// <exception cref="InvalidOperationException"></exception> - public IObservable<TangoMessage<Response>> SendContinuousRequest<Request, Response>(TangoMessage<Request> request, TransportContinuousRequestConfig config = null) where Request : IMessage<Request> where Response : IMessage<Response> - { - request.Container.Continuous = true; - request.Container.Completed = false; - return SendContinuousRequestInternal<TangoMessage<Response>>(request.Container.Token, request, config); + return source.Task; } /// <summary> - /// Sends a continuous request. + /// Sends the response. /// </summary> /// <param name="container">The container.</param> - /// <param name="config">Request configuration.</param> /// <returns></returns> - /// <exception cref="InvalidOperationException"></exception> - public IObservable<MessageContainer> SendContinuousRequest(MessageContainer container, TransportContinuousRequestConfig config = null) + /// <exception cref="System.InvalidOperationException">Matching request token was not found!</exception> + public Task SendResponse(MessageContainer container) { - return SendContinuousRequestInternal<MessageContainer>(container.Token, container, config); - } - - private IObservable<T> SendContinuousRequestInternal<T>(String token, Object request, TransportContinuousRequestConfig config = null) - { - config = config ?? new TransportContinuousRequestConfig(); + String token = container.Token; - String requestName = TransportMessageBase.GetActualMessageTypeName(request); + LogManager.Log("Queuing response message: " + container.Type, LogCategory.Debug); - Func<byte[]> toBytes = null; + PendingResponse pendingResponse = null; - if (request is ITangoMessage tangoMessage) - { - toBytes = () => Encoder.Encode(tangoMessage); - } - else if (request is IMessage protoMessage) + if (State != TransportComponentState.Connected) { - toBytes = () => protoMessage.ToByteArray(); + throw LogManager.Log(new InvalidOperationException($"Could not send the response while transporter state is {State}.")); } - Subject<T> subject = new Subject<T>(); - - TransportMessage<T> message = new TransportMessage<T>(token, request, TransportMessageDirection.Request, toBytes, null); - message.ShouldLog = config.ShouldLog; - message.Immidiate = config.Immediate; - message.Priority = config.Priority; - message.TransportComponentName = GetExtendedComponentName(); - message.IsContinuous = true; - message.ContinuesResponseSubject = subject; - - TimeSpan? timeout = config.Timeout; - TimeSpan? continuousTimeout = config.ContinuousTimeout; + LogManager.Log("Searching for matching request token: " + token, LogCategory.Debug); - if (request is MessageContainer container) + if (_pendingResponses.TryGetValue(token, out pendingResponse)) { - timeout = GetContainerTimeoutOrDefault(container); + LogManager.Log("Found matching request token: " + token, LogCategory.Debug); - if (timeout == null) + if (!pendingResponse.IsContinuous) { - timeout = config.Timeout != null ? config.Timeout.Value : RequestTimeout; - container.Timeout = (uint)timeout.Value.TotalMilliseconds; + LogManager.Log("Removing matching request token.", LogCategory.Debug); + _pendingResponses.Remove(token); + } + else if (container.Completed) + { + LogManager.Log("Response completed. Removing matching request token.", LogCategory.Debug); + _pendingResponses.Remove(token); } - - continuousTimeout = GetContainerContinuousTimeoutOrDefault(container); } - - if (timeout == null) + else { - timeout = RequestTimeout; + //This should never happen. + throw LogManager.Log(new InvalidOperationException("Matching request token was not found!"), LogCategory.Critical); } - if (request is ITangoMessage tanMessage) - { - tanMessage.Container.Continuous = true; - tanMessage.Container.Completed = false; - tanMessage.Container.Timeout = (uint)timeout.Value.TotalMilliseconds; - tanMessage.Container.ContinuousTimeout = continuousTimeout != null ? (UInt32)continuousTimeout.Value.TotalMilliseconds : 0; - } + TaskCompletionSource<object> source = new TaskCompletionSource<object>(); + TransportMessage<object> message = new TransportMessage<object>(token, container, TransportMessageDirection.Response, () => container.ToByteArray(), source); + EnqueueMessageOut(message); + return source.Task; + } + /// <summary> + /// Sends a request and expecting multiple response messages. + /// </summary> + /// <param name="request">The request.</param> + /// <param name="timeout"></param> + /// <returns></returns> + public IObservable<IMessage> SendContinuousRequest(IMessage request, TimeSpan? timeout = default(TimeSpan?)) + { + String requestName = request.GetType().Name; String responseName = requestName.Replace("Request", "Response"); - LogManager.Log($"{GetExtendedComponentName()}: Queuing continuous request message: {requestName} Token: {token}", LogCategory.Debug); - LogManager.Log($"{GetExtendedComponentName()}: Expected response: {responseName}", LogCategory.Debug); + MessageContainer container = new MessageContainer(); + container.Token = Guid.NewGuid().ToString(); + container.Data = request.ToByteString(); + container.Type = MessageFactory.ParseMessageType(requestName); + container.Timeout = timeout.HasValue ? (UInt32)timeout.Value.TotalMilliseconds : (UInt32)RequestTimeout.TotalMilliseconds; + container.Continuous = true; + + LogManager.Log("Queuing continuous request message: " + requestName + " Token: " + container.Token, LogCategory.Debug); if (State != TransportComponentState.Connected) { - throw LogManager.Log(new InvalidOperationException($"{GetExtendedComponentName()}: Could not send the request while transporter state is {State}.")); + throw LogManager.Log(new InvalidOperationException($"Could not send the request while transporter state is {State}.")); } - Action timeoutAction = () => - { - if (!message.AtLeastOneResponseReceived) - { - TimeoutException ex = new TimeoutException($"{GetExtendedComponentName()}: Request message '{requestName}' had timed out after {timeout.Value.TotalSeconds} seconds."); - OnRequestFailed(message, ex); - message.SetException(ex); - } + Subject<IMessage> subject = new Subject<IMessage>(); - if (continuousTimeout != null) - { - Task.Factory.StartNew(async () => - { - while (!message.Completed) - { - await Task.Delay(continuousTimeout.Value).ContinueWith((y) => - { - if (!message.Completed) - { - if (DateTime.Now - message.LastResponseTime > continuousTimeout.Value) - { - TimeoutException ex = new TimeoutException($"{GetExtendedComponentName()}: Continuous request message '{requestName}' had failed to provide a response for a period of {continuousTimeout.Value.TotalSeconds} seconds and has timed out."); - OnRequestFailed(message, ex); - message.SetException(ex); - return; - } - } - }); - } - }); - } - }; + LogManager.Log("Expected response: " + responseName, LogCategory.Debug); - if (config.ThreadingMode == TransportThreadingMode.NewThread) + TransportMessage<IMessage> message = new TransportMessage<IMessage>(container.Token, request, TransportMessageDirection.Request, () => container.ToByteArray(), null) { - message.ActivateTimeout = () => - { - TimeoutTask.StartNew(() => - { - timeoutAction(); - }, timeout.Value); - }; - } - else + IsContinuous = true, + ContinuesResponseSubject = subject, + }; + + message.ActivateTimeout = () => { - message.ActivateTimeout = () => + + TimeoutTask.StartNew(() => { - Task.Delay(timeout.Value).ContinueWith((x) => + + if (!message.AtLeastOneResponseReceived) { - timeoutAction(); - }); - }; - } + TimeoutException ex = new TimeoutException("Request message: " + requestName + " had timed out after " + (timeout != null ? timeout.Value.TotalSeconds : RequestTimeout.TotalSeconds) + " seconds."); + LogManager.Log(ex); + LogManager.Log("Setting request exception...", LogCategory.Debug); + message.SetException(ex); + } + + }, timeout != null ? timeout.Value : RequestTimeout); + + }; EnqueueMessageOut(message); @@ -854,191 +577,200 @@ namespace Tango.Transport } /// <summary> - /// Sends a generic request of any type. + /// Sends a request. /// </summary> /// <typeparam name="Request">The type of the request.</typeparam> /// <typeparam name="Response">The type of the response.</typeparam> /// <param name="request">The request.</param> - /// <param name="config">The configuration.</param> - /// <returns></returns> - public async Task<Response> SendGenericRequest<Request, Response>(Request request, TransportRequestConfig config = null) where Request : class where Response : class - { - GenericRequest genericRequest = new GenericRequest(); - genericRequest.Type = request.GetType().AssemblyQualifiedName; - genericRequest.Data = GenericMessageSerializer.SerializeToByteString<Request>(request, GenericProtocol); - - var response = await SendRequest<GenericRequest, GenericResponse>(genericRequest, config); - var responseObject = GenericMessageSerializer.DeserializeFromByteString<Response>(response.Message.Data, GenericProtocol); - return responseObject; - } - - /// <summary> - /// Sends a generic request and expecting multiple generic response messages. - /// </summary> - /// <typeparam name="Request">The type of the request.</typeparam> - /// <typeparam name="Response">The type of the response.</typeparam> - /// <param name="config">Request configuration.</param> + /// <param name="timeout">Optional timeout. If not specified will use the <see cref="RequestTimeout" />.</param> /// <returns></returns> - public IObservable<Response> SendGenericContinuousRequest<Request, Response>(Request request, TransportContinuousRequestConfig config = null) where Request : class where Response : class + public Task<TangoMessage<Response>> SendRequest<Request, Response>(TangoMessage<Request> request, TimeSpan? timeout = null) where Request : IMessage<Request> where Response : IMessage<Response> { - GenericRequest genericRequest = new GenericRequest(); - genericRequest.Type = request.GetType().AssemblyQualifiedName; + LogManager.Log("Queuing request message: " + typeof(Request).Name + " Token: " + request.Container.Token, LogCategory.Debug); + LogManager.Log("Expected response: " + typeof(Response).Name, LogCategory.Debug); - genericRequest.Data = GenericMessageSerializer.SerializeToByteString<Request>(request, GenericProtocol); - - Subject<Response> subject = new Subject<Response>(); - - SendContinuousRequest<GenericRequest, GenericResponse>(genericRequest, config).Subscribe((response) => + if (State != TransportComponentState.Connected) { + throw LogManager.Log(new InvalidOperationException($"Could not send the request while transporter state is {State}.")); + } - try - { - var responseObject = GenericMessageSerializer.DeserializeFromByteString<Response>(response.Message.Data, GenericProtocol); - subject.OnNext(responseObject); - } - catch (Exception ex) - { - Debugger.Break(); - System.Diagnostics.Debug.WriteLine($"Exception thrown by the generic request continuous handler.\n{ex.ToString()}"); - //Ignore exception at the client side. - } - - }, (ex) => - { + request.Container.Timeout = timeout.HasValue ? (UInt32)timeout.Value.TotalMilliseconds : (UInt32)RequestTimeout.TotalMilliseconds; - try - { - subject.OnError(ex); - } - catch (Exception xx) - { - Debugger.Break(); - System.Diagnostics.Debug.WriteLine($"Exception thrown by the generic request error handler.\n{xx.ToString()}"); - //Ignore exception at the client side. - } + TaskCompletionSource<TangoMessage<Response>> source = new TaskCompletionSource<TangoMessage<Response>>(); + TransportMessage<TangoMessage<Response>> message = new TransportMessage<TangoMessage<Response>>(request.Container.Token, request, TransportMessageDirection.Request, () => Encoder.Encode(request), source); - }, () => + message.ActivateTimeout = () => { - try - { - subject.OnCompleted(); - } - catch (Exception ex) + TimeoutTask.StartNew(() => { - Debugger.Break(); - System.Diagnostics.Debug.WriteLine($"Exception thrown by the generic request completed handler.\n{ex.ToString()}"); - //Ignore exception at the client side. - } - }); - return subject.AsObservable(); - } + if (!source.Task.IsCompleted) + { + TimeoutException ex = new TimeoutException("Request message: " + typeof(Request).Name + " had timed out after " + (timeout != null ? timeout.Value.TotalSeconds : RequestTimeout.TotalSeconds) + " seconds."); + LogManager.Log(ex); + LogManager.Log("Setting request task exception...", LogCategory.Debug); + source.SetException(ex); + } - #endregion + }, timeout != null ? timeout.Value : RequestTimeout); + }; - #region Public Response Methods + EnqueueMessageOut(message); - /// <summary> - /// Sends a response. - /// </summary> - /// <typeparam name="Response">The type of the response.</typeparam> - /// <param name="response">The response.</param> - /// <returns></returns> - public Task SendResponse<Response>(TangoMessage<Response> response) where Response : IMessage<Response> - { - return SendResponse<Response>(response, response.Container.Token); + return source.Task; } /// <summary> - /// Sends the response. + /// Sends a request and expecting multiple response messages. /// </summary> - /// <param name="response"></param> - /// <param name="token">Request token.</param> - /// <param name="config">Response configuration.</param> + /// <typeparam name="Request">The type of the request.</typeparam> + /// <typeparam name="Response">The type of the response.</typeparam> + /// <param name="request">The request.</param> + /// <param name="timeout"></param> /// <returns></returns> - public Task SendResponse(IMessage response, String token, TransportResponseConfig config = null) + public IObservable<TangoMessage<Response>> SendContinuousRequest<Request, Response>(TangoMessage<Request> request, TimeSpan? firstTimeout = null, TimeSpan? continousTimeout = null) where Request : IMessage<Request> where Response : IMessage<Response> { - config = config ?? new TransportResponseConfig(); + LogManager.Log("Queuing continuous request message: " + typeof(Request).Name + " Token: " + request.Container.Token, LogCategory.Debug); - String responseName = response.GetType().Name; + Subject<TangoMessage<Response>> subject = new Subject<TangoMessage<Response>>(); - MessageContainer container = new MessageContainer(); - container.Token = token; - container.Data = response.ToByteString(); - container.Type = MessageFactory.ParseMessageType(responseName); + LogManager.Log("Expected response: " + typeof(Response).Name, LogCategory.Debug); - if (config.ErrorCode.HasValue) + if (State != TransportComponentState.Connected) { - container.Error = config.ErrorCode.Value; + throw LogManager.Log(new InvalidOperationException($"Could not send the request while transporter state is {State}.")); } - if (config.ErrorMessage != null) + request.Container.Continuous = true; + request.Container.Completed = false; + + request.Container.Timeout = firstTimeout.HasValue ? (UInt32)firstTimeout.Value.TotalMilliseconds : (UInt32)RequestTimeout.TotalMilliseconds; + request.Container.ContinuousTimeout = continousTimeout.HasValue ? (UInt32)continousTimeout.Value.TotalMilliseconds : 0; + + TransportMessage<TangoMessage<Response>> message = new TransportMessage<TangoMessage<Response>>(request.Container.Token, request, TransportMessageDirection.Request, () => Encoder.Encode(request), null) { - container.ErrorMessage = config.ErrorMessage; - } + IsContinuous = true, + ContinuesResponseSubject = subject, + }; - container.Completed = config.Completed; + message.ActivateTimeout = () => + { + TimeoutTask.StartNew(() => + { - return SendResponse(container); + if (!message.AtLeastOneResponseReceived) + { + TimeoutException ex = new TimeoutException("Request message: " + typeof(Request).Name + " had timed out after " + (firstTimeout != null ? firstTimeout.Value.TotalSeconds : RequestTimeout.TotalSeconds) + " seconds."); + LogManager.Log(ex); + LogManager.Log("Setting request exception...", LogCategory.Debug); + message.SetException(ex); + } + + if (continousTimeout != null) + { + Task.Factory.StartNew(async () => + { + while (!message.Completed) + { + await Task.Delay(continousTimeout.Value).ContinueWith((y) => + { + if (!message.Completed) + { + if (DateTime.Now - message.LastResponseTime > continousTimeout.Value) + { + TimeoutException ex = new TimeoutException("Continuous request message: " + typeof(Request).Name + " had failed to provide a response for a period of " + (continousTimeout.Value.TotalSeconds) + " seconds and has timed out."); + LogManager.Log(ex); + LogManager.Log("Setting request exception...", LogCategory.Debug); + message.SetException(ex); + return; + } + } + }); + } + }); + } + + }, firstTimeout != null ? firstTimeout.Value : RequestTimeout); + }; + + EnqueueMessageOut(message); + + return subject.AsObservable(); } /// <summary> - /// Sends the response. + /// Sends a continuous request. /// </summary> /// <param name="container">The container.</param> /// <returns></returns> - /// <exception cref="InvalidOperationException"> - /// </exception> - public Task SendResponse(MessageContainer container, TransportResponseConfig config = null) + public IObservable<MessageContainer> SendContinuousRequest(MessageContainer container) { - config = config ?? new TransportResponseConfig(); - - if (_pushThread == null || _pushThread.ThreadState == System.Threading.ThreadState.Aborted) - { - throw new InvalidOperationException("Transporter push thread is not in a running state."); - } + TimeSpan? timeout = GetContainerTimeoutOrDefault(container); + TimeSpan? continuousTimeout = container.ContinuousTimeout > 0 ? TimeSpan.FromMilliseconds(container.ContinuousTimeout) : default(TimeSpan?); - String token = container.Token; - - LogManager.Log($"{GetExtendedComponentName()}: Queuing response message: " + container.Type, LogCategory.Debug); + String requestName = container.Type.ToString(); + String responseName = requestName.Replace("Request", "Response"); - PendingResponse pendingResponse = null; + LogManager.Log("Queuing continuous request message: " + requestName + " Token: " + container.Token, LogCategory.Debug); if (State != TransportComponentState.Connected) { - throw LogManager.Log(new InvalidOperationException($"{GetExtendedComponentName()}: Could not send the response while transporter state is {State}.")); + throw LogManager.Log(new InvalidOperationException($"Could not send the request while transporter state is {State}.")); } - LogManager.Log($"{GetExtendedComponentName()}: Searching for matching request token: " + token, LogCategory.Debug); + Subject<MessageContainer> subject = new Subject<MessageContainer>(); - if (_pendingResponses.TryGetValue(token, out pendingResponse)) + LogManager.Log("Expected response: " + responseName, LogCategory.Debug); + + TransportMessage<MessageContainer> message = new TransportMessage<MessageContainer>(container.Token, container, TransportMessageDirection.Request, () => container.ToByteArray(), null) { - LogManager.Log($"{GetExtendedComponentName()}: Found matching request token: " + token, LogCategory.Debug); + IsContinuous = true, + ContinuesResponseSubject = subject, + }; - if (!pendingResponse.IsContinuous) - { - LogManager.Log($"{GetExtendedComponentName()}: Removing matching request token.", LogCategory.Debug); - _pendingResponses.Remove(token); - } - else if (container.Completed) - { - LogManager.Log($"{GetExtendedComponentName()}: Response completed. Removing matching request token.", LogCategory.Debug); - _pendingResponses.Remove(token); - } - } - else + message.ActivateTimeout = () => { - //This should never happen. - throw LogManager.Log(new InvalidOperationException($"{GetExtendedComponentName()}: Matching request token was not found!"), LogCategory.Critical); - } + TimeoutTask.StartNew(() => + { + + if (!message.AtLeastOneResponseReceived) + { + TimeoutException ex = new TimeoutException("Request message: " + requestName + " had timed out after " + (timeout != null ? timeout.Value.TotalSeconds : RequestTimeout.TotalSeconds) + " seconds."); + LogManager.Log(ex); + LogManager.Log("Setting request exception...", LogCategory.Debug); + message.SetException(ex); + } + + if (continuousTimeout != null) + { + Task.Factory.StartNew(async () => + { + while (!message.Completed) + { + await Task.Delay(continuousTimeout.Value).ContinueWith((y) => + { + if (!message.Completed) + { + if (DateTime.Now - message.LastResponseTime > continuousTimeout.Value) + { + TimeoutException ex = new TimeoutException("Continuous request message: " + requestName + " had failed to provide a response for a period of " + (continuousTimeout.Value.TotalSeconds) + " seconds and has timed out."); + LogManager.Log(ex); + LogManager.Log("Setting request exception...", LogCategory.Debug); + message.SetException(ex); + return; + } + } + }); + } + }); + } + + }, timeout != null ? timeout.Value : RequestTimeout); + }; - TaskCompletionSource<object> source = new TaskCompletionSource<object>(); - TransportMessage<object> message = new TransportMessage<object>(token, container, TransportMessageDirection.Response, () => container.ToByteArray(), source); - message.ShouldLog = config.ShouldLog; - message.Immidiate = config.Immediate; - message.Priority = config.Priority; EnqueueMessageOut(message); - return source.Task; + + return subject.AsObservable(); } /// <summary> @@ -1046,156 +778,94 @@ namespace Tango.Transport /// </summary> /// <typeparam name="Response">The type of the response.</typeparam> /// <param name="response">The response.</param> - /// <param name="token">Request token.</param> - /// <param name="config">Response configuration.</param> /// <returns></returns> - /// <exception cref="InvalidOperationException"> - /// Transporter push thread is not in a running state. - /// </exception> - public Task SendResponse<Response>(TangoMessage<Response> response, String token, TransportResponseConfig config = null) where Response : IMessage<Response> + public Task SendResponse<Response>(TangoMessage<Response> response) where Response : IMessage<Response> { - config = config ?? new TransportResponseConfig(); + return SendResponse<Response>(response, response.Container.Token); + } - if (_pushThread == null || _pushThread.ThreadState == System.Threading.ThreadState.Aborted) + /// <summary> + /// Sends a response for the specified token. + /// </summary> + /// <typeparam name="Response">The type of the response.</typeparam> + /// <param name="response">The response.</param> + /// <param name="token">The token.</param> + /// <param name="completed">The completed.</param> + /// <param name="errorCode">The error code.</param> + /// <param name="errorMessage">The error message.</param> + /// <returns></returns> + /// <exception cref="InvalidOperationException">Matching request token was not found!</exception> + public Task SendResponse<Response>(TangoMessage<Response> response, String token, bool? completed = null, ErrorCode? errorCode = null, String errorMessage = null) where Response : IMessage<Response> + { + if (_pushThread == null || _pushThread.ThreadState == ThreadState.Aborted) { throw new InvalidOperationException("Transporter push thread is not in a running state."); } response.Container.Token = token; - response.Container.Completed = config.Completed; + if (completed.HasValue) + { + response.Container.Completed = completed.Value; + } - if (config.ErrorCode.HasValue) + if (errorCode.HasValue) { - response.Container.Error = config.ErrorCode.Value; + response.Container.Error = errorCode.Value; } - if (!String.IsNullOrEmpty(config.ErrorMessage)) + if (!String.IsNullOrEmpty(errorMessage)) { - response.Container.ErrorMessage = config.ErrorMessage; + response.Container.ErrorMessage = errorMessage; } - LogManager.Log($"{GetExtendedComponentName()}: Queuing response message: " + typeof(Response).Name, LogCategory.Debug); + LogManager.Log("Queuing response message: " + typeof(Response).Name, LogCategory.Debug); if (State != TransportComponentState.Connected) { - throw LogManager.Log(new InvalidOperationException($"{GetExtendedComponentName()}: Could not send the response while transporter state is {State}.")); + throw LogManager.Log(new InvalidOperationException($"Could not send the response while transporter state is {State}.")); } PendingResponse pendingResponse = null; - LogManager.Log($"{GetExtendedComponentName()}: Searching for matching request token: " + token, LogCategory.Debug); + LogManager.Log("Searching for matching request token: " + token, LogCategory.Debug); if (_pendingResponses.TryGetValue(token, out pendingResponse)) { - LogManager.Log($"{GetExtendedComponentName()}: Found matching request token: " + token, LogCategory.Debug); + LogManager.Log("Found matching request token: " + token, LogCategory.Debug); if (!pendingResponse.IsContinuous) { - LogManager.Log($"{GetExtendedComponentName()}: Removing matching request token.", LogCategory.Debug); + LogManager.Log("Removing matching request token.", LogCategory.Debug); _pendingResponses.Remove(token); } else if (response.Container.Completed) { - LogManager.Log($"{GetExtendedComponentName()}: Response completed. Removing matching request token.", LogCategory.Debug); + LogManager.Log("Response completed. Removing matching request token.", LogCategory.Debug); _pendingResponses.Remove(token); } } else { //This should never happen. - throw LogManager.Log(new InvalidOperationException($"{GetExtendedComponentName()}: Matching request token was not found!"), LogCategory.Critical); + throw LogManager.Log(new InvalidOperationException("Matching request token was not found!"), LogCategory.Critical); } TaskCompletionSource<object> source = new TaskCompletionSource<object>(); TransportMessage<object> message = new TransportMessage<object>(token, response, TransportMessageDirection.Response, () => Encoder.Encode(response), source); - message.ShouldLog = config.ShouldLog; - message.Immidiate = config.Immediate; - message.Priority = config.Priority; EnqueueMessageOut(message); return source.Task; } /// <summary> - /// Sends a generic response. - /// </summary> - /// <typeparam name="Response">The type of the response.</typeparam> - /// <param name="response">The response.</param> - /// <param name="token">The request token.</param> - /// <param name="config">The response configuration.</param> - /// <returns></returns> - public async Task SendGenericResponse<Response>(Response response, String token, TransportResponseConfig config = null) where Response : class - { - GenericResponse genericResponse = new GenericResponse(); - - genericResponse.Type = response.GetType().AssemblyQualifiedName; - genericResponse.Data = GenericMessageSerializer.SerializeToByteString<Response>(response, GenericProtocol); - await SendResponse<GenericResponse>(genericResponse, token, config); - } - - /// <summary> /// Sends a general error response agnostic to the type of request. /// </summary> /// <param name="exception">The exception.</param> - /// <param name="config">Response configuration.</param> + /// <param name="token">The token.</param> /// <returns></returns> - public Task SendErrorResponse(Exception exception, String token) + public Task SendErrorResponse(Exception exception, string token) { - return SendResponse<ErrorResponse>(new ErrorResponse() { }, token, new TransportResponseConfig() - { - ErrorCode = ErrorCode.GeneralError, - Completed = true, - ErrorMessage = exception.FlattenMessage() - }); - } - - #endregion - - #region Request Handlers - - /// <summary> - /// Registers a custom request handler. - /// </summary> - /// <typeparam name="Request">The type of the request.</typeparam> - /// <param name="callback">The callback.</param> - public void RegisterRequestHandler<Request>(RequestHandlerCallbackDelegate<Request> callback) where Request : class - { - RequestHandler handler = new RequestHandler(); - handler.RequestType = typeof(Request); - handler.RegisteredCallback = callback; - handler.Callback = (transporter, obj, token) => - { - callback?.Invoke(transporter, obj as Request, token); - }; - - _requestHandlers.Add(handler); - } - - /// <summary> - /// Unregisters a custom request handler. - /// </summary> - /// <typeparam name="Request">The type of the request.</typeparam> - /// <param name="callback">The callback.</param> - public void UnregisterRequestHandler<Request>(RequestHandlerCallbackDelegate<Request> callback) where Request : class - { - var handler = _requestHandlers.FirstOrDefault(x => (x.RegisteredCallback as RequestHandlerCallbackDelegate<Request>) == callback); - if (handler != null) - { - _requestHandlers.Remove(handler); - } - } - - /// <summary> - /// Copies this instance request handlers to the specified instance. - /// </summary> - /// <param name="transporter">The transporter to copy the handlers to.</param> - public void CopyRequestHandlers(ITransporter transporter) - { - foreach (var handler in _requestHandlers.ToList()) - { - (transporter as TransporterBase)._requestHandlers.Add(handler); - _requestHandlers.Remove(handler); - } + return SendResponse<ErrorResponse>(new ErrorResponse() { }, token, true, ErrorCode.GeneralError, exception.Message); } #endregion @@ -1207,27 +877,17 @@ namespace Tango.Transport /// </summary> protected void StartThreads() { - try - { - _pullThread = new Thread(PullThreadMethod); - _pullThread.Name = $"{GetExtendedComponentName()} Pull Thread"; - _pullThread.IsBackground = true; - _pullThread.Start(); + _pullThread = new Thread(PullThreadMethod); + _pullThread.IsBackground = true; + _pullThread.Start(); - _pushThread = new Thread(PushThreadMethod); - _pushThread.Name = $"{GetExtendedComponentName()} Push Thread"; - _pushThread.IsBackground = true; - _pushThread.Start(); + _pushThread = new Thread(PushThreadMethod); + _pushThread.IsBackground = true; + _pushThread.Start(); - _keepAliveThread = new Thread(KeepAliveThreadMethod); - _keepAliveThread.Name = $"{GetExtendedComponentName()} KeepAlive Thread"; - _keepAliveThread.IsBackground = true; - _keepAliveThread.Start(); - } - catch (Exception ex) - { - LogManager.Log(ex, "Error starting transporter threads."); - } + _keepAliveThread = new Thread(KeepAliveThreadMethod); + _keepAliveThread.IsBackground = true; + _keepAliveThread.Start(); } /// <summary> @@ -1241,22 +901,12 @@ namespace Tango.Transport } /// <summary> - /// Gets the container timeout or default. - /// </summary> - /// <param name="container">The container.</param> - /// <returns></returns> - private TimeSpan? GetContainerContinuousTimeoutOrDefault(MessageContainer container) - { - return container.ContinuousTimeout > 0 ? TimeSpan.FromMilliseconds(container.ContinuousTimeout) : default(TimeSpan?); - } - - /// <summary> /// Enqueues the message and releases the push wait handle. /// </summary> /// <param name="message">The message.</param> private void EnqueueMessageOut(TransportMessageBase message) { - _sendingQueue.BlockEnqueue(message, message.Priority); + _sendingQueue.BlockEnqueue(message); } /// <summary> @@ -1289,46 +939,31 @@ namespace Tango.Transport { if (message.Token.Length != MESSAGE_TOKEN_LENGTH) { - var ex = LogManager.Log(new InvalidOperationException($"{GetExtendedComponentName()}: Invalid message token length: " + message.Token)); - OnRequestFailed(message, ex); - message.SetException(ex); + message.SetException(LogManager.Log(new InvalidOperationException("Invalid message token length: " + message.Token))); continue; } + LogManager.Log("Sending message on adapter: " + Adapter.Address + "...", LogCategory.Debug, message.Message); + if (message.Direction == TransportMessageDirection.Request) { - if (message.ShouldLog) - { - LogManager.Log($"{GetExtendedComponentName()}: Sending request '{message.GetActualMessageTypeName()}'...\n{message.GetActualMessage().ToJsonString()}", LogCategory.Info); - OnRequestSent(message); - } - lock (_pendingRequests) { _pendingRequests.Add(message); } } - else - { - if (message.ShouldLog) - { - LogManager.Log($"{GetExtendedComponentName()}: Sending response '{message.GetActualMessageTypeName()}'...\n{message.GetActualMessage().ToJsonString()}", LogCategory.Info); - } - } - Adapter.Write(message.Serialize(), message.Immidiate); + Adapter.Write(message.Serialize()); message.ActivateTimeout?.Invoke(); - LogManager.Log($"{GetExtendedComponentName()}: Message sent...", LogCategory.Debug, message.Message); + LogManager.Log("Message sent on adapter: " + Adapter.Address + "...", LogCategory.Debug, message.Message); } else { if (message.Direction == TransportMessageDirection.Request) { - var ex = new InvalidOperationException($"{GetExtendedComponentName()}: Could not send message " + message.GetActualMessageTypeName() + ". Adapter is disconnected."); - OnRequestFailed(message, ex); - message.SetException(ex); + message.SetException(LogManager.Log(new InvalidOperationException("Could not send message " + message.Message.GetType().Name + ". Adapter is disconnected."))); } } @@ -1337,22 +972,15 @@ namespace Tango.Transport message.SetResult(true, true); } } - catch (ThreadAbortException) - { - Exception requestException = FailedStateException != null ? FailedStateException : new TransporterDisconnectedException("The transporter push thread has been aborted."); - OnRequestFailed(message, requestException); - message.SetException(requestException); - } catch (Exception ex) { - OnRequestFailed(message, ex); message.SetException(ex); } } } catch (ThreadAbortException) { - LogManager.Log($"{GetExtendedComponentName()}: Push thread has been aborted."); + LogManager.Log("Push thread has been aborted."); } catch (Exception ex) { @@ -1375,66 +1003,34 @@ namespace Tango.Transport { byte[] data = _arrivedResponses.BlockDequeue(); - LogManager.Log($"{GetExtendedComponentName()}: Message received...", LogCategory.Debug); + LogManager.Log("Message received on adapter: " + Adapter.Address, LogCategory.Debug); - LogManager.Log($"{GetExtendedComponentName()}: Parsing message container...", LogCategory.Debug); + LogManager.Log("Parsing message container...", LogCategory.Debug); + MessageContainer container = Encoder.DecodeContainer(data); - MessageContainer container = null; - - try - { - container = Encoder.DecodeContainer(data); - } - catch (Exception ex) - { - LogManager.Log(ex, $"{GetExtendedComponentName()}: Error parsing message container. Skipping incoming message..."); - continue; - } - - LogManager.Log($"{GetExtendedComponentName()}: Message was identified as " + container.Type + ".", LogCategory.Debug); + LogManager.Log("Message was identified as " + container.Type + ".", LogCategory.Debug); if (container.Token.Length != MESSAGE_TOKEN_LENGTH) { - LogManager.Log($"{GetExtendedComponentName()}: Invalid message token length received: " + container.Token, LogCategory.Error); + LogManager.Log("Invalid message token length received: " + container.Token, LogCategory.Error); continue; } - LogManager.Log($"{GetExtendedComponentName()}: Searching for pending request token: " + container.Token, LogCategory.Debug); + LogManager.Log("Searching for pending request token: " + container.Token, LogCategory.Debug); TransportMessageBase request = null; lock (_pendingRequests) { - try - { - var requests = _pendingRequests.ToList().Where(x => x.Token == container.Token).ToList(); - - try - { - if (requests.Count > 1) - { - LogManager.Log($"{GetExtendedComponentName()}: {requests.Count} requests with the same token were detected - {requests.First().GetActualMessageTypeName()}.", LogCategory.Warning); - } - } - catch (Exception ex) - { - LogManager.Log(ex, LogCategory.Warning, "Something bad happened please investigate."); - } - - request = requests.LastOrDefault(); - } - catch (Exception ex) - { - LogManager.Log(ex, LogCategory.Warning, "Something bad happened please investigate."); - } + request = _pendingRequests.ToList().SingleOrDefault(x => x.Token == container.Token); } if (request != null) { - LogManager.Log($"{GetExtendedComponentName()}: Found pending request: " + request.GetActualMessageTypeName(), LogCategory.Debug); + LogManager.Log("Found pending request: " + (request.Message.GetType().IsGenericType ? request.Message.GetType().GetGenericArguments()[0].Name : request.Message.GetType().Name), LogCategory.Debug); if (!request.IsContinuous) { - LogManager.Log($"{GetExtendedComponentName()}: Pending request was identified as 'single response'. Removing pending request.", LogCategory.Debug); + LogManager.Log("Pending request was identified as 'single response'. Removing pending request.", LogCategory.Debug); _pendingRequests.Remove(request); @@ -1443,54 +1039,23 @@ namespace Tango.Transport if (container.Error == ErrorCode.None) { var message = Encoder.Decode(data); - - if (request.ShouldLog) - { - try - { - String responseType = message.Type.ToString(); - var messageContent = message.GetType().GetProperty("Message").GetValue(message); - - try - { - if (messageContent.GetType() == typeof(GenericResponse)) - { - Type genericType = Type.GetType((messageContent as GenericResponse).Type); - responseType = genericType.Name; - messageContent = GenericMessageSerializer.DeserializeFromByteString(genericType, (messageContent as GenericResponse).Data, GenericProtocol); - } - } - catch { } - - LogManager.Log($"{GetExtendedComponentName()}: Response received '{responseType}'...\n{messageContent.ToJsonString()}", LogCategory.Info); - OnResponseReceived(messageContent as IMessage); - } - catch - { - LogManager.Log("Error logging response received.", LogCategory.Warning); - } - } - - LogManager.Log($"{GetExtendedComponentName()}: Parsing inner response message and setting pending request task result...", LogCategory.Debug, message); + LogManager.Log("Parsing inner response message and setting pending request task result...", LogCategory.Debug, message); request.SetResult(message, true); - LogManager.Log($"{GetExtendedComponentName()}: Message enquirer released...", LogCategory.Debug); + LogManager.Log("Message enquirer released...", LogCategory.Debug); } else { - var ex = new ResponseErrorException(container, request.GetActualMessageTypeName()); - OnRequestFailed(request, ex); - request.SetException(ex); + request.SetException(LogManager.Log(new ResponseErrorException(container), LogCategory.Warning)); } } catch (Exception ex) { - OnRequestFailed(request, ex); - request.SetException(LogManager.Log(ex, $"{GetExtendedComponentName()}: Error parsing response message.")); + request.SetException(LogManager.Log(ex, "Error parsing response message.")); } } else { - LogManager.Log($"{GetExtendedComponentName()}: Pending request was identified as 'continuous response'. keeping pending request.", LogCategory.Debug); + LogManager.Log("Pending request was identified as 'continuous response'. keeping pending request.", LogCategory.Debug); try { @@ -1498,50 +1063,32 @@ namespace Tango.Transport { var message = Encoder.Decode(data); - if (request.ShouldLog && !request.AtLeastOneResponseReceived) - { - try - { - var messageContent = message.GetType().GetProperty("Message").GetValue(message); - LogManager.Log($"{GetExtendedComponentName()}: Response received '{message.Type}'...\n{messageContent.ToJsonString()}", LogCategory.Info); - OnResponseReceived(messageContent as IMessage); - } - catch - { - LogManager.Log("Error logging response received.", LogCategory.Warning); - } - } - - LogManager.Log($"{GetExtendedComponentName()}: Parsing inner response message and invoking continuous response callback...", LogCategory.Debug, message); + LogManager.Log("Parsing inner response message and invoking continuous response callback...", LogCategory.Debug, message); if (container.Completed) { - LogManager.Log($"{GetExtendedComponentName()}: Continuous sequence completed.", LogCategory.Debug); + LogManager.Log("Continuous sequence completed.", LogCategory.Debug); _pendingRequests.Remove(request); } request.SetResult(message, container.Completed); } else if (container.Error == ErrorCode.ContinuousResponseAborted) { - String m = $"{GetExtendedComponentName()}: Continuous response " + container.Type + " has been aborted: " + container.Error.ToString(); + String m = "Continuous response " + container.Type + " has been aborted: " + container.Error.ToString(); LogManager.Log(m, LogCategory.Info); _pendingRequests.Remove(request); - OnRequestFailed(request, new ContinuousResponseAbortedException(container, m)); - request.SetException(new ContinuousResponseAbortedException(container, m)); + request.SetException(new ContinuousResponseAbortedException(m)); } else { - LogManager.Log($"{GetExtendedComponentName()}: Continuous response has returned with error: " + container.Error.ToString(), LogCategory.Warning); + LogManager.Log("Continuous response has returned with error: " + container.Error.ToString(), LogCategory.Warning); _pendingRequests.Remove(request); - - var exx = new ResponseErrorException(container, request.GetActualMessageTypeName()); - OnRequestFailed(request, exx); - request.SetException(exx); + request.SetException(new ResponseErrorException(container)); } } catch (Exception ex) { - LogManager.Log(ex, $"{GetExtendedComponentName()}: Error parsing response message."); + LogManager.Log(ex, "Error parsing response message."); } } @@ -1558,36 +1105,29 @@ namespace Tango.Transport { if (container.Type.ToString().EndsWith("Response")) { - LogManager.Log($"{GetExtendedComponentName()}: A response message with no awaiting request was identified. {container.Type}, Token: {container.Token}. Message ignored.", LogCategory.Warning); + LogManager.Log(String.Format("A response message with no awaiting request was identified. {0}, Token: {1}. Message ignored.", container.Type, container.Token), LogCategory.Warning); continue; } - LogManager.Log($"{GetExtendedComponentName()}: Message was identified as a new request message: " + container.Type.ToString(), LogCategory.Debug); + LogManager.Log("Message was identified as a new request message: " + container.Type.ToString(), LogCategory.Debug); try { - LogManager.Log($"{GetExtendedComponentName()}: Saving request token: " + container.Token, LogCategory.Debug); + LogManager.Log("Saving request token: " + container.Token, LogCategory.Debug); _pendingResponses.Add(container.Token, new PendingResponse(container.Continuous)); if (container.Type == MessageType.KeepAliveRequest && EnableKeepAliveAutoResponse) { - LogManager.Log($"{GetExtendedComponentName()}: Submitting keep alive response...", LogCategory.Debug); - try - { - SendResponse<KeepAliveResponse>(new KeepAliveResponse(), container.Token, new TransportResponseConfig() - { - Priority = QueuePriority.High - }); - } - catch { } + LogManager.Log("Submitting keep alive response...", LogCategory.Debug); + SendResponse<KeepAliveResponse>(new KeepAliveResponse(), container.Token); } else { - LogManager.Log($"{GetExtendedComponentName()}: Invoking RequestReceived event...", LogCategory.Debug, container); + LogManager.Log("Invoking RequestReceived event...", LogCategory.Debug, container); try { - Task.Factory.StartNew(() => OnRequestReceived(new RequestReceivedEventArgs(container))); + Task.Factory.StartNew(() => OnRequestReceived(container)); } catch { @@ -1604,7 +1144,7 @@ namespace Tango.Transport } catch (ThreadAbortException) { - LogManager.Log($"{GetExtendedComponentName()}: Pull thread has been aborted."); + LogManager.Log("Pull thread has been aborted."); } catch (Exception ex) { @@ -1640,24 +1180,12 @@ namespace Tango.Transport if (_arrivedResponses.Count == 0) { retryCounter--; - - if (State == TransportComponentState.Connected) - { - var response = SendRequest<KeepAliveRequest, KeepAliveResponse>(new KeepAliveRequest(), new TransportRequestConfig() - { - Timeout = KeepAliveTimeout, - Priority = QueuePriority.High - }).Result; - retryCounter = KeepAliveRetries; - } - else - { - continue; - } + var response = SendRequest<KeepAliveRequest, KeepAliveResponse>(new KeepAliveRequest(), KeepAliveTimeout).Result; + retryCounter = KeepAliveRetries; } else { - LogManager.Log($"{GetExtendedComponentName()}: Keep alive request was skipped due to busy response queue.", LogCategory.Debug); + LogManager.Log("Keep alive request was skipped due to busy response queue.", LogCategory.Debug); } } } @@ -1682,14 +1210,14 @@ namespace Tango.Transport else { retryCounter = KeepAliveRetries; - LogManager.Log($"{GetExtendedComponentName()}: The transporter has not received a KeepAlive response within the given time, but was rescued due to other message received within the given time.", LogCategory.Warning); + LogManager.Log("The transporter has not received a KeepAlive response within the given time, but was rescued due to other message received within the given time.", LogCategory.Warning); } } } catch (ThreadAbortException) { aborted = true; - LogManager.Log($"{GetExtendedComponentName()}: KeepAlive thread has been aborted."); + LogManager.Log("KeepAlive thread has been aborted."); return; } catch (Exception ex) @@ -1706,7 +1234,7 @@ namespace Tango.Transport } catch (ThreadAbortException) { - LogManager.Log($"{GetExtendedComponentName()}: KeepAlive thread has been aborted."); + LogManager.Log("KeepAlive thread has been aborted."); } } diff --git a/Software/Visual_Studio/Tango.Transport/TransporterDisconnectedException.cs b/Software/Visual_Studio/Tango.Transport/TransporterDisconnectedException.cs deleted file mode 100644 index cb10360a5..000000000 --- a/Software/Visual_Studio/Tango.Transport/TransporterDisconnectedException.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Tango.Transport -{ - public class TransporterDisconnectedException : Exception - { - public TransporterDisconnectedException(String message) : base(message) - { - - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Transporters/BasicTransporter.cs b/Software/Visual_Studio/Tango.Transport/Transporters/BasicTransporter.cs index 745db67ae..06c1f3921 100644 --- a/Software/Visual_Studio/Tango.Transport/Transporters/BasicTransporter.cs +++ b/Software/Visual_Studio/Tango.Transport/Transporters/BasicTransporter.cs @@ -30,7 +30,7 @@ namespace Tango.Transport.Transporters /// </summary> public BasicTransporter() : base() { - ComponentName = $"Basic Transporter {_component_counter++}"; + } /// <summary> diff --git a/Software/Visual_Studio/Tango.Transport/Web/AutoFileDownloader.cs b/Software/Visual_Studio/Tango.Transport/Web/AutoFileDownloader.cs deleted file mode 100644 index 26433bae7..000000000 --- a/Software/Visual_Studio/Tango.Transport/Web/AutoFileDownloader.cs +++ /dev/null @@ -1,123 +0,0 @@ -using Microsoft.WindowsAzure.Storage.Blob; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading.Tasks; -using Tango.Core.IO; - -namespace Tango.Transport.Web -{ - public class AutoFileDownloader : IWebFileDownloader - { - public enum DownloadMode - { - Standard, - Blob - } - - private bool _disposed; - private StorageBlobDownloader _blobDownloader; - private StandardFileDownloader _standardDownloader; - private bool _isCdnOK = false; - private long _fileSize = -1; - - public event EventHandler<WebFileDownloaderProgressEventArgs> Progress; - - public String Address { get; private set; } - - public String FileName { get; private set; } - - public DownloadMode Mode { get; private set; } - - public AutoFileDownloader(String blobAddress, String cdnAddress, String fileName) - { - FileName = fileName; - - _blobDownloader = new StorageBlobDownloader(blobAddress, fileName); - _standardDownloader = new StandardFileDownloader(cdnAddress, fileName); - - _blobDownloader.Progress += OnProgress; - _standardDownloader.Progress += OnProgress; - } - - private void OnProgress(object sender, WebFileDownloaderProgressEventArgs e) - { - Progress?.Invoke(this, e); - } - - public async Task Download() - { - if (_disposed) - { - throw new ObjectDisposedException("The file downloader can only be used once."); - } - - if (_fileSize == -1) - { - await GetFileSize(); - } - - if (_isCdnOK) - { - await _standardDownloader.Download(); - } - else - { - await _blobDownloader.Download(); - } - } - - public async Task ResolveMode() - { - await GetFileSize(); - } - - public Task<long> GetFileSize() - { - if (_fileSize == -1) - { - return Task.Factory.StartNew<long>(() => - { - try - { - _fileSize = _standardDownloader.GetFileSize().Result; - _isCdnOK = true; - Mode = DownloadMode.Standard; - Address = _standardDownloader.Address; - return _fileSize; - } - catch - { - try - { - _fileSize = _blobDownloader.GetFileSize().Result; - Mode = DownloadMode.Blob; - Address = _blobDownloader.Address; - return _fileSize; - } - catch - { - throw new Exception("Invalid address for standard download or blob."); - } - } - }); - } - else - { - return Task.FromResult(_fileSize); - } - } - - public void Dispose() - { - if (!_disposed) - { - _disposed = true; - _blobDownloader.Dispose(); - _standardDownloader.Dispose(); - } - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Web/IWebFileDownloader.cs b/Software/Visual_Studio/Tango.Transport/Web/IWebFileDownloader.cs deleted file mode 100644 index 2f65553d5..000000000 --- a/Software/Visual_Studio/Tango.Transport/Web/IWebFileDownloader.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Tango.Transport.Web -{ - public interface IWebFileDownloader : IDisposable - { - event EventHandler<WebFileDownloaderProgressEventArgs> Progress; - Task Download(); - Task<long> GetFileSize(); - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Web/StandardFileDownloader.cs b/Software/Visual_Studio/Tango.Transport/Web/StandardFileDownloader.cs deleted file mode 100644 index 1b62fc023..000000000 --- a/Software/Visual_Studio/Tango.Transport/Web/StandardFileDownloader.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading.Tasks; - -namespace Tango.Transport.Web -{ - public class StandardFileDownloader : IWebFileDownloader - { - private WebClient _client; - private TaskCompletionSource<object> _completionSource; - - public String Address { get; private set; } - - public String FileName { get; private set; } - - public event EventHandler<WebFileDownloaderProgressEventArgs> Progress; - - public StandardFileDownloader(String address, String fileName) - { - Address = address; - FileName = fileName; - _client = new WebClient(); - _client.Proxy = null; - _client.DownloadProgressChanged += _client_DownloadProgressChanged; - _client.DownloadFileCompleted += _client_DownloadFileCompleted; - - _completionSource = new TaskCompletionSource<object>(); - } - - private void _client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) - { - if (e.Error != null) - { - _completionSource.SetException(e.Error); - } - else - { - _completionSource.SetResult(true); - } - } - - public Task Download() - { - _client.DownloadFileAsync(new Uri(Address), FileName); - return _completionSource.Task; - } - - private void _client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) - { - Progress?.Invoke(this, new WebFileDownloaderProgressEventArgs() - { - Current = e.BytesReceived, - Total = e.TotalBytesToReceive, - }); - } - - public Task<long> GetFileSize() - { - return Task.Factory.StartNew<long>(() => - { - using (var client = new WebClient()) - { - client.OpenRead(Address); - Int64 bytes_total = Convert.ToInt64(client.ResponseHeaders["Content-Length"]); - return bytes_total; - } - }); - } - - public void Dispose() - { - _client.Dispose(); - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Web/StorageBlobDownloader.cs b/Software/Visual_Studio/Tango.Transport/Web/StorageBlobDownloader.cs index dfbd9f93a..603463823 100644 --- a/Software/Visual_Studio/Tango.Transport/Web/StorageBlobDownloader.cs +++ b/Software/Visual_Studio/Tango.Transport/Web/StorageBlobDownloader.cs @@ -9,33 +9,30 @@ using Tango.Core.IO; namespace Tango.Transport.Web { - public class StorageBlobDownloader : IWebFileDownloader + public class StorageBlobDownloader : IDisposable { private bool _disposed; private FileStreamWrapper _stream; private long _fileSize; - private String _fileName; public CloudBlockBlob Blob { get; private set; } - public String Address { get; private set; } - - public event EventHandler<WebFileDownloaderProgressEventArgs> Progress; + public event EventHandler<StorageBlobProgressEventArgs> Progress; public StorageBlobDownloader(CloudBlockBlob blob, String fileName) { Blob = blob; - _fileName = fileName; + _stream = new FileStreamWrapper(fileName, FileMode.Create, OnProgress); } public StorageBlobDownloader(String blobAddress, String fileName) : this(new CloudBlockBlob(new Uri(blobAddress)), fileName) { - Address = blobAddress; + } private void OnProgress(long current) { - Progress?.Invoke(this, new WebFileDownloaderProgressEventArgs() + Progress?.Invoke(this, new StorageBlobProgressEventArgs() { Current = current, Total = _fileSize, @@ -52,8 +49,6 @@ namespace Tango.Transport.Web await Blob.FetchAttributesAsync(); _fileSize = Blob.Properties.Length; - _stream = new FileStreamWrapper(_fileName, FileMode.Create, OnProgress); - await Blob.DownloadToStreamAsync(_stream); Dispose(); } @@ -63,18 +58,8 @@ namespace Tango.Transport.Web if (!_disposed) { _disposed = true; - - if (_stream != null) - { - _stream.Dispose(); - } + _stream.Dispose(); } } - - public async Task<long> GetFileSize() - { - await Blob.FetchAttributesAsync(); - return Blob.Properties.Length; - } } } diff --git a/Software/Visual_Studio/Tango.Transport/Web/WebFileDownloaderProgressEventArgs.cs b/Software/Visual_Studio/Tango.Transport/Web/StorageBlobProgressEventArgs.cs index 570c4058a..ae48e34cf 100644 --- a/Software/Visual_Studio/Tango.Transport/Web/WebFileDownloaderProgressEventArgs.cs +++ b/Software/Visual_Studio/Tango.Transport/Web/StorageBlobProgressEventArgs.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace Tango.Transport.Web { - public class WebFileDownloaderProgressEventArgs : EventArgs + public class StorageBlobProgressEventArgs : EventArgs { public long Total { get; set; } public long Current { get; set; } diff --git a/Software/Visual_Studio/Tango.Transport/Web/StorageBlobStream.cs b/Software/Visual_Studio/Tango.Transport/Web/StorageBlobStream.cs deleted file mode 100644 index f4cbf7f62..000000000 --- a/Software/Visual_Studio/Tango.Transport/Web/StorageBlobStream.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Microsoft.WindowsAzure.Storage.Blob; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Tango.Transport.Web -{ - public class StorageBlobStream : IDisposable - { - public CloudBlockBlob Blob { get; private set; } - private Stream _blobStream; - - public String Address { get; private set; } - - private StorageBlobStream(CloudBlockBlob blob) - { - Blob = blob; - } - - public StorageBlobStream(String blobAddress) : this(new CloudBlockBlob(new Uri(blobAddress))) - { - Address = blobAddress; - } - - public Stream OpenRead() - { - _blobStream = Blob.OpenRead(); - return _blobStream; - } - - public Stream OpenWrite() - { - _blobStream = Blob.OpenWrite(); - return _blobStream; - } - - public void Dispose() - { - _blobStream?.Dispose(); - } - } -} diff --git a/Software/Visual_Studio/Tango.Transport/Web/StorageBlobUploader.cs b/Software/Visual_Studio/Tango.Transport/Web/StorageBlobUploader.cs index 00600c679..8d645f33f 100644 --- a/Software/Visual_Studio/Tango.Transport/Web/StorageBlobUploader.cs +++ b/Software/Visual_Studio/Tango.Transport/Web/StorageBlobUploader.cs @@ -16,7 +16,7 @@ namespace Tango.Transport.Web public CloudBlockBlob Blob { get; private set; } - public event EventHandler<WebFileDownloaderProgressEventArgs> Progress; + public event EventHandler<StorageBlobProgressEventArgs> Progress; public StorageBlobUploader(CloudBlockBlob blob, String fileName) { @@ -31,7 +31,7 @@ namespace Tango.Transport.Web private void OnProgress(long current) { - Progress?.Invoke(this, new WebFileDownloaderProgressEventArgs() + Progress?.Invoke(this, new StorageBlobProgressEventArgs() { Current = current, Total = _stream.Length, diff --git a/Software/Visual_Studio/Tango.Transport/Web/WebTransportClient.cs b/Software/Visual_Studio/Tango.Transport/Web/WebTransportClient.cs index 4d68dbf59..ed2e69468 100644 --- a/Software/Visual_Studio/Tango.Transport/Web/WebTransportClient.cs +++ b/Software/Visual_Studio/Tango.Transport/Web/WebTransportClient.cs @@ -21,12 +21,6 @@ namespace Tango.Transport.Web public string AuthenticationToken { get; set; } - public TimeSpan RequestTimeout - { - get { return _httpClient.Timeout; } - set { _httpClient.Timeout = value; } - } - static WebTransportClient() { _settings = new JsonSerializerSettings() @@ -103,53 +97,30 @@ namespace Tango.Transport.Web } catch (HttpRequestException ex) { - bool handled = false; + String message = JObject.Parse(data).GetValue("Message").ToString(); + Exception exception = null; try { - String message = JObject.Parse(data).GetValue("Message").ToString(); - Exception exception = null; - - try + String exceptionMessage = JObject.Parse(data).GetValue("ExceptionMessage").ToString(); + String exceptionType = JObject.Parse(data).GetValue("ExceptionType").ToString(); + String stackTrace = JObject.Parse(data).GetValue("StackTrace").ToString(); + Type type = GetType(exceptionType); + if (type != null) { - String exceptionMessage = JObject.Parse(data).GetValue("ExceptionMessage").ToString(); - String exceptionType = JObject.Parse(data).GetValue("ExceptionType").ToString(); - String stackTrace = JObject.Parse(data).GetValue("StackTrace").ToString(); - Type type = GetType(exceptionType); - if (type != null) - { - exception = Activator.CreateInstance(type, new object[] { exceptionMessage + "\n" + stackTrace }) as Exception; - - } - else - { - exception = new HttpException(exceptionMessage + "\n" + stackTrace); - } + exception = Activator.CreateInstance(type, new object[] { exceptionMessage + "\n" + stackTrace }) as Exception; } - catch + else { - if (message == null) - { - Logging.LogManager.Default.Log($"Error parsing response message!\n{data}"); - } - - throw new HttpRequestException(ex.Message + " " + message); + exception = new HttpException(exceptionMessage + "\n" + stackTrace); } - - handled = true; - throw exception; } - catch (Exception handledException) + catch { - if (handled) - { - throw handledException; - } - else - { - throw ex; - } + throw new HttpRequestException(ex.Message + " " + message); } + + throw exception; } return JsonConvert.DeserializeObject<Response>(data); diff --git a/Software/Visual_Studio/Tango.Transport/packages.config b/Software/Visual_Studio/Tango.Transport/packages.config index a664d7b49..e1a21695a 100644 --- a/Software/Visual_Studio/Tango.Transport/packages.config +++ b/Software/Visual_Studio/Tango.Transport/packages.config @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <packages> <package id="Google.Protobuf" version="3.4.1" targetFramework="net46" /> - <package id="Microsoft.AspNet.SignalR.Client" version="2.4.1" targetFramework="net461" /> <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" /> <package id="System.Reactive" version="3.1.1" targetFramework="net46" /> <package id="System.Reactive.Core" version="3.1.1" targetFramework="net46" /> |
