Rev 8170 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 8170 | Rev 8184 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | #ifndef __KOLIBRI_FILE_H_INCLUDED_ |
1 | #ifndef __KOLIBRI_FILE_H_INCLUDED_ |
2 | #define __KOLIBRI_FILE_H_INCLUDED_ |
2 | #define __KOLIBRI_FILE_H_INCLUDED_ |
Line 3... | Line 3... | ||
3 | 3 | ||
4 | #include |
4 | #include "kolibri.h" |
Line 5... | Line 5... | ||
5 | #include |
5 | #include "kos_heap.h" |
Line 6... | Line 6... | ||
6 | 6 | ||
7 | // Kolibri file interface. |
7 | // Kolibri file interface. |
8 | 8 | ||
9 | namespace Kolibri // All kolibri functions, types and data are nested in the (Kolibri) namespace. |
- | |
10 | { |
- | |
11 | struct _FileDataStruct; |
- | |
12 | typedef _FileDataStruct *TFileData; |
- | |
13 | - | ||
14 | TFileData FileOpen(const char *name, unsigned int buffer_length = 1024); |
9 | namespace Kolibri // All kolibri functions, types and data are nested in the (Kolibri) namespace. |
15 | int FileClose(TFileData file_data); |
- | |
16 | bool FileEof(TFileData file_data); |
- | |
17 | unsigned int FileGetPosition(TFileData file_data); |
10 | { |
18 | void FileSetPosition(TFileData file_data, unsigned int pos); |
- | |
19 | void FileReset(TFileData file_data); |
- | |
20 | unsigned int FileGetLength(TFileData file_data); |
11 | struct FileDateTime{ |
21 | int FileTestRead(TFileData file_data); |
- | |
22 | int FileRead(TFileData file_data, void *mem, int size); |
12 | unsigned long int time; |
23 | } |
- | |
24 | - | ||
25 | #ifdef __KOLIBRI__ |
13 | unsigned long int date; |
26 | 14 | }; |
|
- | 15 | struct FileInfoBlock |
|
- | 16 | { |
|
- | 17 | unsigned long int Function; |
|
- | 18 | unsigned long int Position; |
|
- | 19 | unsigned long int Flags; |
|
- | 20 | unsigned long int Count; |
|
27 | namespace Kolibri |
21 | char *Buffer; |
28 | { |
22 | char *FileName1; |
29 | // Define the file data structure. |
23 | char *FileName2; |
30 | 24 | }; |
|
31 | struct _FileDataStruct |
25 | struct FileInfoA |
- | 26 | { |
|
- | 27 | unsigned long int Attributes; |
|
32 | { |
28 | unsigned long int Flags; |
33 | unsigned int length; |
29 | FileDateTime DateCreate; |
34 | unsigned int position; |
- | |
35 | unsigned int *buffer; |
30 | FileDateTime DateAccess; |
- | 31 | FileDateTime DateModify; |
|
36 | unsigned int access_param[5]; |
32 | unsigned long int FileSizeLow; |
Line 37... | Line 33... | ||
37 | 33 | unsigned long int FileSizeHigh; |
|
Line 38... | Line 34... | ||
38 | enum {PosName = (unsigned int)(((_FileDataStruct*)0)->access_param + 5)}; |
34 | char FileName[520]; |
39 | }; |
- | |
40 | - | ||
41 | // Inline functions. |
- | |
Line 42... | Line 35... | ||
42 | 35 | }; |
|
43 | inline bool FileEof(TFileData file_data) |
36 | |
- | 37 | // Functions. |
|
44 | { |
38 | |
- | 39 | int _FileAccess(FileInfoBlock *file_access); |
|
45 | return file_data && file_data->position >= file_data->length; |
40 | |
46 | } |
- | |
47 | 41 | FileInfoBlock* FileOpen(const char *name) |
|
48 | inline unsigned int FileGetPosition(TFileData file_data) |
- | |
49 | { |
42 | { |
50 | return file_data ? file_data->position : 0; |
43 | if (!name || !name[0]){ |
51 | } |
44 | DebugPutString("name is 0"); |
52 | - | ||
53 | inline void FileReset(TFileData file_data) |
45 | return 0; |
- | 46 | } |
|
- | 47 | FileInfoBlock* file = (FileInfoBlock*)Alloc(sizeof(FileInfoBlock)+sizeof(FileInfoA)); |
|
- | 48 | if (!file){ |
|
- | 49 | DebugPutString("mem_Alloc -> 0"); |
|
- | 50 | return 0; |
|
- | 51 | } |
|
- | 52 | file->Function = 5; //SSF_GET_INFO |
|
- | 53 | file->Position = 0; |
|
- | 54 | file->Flags = 0; |
|
Line 54... | Line -... | ||
54 | { |
- | |
55 | if (!file_data) return; |
- | |
56 | file_data->length = -1; |
- | |
57 | file_data->position = 0; |
- | |
58 | if (file_data->buffer) file_data->buffer[1] = 0; |
- | |
59 | } |
- | |
60 | - | ||
61 | // Functions. |
- | |
62 | - | ||
63 | int _FileAccess(void *file_access_param); |
- | |
64 | - | ||
65 | TFileData FileOpen(const char *name, unsigned int buffer_length) |
- | |
66 | { |
- | |
67 | if (!name || !name[0]) return 0; |
- | |
68 | unsigned int name_len = StrLen(name) + 1; |
- | |
69 | unsigned int data_len = (_FileDataStruct::PosName + name_len + 3) & ~3; |
- | |
70 | buffer_length = (buffer_length / KOLIBRI_FILE_BLOCK_SIZE) * KOLIBRI_FILE_BLOCK_SIZE; |
- | |
71 | if (buffer_length) data_len += buffer_length + 2*sizeof(unsigned int); |
- | |
72 | TFileData file = (TFileData)Alloc(_FileDataStruct::PosName + data_len); |
- | |
73 | if (!file) return 0; |
- | |
74 | file->length = -1; |
- | |
75 | file->position = 0; |
- | |
76 | if (buffer_length) |
- | |
77 | { |
- | |
78 | file->buffer = (unsigned int*)((char*)file + data_len) - 2; |
- | |
79 | file->buffer[0] = buffer_length; |
- | |
80 | file->buffer[1] = 0; |
- | |
81 | } |
- | |
82 | MemCopy(file->access_param + 5, name, name_len); |
55 | file->Count = 0; |
83 | unsigned int attr[40/4]; |
- | |
84 | file->access_param[0] = 5; |
56 | file->Buffer = (char*)file+sizeof(FileInfoBlock); |
85 | file->access_param[1] = 0; |
57 | file->FileName1 = (char*)name; |
Line 86... | Line 58... | ||
86 | file->access_param[2] = 0; |
58 | file->FileName2 = (char*)name; |
87 | file->access_param[3] = 0; |
59 | file->FileName1 = (char*)((long)file->FileName1 << 8); |
88 | file->access_param[4] = (int)attr; |
60 | file->FileName2 = (char*)((long)file->FileName2 >> 24); |
89 | _FileAccess(file->access_param); |
61 | |
90 | file->length = attr[32/4]; |
62 | _FileAccess(file); |
91 | return file; |
63 | return file; |
Line 92... | Line 64... | ||
92 | } |
64 | } |
93 | - | ||
94 | int FileClose(TFileData file_data) |
- | |
95 | { |
- | |
96 | if (!file_data) return -1; |
- | |
97 | Free(file_data); |
- | |
98 | return 0; |
65 | |
99 | } |
66 | int FileClose(FileInfoBlock* file_data) |
100 | - | ||
101 | void FileSetPosition(TFileData file_data, unsigned int pos) |
67 | { |
102 | { |
68 | if (!file_data) return -1; |
103 | if (!file_data) return; |
69 | Free(file_data); |
104 | if (file_data->buffer && file_data->buffer[1]) |
- | |
- | 70 | return 0; |
|
Line 105... | Line -... | ||
105 | { |
- | |
106 | if (pos >= file_data->position && pos < file_data->position + file_data->buffer[1]) |
- | |
107 | { |
- | |
108 | file_data->buffer[1] -= pos - file_data->position; |
- | |
109 | } |
71 | } |
110 | else file_data->buffer[1] = 0; |
- | |
111 | } |
- | |
112 | file_data->position = pos; |
- | |
113 | } |
- | |
114 | 72 | ||
115 | int _FileReadBuffer(TFileData file_data, void *mem, int size, void *temp_mem = 0) |
- | |
116 | { |
- | |
117 | unsigned int *buffer; |
- | |
118 | if (!file_data || !mem || size <= 0) return -1; |
- | |
119 | if (file_data->buffer) buffer = file_data->buffer; |
- | |
120 | else if (temp_mem) |
- | |
121 | { |
- | |
122 | buffer = (unsigned int*)((char*)temp_mem + KOLIBRI_FILE_BLOCK_SIZE); |
- | |
123 | } |
- | |
124 | else return 0; |
- | |
125 | if (!buffer[1]) return 0; |
- | |
126 | if (file_data->position >= file_data->length) |
- | |
127 | { |
- | |
128 | buffer[1] = 0; |
- | |
129 | return 0; |
- | |
130 | } |
- | |
131 | unsigned int buf_size = file_data->length - file_data->position; |
- | |
132 | if (buf_size > buffer[1]) buf_size = buffer[1]; |
- | |
133 | if ((unsigned int)size >= buf_size) size = buf_size; |
- | |
134 | MemCopy(mem, (char*)buffer - buffer[1], size); |
- | |
135 | file_data->position += size; |
- | |
136 | if ((unsigned int)size >= buf_size) buffer[1] = 0; |
- | |
137 | else buffer[1] -= size; |
- | |
138 | return size; |
- | |
139 | } |
- | |
140 | - | ||
141 | int _FileReadSystem(TFileData file_data, void *mem, int size) |
- | |
142 | { |
- | |
143 | int res; |
- | |
144 | unsigned int len0, len1; |
- | |
145 | size /= KOLIBRI_FILE_BLOCK_SIZE; |
- | |
146 | if (!file_data || !mem || size <= 0) return -1; |
- | |
147 | file_data->access_param[0] = 0; |
- | |
148 | file_data->access_param[1] = (file_data->position / KOLIBRI_FILE_BLOCK_SIZE) * KOLIBRI_FILE_BLOCK_SIZE; |
- | |
149 | file_data->access_param[2] = 0; |
- | |
150 | file_data->access_param[3] = size * KOLIBRI_FILE_BLOCK_SIZE; |
- | |
151 | file_data->access_param[4] = (unsigned int)mem; |
- | |
152 | res = _FileAccess(file_data->access_param); |
- | |
153 | if (res != 0 && res != 6) return (res & 255) - 1024; |
- | |
154 | if (file_data->length <= file_data->position) return 0; |
- | |
155 | len0 = file_data->length - file_data->position; |
- | |
156 | len1 = size * KOLIBRI_FILE_BLOCK_SIZE - (file_data->position % KOLIBRI_FILE_BLOCK_SIZE); |
- | |
157 | return (len0 <= len1) ? len0 : len1; |
- | |
158 | } |
- | |
159 | - | ||
160 | int _FileBufferSystem(TFileData file_data, void *&temp_mem) |
- | |
161 | { |
- | |
162 | int res; |
- | |
163 | unsigned int *buffer; |
- | |
164 | if (!file_data) return -1; |
- | |
165 | if (file_data->buffer) buffer = file_data->buffer; |
- | |
166 | else |
- | |
167 | { |
- | |
168 | if (!temp_mem) |
- | |
169 | { |
- | |
170 | temp_mem = Alloc(KOLIBRI_FILE_BLOCK_SIZE + 2*sizeof(unsigned int)); |
- | |
171 | if (!temp_mem) return -10; |
- | |
172 | } |
- | |
173 | buffer = (unsigned int*)((char*)temp_mem + KOLIBRI_FILE_BLOCK_SIZE); |
- | |
174 | buffer[0] = KOLIBRI_FILE_BLOCK_SIZE; |
- | |
175 | } |
- | |
176 | buffer[1] = buffer[0]; |
- | |
177 | res = _FileReadSystem(file_data, (char*)buffer - buffer[1], buffer[1]); |
- | |
178 | if (res < 0) buffer[1] = 0; |
- | |
179 | else buffer[1] -= file_data->position % KOLIBRI_FILE_BLOCK_SIZE; |
- | |
180 | return res; |
- | |
181 | } |
- | |
182 | - | ||
183 | int FileTestRead(TFileData file_data) |
- | |
184 | { |
- | |
185 | int res; |
- | |
186 | void *temp_mem = 0; |
- | |
187 | if (!file_data) return -1; |
- | |
188 | if (file_data->buffer && file_data->buffer[1]) return 0; |
- | |
189 | res = _FileBufferSystem(file_data, temp_mem); |
- | |
190 | if (temp_mem) Free(temp_mem); |
- | |
191 | return (res < 0) ? res : 0; |
- | |
192 | } |
- | |
193 | - | ||
194 | int FileRead(TFileData file_data, void *mem, int size) |
- | |
195 | { |
- | |
196 | int tlen, res, read_len; |
- | |
197 | void *temp_mem = 0; |
- | |
198 | res = _FileReadBuffer(file_data, mem, size); |
- | |
199 | if (res < 0 || res >= size) return res; |
- | |
200 | read_len = res; |
- | |
201 | mem = (char*)mem + res; |
- | |
202 | size -= res; |
- | |
203 | tlen = file_data->position % KOLIBRI_FILE_BLOCK_SIZE; |
- | |
204 | if (tlen) |
- | |
205 | { |
- | |
206 | res = _FileBufferSystem(file_data, temp_mem); |
- | |
207 | if (res < 0) |
- | |
208 | { |
- | |
209 | if (temp_mem) Free(temp_mem); |
- | |
210 | return read_len ? read_len : res; |
- | |
211 | } |
- | |
212 | res = _FileReadBuffer(file_data, mem, size); |
- | |
213 | read_len += res; |
- | |
214 | if (res >= size || file_data->length <= file_data->position || |
- | |
215 | file_data->length - file_data->position <= res) |
- | |
216 | { |
- | |
217 | if (temp_mem) Free(temp_mem); |
- | |
218 | return read_len; |
- | |
219 | } |
- | |
220 | mem = (char*)mem + res; |
- | |
221 | size -= res; |
- | |
222 | } |
- | |
223 | if (size >= (file_data->buffer ? file_data->buffer[0] : KOLIBRI_FILE_BLOCK_SIZE)) |
- | |
224 | { |
- | |
225 | res = _FileReadSystem(file_data, mem, size); |
- | |
226 | if (res < 0) |
- | |
227 | { |
- | |
228 | if (temp_mem) Free(temp_mem); |
- | |
229 | return read_len ? read_len : res; |
- | |
230 | } |
- | |
231 | file_data->position += res; |
- | |
232 | read_len += res; |
- | |
233 | if (res < (size / KOLIBRI_FILE_BLOCK_SIZE) * KOLIBRI_FILE_BLOCK_SIZE) |
- | |
234 | { |
- | |
235 | if (temp_mem) Free(temp_mem); |
- | |
236 | return read_len; |
- | |
237 | } |
- | |
238 | mem = (char*)mem + res; |
- | |
239 | size -= res; |
- | |
240 | } |
- | |
241 | if (size) |
- | |
242 | { |
- | |
243 | res = _FileBufferSystem(file_data, temp_mem); |
73 | unsigned long int FileRead(FileInfoBlock* file_data, void *mem, int size) |
Line 244... | Line 74... | ||
244 | if (res < 0) |
74 | { |
Line 245... | Line 75... | ||
245 | { |
75 | file_data->Function = 0; //SSF_READ_FILE |
246 | if (temp_mem) Free(temp_mem); |
76 | file_data->Position = 0; |
247 | return read_len ? read_len : res; |
77 | file_data->Flags = 0; |
248 | } |
78 | file_data->Count = size; |
249 | read_len += _FileReadBuffer(file_data, mem, size, temp_mem); |
- | |
250 | } |
79 | file_data->Buffer = (char*)mem; |
251 | if (temp_mem) Free(temp_mem); |
80 | |
Line 252... | Line -... | ||
252 | return read_len; |
- | |
253 | } |
- | |
254 | - | ||
255 | // Inline functions. |
- | |
256 | - | ||
257 | inline unsigned int FileGetLength(TFileData file_data) |
- | |
258 | { |
- | |
259 | if (!file_data) return -1; |
- | |
260 | if (file_data->length == -1) FileTestRead(file_data); |
- | |
261 | return file_data->length; |
- | |
262 | } |
- | |
263 | } |
- | |
264 | 81 | if(!_FileAccess(file_data)) return file_data->Function; |