-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathLookaheadTextReader.cs
More file actions
113 lines (68 loc) · 2.59 KB
/
LookaheadTextReader.cs
File metadata and controls
113 lines (68 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
using Gsemac.Collections;
using System;
using System.IO;
using System.Text;
namespace Gsemac.IO {
public class LookaheadTextReader :
TextReader {
// Public members
public LookaheadTextReader(Stream stream) :
this(new StreamReader(stream)) {
}
public LookaheadTextReader(Stream stream, Encoding encoding) :
this(new StreamReader(stream, encoding)) {
}
public LookaheadTextReader(string value) :
this(new StringReader(value)) {
}
public LookaheadTextReader(TextReader reader) {
this.reader = reader;
}
public override int Read() {
if (peekBuffer.Length > 0)
return peekBuffer.Read();
return reader.Read();
}
public override int Read(char[] buffer, int index, int count) {
int charsRead = 0;
if (peekBuffer.Length > 0) {
charsRead += peekBuffer.Read(buffer, index, count);
index += charsRead;
count -= charsRead;
}
if (count > 0)
charsRead += reader.Read(buffer, index, count);
return charsRead;
}
public override int Peek() {
if (peekBuffer.Length > 0)
return peekBuffer.Peek();
return reader.Peek();
}
public int Peek(char[] buffer, int index, int count) {
// Read the requested number of chars into the peek buffer.
// We only need to read enough that the buffer's length is equal to or greater than count.
EnsurePeekBufferFilled(count);
// Copy from the peek buffer to the output buffer.
int charsReadFromPeekBuffer = Math.Min(count, buffer.Length);
for (int i = 0; i < charsReadFromPeekBuffer; ++i)
buffer[index + i] = peekBuffer[i];
return charsReadFromPeekBuffer;
}
public override void Close() {
reader.Close();
base.Close();
}
// Private members
private readonly TextReader reader;
private readonly CircularBuffer<char> peekBuffer = new CircularBuffer<char>();
private void EnsurePeekBufferFilled(int count) {
if (peekBuffer.Length < count) {
int charsRequired = count - peekBuffer.Length;
char[] temp = new char[charsRequired];
int charsRead = reader.Read(temp, 0, charsRequired);
peekBuffer.Write(temp, 0, charsRead);
}
}
}
}