Subversion Repositories Kolibri OS

Rev

Rev 7172 | Blame | Last modification | View Log | Download | RSS feed

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <kolibrisys.h>
  5.  
  6. int fread(void *buffer,int size,int count,FILE* file)
  7. {
  8.         dword res, readbytes;
  9.         dword fullsize, read4cache, toread, readcount;
  10.  
  11.     if(!file || !buffer)
  12.     {
  13.         errno = E_INVALIDPTR;
  14.         return 0;
  15.     }
  16.  
  17.         if ((file->mode &3)!=FILE_OPEN_READ && (file->mode & FILE_OPEN_PLUS)==0)
  18.     {
  19.         errno = E_ACCESS;
  20.         return 0;
  21.     }
  22.  
  23.         fullsize=count*size;
  24.         if (fullsize + file->filepos >= file->filesize)
  25.         {
  26.                 fullsize=file->filesize - file->filepos;
  27.                 if (fullsize <= 0) return 0;
  28.         }
  29.  
  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)
  36.         {
  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;
  48.         }
  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
  58.         else
  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)
  88.     {
  89.                 file->ungetc_buf = EOF;
  90.         errno = -res;
  91.     }
  92.        
  93.         return readcount;  // really full readed plus cached items
  94. }
  95.