Skip to content

Commit 9591ae2

Browse files
committed
Set up ITextReader methods for handling strings.
1 parent 27cd679 commit 9591ae2

5 files changed

Lines changed: 574 additions & 0 deletions
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
namespace schema.text.reader;
2+
3+
public partial interface ITextReader : ITextStream, IDataReader {
4+
bool Matches(string match);
5+
6+
string ReadUpToStartOfTerminator(string terminator);
7+
string ReadUpToAndPastTerminator(string terminator);
8+
9+
string ReadWhile(string match);
10+
11+
void SkipOnceIfPresent(string match);
12+
void SkipManyIfPresent(string match);
13+
14+
byte[] ReadBytes(string separator, string terminator);
15+
16+
byte?[] ReadBytesIncludingEmpty(string separator,
17+
string terminator);
18+
19+
byte[] ReadHexBytes(string separator, string terminator);
20+
byte?[] ReadHexBytesIncludingEmpty(string separator, string terminator);
21+
22+
sbyte[] ReadSBytes(string separator,
23+
string terminator);
24+
25+
sbyte?[] ReadSBytesIncludingEmpty(string separator, string terminator);
26+
27+
sbyte[] ReadHexSBytes(string separator, string terminator);
28+
sbyte?[] ReadHexSBytesIncludingEmpty(string separator, string terminator);
29+
30+
short[] ReadInt16s(string separator, string terminator);
31+
short?[] ReadInt16sIncludingEmpty(string separator, string terminator);
32+
33+
short[] ReadHexInt16s(string separator, string terminator);
34+
short?[] ReadHexInt16sIncludingEmpty(string separator, string terminator);
35+
36+
ushort[] ReadUInt16s(string separator, string terminator);
37+
ushort?[] ReadUInt16sIncludingEmpty(string separator, string terminator);
38+
39+
ushort[] ReadHexUInt16s(string separator, string terminator);
40+
ushort?[] ReadHexUInt16sIncludingEmpty(string separator, string terminator);
41+
42+
int[] ReadInt32s(string separator, string terminator);
43+
int?[] ReadInt32sIncludingEmpty(string separator, string terminator);
44+
45+
int[] ReadHexInt32s(string separator, string terminator);
46+
int?[] ReadHexInt32sIncludingEmpty(string separator, string terminator);
47+
48+
uint[] ReadUInt32s(string separator, string terminator);
49+
uint?[] ReadUInt32sIncludingEmpty(string separator, string terminator);
50+
51+
uint[] ReadHexUInt32s(string separator, string terminator);
52+
uint?[] ReadHexUInt32sIncludingEmpty(string separator, string terminator);
53+
54+
long[] ReadInt64s(string separator, string terminator);
55+
long?[] ReadInt64sIncludingEmpty(string separator, string terminator);
56+
57+
long[] ReadHexInt64s(string separator,
58+
string terminator);
59+
60+
long?[] ReadHexInt64sIncludingEmpty(string separator,
61+
string terminator);
62+
63+
ulong[] ReadUInt64s(string separator,
64+
string terminator);
65+
66+
ulong?[] ReadUInt64sIncludingEmpty(string separator,
67+
string terminator);
68+
69+
ulong[] ReadHexUInt64s(string separator,
70+
string terminator);
71+
72+
ulong?[] ReadHexUInt64sIncludingEmpty(string separator,
73+
string terminator);
74+
75+
float[] ReadSingles(string separator,
76+
string terminator);
77+
78+
float?[] ReadSinglesIncludingEmpty(string separator,
79+
string terminator);
80+
81+
double[] ReadDoubles(string separator,
82+
string terminator);
83+
84+
double?[] ReadDoublesIncludingEmpty(string separator,
85+
string terminator);
86+
87+
string[] ReadStrings(string separator,
88+
string terminator);
89+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
using System;
2+
using System.Text;
3+
4+
5+
namespace schema.text.reader;
6+
7+
public sealed partial class SchemaTextReader {
8+
public bool Matches(string match) {
9+
var originalLineNumber = this.LineNumber;
10+
var originalIndexInLine = this.IndexInLine;
11+
var originalPosition = this.PositionInternal_;
12+
13+
var maxLength = match.Length;
14+
15+
var readLength =
16+
Math.Min(maxLength, this.Length - this.PositionInternal_);
17+
Span<char> peeked = stackalloc char[(int) readLength];
18+
this.ReadChars(peeked);
19+
20+
this.LineNumber = originalLineNumber;
21+
this.IndexInLine = originalIndexInLine;
22+
this.PositionInternal_ = originalPosition;
23+
24+
for (var j = 0; j < match.Length; ++j) {
25+
if (match[j] != peeked[j]) {
26+
return false;
27+
}
28+
}
29+
30+
this.Position += match.Length;
31+
return true;
32+
}
33+
34+
public string ReadUpToStartOfTerminator(string terminator) {
35+
var sb = new StringBuilder();
36+
37+
while (!this.Eof) {
38+
var originalLineNumber = this.LineNumber;
39+
var originalIndexInLine = this.IndexInLine;
40+
var originalPosition = this.PositionInternal_;
41+
42+
if (this.Matches(terminator)) {
43+
this.LineNumber = originalLineNumber;
44+
this.IndexInLine = originalIndexInLine;
45+
this.PositionInternal_ = originalPosition;
46+
break;
47+
}
48+
49+
sb.Append(this.ReadChar());
50+
}
51+
52+
return sb.ToString();
53+
}
54+
55+
public string ReadUpToAndPastTerminator(string terminator) {
56+
var sb = new StringBuilder();
57+
58+
while (!this.Eof) {
59+
if (this.Matches(terminator)) {
60+
break;
61+
}
62+
63+
sb.Append(this.ReadChar());
64+
}
65+
66+
return sb.ToString();
67+
}
68+
69+
public string ReadWhile(string match) {
70+
var sb = new StringBuilder();
71+
72+
while (!this.Eof && this.Matches(match)) {
73+
sb.Append(match);
74+
}
75+
76+
return sb.ToString();
77+
}
78+
79+
public void SkipManyIfPresent(string match) {
80+
while (!this.Eof && this.Matches(match)) { }
81+
}
82+
83+
public void SkipOnceIfPresent(string match) => this.Matches(match);
84+
}
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
using schema.util.strings;
6+
7+
8+
namespace schema.text.reader;
9+
10+
public sealed partial class SchemaTextReader {
11+
public byte?[] ReadBytesIncludingEmpty(string separators,
12+
string terminators)
13+
=> this.ConvertSplitUpToAndPastTerminatorsIncludingEmpty_(separators,
14+
terminators,
15+
this.ConvertByte_);
16+
17+
public byte?[] ReadHexBytesIncludingEmpty(string separators,
18+
string terminators)
19+
=> this.ConvertSplitUpToAndPastHexTerminatorsIncludingEmpty_(separators,
20+
terminators,
21+
this.ConvertHexByte_);
22+
23+
24+
public sbyte?[] ReadSBytesIncludingEmpty(string separators,
25+
string terminators)
26+
=> this.ConvertSplitUpToAndPastTerminatorsIncludingEmpty_(separators,
27+
terminators,
28+
this.ConvertSByte_);
29+
30+
public sbyte?[] ReadHexSBytesIncludingEmpty(string separators,
31+
string terminators)
32+
=> this.ConvertSplitUpToAndPastHexTerminatorsIncludingEmpty_(separators,
33+
terminators,
34+
this.ConvertHexSByte_);
35+
36+
37+
public short?[] ReadInt16sIncludingEmpty(string separators,
38+
string terminators)
39+
=> this.ConvertSplitUpToAndPastTerminatorsIncludingEmpty_(separators,
40+
terminators,
41+
this.ConvertInt16_);
42+
43+
public short?[] ReadHexInt16sIncludingEmpty(string separators,
44+
string terminators)
45+
=> this.ConvertSplitUpToAndPastHexTerminatorsIncludingEmpty_(separators,
46+
terminators,
47+
this.ConvertHexInt16_);
48+
49+
50+
public ushort?[] ReadUInt16sIncludingEmpty(string separators,
51+
string terminators)
52+
=> this.ConvertSplitUpToAndPastTerminatorsIncludingEmpty_(separators,
53+
terminators,
54+
this.ConvertUInt16_);
55+
56+
public ushort?[] ReadHexUInt16sIncludingEmpty(
57+
string separators,
58+
string terminators)
59+
=> this.ConvertSplitUpToAndPastHexTerminatorsIncludingEmpty_(separators,
60+
terminators,
61+
this.ConvertHexUInt16_);
62+
63+
64+
public int?[] ReadInt32sIncludingEmpty(string separators,
65+
string terminators)
66+
=> this.ConvertSplitUpToAndPastTerminatorsIncludingEmpty_(separators,
67+
terminators,
68+
this.ConvertInt32_);
69+
70+
71+
public int?[] ReadHexInt32sIncludingEmpty(string separators,
72+
string terminators)
73+
=> this.ConvertSplitUpToAndPastHexTerminatorsIncludingEmpty_(separators,
74+
terminators,
75+
this.ConvertHexInt32_);
76+
77+
public uint?[] ReadUInt32sIncludingEmpty(string separators,
78+
string terminators)
79+
=> this.ConvertSplitUpToAndPastTerminatorsIncludingEmpty_(separators,
80+
terminators,
81+
this.ConvertUInt32_);
82+
83+
public uint?[] ReadHexUInt32sIncludingEmpty(string separators,
84+
string terminators)
85+
=> this.ConvertSplitUpToAndPastHexTerminatorsIncludingEmpty_(separators,
86+
terminators,
87+
this.ConvertHexUInt32_);
88+
89+
public long?[] ReadInt64sIncludingEmpty(string separators,
90+
string terminators)
91+
=> this.ConvertSplitUpToAndPastTerminatorsIncludingEmpty_(separators,
92+
terminators,
93+
this.ConvertInt64_);
94+
95+
public long?[] ReadHexInt64sIncludingEmpty(string separators,
96+
string terminators)
97+
=> this.ConvertSplitUpToAndPastHexTerminatorsIncludingEmpty_(separators,
98+
terminators,
99+
this.ConvertHexInt64_);
100+
101+
102+
public ulong?[] ReadUInt64sIncludingEmpty(string separators,
103+
string terminators)
104+
=> this.ConvertSplitUpToAndPastTerminatorsIncludingEmpty_(separators,
105+
terminators,
106+
this.ConvertUInt64_);
107+
108+
109+
public ulong?[] ReadHexUInt64sIncludingEmpty(
110+
string separators,
111+
string terminators)
112+
=> this.ConvertSplitUpToAndPastHexTerminatorsIncludingEmpty_(separators,
113+
terminators,
114+
this.ConvertHexUInt64_);
115+
116+
117+
public float?[] ReadSinglesIncludingEmpty(string separators,
118+
string terminators)
119+
=> this.ConvertSplitUpToAndPastTerminatorsIncludingEmpty_(separators,
120+
terminators,
121+
this.ConvertSingle_);
122+
123+
public double?[] ReadDoublesIncludingEmpty(string separators,
124+
string terminators)
125+
=> this.ConvertSplitUpToAndPastTerminatorsIncludingEmpty_(separators,
126+
terminators,
127+
this.ConvertDouble_);
128+
129+
130+
private IEnumerable<string> ReadSplitUpToAndPastTerminatorsIncludingEmpty_(
131+
string separators,
132+
string terminators) {
133+
var match = this.ReadUpToAndPastTerminator(terminators);
134+
if (match.Length == 0) {
135+
return [];
136+
}
137+
138+
return match.SplitViaChar(separators, true);
139+
}
140+
141+
private T?[] ConvertSplitUpToAndPastTerminatorsIncludingEmpty_<T>(
142+
string separators,
143+
string terminators,
144+
Func<string, T> converter) where T : struct
145+
=> this.ReadSplitUpToAndPastTerminatorsIncludingEmpty_(
146+
separators,
147+
terminators)
148+
.Select(t => {
149+
var start = 0;
150+
151+
int i;
152+
for (i = 0; i < t.Length; ++i) {
153+
var c = t[i];
154+
if (c is '\t' or ' ' or '\r' or '\n') {
155+
start++;
156+
}
157+
}
158+
159+
if (t.Length - start == 0) {
160+
return null;
161+
}
162+
163+
return start == 0 ? t : t.Substring(start);
164+
})
165+
.Select(text => text != null ? converter(text) : (T?) null)
166+
.ToArray();
167+
168+
private T?[] ConvertSplitUpToAndPastHexTerminatorsIncludingEmpty_<T>(
169+
string separators,
170+
string terminators,
171+
Func<string, T> converter) where T : struct
172+
=> this.ReadSplitUpToAndPastTerminatorsIncludingEmpty_(
173+
separators,
174+
terminators)
175+
.Select(t => {
176+
var start = 0;
177+
178+
int i;
179+
for (i = 0; i < t.Length; ++i) {
180+
var c = t[i];
181+
if (c is '\t' or ' ' or '\r' or '\n') {
182+
start++;
183+
} else {
184+
break;
185+
}
186+
}
187+
188+
if (t.Length - start == 0) {
189+
return (T?) null;
190+
}
191+
192+
if (t[i] == '0' && i < t.Length - 1 && t[i + 1] == 'x') {
193+
start += 2;
194+
}
195+
196+
return converter(start == 0 ? t : t.Substring(start));
197+
})
198+
.ToArray();
199+
}

0 commit comments

Comments
 (0)