Esempio n. 1
0
long mfseek(MEMFILE *mf,long offset,int whence)
{
  long length;

  assert(mf!=NULL);
  if (mf->usedoffs == 0)
    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:
    offset+=mf->offs;
    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 */
  memfile_seek(mf, offset);
  return offset;
}
Esempio n. 2
0
unsigned int mfread(MEMFILE *mf,unsigned char *buffer,unsigned int size)
{
    long length;
    long numblocks;
    int blockpos,blocksize;
    unsigned int bytes;
    MEMFILE *block;

    assert(mf!=NULL);

    /* adjust the size to read */
    length=mflength(mf);
    assert(mf->bufpos>=0 && mf->bufpos<=length);
    if (mf->bufpos+size>(unsigned long)length)
        size=(int)(length-mf->bufpos);
    assert(mf->bufpos+size<=(unsigned long)length);
    if (size==0)
        return 0;

    /* find the block to start reading from */
    numblocks=mf->bufpos/BUFFERSIZE;      /* # blocks to skip */
    block=mf->next;
    while (numblocks-->0) {
        assert(block!=NULL);
        block=block->next;
    } /* while */
    assert(block!=NULL);

    /* copy out of memory */
    bytes=0;
    blockpos=(int)(mf->bufpos % BUFFERSIZE);
    do {
        blocksize=BUFFERSIZE-blockpos;
        if ((unsigned int)blocksize>size)
            blocksize=size;

        assert(block!=NULL);
        assert(block->bufpos>=0 && (unsigned long)block->bufpos<=BUFFERSIZE);
        assert(blockpos+blocksize<=block->bufpos);
        memcpy(buffer,block->buffer+blockpos,blocksize);
        buffer+=blocksize;
        size-=blocksize;
        bytes+=blocksize;

        block=block->next;
        blockpos=0;
    } while (size>0);

    /* adjust file pointer */
    mf->bufpos+=bytes;

    return bytes;
}
Esempio n. 3
0
unsigned int mfwrite(MEMFILE *mf,unsigned char *buffer,unsigned int size)
{
    long length;
    long numblocks;
    int blockpos,blocksize;
    unsigned int bytes;
    MEMFILE *block;

    assert(mf!=NULL);

    /* see whether more memory must be allocated */
    length=mflength(mf);
    assert(mf->bufpos>=0 && mf->bufpos<=length);
    numblocks=(length+BUFFERSIZE-1)/BUFFERSIZE;   /* # allocated blocks */
    while (mf->bufpos+size>numblocks*BUFFERSIZE) {
        /* append a block */
        MEMFILE *last;
        block=(MEMFILE*)malloc(sizeof(MEMFILE));
        if (block==NULL)
            return 0;
        memset(block,0,sizeof(MEMFILE));
        block->buffer=(unsigned char*)malloc(BUFFERSIZE);
        if (block->buffer==NULL) {
            free(block);
            return 0;
        } /* if */
        for (last=mf; last->next!=NULL; last=last->next)
            /* nothing */;
        assert(last!=NULL);
        assert(last->next==NULL);
        last->next=block;
        numblocks++;
    } /* while */

    if (size==0)
        return 0;

    /* find the block to start writing to */
    numblocks=mf->bufpos/BUFFERSIZE;      /* # blocks to skip */
    block=mf->next;
    while (numblocks-->0) {
        assert(block!=NULL);
        block=block->next;
    } /* while */
    assert(block!=NULL);

    /* copy into memory */
    bytes=0;
    blockpos=(int)(mf->bufpos % BUFFERSIZE);
    do {
        blocksize=BUFFERSIZE-blockpos;
        assert(blocksize>=0);
        if ((unsigned int)blocksize>size)
            blocksize=size;

        assert(block!=NULL);
        memcpy(block->buffer+blockpos,buffer,blocksize);
        buffer+=blocksize;
        size-=blocksize;
        bytes+=blocksize;

        if (blockpos+blocksize>block->bufpos)
            block->bufpos=blockpos+blocksize;
        assert(block->bufpos>=0 && (unsigned long)block->bufpos<=BUFFERSIZE);
        block=block->next;
        blockpos=0;
    } while (size>0);

    /* adjust file pointer */
    mf->bufpos+=bytes;

    return bytes;
}