2005-07-24 20:00:55 +00:00
|
|
|
/* Pawn compiler
|
|
|
|
*
|
|
|
|
* Routines to maintain a "text file" in memory.
|
|
|
|
*
|
|
|
|
* Copyright (c) ITB CompuPhase, 2003-2005
|
|
|
|
*
|
|
|
|
* This software is provided 'as-is', without any express or implied warranty.
|
|
|
|
* In no event will the authors be held liable for any damages arising from the
|
|
|
|
* use of this software.
|
|
|
|
*
|
|
|
|
* Permission is granted to anyone to use this software for any purpose,
|
|
|
|
* including commercial applications, and to alter it and redistribute it
|
|
|
|
* freely, subject to the following restrictions:
|
|
|
|
*
|
|
|
|
* 1. The origin of this software must not be misrepresented; you must not
|
|
|
|
* claim that you wrote the original software. If you use this software in
|
|
|
|
* a product, an acknowledgment in the product documentation would be
|
|
|
|
* appreciated but is not required.
|
|
|
|
*
|
|
|
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
|
|
* misrepresented as being the original software.
|
|
|
|
*
|
|
|
|
* 3. This notice may not be removed or altered from any source distribution.
|
|
|
|
*
|
|
|
|
* Version: $Id$
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2006-07-16 02:25:32 +00:00
|
|
|
#include "memfile.h"
|
2005-07-24 20:00:55 +00:00
|
|
|
|
|
|
|
#if defined FORTIFY
|
|
|
|
#include "fortify.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#define BUFFERSIZE 512u
|
|
|
|
|
|
|
|
/* For every block, except the first:
|
|
|
|
* buffer points to a block that is BUFFERSIZE long that holds the data
|
|
|
|
* bufpos is the "used size" of the block
|
|
|
|
* For the first block:
|
|
|
|
* buffer points to the "file name"
|
|
|
|
* bufpos is the current "file pointer"
|
|
|
|
*/
|
2006-07-16 02:25:32 +00:00
|
|
|
typedef memfile_t MEMFILE;
|
2005-07-24 20:00:55 +00:00
|
|
|
#define tMEMFILE 1
|
|
|
|
|
|
|
|
#include "sc.h"
|
|
|
|
|
|
|
|
|
|
|
|
MEMFILE *mfcreate(char *filename)
|
|
|
|
{
|
2006-07-16 02:25:32 +00:00
|
|
|
return memfile_creat(filename, 4096);
|
2005-07-24 20:00:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void mfclose(MEMFILE *mf)
|
|
|
|
{
|
2006-07-16 02:25:32 +00:00
|
|
|
memfile_destroy(mf);
|
2005-07-24 20:00:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int mfdump(MEMFILE *mf)
|
|
|
|
{
|
|
|
|
FILE *fp;
|
|
|
|
int okay;
|
|
|
|
|
|
|
|
assert(mf!=NULL);
|
|
|
|
/* create the file */
|
2006-07-16 02:25:32 +00:00
|
|
|
fp=fopen(mf->name, "wb");
|
2005-07-24 20:00:55 +00:00
|
|
|
if (fp==NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
okay=1;
|
2006-07-16 02:25:32 +00:00
|
|
|
okay = okay & (fwrite(mf->base, mf->usedoffs, 1, fp)==(size_t)mf->usedoffs);
|
2005-07-24 20:00:55 +00:00
|
|
|
|
|
|
|
fclose(fp);
|
|
|
|
return okay;
|
|
|
|
}
|
|
|
|
|
|
|
|
long mflength(MEMFILE *mf)
|
|
|
|
{
|
2006-07-16 02:25:32 +00:00
|
|
|
return mf->usedoffs;
|
2005-07-24 20:00:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
long mfseek(MEMFILE *mf,long offset,int whence)
|
|
|
|
{
|
|
|
|
long length;
|
|
|
|
|
|
|
|
assert(mf!=NULL);
|
2006-07-16 02:25:32 +00:00
|
|
|
if (mf->usedoffs == 0)
|
2005-07-24 20:00:55 +00:00
|
|
|
return 0L; /* early exit: not a single byte in the file */
|
|
|
|
|
|
|
|
/* find the size of the memory file */
|
|
|
|
length=mflength(mf);
|
|
|
|
|
|
|
|
/* convert the offset to an absolute position */
|
|
|
|
switch (whence) {
|
|
|
|
case SEEK_SET:
|
|
|
|
break;
|
|
|
|
case SEEK_CUR:
|
2006-07-16 02:25:32 +00:00
|
|
|
offset+=mf->offs;
|
2005-07-24 20:00:55 +00:00
|
|
|
break;
|
|
|
|
case SEEK_END:
|
|
|
|
assert(offset<=0);
|
|
|
|
offset+=length;
|
|
|
|
break;
|
|
|
|
} /* switch */
|
|
|
|
|
|
|
|
/* clamp to the file length limit */
|
|
|
|
if (offset<0)
|
|
|
|
offset=0;
|
|
|
|
else if (offset>length)
|
|
|
|
offset=length;
|
|
|
|
|
|
|
|
/* set new position and return it */
|
2006-07-16 02:25:32 +00:00
|
|
|
memfile_seek(mf, offset);
|
2005-07-24 20:00:55 +00:00
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int mfwrite(MEMFILE *mf,unsigned char *buffer,unsigned int size)
|
|
|
|
{
|
2006-07-16 02:25:32 +00:00
|
|
|
return (memfile_write(mf, buffer, size) ? size : 0);
|
2005-07-24 20:00:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int mfread(MEMFILE *mf,unsigned char *buffer,unsigned int size)
|
|
|
|
{
|
2006-07-16 02:25:32 +00:00
|
|
|
return memfile_read(mf, buffer, size);
|
2005-07-24 20:00:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char *mfgets(MEMFILE *mf,char *string,unsigned int size)
|
|
|
|
{
|
|
|
|
char *ptr;
|
|
|
|
unsigned int read;
|
|
|
|
long seek;
|
|
|
|
|
|
|
|
assert(mf!=NULL);
|
|
|
|
|
|
|
|
read=mfread(mf,(unsigned char *)string,size);
|
|
|
|
if (read==0)
|
|
|
|
return NULL;
|
|
|
|
seek=0L;
|
|
|
|
|
|
|
|
/* make sure that the string is zero-terminated */
|
|
|
|
assert(read<=size);
|
|
|
|
if (read<size) {
|
|
|
|
string[read]='\0';
|
|
|
|
} else {
|
|
|
|
string[size-1]='\0';
|
|
|
|
seek=-1; /* undo reading the character that gets overwritten */
|
|
|
|
} /* if */
|
|
|
|
|
|
|
|
/* find the first '\n' */
|
|
|
|
ptr=strchr(string,'\n');
|
|
|
|
if (ptr!=NULL) {
|
|
|
|
*(ptr+1)='\0';
|
|
|
|
seek=(long)(ptr-string)+1-(long)read;
|
|
|
|
} /* if */
|
|
|
|
|
|
|
|
/* undo over-read */
|
|
|
|
assert(seek<=0); /* should seek backward only */
|
|
|
|
if (seek!=0)
|
|
|
|
mfseek(mf,seek,SEEK_CUR);
|
|
|
|
|
|
|
|
return string;
|
|
|
|
}
|
|
|
|
|
|
|
|
int mfputs(MEMFILE *mf,char *string)
|
|
|
|
{
|
|
|
|
unsigned int written,length;
|
|
|
|
|
|
|
|
assert(mf!=NULL);
|
|
|
|
|
|
|
|
length=strlen(string);
|
|
|
|
written=mfwrite(mf,(unsigned char *)string,length);
|
|
|
|
return written==length;
|
|
|
|
}
|