173
|
1 using System;
|
|
2 using Implab.Components;
|
|
3
|
|
4 namespace Implab.Formats {
|
|
5 public abstract class TextScanner<TTag> : Disposable {
|
|
6
|
|
7 char[] m_buffer;
|
|
8 int m_offset;
|
|
9 int m_length;
|
|
10 int m_tokenOffset;
|
|
11 int m_tokenLength;
|
|
12 TTag[] m_tags;
|
|
13
|
|
14 BufferScanner<TTag> m_scanner;
|
|
15
|
|
16 protected bool ReadTokenInternal() {
|
|
17 if (EOF)
|
|
18 return false;
|
|
19
|
|
20 // create a new scanner from template (scanners are structs)
|
|
21 var inst = m_scanner;
|
|
22
|
|
23 // initialize the scanner
|
|
24 inst.Init(m_buffer, m_offset, m_length);
|
|
25
|
|
26 // do work
|
|
27 while (inst.Scan())
|
|
28 Feed(ref inst);
|
|
29
|
|
30 // save result;
|
|
31 m_buffer = inst.Buffer;
|
|
32 m_length = inst.Length;
|
|
33 m_offset = inst.Position;
|
|
34 m_tokenOffset = inst.TokenOffset;
|
|
35 m_tokenLength = inst.TokenLength;
|
|
36
|
|
37 m_tags = inst.GetTokenTags();
|
|
38 }
|
|
39
|
|
40 protected string GetToken() {
|
|
41 return new String(m_buffer, m_tokenOffset, m_tokenLength);
|
|
42 }
|
|
43
|
|
44 protected TTag[] Tags {
|
|
45 get {
|
|
46 return m_tags;
|
|
47 }
|
|
48 }
|
|
49
|
|
50 /// <summary>
|
|
51 /// Feed the specified scanner.
|
|
52 /// </summary>
|
|
53 /// <param name="scanner">Scanner.</param>
|
|
54 /// <example>
|
|
55 /// protected override void Feed(ref BufferScanner<TTag> scanner) {
|
|
56 /// var size = scanner.Extend();
|
|
57 /// var actual = m_reader.Read(scanner.Buffer, scanner.HiMark, size);
|
|
58 /// if (actual == 0) {
|
|
59 /// m_eof = true;
|
|
60 /// scanner.Eof();
|
|
61 /// } else {
|
|
62 /// scanner.RaiseHiMark(actual);
|
|
63 /// }
|
|
64 /// }
|
|
65 /// </example>
|
|
66 protected abstract void Feed(ref BufferScanner<TTag> scanner);
|
|
67
|
|
68 public abstract bool EOF { get; }
|
|
69
|
|
70 }
|
|
71 }
|
|
72
|