/*

  This is a part of the Project Frontier's Source code.

  Copyright (C) 1997-98 Francis Gastellu
                    aka Lone Runner/Aegis

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

/**************************************************************************/
/******** VFS 1.0                                                  ********/
/********                                          Functions Body  ********/
/********     Virtual File System                                  ********/
/**************************************************************************/
#include "vfs.h"
#ifndef __STDIO_H
#include <stdio.h>
#endif
#ifndef __ALLOC_H
#include <alloc.h>
#endif
#ifndef __PROCESS_H
#include <process.h>
#endif
#ifndef __STRING_H
#include <string.h>
#endif
#ifndef __IOSTREAM_H
#include <iostream.h>
#endif

char far copyright[] = "VFS 1.O þ Virtual File System þ (C)96 Lone Runner/AGS";
char far notenoughmemory[] = "VFS: Not enough memory\n";

_file *_fopenread(char *fl, int mode)
{
FILE *__in;
_file *buf;
char md[3] = "rX";
long l;

buf = (_file *)farmalloc(sizeof(_file));
if (buf == NULL)
	{
	printf(notenoughmemory);
	fcloseall();
	exit(1);
    }

if (mode == _FILE_READBIN)
	md[1] = 'b';
else
	md[1] = 't';

if ((__in = fopen(fl, md)) == NULL)
	{
    printf("VFS: Enable to open %s!\n", fl);
	fcloseall();
	exit(1);
    }

fseek(__in, 0, SEEK_END);
buf->data = (char *)farmalloc(ftell(__in)+1);
if (buf->data == NULL)
	{
	printf(notenoughmemory);
	fcloseall();
	exit(1);
    }
buf->ptr = 0;
buf->size = ftell(__in);
fseek(__in, 0, SEEK_SET);
l = buf->size;
fread(buf->data, l>>1, 2, __in);
l-=(l>>1) << 1;
if (l > 0)
	fread(buf->data+(buf->size-1), 1, 1, __in);

if (mode == _FILE_READTXT)
	{
    unsigned char huge *p;
    long n, o;
    for (n=0,o=0,p=buf->data;n < buf->size;n++,o++,p++)
        if (*p == '\n')
        	n++;
	buf->size = o;
    }

buf->data = (char *)farrealloc(buf->data, buf->size+1);
if (buf->data == NULL)
	{
	printf(notenoughmemory);
	fcloseall();
	exit(1);
    }

fclose(__in);
strcpy(buf->filename, fl);
buf->mode = mode;

return buf;
}

void _fread(void *ptr, size_t size, size_t n, _file *buf)
{
size_t i,j;
unsigned char *_ptr = (unsigned char *)ptr;

for (j=0;j<n;j++)
	for (i=0;i<size;i++)
		{
	    _ptr[0] = buf->data[(long)buf->ptr];
	    _ptr++;
	    buf->ptr++;
	    }
}

void _fseek(_file *fl, unsigned long i, int whence)
{
switch (whence)
	{
    case SEEK_SET:
    	fl->ptr = i;
    	break;
    case SEEK_CUR:
    	fl->ptr += i;
        break;
    case SEEK_END:
    	fl->ptr = fl->size-i;
        break;
    }
}

unsigned long _ftell(_file *fl)
{
return fl->ptr;
}

void _fclose(_file *fl)
{
unsigned long l;

if (fl->mode == _FILE_WRITEBIN || fl->mode == _FILE_WRITETXT)
	{
	FILE *__out;
    char md[3]="wX";
    if (fl->mode == _FILE_WRITEBIN)
    	md[1] = 'b';
    else
    	md[1] = 't';
	if ((__out = fopen(fl->filename, md)) == NULL)
    	{
	    printf("VFS: Enable to create %s!\n", fl->filename);
		fcloseall();
		exit(1);
	    }
    l = fl->limit;
    fwrite(fl->data, fl->limit>>1, 2, __out);
    fl->limit-=(fl->limit>>1) << 1;
    if (fl->limit > 0)
	    fwrite(fl->data+(l-1), 1, 1, __out);
    fclose(__out);
    }

free(fl->data);
fl->ptr=0;
fl->size=0;
free(fl);
fl = NULL;
}

_file *_fopenwrite(char *fl, int mode)
{
FILE *__in;
_file *buf;

buf = (_file *)farmalloc(sizeof(_file));
if (buf == NULL)
	{
	printf(notenoughmemory);
	fcloseall();
	exit(1);
    }

strcpy(buf->filename, fl);
buf->size = _FILE_INC;
buf->data = (char *)farmalloc(buf->size+1);
if (buf->data == NULL)
	{
	printf(notenoughmemory);
	fcloseall();
	exit(1);
    }

buf->ptr = 0;
buf->mode = mode;
buf->limit=0;

return buf;
}

void _fwrite(void *ptr, size_t size, size_t n, _file *buf)
{

while (buf->ptr+size*n >= buf->size)
	{
	buf->data = (char *)farrealloc(buf->data, buf->size + _FILE_INC);
    if (buf->data == NULL)
		{
		printf(notenoughmemory);
		fcloseall();
		exit(1);
	    }
    buf->size += _FILE_INC;
    }

memcpy(buf->data+buf->ptr, ptr, size*n);

buf->ptr += size*n;
if (buf->limit < buf->ptr)
	buf->limit = buf->ptr;
}

void _fputs(char *str, _file *fl)
{
_fwrite(str, strlen(str), 1, fl);
}

void _fputc(char c, _file *fl)
{
_fwrite(&c, 1, 1, fl);
}

int _feof(_file *fl)
{
return (fl->ptr >= fl->/*true*/size);
}

char *_fgets(char *dest, int n, _file *fl)
{
unsigned char c=0;
char *p;
int l=0;

p = dest;
while (c != '\n' && l < n)
	{
	c = fl->data[fl->ptr];
    fl->ptr++;
    *p = c;
    p++;
    n++;
    }
*p=0;
return dest;
}

char _fgetc(_file *fl)
{
return fl->data[fl->ptr++];
}

_file *_outtoin(_file *fl, int mode)
{
FILE *__in;
_file *buf;
char md[3] = "rX";
long l;

buf = (_file *)farmalloc(sizeof(_file));
if (buf == NULL)
	{
	printf(notenoughmemory);
	fcloseall();
	exit(1);
    }

if (mode == _FILE_READBIN)
	md[1] = 'b';
else
	md[1] = 't';

buf->data = fl->data;
buf->ptr = 0;
buf->size = fl->limit;

buf->data = (char *)farrealloc(buf->data, buf->size+1);

if (buf->data == NULL)
	{
	printf(notenoughmemory);
	fcloseall();
	exit(1);
    }

strcpy(buf->filename, fl->filename);
buf->mode = mode;

fl->ptr=0;
fl->size=0;
fl = NULL;

return buf;

}


