Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
647 andrew_pro 1
#include 
7184 siemargl 2
#include 
3
#include 
647 andrew_pro 4
#include 
5
 
6
int fread(void *buffer,int size,int count,FILE* file)
7
{
7184 siemargl 8
	dword res, readbytes;
9
	dword fullsize, read4cache, toread, readcount;
647 andrew_pro 10
 
6433 siemargl 11
    if(!file || !buffer)
12
    {
13
        errno = E_INVALIDPTR;
14
        return 0;
15
    }
647 andrew_pro 16
 
7172 siemargl 17
	if ((file->mode &3)!=FILE_OPEN_READ && (file->mode & FILE_OPEN_PLUS)==0)
6433 siemargl 18
    {
19
        errno = E_ACCESS;
20
        return 0;
21
    }
22
 
647 andrew_pro 23
	fullsize=count*size;
7184 siemargl 24
	if (fullsize + file->filepos >= file->filesize)
647 andrew_pro 25
	{
7184 siemargl 26
		fullsize=file->filesize - file->filepos;
27
		if (fullsize <= 0) return 0;
647 andrew_pro 28
	}
29
 
7184 siemargl 30
	/***** file buffering strategy, just read forward *****
31
	if we read small part - read full buffer, but if buffer have this data - dont read again nothing (or partial read forward 4k pages)
32
	any writes drops buffers as ungetc_buf */
33
	read4cache = 0;
34
	readcount = 0;
35
	if (file->filepos >= file->buffer_start && file->filepos < file->buffer_end)
6433 siemargl 36
	{
7184 siemargl 37
		read4cache = min(file->buffer_end - file->filepos, fullsize);
38
		memcpy(buffer, file->buffer + file->filepos - file->buffer_start, read4cache);
39
		file->filepos += read4cache;
40
		if (file->ungetc_buf != EOF)  // subst ungetc byte
41
		{
42
			*((char*)buffer) = (char)file->ungetc_buf;
43
			file->ungetc_buf = EOF;
44
		}
45
		buffer += read4cache;   // ! advance
46
		fullsize -= read4cache;
47
		readcount = read4cache / size;
647 andrew_pro 48
	}
7184 siemargl 49
 
50
	toread = max(fullsize, file->buffersize);
51
	if (toread + file->filepos >= file->filesize)
52
	{
53
		toread = file->filesize - file->filepos;
54
	}
55
 
56
	if (fullsize <= 0 || toread <= 0)
57
		res = 0;  // already read or file end
6433 siemargl 58
	else
7184 siemargl 59
	{
60
		file->buffer_start = file->filepos;
61
		if (toread <= fullsize) // read to bigger buffer
62
		{
63
			res = _ksys_readfile(file->filename, file->filepos, toread, buffer, &readbytes);
64
			read4cache = min(readbytes, file->buffersize);
65
			memcpy(file->buffer, buffer, read4cache);
66
			file->filepos += readbytes;
67
		} else
68
		{
69
			res = _ksys_readfile(file->filename, file->filepos, toread, file->buffer, &readbytes);
70
			read4cache = readbytes;
71
			memcpy(buffer, file->buffer, min(fullsize, read4cache));
72
			file->filepos += min(fullsize, read4cache);
73
		}
74
		file->buffer_end = file->buffer_start + read4cache;
75
		if (readbytes >= fullsize)
76
			readcount += fullsize / size;
77
		else
78
			readcount += readbytes / size;
79
	}
80
 
81
	if (file->ungetc_buf != EOF)  // subst ungetc byte
82
	{
83
		*((char*)buffer) = (char)file->ungetc_buf;
84
		file->ungetc_buf = EOF;
85
	}
86
 
87
	if (res != 0)
6433 siemargl 88
    {
7184 siemargl 89
		file->ungetc_buf = EOF;
6433 siemargl 90
        errno = -res;
91
    }
7184 siemargl 92
 
93
	return readcount;  // really full readed plus cached items
6433 siemargl 94
}