/*
	MODULE:	FMBLoadFile.c  (SAS/C Lattice C source!)

	AUTHOR:	Ralph Seichter.  This source is declared public domain!

	ABSTRACT:	Load file(s) into memory and remove them later on.
*/

#include <exec/types.h>
#include <exec/memory.h>
#include <proto/dos_protos.h>
#include <proto/exec_protos.h>

#include "FMBLoadFile.h"


/* function prototypes (export) */

VOID FMBDiscardFile (FILEMEMBLOCK *fmb);
SHORT FMBLoadFile (UBYTE *filename, FILEMEMBLOCK *fmb);
SHORT FMBWriteFile (UBYTE *filename, FILEMEMBLOCK *fmb);



/*
	FUNCTION:	SHORT FMBLoadFile (UBYTE *filename, FILEMEMBLOCK *fmb)

	ABSTRACT:	Load a file into memory and store info in FILEMEMBLOCK.

	RETURNS:	0 = No errors.
			1 = Lock failed.
			2 = Examine failed.
			3 = One of: File empty / Lock is no file / Open failed.
			4 = Memory allocation failed.
			5 = Read failed.
*/

SHORT FMBLoadFile (UBYTE *filename, FILEMEMBLOCK *fmb)
{
	struct FileInfoBlock __aligned fib;
	SHORT retcode = 1;
	BPTR lock, file;

	if (lock = Lock (filename, SHARED_LOCK)) {
		++retcode;
		if (Examine (lock, &fib)) {
			++retcode;
			if (fib.fib_Size > 0 && fib.fib_DirEntryType < 0 && (file = Open (filename, MODE_OLDFILE)) != NULL) {
				++retcode;
				fmb->fmb_Size = fib.fib_Size;
				if (fmb->fmb_Data = AllocMem (fmb->fmb_Size, MEMF_ANY)) {
					++retcode;
					if (fmb->fmb_Size == Read (file, fmb->fmb_Data, fmb->fmb_Size))
						retcode = 0;
					else
						FreeMem (fmb->fmb_Data, fmb->fmb_Size);
				}
				Close (file);
			}
		}
		UnLock (lock);
	}

	return (retcode);
}



/*
	FUNCTION:	VOID FMBDiscardFile (FILEMEMBLOCK *fmb)

	ABSTRACT:	Discard file previously loaded by FMBLoadFile().

	NOTE:	If you supply an invalid FILEMEMBLOCK structure,
			your system will crash mercilessly!

	RETURNS:	NONE!
*/

VOID FMBDiscardFile (FILEMEMBLOCK *fmb)
{
	FreeMem (fmb->fmb_Data, fmb->fmb_Size);
}



/*
	FUNCTION:	SHORT FMBWriteFile (UBYTE *filename, FILEMEMBLOCK *fmb)

	ABSTRACT:	Write a file from memory to disk.

	NOTE:	If destination file already exists, it will be OVERWRITTEN !

	RETURNS:	0 = No errors.
			1 = Open failed.
			2 = Write failed.
*/

SHORT FMBWriteFile (UBYTE *filename, FILEMEMBLOCK *fmb)
{
	SHORT retcode = 1;
	BPTR file;

	if (file = Open (filename, MODE_NEWFILE)) {
		++retcode;
		if (fmb->fmb_Size == Write (file, fmb->fmb_Data, fmb->fmb_Size))
			retcode = 0;
		Close (file);
	}

	return (retcode);
}
