📄 memfile.c
字号:
#include "memfile.h"
#include <malloc.h>
#include <memory.h>
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#define mf_point_cmp(point1 , point2) \
((point1.block!=point2.block)? \
(point1.block<point2.block) : \
(point1.offset<point2.offset))
int _mf_block_size[9] = {
512, /*0.5k */
512 << 3, /*4.0k */
512 << 6, /*32.0k */
512 << 9, /*256.0k */
512 << 12, /*2.0m */
512 << 15, /*16.0m */
512 << 18, /*128.0m */
512 << 21, /*1024m */
512 << 24 /*8g */
};
MEMFILE * mf_alloc ()
{
MEMFILE *mf = (MEMFILE *) malloc (sizeof (MEMFILE));
memset (mf, 0, sizeof (MEMFILE));
return mf;
}
void mf_free(MEMFILE *mf)
{
int i;
assert(mf!=0);
for (i=0;i < mf->alloc_block;++i)
{
assert(mf->data[i]);
free(mf->data[i]);
}
free(mf);
}
FILE *fp=NULL;
int mf_read (MEMFILE * mf, void *buf, int size)
{
int need = size;
unsigned char *pb = (unsigned char *) buf;
if (fp==NULL) fp=fopen("dbg.txt","wt");
fprintf(fp,"(%d,%d) ",mf->current_point.block,mf->current_point.offset);
while (need > 0 && mf_point_cmp (mf->current_point, mf->end_point) /*Is EOF */
)
{
int current_block = mf->current_point.block;
int current_offset = mf->current_point.offset;
int current_size = (mf->end_point.block > current_block) ? /*not the last block */
_mf_block_size[current_block] : /*full size */
mf->end_point.offset;
int block_left = current_size - current_offset;
int byte_to_copy = (need >= block_left) ? block_left : need;
memcpy (pb,mf->data[current_block]+mf->current_point.offset, byte_to_copy);
need -= byte_to_copy;
pb += byte_to_copy;
/*update the point */
if (byte_to_copy == block_left)
{
++mf->current_point.block;
mf->current_point.offset = 0;
}
else
{
mf->current_point.offset += byte_to_copy;
}
}
fprintf(fp,"%d (%d,%d)\n",size-need,mf->current_point.block,mf->current_point.offset);
return size - need;
}
void mf_write (MEMFILE * mf, const void *buf, int size)
{
const unsigned char *pb = (const unsigned char *) buf;
int need = size;
while (need > 0)
{
int current_block = mf->current_point.block;
int current_offset = mf->current_point.offset;
int block_left,byte_to_copy;
if (current_block == mf->alloc_block)
{
mf->data[current_block] = (unsigned char *)
malloc (_mf_block_size[current_block]);
++mf->alloc_block;
}
block_left = _mf_block_size[current_block] - current_offset;
byte_to_copy = (need >= block_left) ? block_left : need;
memcpy (mf->data[current_block] + current_offset, pb, byte_to_copy);
need -= byte_to_copy;
pb += byte_to_copy;
if (byte_to_copy == block_left)
{
++mf->current_point.block;
mf->current_point.offset = 0;
}
else
{
mf->current_point.offset += byte_to_copy;
}
}
if (mf_point_cmp (mf->end_point, mf->current_point))
mf->end_point = mf->current_point;
}
#define positive_seek \
while (offset>0 && mf_point_cmp(mf->current_point,mf->end_point))\
{\
if (offset<_mf_block_size[mf->current_point.block])\
{\
mf->current_point.offset+=offset;\
offset=0;\
}\
else\
{\
offset-=_mf_block_size[mf->current_point.block] -\
mf->current_point.offset;\
++mf->current_point.block;\
mf->current_point.offset=0;\
}\
}
#define negtive_seek \
{\
offset=-offset;\
mf->current_point.offset-=offset;\
while(mf->current_point.offset<0)\
{\
--mf->current_point.block;\
if (mf->current_point.block<0)\
{\
mf->current_point.block=0;\
mf->current_point.offset=0;\
break;\
}\
mf->current_point.offset+=_mf_block_size[mf->current_point.block];\
}\
}
void mf_seek (MEMFILE * mf, int pos, int offset)
{
switch (pos)
{
case MEMFILE_START:
mf->current_point.block = 0;
mf->current_point.offset = 0;
positive_seek;
break;
case MEMFILE_CURRENT:
if (offset > 0)
{
positive_seek;
}
else
{
negtive_seek}
break;
case MEMFILE_END:
if (offset < 0)
{
mf->current_point = mf->end_point;
negtive_seek}
break;
default:
break;
}
}
int mf_length (MEMFILE * mf)
{
int size = 0;
int i;
for (i = 0; i < mf->end_point.block ; ++i)
size += _mf_block_size[i];
size += mf->end_point.offset;
return size;
}
void mf_dump (MEMFILE * mf, int bdata)
{
int i;
printf ("current point = (%d,%d)\n", mf->current_point.block,
mf->current_point.offset);
if (bdata)
for (i = 0; i < 8; ++i)
{
printf ("data[%d] = ", i);
if (mf->data[i] == NULL)
printf ("NULL");
else
{
int j;
for (j = 0; j < _mf_block_size[i]; ++j)
putchar ((int) (*(mf->data[i] + j)));
}
putchar ('\n');
}
}
int mf_test (int size, int block)
{
unsigned char *buf = (unsigned char *)malloc (block);
int i;
int totalsize;
MEMFILE *mf;
for (i = 0; i < block; ++i)
buf[i] =(unsigned char) i;
mf = mf_alloc ();
for (i = 0; i < size / block; ++i)
mf_write (mf, buf, block);
mf_write (mf, buf, size % block);
if (mf_length (mf) != size)
{
printf ("endpoint=(%d,%d)\n", mf->end_point.block,
mf->end_point.offset);
printf ("current point=(%d,%d)\n", mf->current_point.block,
mf->current_point.offset);
printf ("size:%d\n", mf_length (mf));
return 1;
}
mf_seek (mf, MEMFILE_START, 0);
totalsize = 0;
while (1)
{
int persize;
int i;
persize = mf_read (mf, buf, block);
totalsize += persize;
for (i = 0; i < persize; ++i)
if (buf[i] != (unsigned char) i)
return 2;
if (persize < block)
break;
}
return 0;
mf_free (mf);
free (buf);
}
void mf_putc(MEMFILE* mf,char c)
{
if (mf->alloc_block == mf->current_point.block)
{
mf->data[mf->current_point.block] = (unsigned char *)
malloc (_mf_block_size[mf->current_point.block]);
++mf->alloc_block;
}
*(mf->data[mf->current_point.block] + mf->current_point.offset) = c;
++mf->current_point.offset;
if (mf->current_point.offset == _mf_block_size[mf->current_point.block])
{
++mf->current_point.block;
mf->current_point.offset=0;
}
if (mf_point_cmp(mf->end_point,mf->current_point))
mf->end_point = mf->current_point;
}
void mf_flush(MEMFILE* mf)
{
return;
}
void mf_clear(MEMFILE* mf)
{
mf->current_point.block=0;
mf->current_point.offset=0;
mf->end_point.block=0;
mf->end_point.offset=0;
}
void mf_printf(MEMFILE*mf,const char* format,...)
{
#define bufsize 1024
char buf[bufsize];
int size;
va_list arglist;
va_start(arglist, format);
size=vsprintf(buf,format,arglist);
va_end(arglist);
assert(size<bufsize);
mf_write(mf,buf,size);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -