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