Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1769 yogev_ezra 1
#ifndef __MENUET_FILE_H_INCLUDED_
2
#define __MENUET_FILE_H_INCLUDED_
3
 
4
#include 
5
#include 
6
 
7
// Menuet file interface.
8
 
9
namespace Menuet   // All menuet functions, types and data are nested in the (Menuet) 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
 
25
#ifdef __MENUET__
26
 
27
namespace Menuet
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;
70
		buffer_length = (buffer_length / MENUET_FILE_BLOCK_SIZE) * MENUET_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);
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
		{
122
			buffer = (unsigned int*)((char*)temp_mem + MENUET_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 /= MENUET_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 / MENUET_FILE_BLOCK_SIZE) * MENUET_FILE_BLOCK_SIZE;
149
		file_data->access_param[2] = 0;
150
		file_data->access_param[3] = size * MENUET_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 * MENUET_FILE_BLOCK_SIZE - (file_data->position % MENUET_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(MENUET_FILE_BLOCK_SIZE + 2*sizeof(unsigned int));
171
				if (!temp_mem) return -10;
172
			}
173
			buffer = (unsigned int*)((char*)temp_mem + MENUET_FILE_BLOCK_SIZE);
174
			buffer[0] = MENUET_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 % MENUET_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 % MENUET_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] : MENUET_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 / MENUET_FILE_BLOCK_SIZE) * MENUET_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);
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
 
265
#else   // def  __MENUET__
266
 
267
namespace Menuet
268
{
269
	struct _FileDataStruct
270
	{
271
		unsigned int data;
272
	};
273
}
274
 
275
#endif  // else: def  __MENUET__
276
 
277
#endif  // ndef __MENUET_FILE_H_INCLUDED_
278