1014 lines · 44.4 KB · C#
RawDownload
        DefaultValue(DefaultAutoRepeat),        Description("Indicates whether receiving (reading) of data is to be repeated endlessly.")]        public bool AutoRepeat        {            get            {                return m_autoRepeat;            }            set            {                if (value && m_fileAccessMode == FileAccess.ReadWrite)                    throw new InvalidOperationException("AutoRepeat cannot be enabled when FileAccessMode is FileAccess.ReadWrite");                 m_autoRepeat = value;            }        }         /// <summary>        /// Gets or sets a boolean value that indicates whether receiving (reading) of data will be initiated manually by calling <see cref="ReadNextBuffer"/>.        /// </summary>        /// <remarks>        /// <see cref="ReceiveInterval"/> will be set to -1 when <see cref="ReceiveOnDemand"/> is enabled.        /// </remarks>        [Category("Data"),        DefaultValue(DefaultReceiveOnDemand),        Description("Indicates whether receiving (reading) of data will be initiated manually by calling ReceiveData().")]        public bool ReceiveOnDemand        {            get            {                return m_receiveOnDemand;            }            set            {                m_receiveOnDemand = value;                 if (m_receiveOnDemand)                    // We'll disable receiving data at a set interval if user wants to receive data on demand.                    m_receiveInterval = -1;            }        }         /// <summary>        /// Gets or sets the number of milliseconds to pause before receiving (reading) the next available set of data.        /// </summary>        /// <remarks>        /// Set <see cref="ReceiveInterval"/> = -1 to receive (read) data continuously without pausing.        /// </remarks>        [Category("Data"),        DefaultValue(DefaultReceiveInterval),        Description("The number of milliseconds to pause before receiving (reading) the next available set of data. Set ReceiveInterval = -1 to receive data continuously without pausing.")]        public double ReceiveInterval        {            get            {                return m_receiveInterval;            }            set            {                if (value < 1)                    m_receiveInterval = -1;                else                    m_receiveInterval = value;            }        }         /// <summary>        /// Gets or sets the starting point relative to the beginning of the file from where the data is to be received (read).        /// </summary>        /// <exception cref="ArgumentException">The value being assigned is not a positive number.</exception>        [Category("File"),        DefaultValue(DefaultStartingOffset),        Description("The starting point relative to the beginning of the file from where the data is to be received (read).")]        public long StartingOffset        {            get            {                return m_startingOffset;            }            set            {                if (value < 0)                    throw new ArgumentException("Value must be positive");                 m_startingOffset = value;            }        }         /// <summary>        /// Gets or sets the <see cref="FileMode"/> value to be used when opening the file.        /// </summary>        [Category("File"),        DefaultValue(DefaultFileOpenMode),        Description("The System.IO.FileMode value to be used when opening the file.")]        public FileMode FileOpenMode        {            get            {                return m_fileOpenMode;            }            set            {                m_fileOpenMode = value;            }        }         /// <summary>        /// Gets or set the <see cref="FileShare"/> value to be used when opening the file.        /// </summary>        [Category("File"),        DefaultValue(DefaultFileShareMode),        Description("The System.IO.FileShare value to be used when opening the file.")]        public FileShare FileShareMode        {            get            {                return m_fileShareMode;            }            set            {                m_fileShareMode = value;            }        }         /// <summary>        /// Gets or sets the <see cref="FileAccess"/> value to be used when opening the file.        /// </summary>        /// <exception cref="InvalidOperationException"><see cref="FileAccessMode"/> is set to <see cref="FileAccess.ReadWrite"/> when <see cref="AutoRepeat"/> is enabled.</exception>        [Category("File"),        DefaultValue(DefaultFileAccessMode),        Description("The System.IO.FileAccess value to be used when opening the file.")]        public FileAccess FileAccessMode        {            get            {                return m_fileAccessMode;            }            set            {                if (value == FileAccess.ReadWrite && m_autoRepeat)                    throw new InvalidOperationException("FileAccessMode cannot be set to FileAccess.ReadWrite when AutoRepeat is enabled");                 m_fileAccessMode = value;            }        }         /// <summary>        /// Gets the <see cref="TransportProvider{FileStream}"/> object for the <see cref="FileClient"/>.        /// </summary>        [Browsable(false)]        public TransportProvider<FileStream> Client        {            get            {                return m_fileClient;            }        }         /// <summary>        /// Gets the server URI of the <see cref="FileClient"/>.        /// </summary>        [Browsable(false)]        public override string ServerUri        {            get            {                return string.Format("{0}://{1}", TransportProtocol, m_connectData["file"]).ToLower();            }        }         #endregion         #region [ Methods ]         /// <summary>        /// Reads a number of bytes from the current received data buffer and writes those bytes into a byte array at the specified offset.        /// </summary>        /// <param name="buffer">Destination buffer used to hold copied bytes.</param>        /// <param name="startIndex">0-based starting index into destination <paramref name="buffer"/> to begin writing data.</param>        /// <param name="length">The number of bytes to read from current received data buffer and write into <paramref name="buffer"/>.</param>        /// <returns>The number of bytes read.</returns>        /// <remarks>        /// This function should only be called from within the <see cref="ClientBase.ReceiveData"/> event handler. Calling this method outside        /// this event will have unexpected results.        /// </remarks>        /// <exception cref="InvalidOperationException">No received data buffer has been defined to read.</exception>        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>        /// <exception cref="ArgumentOutOfRangeException">        /// <paramref name="startIndex"/> or <paramref name="length"/> is less than 0 -or-         /// <paramref name="startIndex"/> and <paramref name="length"/> will exceed <paramref name="buffer"/> length.        /// </exception>        public override int Read(byte[] buffer, int startIndex, int length)        {            buffer.ValidateParameters(startIndex, length);             if ((object)m_fileClient.ReceiveBuffer != null)            {                int sourceLength = m_fileClient.BytesReceived - ReadIndex;                int readBytes = length > sourceLength ? sourceLength : length;                Buffer.BlockCopy(m_fileClient.ReceiveBuffer, ReadIndex, buffer, startIndex, readBytes);                 // Update read index for next call                ReadIndex += readBytes;                 if (ReadIndex >= m_fileClient.BytesReceived)                    ReadIndex = 0;                 return readBytes;            }             throw new InvalidOperationException("No received data buffer has been defined to read.");        }         /// <summary>        /// Reads next data buffer from the <see cref="FileStream"/>.        /// </summary>        /// <exception cref="InvalidOperationException"><see cref="ReadNextBuffer"/> is called when <see cref="FileClient"/> is not connected.</exception>        /// <exception cref="InvalidOperationException"><see cref="ReadNextBuffer"/> is called when <see cref="ReceiveOnDemand"/> is disabled.</exception>        public void ReadNextBuffer()        {            if (m_receiveOnDemand)            {                if (CurrentState == ClientState.Connected)                    ReadData();                else                    throw new InvalidOperationException("Client is currently not connected");            }            else            {                throw new InvalidOperationException("ReadNextBuffer() cannot be used when ReceiveOnDemand is disabled");            }        }         /// <summary>        /// Disconnects the <see cref="FileClient"/> from the <see cref="FileStream"/>.        /// </summary>        public override void Disconnect()        {            if (CurrentState != ClientState.Disconnected)            {                m_fileClient.Reset();                m_receiveDataTimer.Stop();                 if (m_connectionThread != null)                    m_connectionThread.Abort();                 OnConnectionTerminated();            }        }         /// <summary>        /// Connects the <see cref="FileClient"/> to the <see cref="FileStream"/> asynchronously.        /// </summary>        /// <exception cref="InvalidOperationException">Attempt is made to connect the <see cref="FileClient"/> when it is not disconnected.</exception>        /// <returns><see cref="WaitHandle"/> for the asynchronous operation.</returns>        public override WaitHandle ConnectAsync()        {            m_connectionHandle = (ManualResetEvent)base.ConnectAsync();             m_fileClient.SetReceiveBuffer(ReceiveBufferSize); #if ThreadTracking            m_connectionThread = new ManagedThread(OpenFile);            m_connectionThread.Name = "TVA.Communication.FileClient.OpenFile()";#else            m_connectionThread = new Thread(OpenFile);#endif            m_connectionThread.Start();             return m_connectionHandle;        }         /// <summary>        /// Saves <see cref="FileClient"/> settings to the config file if the <see cref="ClientBase.PersistSettings"/> property is set to true.        /// </summary>        public override void SaveSettings()        {            base.SaveSettings();            //if (PersistSettings)            //{            //    // Save settings under the specified category.            //    ConfigurationFile config = ConfigurationFile.Current;            //    CategorizedSettingsElementCollection settings = config.Settings[SettingsCategory];            //    settings["AutoRepeat", true].Update(m_autoRepeat);            //    settings["ReceiveOnDemand", true].Update(m_receiveOnDemand);            //    settings["ReceiveInterval", true].Update(m_receiveInterval);            //    settings["StartingOffset", true].Update(m_startingOffset);            //    settings["FileOpenMode", true].Update(m_fileOpenMode);            //    settings["FileShareMode", true].Update(m_fileShareMode);            //    settings["FileAccessMode", true].Update(m_fileAccessMode);            //    config.Save();            //}        }         /// <summary>        /// Loads saved <see cref="FileClient"/> settings from the config file if the <see cref="ClientBase.PersistSettings"/> property is set to true.        /// </summary>        public override void LoadSettings()        {            base.LoadSettings();            //if (PersistSettings)            //{            //    // Load settings from the specified category.            //    ConfigurationFile config = ConfigurationFile.Current;            //    CategorizedSettingsElementCollection settings = config.Settings[SettingsCategory];            //    settings.Add("AutoRepeat", m_autoRepeat, "True if receiving (reading) of data is to be repeated endlessly, otherwise False.");            //    settings.Add("ReceiveOnDemand", m_receiveOnDemand, "True if receiving (reading) of data will be initiated manually, otherwise False.");            //    settings.Add("ReceiveInterval", m_receiveInterval, "Number of milliseconds to pause before receiving (reading) the next available set of data.");            //    settings.Add("StartingOffset", m_startingOffset, "Starting point relative to the beginning of the file from where the data is to be received (read).");            //    settings.Add("FileOpenMode", m_fileOpenMode, "Open mode (CreateNew; Create; Open; OpenOrCreate; Truncate; Append) to be used when opening the file.");            //    settings.Add("FileShareMode", m_fileShareMode, "Share mode (None; Read; Write; ReadWrite; Delete; Inheritable) to be used when opening the file.");            //    settings.Add("FileAccessMode", m_fileAccessMode, "Access mode (Read; Write; ReadWrite) to be used when opening the file.");            //    AutoRepeat = settings["AutoRepeat"].ValueAs(m_autoRepeat);            //    ReceiveOnDemand = settings["ReceiveOnDemand"].ValueAs(m_receiveOnDemand);            //    ReceiveInterval = settings["ReceiveInterval"].ValueAs(m_receiveInterval);            //    StartingOffset = settings["StartingOffset"].ValueAs(m_startingOffset);            //    FileOpenMode = settings["FileOpenMode"].ValueAs(m_fileOpenMode);            //    FileShareMode = settings["FileShareMode"].ValueAs(m_fileShareMode);            //    FileAccessMode = settings["FileAccessMode"].ValueAs(m_fileAccessMode);            //}        }         /// <summary>        /// Releases the unmanaged resources used by the <see cref="FileClient"/> and optionally releases the managed resources.        /// </summary>        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>        protected override void Dispose(bool disposing)        {            if (!m_disposed)            {                try                {                    // This will be done regardless of whether the object is finalized or disposed.                    if (disposing)                    {                        // This will be done only when the object is disposed by calling Dispose().                        if (m_connectionHandle != null)                            m_connectionHandle.Close();                         if (m_receiveDataTimer != null)                        {                            m_receiveDataTimer.Elapsed -= m_receiveDataTimer_Elapsed;                            m_receiveDataTimer.Dispose();                        }                    }                }                finally                {                    m_disposed = true;          // Prevent duplicate dispose.                    base.Dispose(disposing);    // Call base class Dispose().                }            }        }         /// <summary>        /// Validates the specified <paramref name="connectionString"/>.        /// </summary>        /// <param name="connectionString">Connection string to be validated.</param>        /// <exception cref="ArgumentException">File property is missing.</exception>        protected override void ValidateConnectionString(string connectionString)        {            m_connectData = connectionString.ParseKeyValuePairs();             if (!m_connectData.ContainsKey("file"))                throw new ArgumentException(string.Format("File property is missing (Example: {0})", DefaultConnectionString));        }         /// <summary>        /// Sends (writes) data to the file asynchronously.        /// </summary>        /// <param name="data">The buffer that contains the binary data to be sent (written).</param>        /// <param name="offset">The zero-based position in the <paramref name="data"/> at which to begin sending (writing) data.</param>        /// <param name="length">The number of bytes to be sent (written) from <paramref name="data"/> starting at the <paramref name="offset"/>.</param>        /// <returns><see cref="WaitHandle"/> for the asynchronous operation.</returns>        protected override WaitHandle SendDataAsync(byte[] data, int offset, int length)        {            WaitHandle handle;             // Send data to the file asynchronously.            handle = m_fileClient.Provider.BeginWrite(data, offset, length, SendDataAsyncCallback, null).AsyncWaitHandle;             // Notify that the send operation has started.            m_fileClient.Statistics.UpdateBytesSent(length);            OnSendDataStart();             // Return the async handle that can be used to wait for the async operation to complete.            return handle;        }         /// <summary>        /// Callback method for asynchronous send operation.        /// </summary>        private void SendDataAsyncCallback(IAsyncResult asyncResult)        {            try            {                // Send operation is complete.                m_fileClient.Provider.EndWrite(asyncResult);                OnSendDataComplete();            }            catch (Exception ex)            {                // Send operation failed to complete.                OnSendDataException(ex);            }        }         /// <summary>        /// Connects to the <see cref="FileStream"/>.        /// </summary>        private void OpenFile()        {            int connectionAttempts = 0;            while (MaxConnectionAttempts == -1 || connectionAttempts < MaxConnectionAttempts)            {                try                {                    OnConnectionAttempt();                     // Open the file.                    m_fileClient.Provider = new FileStream(FilePath.GetAbsolutePath(m_connectData["file"]), m_fileOpenMode, m_fileAccessMode, m_fileShareMode);                     // Move to the specified offset.                    m_fileClient.Provider.Seek(m_startingOffset, SeekOrigin.Begin);                     m_connectionHandle.Set();                    OnConnectionEstablished();                     if (!m_receiveOnDemand)                    {                        if (m_receiveInterval > 0)                        {                            // Start receiving data at interval.                            m_receiveDataTimer.Interval = m_receiveInterval;                            m_receiveDataTimer.Start();                        }                        else                        {                            // Start receiving data continuously.                            while (true)                            {                                ReadData();         // Read all available data.                                Thread.Sleep(1000); // Wait for more data to be available.                            }                        }                    }                     break;  // We're done here.                }                catch (ThreadAbortException)                {                    // Exit gracefully.                    break;                }                catch (Exception ex)                {                    // Keep retrying connecting to the file.                    Thread.Sleep(1000);                    connectionAttempts++;                    OnConnectionException(ex);                }            }        }         /// <summary>        /// Receive (reads) data from the <see cref="FileStream"/>.        /// </summary>        private void ReadData()        {            try            {                // Process the entire file content                while (m_fileClient.Provider.Position < m_fileClient.Provider.Length)                {                    // Retrieve data from the file.                    m_fileClient.BytesReceived = m_fileClient.Provider.Read(m_fileClient.ReceiveBuffer, 0, m_fileClient.ReceiveBufferSize);                    m_fileClient.Statistics.UpdateBytesReceived(m_fileClient.BytesReceived);                     // Notify of the retrieved data.                    OnReceiveDataComplete(m_fileClient.ReceiveBuffer, m_fileClient.BytesReceived);                     // Re-read the file if the user wants to repeat when done reading the file.                    if (m_autoRepeat && m_fileClient.Provider.Position == m_fileClient.Provider.Length)                    {                        m_fileClient.Provider.Seek(m_startingOffset, SeekOrigin.Begin);                    }                     // Stop processing the file if user has either opted to receive data on demand or receive data at a predefined interval.                    if (m_receiveOnDemand || m_receiveInterval > 0)                    {                        break;                    }                }            }            catch (ThreadAbortException)            {                // Exit gracefully.            }            catch (Exception ex)            {

Lines 501–1000 of 1014. Previous lines

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t