Subversion Repositories Kolibri OS

Rev

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

  1. #ifndef __MENUET_FILE_H_INCLUDED_
  2. #define __MENUET_FILE_H_INCLUDED_
  3.  
  4. #include <menuet.h>
  5. #include <me_heap.h>
  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.  
  279.