Stream

“Stream” avançado para leitura de strings

A um tempo atras tive a necessidade de implementar uma classe semelhante à System.IO.StringReader, só que mais avançada.

Fiz isso no vb.net, porém acabei nunca usando. Recentemente precisei usa-la em c#, e portanto, realizei a conversão. Não testei muito afundo, por isso se encontrarem algum bug, por favor comentem para que eu possa corrigi-lo.

Segue o código da classe, que é compatível inclusive com projetos do tipo Portable Library (ou seja, funcionará em qualquer plataforma que rode o .Net Framework):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HL
{
    public class TextReader : IDisposable
    {

        #region "Constructor"

        public TextReader(string Str)
        {
            _Buffer = Str.ToCharArray();
            _Lenght = _Buffer.Length;
            _Position = 0;
        }

        public TextReader(System.IO.TextReader TextReader)
        {
            _Buffer = TextReader.ReadToEnd().ToCharArray();
            _Lenght = _Buffer.Length;
            _Position = 0;
        }

        public TextReader(System.IO.Stream Stream)
        {
            System.IO.StreamReader StreamReader = new System.IO.StreamReader(Stream);
            _Buffer = StreamReader.ReadToEnd().ToCharArray();
            _Lenght = _Buffer.Length;
            _Position = 0;
        }

        public TextReader(System.IO.Stream Stream, System.Text.Encoding Encoding)
        {
            System.IO.StreamReader StreamReader = new System.IO.StreamReader(Stream, Encoding);
            _Buffer = StreamReader.ReadToEnd().ToCharArray();
            _Lenght = _Buffer.Length;
            _Position = 0;
        }

        #endregion

        #region "Fields"

        private char[] _Buffer;

        private long _Lenght;

        private long _Position;

        #endregion

        #region "Properties"

        public long Lenght
        {
            get { return _Lenght; }
        }

        public char[] Buffer
        {
            get { return _Buffer; }
        }

        public long Position
        {
            get { return _Position; }
            set
            {
                if (value > _Lenght | value < 0)
                    throw new ArgumentOutOfRangeException("Value");
                _Position = value;
            }
        }

        public bool EndOfStream
        {
            get { return Position == _Lenght; }
        }

        public char NextChar
        {
            get
            {
                if (_Position > (_Lenght - 1))
                {
                    return (char)0;
                }
                else
                {
                    return _Buffer[_Position];
                }
            }
        }

        public char PreviousChar
        {
            get
            {
                if ((_Position - 2) < 0)
                {
                    return (char)0;
                }
                else
                {
                    return _Buffer[_Position - 2];
                }
            }
        }

        #endregion

        #region "Methods"

        public char Read()
        {
            if (EndOfStream)
                return (char)0;
            Position += 1;
            return Buffer[Position - 1];
        }

        public string Read(int Count)
        {
            if (EndOfStream)
                return null;
            System.Text.StringBuilder strBuilder = new System.Text.StringBuilder(Count);
            for (int i = 0; i <= Count; i++)
            {
                char chr = this.Read();
                if (chr != (char)0)
                {
                    strBuilder.Append(chr);
                }
                else
                {
                    break;
                }
            }
            return strBuilder.ToString();
        }

        public char Peek()
        {
            return NextChar;
        }

        public string Peek(int Count)
        {
            if (EndOfStream)
                return null;
            System.Text.StringBuilder strBuilder = new System.Text.StringBuilder(Count);
            for (long i = Position ; i < (Position + Count); i++)
            {
                if (i > (_Lenght - 1))
                    break;
                char chr = _Buffer[i];
                if (chr != (char)0)
                {
                    strBuilder.Append(chr);
                }
                else
                {
                    break;
                }
            }
            return strBuilder.ToString();
        }

        public char PeekBack()
        {
            return PreviousChar;
        }

        public string PeekBack(int Count)
        {
            if (EndOfStream)
                return null;
            System.Text.StringBuilder strBuilder = new System.Text.StringBuilder(Count);
            long start = (Position - 2) - Count;
            if (start < 0)
                start = 0;
            for (long i = start; i < (Position - 2); i++)
            {
                strBuilder.Append(_Buffer[i]);
            }
            return strBuilder.ToString();
        }

        public void Close()
        {
            _Buffer = null;
            _Position = (char)0;
            _Lenght = (char)0;
        }

        public void Dispose()
        {
            this.Close();
        }

        #endregion
    }
}

Minha classe segue, basicamente, o conceito dos Streams. Ela possui uma propriedade EndOfStream que indica quando chegamos no fim do arquivo, neste caso, da string.

Possui um método Peek, para espiar qual é o próximo caractere sem alterar a posição do Stream. E assim por diante…

Se descobrirem algum erro no código comentem para que eu possa conserta-lo.

Anúncios