-
Notifications
You must be signed in to change notification settings - Fork 1
/
filerange.d
90 lines (76 loc) · 1.42 KB
/
filerange.d
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
module util.filerange;
import std.mmfile;
auto fileRange(ByteType = ubyte)(string file) {
import std.traits;
static if(is(ByteType == ubyte)) {
FileRange!ByteType fr;
fr.file = new MmFile(file);
fr.end = fr.file.length;
return fr;
} else
static if(isSomeChar!ByteType) {
UtfFileRange!ByteType u8fr;
u8fr.fr.file = new MmFile(file);
u8fr.fr.end = u8fr.fr.file.length;
u8fr.prime();
return u8fr;
} else
static assert(false, "Supported FileRange bytes: ubyte, dchar, wchar, char");
}
struct UtfFileRange(C) {
FileRange!C fr;
dchar cur;
@property auto empty() {
return cur == dchar.init;
}
auto popFront() {
assert(!empty, "Popping front of empty range");
if(fr.empty) {
cur = dchar.init;
return;
}
prime();
}
auto prime() {
import std.utf;
cur = fr.decodeFront;
}
auto front() {
return cur;
}
auto save() {
return this;
}
}
struct FileRange(ByteType = ubyte) {
private:
ulong index;
ulong end;
MmFile file;
public:
@property auto empty() {
assert(index <= end);
return index == end;
}
auto popFront() {
index++;
}
auto front() {
return cast(ByteType)file[index];
}
@property ulong length() {
return end - index;
}
auto opSlice(size_t x, size_t y) {
import core.exception;
import std.exception;
enforceEx!RangeError(y+index <= end);
FileRange fr = this;
fr.end = y + index;
fr.index += x;
return fr;
}
@property auto save() {
return this;
}
}