Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
8133 IgorA 1
#ifndef __KOLIBRI_FILE_H_INCLUDED_
2
#define __KOLIBRI_FILE_H_INCLUDED_
8129 IgorA 3
 
4
#include 
5
#include 
6
 
7
// Kolibri file interface.
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);
15
	int FileClose(TFileData file_data);
16
	bool FileEof(TFileData file_data);
17
	unsigned int FileGetPosition(TFileData file_data);
18
	void FileSetPosition(TFileData file_data, unsigned int pos);
19
	void FileReset(TFileData file_data);
20
	unsigned int FileGetLength(TFileData file_data);
21
	int FileTestRead(TFileData file_data);
22
	int FileRead(TFileData file_data, void *mem, int size);
23
}
24
 
8170 IgorA 25
#ifdef __KOLIBRI__
8129 IgorA 26
 
27
namespace Kolibri
28
{
29
// Define the file data structure.
30
 
31
	struct _FileDataStruct
32
	{
33
		unsigned int length;
34
		unsigned int position;
35
		unsigned int *buffer;
36
		unsigned int access_param[5];
37
 
38
		enum {PosName = (unsigned int)(((_FileDataStruct*)0)->access_param + 5)};
39
	};
40
 
41
// Inline functions.
42
 
43
	inline bool FileEof(TFileData file_data)
44
	{
45
		return file_data && file_data->position >= file_data->length;
46
	}
47
 
48
	inline unsigned int FileGetPosition(TFileData file_data)
49
	{
50
		return file_data ? file_data->position : 0;
51
	}
52
 
53
	inline void FileReset(TFileData file_data)
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;
8133 IgorA 70
		buffer_length = (buffer_length / KOLIBRI_FILE_BLOCK_SIZE) * KOLIBRI_FILE_BLOCK_SIZE;
8129 IgorA 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);
83
		unsigned int attr[40/4];
84
		file->access_param[0] = 5;
85
		file->access_param[1] = 0;
86
		file->access_param[2] = 0;
87
		file->access_param[3] = 0;
88
		file->access_param[4] = (int)attr;
89
		_FileAccess(file->access_param);
90
		file->length = attr[32/4];
91
		return file;
92
	}
93
 
94
	int FileClose(TFileData file_data)
95
	{
96
		if (!file_data) return -1;
97
		Free(file_data);
98
		return 0;
99
	}
100
 
101
	void FileSetPosition(TFileData file_data, unsigned int pos)
102
	{
103
		if (!file_data) return;
104
		if (file_data->buffer && file_data->buffer[1])
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
			}
110
			else file_data->buffer[1] = 0;
111
		}
112
		file_data->position = pos;
113
	}
114
 
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
		{
8133 IgorA 122
			buffer = (unsigned int*)((char*)temp_mem + KOLIBRI_FILE_BLOCK_SIZE);
8129 IgorA 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;
8133 IgorA 145
		size /= KOLIBRI_FILE_BLOCK_SIZE;
8129 IgorA 146
		if (!file_data || !mem || size <= 0) return -1;
147
		file_data->access_param[0] = 0;
8133 IgorA 148
		file_data->access_param[1] = (file_data->position / KOLIBRI_FILE_BLOCK_SIZE) * KOLIBRI_FILE_BLOCK_SIZE;
8129 IgorA 149
		file_data->access_param[2] = 0;
8133 IgorA 150
		file_data->access_param[3] = size * KOLIBRI_FILE_BLOCK_SIZE;
8129 IgorA 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;
8133 IgorA 156
		len1 = size * KOLIBRI_FILE_BLOCK_SIZE - (file_data->position % KOLIBRI_FILE_BLOCK_SIZE);
8129 IgorA 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
			{
8133 IgorA 170
				temp_mem = Alloc(KOLIBRI_FILE_BLOCK_SIZE + 2*sizeof(unsigned int));
8129 IgorA 171
				if (!temp_mem) return -10;
172
			}
8133 IgorA 173
			buffer = (unsigned int*)((char*)temp_mem + KOLIBRI_FILE_BLOCK_SIZE);
174
			buffer[0] = KOLIBRI_FILE_BLOCK_SIZE;
8129 IgorA 175
		}
176
		buffer[1] = buffer[0];
177
		res = _FileReadSystem(file_data, (char*)buffer - buffer[1], buffer[1]);
178
		if (res < 0) buffer[1] = 0;
8133 IgorA 179
		else buffer[1] -= file_data->position % KOLIBRI_FILE_BLOCK_SIZE;
8129 IgorA 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;
8133 IgorA 203
		tlen = file_data->position % KOLIBRI_FILE_BLOCK_SIZE;
8129 IgorA 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
		}
8133 IgorA 223
		if (size >= (file_data->buffer ? file_data->buffer[0] : KOLIBRI_FILE_BLOCK_SIZE))
8129 IgorA 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;
8133 IgorA 233
			if (res < (size / KOLIBRI_FILE_BLOCK_SIZE) * KOLIBRI_FILE_BLOCK_SIZE)
8129 IgorA 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);
244
			if (res < 0)
245
			{
246
				if (temp_mem) Free(temp_mem);
247
				return read_len ? read_len : res;
248
			}
249
			read_len += _FileReadBuffer(file_data, mem, size, temp_mem);
250
		}
251
		if (temp_mem) Free(temp_mem);
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
 
8170 IgorA 265
#else   // def  __KOLIBRI__
8129 IgorA 266
 
267
namespace Kolibri
268
{
269
	struct _FileDataStruct
270
	{
271
		unsigned int data;
272
	};
273
}
274
 
8170 IgorA 275
#endif  // else: def  __KOLIBRI__
8129 IgorA 276
 
8133 IgorA 277
#endif  // ndef __KOLIBRI_FILE_H_INCLUDED_
8129 IgorA 278