1 module dlangui.core.textsource;
2
3 private import std.utf;
4 private import std.array;
5
6 /**
7 * Source file information.
8 * Even if contains only file name, it's better to use it instead of string - object reference size is twice less than array ref.
9 */
10 class SourceFile {
11 protected string _filename;
12 @property string filename() { return _filename; }
13 public this(string filename) {
14 _filename = filename;
15 }
16 override @property string toString() const {
17 return _filename;
18 }
19 }
20
21 /// source lines for tokenizer
22 interface SourceLines {
23 /// source file
24 @property SourceFile file();
25 /// last read line
26 @property uint line();
27 /// source encoding
28 //@property EncodingType encoding() { return _encoding; }
29 /// error code
30 @property int errorCode();
31 /// error message
32 @property string errorMessage();
33 /// error line
34 @property int errorLine();
35 /// error position
36 @property int errorPos();
37 /// end of file reached
38 @property bool eof();
39
40 /// read line, return null if EOF reached or error occured
41 dchar[] readLine();
42 }
43
44 const TEXT_SOURCE_ERROR_EOF = 1;
45
46 /// Simple text source based on array
47 class ArraySourceLines : SourceLines {
48 protected SourceFile _file;
49 protected uint _line;
50 protected uint _firstLine;
51 protected dstring[] _lines;
52 static __gshared protected dchar[] _emptyLine = ""d.dup;
53
54 this() {
55 }
56
57 this(dstring[] lines, SourceFile file, uint firstLine = 0) {
58 initialize(lines, file, firstLine);
59 }
60
61 this(string code, string filename) {
62 _lines = (toUTF32(code)).split("\n");
63 _file = new SourceFile(filename);
64 }
65
66 void close() {
67 _lines = null;
68 _line = 0;
69 _firstLine = 0;
70 _file = null;
71 }
72
73 void initialize(dstring[] lines, SourceFile file, uint firstLine = 0) {
74 _lines = lines;
75 _firstLine = firstLine;
76 _line = 0;
77 _file = file;
78 }
79
80 bool reset(int line) {
81 _line = line;
82 return true;
83 }
84
85 /// end of file reached
86 override @property bool eof() {
87 return _line >= _lines.length;
88 }
89 /// source file
90 override @property SourceFile file() { return _file; }
91 /// last read line
92 override @property uint line() { return _line + _firstLine; }
93 /// source encoding
94 //@property EncodingType encoding() { return _encoding; }
95 /// error code
96 override @property int errorCode() { return 0; }
97 /// error message
98 override @property string errorMessage() { return ""; }
99 /// error line
100 override @property int errorLine() { return 0; }
101 /// error position
102 override @property int errorPos() { return 0; }
103
104 /// read line, return null if EOF reached or error occured
105 override dchar[] readLine() {
106 if (_line < _lines.length) {
107 if (_lines[_line])
108 return cast(dchar[])_lines[_line++];
109 _line++;
110 return _emptyLine;
111 }
112 return null; // EOF
113 }
114 }
115