Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 8183 → Rev 8184

/programs/demos/life2/include/kos_file.h
1,97 → 1,69
#ifndef __KOLIBRI_FILE_H_INCLUDED_
#define __KOLIBRI_FILE_H_INCLUDED_
 
#include <kolibri.h>
#include <kos_heap.h>
#include "kolibri.h"
#include "kos_heap.h"
 
// Kolibri file interface.
 
namespace Kolibri // All kolibri functions, types and data are nested in the (Kolibri) namespace.
{
struct _FileDataStruct;
typedef _FileDataStruct *TFileData;
 
TFileData FileOpen(const char *name, unsigned int buffer_length = 1024);
int FileClose(TFileData file_data);
bool FileEof(TFileData file_data);
unsigned int FileGetPosition(TFileData file_data);
void FileSetPosition(TFileData file_data, unsigned int pos);
void FileReset(TFileData file_data);
unsigned int FileGetLength(TFileData file_data);
int FileTestRead(TFileData file_data);
int FileRead(TFileData file_data, void *mem, int size);
}
 
#ifdef __KOLIBRI__
 
namespace Kolibri
struct FileDateTime{
unsigned long int time;
unsigned long int date;
};
struct FileInfoBlock
{
// Define the file data structure.
 
struct _FileDataStruct
unsigned long int Function;
unsigned long int Position;
unsigned long int Flags;
unsigned long int Count;
char *Buffer;
char *FileName1;
char *FileName2;
};
struct FileInfoA
{
unsigned int length;
unsigned int position;
unsigned int *buffer;
unsigned int access_param[5];
 
enum {PosName = (unsigned int)(((_FileDataStruct*)0)->access_param + 5)};
unsigned long int Attributes;
unsigned long int Flags;
FileDateTime DateCreate;
FileDateTime DateAccess;
FileDateTime DateModify;
unsigned long int FileSizeLow;
unsigned long int FileSizeHigh;
char FileName[520];
};
 
// Inline functions.
// Functions.
 
inline bool FileEof(TFileData file_data)
{
return file_data && file_data->position >= file_data->length;
}
int _FileAccess(FileInfoBlock *file_access);
 
inline unsigned int FileGetPosition(TFileData file_data)
FileInfoBlock* FileOpen(const char *name)
{
return file_data ? file_data->position : 0;
if (!name || !name[0]){
DebugPutString("name is 0");
return 0;
}
 
inline void FileReset(TFileData file_data)
{
if (!file_data) return;
file_data->length = -1;
file_data->position = 0;
if (file_data->buffer) file_data->buffer[1] = 0;
FileInfoBlock* file = (FileInfoBlock*)Alloc(sizeof(FileInfoBlock)+sizeof(FileInfoA));
if (!file){
DebugPutString("mem_Alloc -> 0");
return 0;
}
file->Function = 5; //SSF_GET_INFO
file->Position = 0;
file->Flags = 0;
file->Count = 0;
file->Buffer = (char*)file+sizeof(FileInfoBlock);
file->FileName1 = (char*)name;
file->FileName2 = (char*)name;
file->FileName1 = (char*)((long)file->FileName1 << 8);
file->FileName2 = (char*)((long)file->FileName2 >> 24);
 
// Functions.
 
int _FileAccess(void *file_access_param);
 
TFileData FileOpen(const char *name, unsigned int buffer_length)
{
if (!name || !name[0]) return 0;
unsigned int name_len = StrLen(name) + 1;
unsigned int data_len = (_FileDataStruct::PosName + name_len + 3) & ~3;
buffer_length = (buffer_length / KOLIBRI_FILE_BLOCK_SIZE) * KOLIBRI_FILE_BLOCK_SIZE;
if (buffer_length) data_len += buffer_length + 2*sizeof(unsigned int);
TFileData file = (TFileData)Alloc(_FileDataStruct::PosName + data_len);
if (!file) return 0;
file->length = -1;
file->position = 0;
if (buffer_length)
{
file->buffer = (unsigned int*)((char*)file + data_len) - 2;
file->buffer[0] = buffer_length;
file->buffer[1] = 0;
}
MemCopy(file->access_param + 5, name, name_len);
unsigned int attr[40/4];
file->access_param[0] = 5;
file->access_param[1] = 0;
file->access_param[2] = 0;
file->access_param[3] = 0;
file->access_param[4] = (int)attr;
_FileAccess(file->access_param);
file->length = attr[32/4];
_FileAccess(file);
return file;
}
 
int FileClose(TFileData file_data)
int FileClose(FileInfoBlock* file_data)
{
if (!file_data) return -1;
Free(file_data);
98,181 → 70,26
return 0;
}
 
void FileSetPosition(TFileData file_data, unsigned int pos)
unsigned long int FileRead(FileInfoBlock* file_data, void *mem, int size)
{
if (!file_data) return;
if (file_data->buffer && file_data->buffer[1])
{
if (pos >= file_data->position && pos < file_data->position + file_data->buffer[1])
{
file_data->buffer[1] -= pos - file_data->position;
}
else file_data->buffer[1] = 0;
}
file_data->position = pos;
}
file_data->Function = 0; //SSF_READ_FILE
file_data->Position = 0;
file_data->Flags = 0;
file_data->Count = size;
file_data->Buffer = (char*)mem;
 
int _FileReadBuffer(TFileData file_data, void *mem, int size, void *temp_mem = 0)
{
unsigned int *buffer;
if (!file_data || !mem || size <= 0) return -1;
if (file_data->buffer) buffer = file_data->buffer;
else if (temp_mem)
{
buffer = (unsigned int*)((char*)temp_mem + KOLIBRI_FILE_BLOCK_SIZE);
}
if(!_FileAccess(file_data)) return file_data->Function;
else return 0;
if (!buffer[1]) return 0;
if (file_data->position >= file_data->length)
{
buffer[1] = 0;
return 0;
}
unsigned int buf_size = file_data->length - file_data->position;
if (buf_size > buffer[1]) buf_size = buffer[1];
if ((unsigned int)size >= buf_size) size = buf_size;
MemCopy(mem, (char*)buffer - buffer[1], size);
file_data->position += size;
if ((unsigned int)size >= buf_size) buffer[1] = 0;
else buffer[1] -= size;
return size;
}
 
int _FileReadSystem(TFileData file_data, void *mem, int size)
{
int res;
unsigned int len0, len1;
size /= KOLIBRI_FILE_BLOCK_SIZE;
if (!file_data || !mem || size <= 0) return -1;
file_data->access_param[0] = 0;
file_data->access_param[1] = (file_data->position / KOLIBRI_FILE_BLOCK_SIZE) * KOLIBRI_FILE_BLOCK_SIZE;
file_data->access_param[2] = 0;
file_data->access_param[3] = size * KOLIBRI_FILE_BLOCK_SIZE;
file_data->access_param[4] = (unsigned int)mem;
res = _FileAccess(file_data->access_param);
if (res != 0 && res != 6) return (res & 255) - 1024;
if (file_data->length <= file_data->position) return 0;
len0 = file_data->length - file_data->position;
len1 = size * KOLIBRI_FILE_BLOCK_SIZE - (file_data->position % KOLIBRI_FILE_BLOCK_SIZE);
return (len0 <= len1) ? len0 : len1;
}
 
int _FileBufferSystem(TFileData file_data, void *&temp_mem)
{
int res;
unsigned int *buffer;
if (!file_data) return -1;
if (file_data->buffer) buffer = file_data->buffer;
else
{
if (!temp_mem)
{
temp_mem = Alloc(KOLIBRI_FILE_BLOCK_SIZE + 2*sizeof(unsigned int));
if (!temp_mem) return -10;
}
buffer = (unsigned int*)((char*)temp_mem + KOLIBRI_FILE_BLOCK_SIZE);
buffer[0] = KOLIBRI_FILE_BLOCK_SIZE;
}
buffer[1] = buffer[0];
res = _FileReadSystem(file_data, (char*)buffer - buffer[1], buffer[1]);
if (res < 0) buffer[1] = 0;
else buffer[1] -= file_data->position % KOLIBRI_FILE_BLOCK_SIZE;
return res;
}
 
int FileTestRead(TFileData file_data)
{
int res;
void *temp_mem = 0;
if (!file_data) return -1;
if (file_data->buffer && file_data->buffer[1]) return 0;
res = _FileBufferSystem(file_data, temp_mem);
if (temp_mem) Free(temp_mem);
return (res < 0) ? res : 0;
}
 
int FileRead(TFileData file_data, void *mem, int size)
{
int tlen, res, read_len;
void *temp_mem = 0;
res = _FileReadBuffer(file_data, mem, size);
if (res < 0 || res >= size) return res;
read_len = res;
mem = (char*)mem + res;
size -= res;
tlen = file_data->position % KOLIBRI_FILE_BLOCK_SIZE;
if (tlen)
{
res = _FileBufferSystem(file_data, temp_mem);
if (res < 0)
{
if (temp_mem) Free(temp_mem);
return read_len ? read_len : res;
}
res = _FileReadBuffer(file_data, mem, size);
read_len += res;
if (res >= size || file_data->length <= file_data->position ||
file_data->length - file_data->position <= res)
{
if (temp_mem) Free(temp_mem);
return read_len;
}
mem = (char*)mem + res;
size -= res;
}
if (size >= (file_data->buffer ? file_data->buffer[0] : KOLIBRI_FILE_BLOCK_SIZE))
{
res = _FileReadSystem(file_data, mem, size);
if (res < 0)
{
if (temp_mem) Free(temp_mem);
return read_len ? read_len : res;
}
file_data->position += res;
read_len += res;
if (res < (size / KOLIBRI_FILE_BLOCK_SIZE) * KOLIBRI_FILE_BLOCK_SIZE)
{
if (temp_mem) Free(temp_mem);
return read_len;
}
mem = (char*)mem + res;
size -= res;
}
if (size)
{
res = _FileBufferSystem(file_data, temp_mem);
if (res < 0)
{
if (temp_mem) Free(temp_mem);
return read_len ? read_len : res;
}
read_len += _FileReadBuffer(file_data, mem, size, temp_mem);
}
if (temp_mem) Free(temp_mem);
return read_len;
}
// Inline functions.
 
inline unsigned int FileGetLength(TFileData file_data)
inline unsigned long int FileGetLength(FileInfoBlock* file_data)
{
if (!file_data) return -1;
if (file_data->length == -1) FileTestRead(file_data);
return file_data->length;
return (unsigned long int)*(long*)((char*)file_data+sizeof(FileInfoBlock)+32);
}
}
 
#else // def __KOLIBRI__
 
namespace Kolibri
{
struct _FileDataStruct
{
unsigned int data;
};
}
 
#endif // else: def __KOLIBRI__
 
#endif // ndef __KOLIBRI_FILE_H_INCLUDED_