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
 
7983 leency 4
    Copyright (c) 2018-2020, Anton Krotov
7597 akron1 5
    All rights reserved.
6
*)
7
 
8
MODULE FILES;
9
 
10
IMPORT UTILS, C := COLLECTIONS, CONSOLE;
11
 
12
 
13
TYPE
14
 
15
    FILE* = POINTER TO RECORD (C.ITEM)
16
 
17
        ptr: INTEGER;
18
 
19
        buffer: ARRAY 64*1024 OF BYTE;
7983 leency 20
        count:  INTEGER;
7597 akron1 21
 
7983 leency 22
        chksum*: INTEGER
23
 
7597 akron1 24
    END;
25
 
26
VAR
27
 
28
    files: C.COLLECTION;
29
 
30
 
31
PROCEDURE copy (src: ARRAY OF BYTE; src_idx: INTEGER; VAR dst: ARRAY OF BYTE; dst_idx: INTEGER; bytes: INTEGER);
32
BEGIN
33
    WHILE bytes > 0 DO
34
        dst[dst_idx] := src[src_idx];
35
        INC(dst_idx);
36
        INC(src_idx);
37
        DEC(bytes)
38
    END
39
END copy;
40
 
41
 
42
PROCEDURE flush (file: FILE): INTEGER;
43
VAR
44
    res: INTEGER;
45
 
46
BEGIN
47
    IF file # NIL THEN
48
        res := UTILS.FileWrite(file.ptr, file.buffer, file.count);
49
        IF res < 0 THEN
50
            res := 0
51
        END
52
    ELSE
53
        res := 0
54
    END
55
 
56
    RETURN res
57
END flush;
58
 
59
 
60
PROCEDURE NewFile (): FILE;
61
VAR
62
    file:  FILE;
63
    citem: C.ITEM;
64
 
65
BEGIN
66
    citem := C.pop(files);
67
    IF citem = NIL THEN
68
        NEW(file)
69
    ELSE
70
        file := citem(FILE)
71
    END
72
 
73
    RETURN file
74
END NewFile;
75
 
76
 
77
PROCEDURE create* (name: ARRAY OF CHAR): FILE;
78
VAR
79
    file: FILE;
80
    ptr:  INTEGER;
81
 
82
BEGIN
83
    ptr := UTILS.FileCreate(name);
84
 
85
    IF ptr > 0 THEN
86
        file := NewFile();
87
        file.ptr := ptr;
7983 leency 88
        file.count := 0;
89
        file.chksum := 0
7597 akron1 90
    ELSE
91
        file := NIL
92
    END
93
 
94
    RETURN file
95
END create;
96
 
97
 
98
PROCEDURE open* (name: ARRAY OF CHAR): FILE;
99
VAR
100
    file: FILE;
101
    ptr:  INTEGER;
102
 
103
BEGIN
104
    ptr := UTILS.FileOpen(name);
105
 
106
    IF ptr > 0 THEN
107
        file := NewFile();
108
        file.ptr := ptr;
109
        file.count := -1
110
    ELSE
111
        file := NIL
112
    END
113
 
114
    RETURN file
115
END open;
116
 
117
 
118
PROCEDURE close* (VAR file: FILE);
119
VAR
120
    n: INTEGER;
121
 
122
BEGIN
123
    IF file # NIL THEN
124
 
125
        IF file.count > 0 THEN
126
            n := flush(file)
127
        END;
128
 
129
        file.count := -1;
130
 
131
        UTILS.FileClose(file.ptr);
132
        file.ptr := 0;
133
 
134
        C.push(files, file);
135
        file := NIL
136
    END
137
END close;
138
 
139
 
7696 akron1 140
PROCEDURE read* (file: FILE; VAR chunk: ARRAY OF CHAR; bytes: INTEGER): INTEGER;
7597 akron1 141
VAR
142
    res: INTEGER;
143
 
144
BEGIN
145
    IF file # NIL THEN
146
        res := UTILS.FileRead(file.ptr, chunk, MAX(MIN(bytes, LEN(chunk)), 0));
147
        IF res < 0 THEN
148
            res := 0
149
        END
150
    ELSE
151
        res := 0
152
    END
153
 
154
    RETURN res
155
END read;
156
 
157
 
158
PROCEDURE write* (file: FILE; chunk: ARRAY OF BYTE; bytes: INTEGER): INTEGER;
159
VAR
160
    free, n, k, res, idx: INTEGER;
161
 
162
BEGIN
163
    idx := 0;
164
    res := 0;
165
    IF (file # NIL) & (file.count >= 0) THEN
166
 
167
        free := LEN(file.buffer) - file.count;
168
        WHILE bytes > 0 DO
169
            n := MIN(free, bytes);
170
            copy(chunk, idx, file.buffer, file.count, n);
171
            INC(res, n);
172
            DEC(free, n);
173
            DEC(bytes, n);
174
            INC(idx, n);
175
            INC(file.count, n);
176
            IF free = 0 THEN
177
                k := flush(file);
178
                IF k # LEN(file.buffer) THEN
179
                    bytes := 0;
180
                    DEC(res, n)
181
                ELSE
182
                    file.count := 0;
183
                    free := LEN(file.buffer)
184
                END
185
            END
186
        END
187
 
188
    END
189
 
190
    RETURN res
191
END write;
192
 
193
 
194
PROCEDURE WriteByte* (file: FILE; byte: BYTE): BOOLEAN;
195
VAR
7983 leency 196
    arr: ARRAY 1 OF BYTE;
7597 akron1 197
 
198
BEGIN
7983 leency 199
    arr[0] := byte
200
    RETURN write(file, arr, 1) = 1
7597 akron1 201
END WriteByte;
202
 
203
 
204
BEGIN
205
    files := C.create()
7983 leency 206
END FILES.