TextScanner.cs
61 lines
| 1.4 KiB
| text/x-csharp
|
CSharpLexer
|
|
r173 | using System; | ||
| using Implab.Components; | ||||
| namespace Implab.Formats { | ||||
| public abstract class TextScanner<TTag> : Disposable { | ||||
|
|
r174 | readonly int[] m_buffer; | ||
| int m_bufferOffset; | ||||
| int m_dataLength; | ||||
|
|
r173 | int m_tokenLength; | ||
|
|
r174 | |||
|
|
r173 | TTag[] m_tags; | ||
| BufferScanner<TTag> m_scanner; | ||||
| protected bool ReadTokenInternal() { | ||||
| if (EOF) | ||||
| return false; | ||||
|
|
r174 | // create a new scanner from template (scanners are value types) | ||
|
|
r173 | var inst = m_scanner; | ||
|
|
r174 | m_tokenLength = 0; | ||
| while (inst.Scan(m_buffer, m_bufferOffset, m_dataLength)) { | ||||
| m_tokenLength += m_dataLength; | ||||
| var actual = Read(m_buffer, 0, m_buffer.Length); | ||||
| m_bufferOffset = 0; | ||||
| m_dataLength = actual; | ||||
|
|
r173 | |||
|
|
r174 | if (actual == 0) { | ||
| inst.Eof(); | ||||
| break; | ||||
| } | ||||
| } | ||||
| var len = inst.Position - m_bufferOffset; | ||||
| m_tokenLength += len; | ||||
| m_dataLength -= len; | ||||
| m_bufferOffset = inst.Position; | ||||
|
|
r173 | |||
| // save result; | ||||
|
|
r174 | |||
|
|
r173 | m_tags = inst.GetTokenTags(); | ||
| } | ||||
|
|
r174 | protected abstract int Read(int[] buffer, int offset, int size); | ||
|
|
r173 | |||
| protected TTag[] Tags { | ||||
| get { | ||||
| return m_tags; | ||||
| } | ||||
| } | ||||
| public abstract bool EOF { get; } | ||||
|
|
r174 | |||
|
|
r173 | } | ||
| } | ||||
