173
|
1 using System;
|
|
2 using Implab.Components;
|
|
3
|
|
4 namespace Implab.Formats {
|
|
5 public abstract class TextScanner<TTag> : Disposable {
|
|
6
|
174
|
7 readonly int[] m_buffer;
|
|
8 int m_bufferOffset;
|
|
9 int m_dataLength;
|
173
|
10 int m_tokenLength;
|
174
|
11
|
173
|
12 TTag[] m_tags;
|
|
13
|
|
14 BufferScanner<TTag> m_scanner;
|
|
15
|
|
16 protected bool ReadTokenInternal() {
|
|
17 if (EOF)
|
|
18 return false;
|
|
19
|
174
|
20 // create a new scanner from template (scanners are value types)
|
173
|
21 var inst = m_scanner;
|
|
22
|
174
|
23 m_tokenLength = 0;
|
|
24
|
|
25 while (inst.Scan(m_buffer, m_bufferOffset, m_dataLength)) {
|
|
26 m_tokenLength += m_dataLength;
|
|
27
|
|
28 var actual = Read(m_buffer, 0, m_buffer.Length);
|
|
29
|
|
30 m_bufferOffset = 0;
|
|
31 m_dataLength = actual;
|
173
|
32
|
174
|
33 if (actual == 0) {
|
|
34 inst.Eof();
|
|
35 break;
|
|
36 }
|
|
37 }
|
|
38
|
|
39 var len = inst.Position - m_bufferOffset;
|
|
40 m_tokenLength += len;
|
|
41 m_dataLength -= len;
|
|
42 m_bufferOffset = inst.Position;
|
173
|
43
|
|
44 // save result;
|
174
|
45
|
173
|
46 m_tags = inst.GetTokenTags();
|
|
47 }
|
|
48
|
174
|
49 protected abstract int Read(int[] buffer, int offset, int size);
|
173
|
50
|
|
51 protected TTag[] Tags {
|
|
52 get {
|
|
53 return m_tags;
|
|
54 }
|
|
55 }
|
|
56
|
|
57 public abstract bool EOF { get; }
|
174
|
58
|
173
|
59 }
|
|
60 }
|
|
61
|