Exemplo n.º 1
0
        /// <summary>
        /// Reads data from this stream
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public override int Read(byte[] buffer, int offset, int count)
        {
            lock (this)
            {
                // 1. attempt to fill the circular buffer with enough data to meet our request
                while (BufferEndPosition < position + count)
                {
                    int sourceReadCount = count;
                    if (sourceReadCount % sourceStream.BlockAlign != 0)
                    {
                        sourceReadCount = (count + sourceStream.BlockAlign) - (count % sourceStream.BlockAlign);
                    }

                    int sourceRead = sourceStream.Read(GetSourceBuffer(sourceReadCount), 0, sourceReadCount);
                    circularBuffer.Write(GetSourceBuffer(sourceReadCount), 0, sourceRead);
                    if (sourceRead == 0)
                    {
                        // assume we have run out of data
                        break;
                    }
                }

                // 2. discard any unnecessary stuff from the start
                if (bufferStartPosition < position)
                {
                    circularBuffer.Advance((int)(position - bufferStartPosition));
                    bufferStartPosition = position;
                }

                // 3. now whatever is in the buffer we can return
                int bytesRead = circularBuffer.Read(buffer, offset, count);
                position += bytesRead;
                // anything left in buffer is at start position
                bufferStartPosition = position;

                return(bytesRead);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Reads bytes from this stream
        /// </summary>
        /// <param name="array">Buffer to read into</param>
        /// <param name="offset">Offset in array to read into</param>
        /// <param name="count">Number of bytes to read</param>
        /// <returns>Number of bytes read</returns>
        public override int Read(byte[] array, int offset, int count)
        {
            int bytesRead = 0;

            if (count % BlockAlign != 0)
            {
                //throw new ApplicationException("Must read complete blocks");
                count -= (count % BlockAlign);
            }

            while (bytesRead < count)
            {
                int destBytesRequired = count - bytesRead;
                int sourceBytes       = DestToSource(destBytesRequired);

                sourceBytes = Math.Min(conversionStream.SourceBuffer.Length, sourceBytes);
                // temporary fix for alignment problems
                // TODO: a better solution is to save any extra we convert for the next read

                /* MRH: ignore this for now - need to check ramifications
                 * if (DestToSource(SourceToDest(sourceBytes)) != sourceBytes)
                 * {
                 *  if (bytesRead == 0)
                 *      throw new ApplicationException("Not a one-to-one conversion");
                 *  break;
                 * }*/

                int sourceBytesRead = sourceStream.Read(conversionStream.SourceBuffer, 0, sourceBytes);
                if (sourceBytesRead == 0)
                {
                    break;
                }
                int silenceBytes = 0;
                if (sourceBytesRead % sourceStream.BlockAlign != 0)
                {
                    // we have been returned something that cannot be converted - a partial
                    // buffer. We will increase the size we supposedly read, and zero out
                    // the end.
                    sourceBytesRead -= (sourceBytesRead % sourceStream.BlockAlign);
                    sourceBytesRead += sourceStream.BlockAlign;
                    silenceBytes     = SourceToDest(sourceStream.BlockAlign);
                }

                int sourceBytesConverted;
                int bytesConverted = conversionStream.Convert(sourceBytesRead, out sourceBytesConverted);
                if (sourceBytesConverted < sourceBytesRead)
                {
                    // MRH: would normally throw an exception here
                    // back up - is this the right thing to do, not sure
                    sourceStream.Position -= (sourceBytesRead - sourceBytesConverted);
                }

                if (bytesConverted > 0)
                {
                    position += bytesConverted;
                    int availableSpace = array.Length - bytesRead - offset;
                    int toCopy         = Math.Min(bytesConverted, availableSpace);
                    //System.Diagnostics.Debug.Assert(toCopy == bytesConverted);
                    // TODO: save leftovers
                    Array.Copy(conversionStream.DestBuffer, 0, array, bytesRead + offset, toCopy);
                    bytesRead += toCopy;
                    if (silenceBytes > 0)
                    {
                        // clear out the final bit
                        Array.Clear(array, bytesRead - silenceBytes, silenceBytes);
                    }
                }
                else
                {
                    break;
                }
            }
            return(bytesRead);
        }