Jump to content

FIFO memory buffer

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
1 reply to this topic

#1
eagle123

eagle123

    Newbie

  • Members
  • Pip
  • 1 posts
It's purpose is to be an in-memory stream class that acts as a FIFO buffer. The first you write to it is the first **** that you get when you read from it. It needs to be thread safe.

It works for awhile, but after enough random reads/writes it gets thrown off and starts returning data out of order.



using System;

using System.Collections.Generic;

using System.Text;

using System.IO;


namespace Turbzy.IO

{

    public class FifoStream : Stream

    {

        private const double GROWTH_FACTOR = 1.5;


        private byte[] _buffer;

        private int _index;

        private int _length;


        public FifoStream()

            : this(8192)

        {

        }


        public FifoStream(int initialCapacity)

        {

            _buffer = new byte[initialCapacity];

        }


        void ResizeBuffer(int length)

        {

            if (length > _buffer.Length)

            {


                byte[] newbuffer = new byte[(int)(length * GROWTH_FACTOR)];


                int first = Math.Min(_length, (_buffer.Length - _index));

                int second = _length - first;


                Buffer.BlockCopy(_buffer, _index, newbuffer, 0, first);

                if (second > 0)

                    Buffer.BlockCopy(_buffer, 0, newbuffer, first, second);


                _index = 0;

                _buffer = newbuffer;

            }

        }


        public override int Read(byte[] buffer, int offset, int length)

        {

            lock (this)

            {

                length = Math.Min(length, _length);


                if ((_index + _length) > _buffer.Length)

                {

                    int fromIndex = Math.Min(_buffer.Length - _index, length);

                    int fromBeginning = length - fromIndex;


                    Buffer.BlockCopy(_buffer, _index, buffer, offset, fromIndex);

                    Buffer.BlockCopy(_buffer, 0, buffer, offset + fromIndex, fromBeginning);

                }

                else

                {

                    Buffer.BlockCopy(_buffer, _index, buffer, offset, length);

                }


                _length -= length;

                _index = (_index + length) % _buffer.Length;


                return length;

            }

        }


        public override void Write(byte[] buffer, int offset, int length)

        {

            lock (this)

            {

                ResizeBuffer(_length + length);


                int startFrom = (_index + _length) % _buffer.Length;


                if ((_index + _length + length) > _buffer.Length)

                {

                    int firstChunk = Math.Min(_buffer.Length - startFrom, length);

                    int secondChunk = length - firstChunk;


                    Buffer.BlockCopy(buffer, offset, _buffer, startFrom, firstChunk);

                    if (secondChunk > 0)

                        Buffer.BlockCopy(buffer, offset + firstChunk, _buffer, 0, secondChunk);

                }

                else

                {

                    Buffer.BlockCopy(buffer, offset, _buffer, startFrom, length);

                }


                _length += length;

            }

        }


        public byte PeekByte(int offset)

        {

            return _buffer[(_index + offset) % _buffer.Length];

        }


        /* i don't care about this bull**** 


        public override bool CanRead

        {

            get { return true; }

        }


        public override bool CanSeek

        {

            get { return false; }

        }


        public override bool CanWrite

        {

            get { return true; }

        }


        public override void Flush()

        {

            throw new NotImplementedException();

        }


        public override long Length

        {

            get { return _length; }

        }


        public override long Position

        {

            get

            {

                throw new NotImplementedException();

            }

            set

            {

                throw new NotImplementedException();

            }

        }


        public override long Seek(long offset, SeekOrigin origin)

        {

            throw new NotImplementedException();

        }


        public override void SetLength(long value)

        {

            throw new NotImplementedException();

        }

         

        */

    }

}


#2
lobo521

lobo521

    Learning Programmer

  • Members
  • PipPipPip
  • 57 posts
Using Queue class in C#