vbagx/source/vba/common/memfile.cpp

133 lines
4.1 KiB
C++
Raw Permalink Normal View History

2008-10-27 05:31:59 +01:00
/****************************************************************************
* Memory-based replacement for standard C file functions
* This allows standard file calls to be replaced by memory based ones
* With little modification required to the code
*
* Written By: Daryl Borth, October 2008
*
* This code 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, or (at your option)
* any later version.
***************************************************************************/
#include <string.h>
#include <stdlib.h>
#include "memfile.h"
/****************************************************************************
* memfopen
* memory replacement for fopen
*
* Creates a memory-based file
***************************************************************************/
MFILE * memfopen(char * buffer, int size)
{
MFILE *f = (MFILE *)malloc(sizeof(MFILE));
f->buffer = buffer;
f->offset = 0;
f->size = size;
return f;
}
/****************************************************************************
* memfclose
* memory replacement for fclose
*
* 'Closes' the memory file specified
***************************************************************************/
int memfclose(MFILE * src)
{
free(src);
return 0;
}
/****************************************************************************
* memfseek
* memory replacement for fseek
*
* Sets the position indicator associated with the stream to a new position
* defined by adding offset to a reference position specified by origin.
***************************************************************************/
int memfseek ( MFILE * m, long int offset, int origin )
{
int success = 0; // 0 indicates success
switch(origin)
{
case MSEEK_SET:
if(offset >= 0 && offset <= m->size)
m->offset = offset;
else
success = 1; // failure
break;
case MSEEK_CUR:
if((m->offset + offset) >= 0 && (m->offset + offset) <= m->size)
m->offset += offset;
else
success = 1; // failure
break;
case MSEEK_END:
if((m->size + offset) >= 0 && (m->size + offset) <= m->size)
m->offset = m->size + offset;
else
success = 1; // failure
break;
}
return success;
}
/****************************************************************************
* memftell
* memory replacement for ftell
*
* Get current position in stream (offset + 1)
***************************************************************************/
long int memftell (MFILE * stream)
{
return stream->offset; // to emulate ftell behavior
}
/****************************************************************************
* memfread
* memory replacement for fread
*
* Reads an array of count elements, each one with a size of size bytes, from
* the buffer and stores them in the block of memory specified by ptr. The
* postion indicator of the buffer is advanced by the total amount of bytes
* read. The total amount of bytes read if successful is (size * count).
***************************************************************************/
size_t memfread(void * dst, size_t size, size_t count, MFILE * src)
{
if(src->offset >= src->size) // reached end of buffer
return 0;
int numbytes = size*count;
if((src->offset + numbytes) > src->size) // can't read full # requested
numbytes = src->size - src->offset; // do a partial read
if(numbytes > 0)
memcpy(dst, src->buffer+src->offset, numbytes);
src->offset += numbytes;
return numbytes;
}
/****************************************************************************
* memfgetc
* memory replacement for fgetc
*
* Returns the next character in the buffer specified, and advances the
* postion indicator of the buffer by 1.
***************************************************************************/
int memfgetc(MFILE * src)
{
if(src->offset >= src->size) // reached end of buffer
return MEOF;
else
return src->buffer[src->offset++];
}