Subversion Repositories Kolibri OS

Rev

Rev 7696 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7983 leency 1
(*
7597 akron1 2
    BSD 2-Clause License
3
 
7696 akron1 4
    Copyright (c) 2018-2019, Anton Krotov
7597 akron1 5
    All rights reserved.
6
*)
7
 
8
MODULE TEXTDRV;
9
 
10
IMPORT FILES, C := COLLECTIONS;
11
 
12
 
13
CONST
14
 
15
    CR = 0DX; LF = 0AX;
16
 
17
    CHUNK = 1024 * 256;
18
 
19
 
20
TYPE
21
 
22
    TEXT* = POINTER TO RECORD (C.ITEM)
23
 
7696 akron1 24
        chunk:        ARRAY CHUNK OF CHAR;
7597 akron1 25
        pos, size:    INTEGER;
26
        file:         FILES.FILE;
27
        utf8:         BOOLEAN;
28
        CR:           BOOLEAN;
29
 
30
        line*, col*:  INTEGER;
31
        eof*:         BOOLEAN;
32
        eol*:         BOOLEAN;
7693 akron1 33
        peak*:        CHAR
7597 akron1 34
 
35
    END;
36
 
37
 
38
VAR
39
 
40
    texts: C.COLLECTION;
41
 
42
 
43
PROCEDURE load (text: TEXT);
44
BEGIN
45
    IF ~text.eof THEN
46
        text.size := FILES.read(text.file, text.chunk, LEN(text.chunk));
47
        text.pos := 0;
48
        IF text.size = 0 THEN
49
            text.eof := TRUE;
7696 akron1 50
            text.chunk[0] := 0X
7693 akron1 51
        END;
7696 akron1 52
        text.peak := text.chunk[0]
7597 akron1 53
    END
54
END load;
55
 
56
 
7693 akron1 57
PROCEDURE next* (text: TEXT);
7597 akron1 58
VAR
59
    c: CHAR;
7693 akron1 60
 
7597 akron1 61
BEGIN
62
    IF text.pos < text.size - 1 THEN
7693 akron1 63
        INC(text.pos);
7696 akron1 64
        text.peak := text.chunk[text.pos]
7597 akron1 65
    ELSE
66
        load(text)
67
    END;
68
 
69
    IF ~text.eof THEN
70
 
7693 akron1 71
        c := text.peak;
7597 akron1 72
 
73
        IF c = CR THEN
74
            INC(text.line);
7693 akron1 75
            text.col := 0;
76
            text.eol := TRUE;
77
            text.CR  := TRUE
7597 akron1 78
        ELSIF c = LF THEN
79
            IF ~text.CR THEN
80
                INC(text.line);
7693 akron1 81
                text.col := 0;
82
                text.eol := TRUE
7597 akron1 83
            ELSE
7693 akron1 84
                text.eol := FALSE
7597 akron1 85
            END;
86
            text.CR := FALSE
87
        ELSE
88
            text.eol  := FALSE;
89
            IF text.utf8 THEN
7696 akron1 90
                IF ORD(c) DIV 64 # 2 THEN
7597 akron1 91
                    INC(text.col)
92
                END
93
            ELSE
94
                INC(text.col)
95
            END;
96
            text.CR := FALSE
97
        END
98
 
99
    END
100
 
101
END next;
102
 
103
 
104
PROCEDURE init (text: TEXT);
105
BEGIN
106
    IF (text.pos = 0) & (text.size >= 3) THEN
7696 akron1 107
        IF (text.chunk[0] = 0EFX) &
108
           (text.chunk[1] = 0BBX) &
109
           (text.chunk[2] = 0BFX) THEN
7597 akron1 110
            text.pos := 3;
111
            text.utf8 := TRUE
112
        END
113
    END;
114
 
115
    IF text.size = 0 THEN
7696 akron1 116
        text.chunk[0] := 0X;
7597 akron1 117
        text.size := 1;
118
        text.eof := FALSE
119
    END;
120
 
121
    text.line := 1;
7693 akron1 122
    text.col  := 1;
7597 akron1 123
 
7696 akron1 124
    text.peak := text.chunk[text.pos]
7597 akron1 125
END init;
126
 
127
 
7693 akron1 128
PROCEDURE close* (VAR text: TEXT);
7597 akron1 129
BEGIN
7693 akron1 130
    IF text # NIL THEN
131
        IF text.file # NIL THEN
132
            FILES.close(text.file)
133
        END;
7597 akron1 134
 
7693 akron1 135
        C.push(texts, text);
136
        text := NIL
7597 akron1 137
    END
7693 akron1 138
END close;
7597 akron1 139
 
140
 
7693 akron1 141
PROCEDURE open* (name: ARRAY OF CHAR): TEXT;
7597 akron1 142
VAR
7693 akron1 143
    text: TEXT;
7597 akron1 144
    citem: C.ITEM;
145
 
146
BEGIN
147
    citem := C.pop(texts);
148
    IF citem = NIL THEN
149
        NEW(text)
150
    ELSE
151
        text := citem(TEXT)
7693 akron1 152
    END;
7597 akron1 153
 
154
    IF text # NIL THEN
7696 akron1 155
        text.chunk[0] := 0X;
7693 akron1 156
        text.pos  := 0;
157
        text.size := 0;
158
        text.utf8 := FALSE;
159
        text.CR   := FALSE;
160
        text.line := 1;
161
        text.col  := 1;
162
        text.eof  := FALSE;
163
        text.eol  := FALSE;
164
        text.peak := 0X;
165
        text.file := FILES.open(name);
7597 akron1 166
        IF text.file # NIL THEN
7693 akron1 167
            load(text);
168
            init(text)
169
        ELSE
170
            close(text)
171
        END
7597 akron1 172
    END
173
 
7693 akron1 174
    RETURN text
175
END open;
7597 akron1 176
 
7693 akron1 177
 
7597 akron1 178
BEGIN
179
    texts := C.create()
7983 leency 180
END TEXTDRV.