view Implab/Formats/TextScanner.cs @ 173:ecfece82ca11 ref20160224

Working on text scanner
author cin
date Tue, 15 Mar 2016 02:11:06 +0300
parents
children 983df35b3ca1
line wrap: on
line source

using System;
using Implab.Components;

namespace Implab.Formats {
    public abstract class TextScanner<TTag> : Disposable {

        char[] m_buffer;
        int m_offset;
        int m_length;
        int m_tokenOffset;
        int m_tokenLength;
        TTag[] m_tags;

        BufferScanner<TTag> m_scanner;

        protected bool ReadTokenInternal() {
            if (EOF)
                return false;
            
            // create a new scanner from template (scanners are structs)
            var inst = m_scanner;

            // initialize the scanner
            inst.Init(m_buffer, m_offset, m_length);

            // do work
            while (inst.Scan())
                Feed(ref inst);

            // save result;
            m_buffer = inst.Buffer;
            m_length = inst.Length;
            m_offset = inst.Position;
            m_tokenOffset = inst.TokenOffset;
            m_tokenLength = inst.TokenLength;

            m_tags = inst.GetTokenTags();
        }

        protected string GetToken() {
            return new String(m_buffer, m_tokenOffset, m_tokenLength);
        }

        protected TTag[] Tags {
            get {
                return m_tags; 
            }
        }

        /// <summary>
        /// Feed the specified scanner.
        /// </summary>
        /// <param name="scanner">Scanner.</param>
        /// <example>
        /// protected override void Feed(ref BufferScanner<TTag> scanner) {
        ///     var size = scanner.Extend();
        ///     var actual = m_reader.Read(scanner.Buffer, scanner.HiMark, size);
        ///     if (actual == 0) {
        ///         m_eof = true;
        ///         scanner.Eof();
        ///     } else {
        ///         scanner.RaiseHiMark(actual);
        ///     }
        /// }
        /// </example>
        protected abstract void Feed(ref BufferScanner<TTag> scanner);

        public abstract bool EOF { get; }

    }
}