diff 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 diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Formats/TextScanner.cs	Tue Mar 15 02:11:06 2016 +0300
@@ -0,0 +1,72 @@
+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; }
+
+    }
+}
+