/// <summary>
        /// Decode the ADCP data received using a seperate
        /// thread.  This thread will also pass data to all
        /// _observers.
        /// </summary>
        private void ProcessDataThread()
        {
            while (_continue)
            {
                try
                {
                    // Block until awoken when data is received
                    // Timeout every 60 seconds to see if shutdown occured
                    _eventWaitData.WaitOne();

                    // If wakeup was called to kill thread
                    if (!_continue)
                    {
                        return;
                    }

                    // Process all data in the buffer
                    // If the buffer cannot be processed
                    while (_incomingDataBuffer.Remaining() > DataSet.Ensemble.ENSEMBLE_HEADER_LEN)
                    {
                        // Decode the data sent to the codec
                        DecodeIncomingData();

                        // If wakeup was called to kill thread
                        if (!_continue)
                        {
                            return;
                        }
                    }
                }
                catch (ThreadAbortException)
                {
                    // Thread is aborted to stop processing
                    return;
                }
                catch (Exception e)
                {
                    log.Error("Error processing binary codec data.", e);
                    return;
                }

                // Send an event that processing is complete
                if (ProcessDataCompleteEvent != null)
                {
                    ProcessDataCompleteEvent();

                    // Clear the buffer
                    byte[] data = _incomingDataBuffer.ToArray().Skip((int)_incomingDataBuffer.Position).ToArray();
                    _incomingDataBuffer          = new MemoryStreamExtensions(data);
                    _incomingDataBuffer.Position = 0;
                }
            }
        }
        /// <summary>
        /// Clear the incoming buffer of all data.
        /// </summary>
        public void ClearIncomingData()
        {
            // Clear the buffer
            //_incomingDataBuffer = new BlockingCollection<Byte>();
            _incomingDataBuffer          = new MemoryStreamExtensions(1028);
            _incomingDataBuffer.Position = 0;
            _headerStart.Clear();

            lock (_nmeaBufferLock)
            {
                _nmeaBuffer.Clear();
            }
        }
        /// <summary>
        /// Constructor
        /// Initialize values.
        /// </summary>
        public AdcpBinaryCodecForFiles()
        {
            _nmeaBuffer = new LinkedList <string>();

            // Initialize buffer
            //_incomingDataBuffer = new BlockingCollection<Byte>();
            _incomingDataBuffer          = new MemoryStreamExtensions(1028);
            _incomingDataBuffer.Position = 0;
            _headerStart = new List <byte>();

            // Initialize the ensemble size to at least the HDRLEN
            _currentEnsembleSize = DataSet.Ensemble.ENSEMBLE_HEADER_LEN;

            // Initialize the thread
            _continue               = true;
            _eventWaitData          = new EventWaitHandle(false, EventResetMode.AutoReset);
            _processDataThread      = new Thread(ProcessDataThread);
            _processDataThread.Name = "ADCP Binary Codec";
            _processDataThread.Start();
        }
        /// <summary>
        /// Decode the ADCP data received using a seperate
        /// thread.  This thread will also pass data to all
        /// _observers.
        /// </summary>
        private void ProcessDataThread()
        {
            while (_continue)
            {
                try
                {
                    // Block until awoken when data is received
                    // Timeout every 60 seconds to see if shutdown occured
                    _eventWaitData.WaitOne();

                    // If wakeup was called to kill thread
                    if (!_continue)
                    {
                        return;
                    }

                    // Process all data in the buffer
                    // If the buffer cannot be processed
                    while (_incomingDataBuffer.Remaining() > DataSet.Ensemble.ENSEMBLE_HEADER_LEN)
                    {
                        // Decode the data sent to the codec
                        DecodeIncomingData();

                        // If wakeup was called to kill thread
                        if (!_continue)
                        {
                            return;
                        }
                    }
                }
                catch (ThreadAbortException)
                {
                    // Thread is aborted to stop processing
                    return;
                }
                catch (Exception e)
                {
                    log.Error("Error processing binary codec data.", e);
                    return;
                }

                // Send an event that processing is complete
                if (ProcessDataCompleteEvent != null)
                {
                    ProcessDataCompleteEvent();

                    // Clear the buffer
                    byte[] data = _incomingDataBuffer.ToArray().Skip((int)_incomingDataBuffer.Position).ToArray();
                    _incomingDataBuffer = new MemoryStreamExtensions(data);
                    _incomingDataBuffer.Position = 0;
                }
            }
        }
        /// <summary>
        /// Clear the incoming buffer of all data.
        /// </summary>
        public void ClearIncomingData()
        {
            // Clear the buffer
            //_incomingDataBuffer = new BlockingCollection<Byte>();
            _incomingDataBuffer = new MemoryStreamExtensions(1028);
            _incomingDataBuffer.Position = 0;
            _headerStart.Clear();

            lock (_nmeaBufferLock)
            {
                _nmeaBuffer.Clear();
            }
        }
        /// <summary>
        /// Constructor
        /// Initialize values.
        /// </summary>
        public AdcpBinaryCodecForFiles()
        {
            _nmeaBuffer = new LinkedList<string>();

            // Initialize buffer
            //_incomingDataBuffer = new BlockingCollection<Byte>();
            _incomingDataBuffer = new MemoryStreamExtensions(1028);
            _incomingDataBuffer.Position = 0;
            _headerStart = new List<byte>();

            // Initialize the ensemble size to at least the HDRLEN
            _currentEnsembleSize = DataSet.Ensemble.ENSEMBLE_HEADER_LEN;

            // Initialize the thread
            _continue = true;
            _eventWaitData = new EventWaitHandle(false, EventResetMode.AutoReset);
            _processDataThread = new Thread(ProcessDataThread);
            _processDataThread.Name = "ADCP Binary Codec";
            _processDataThread.Start();
        }