1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include "machine_type.h"
#include "config.h"
#include "buffers.h"
// retval: OK
//
tUInt32 openbuf(tBuffer* hBuf,tUInt8 bufnum,char* filename)
{
unsigned int filenamelen=0;
if (filename == NULL)
return RETNOK;
filenamelen=strlen(filename);
if (filenamelen>510)
filenamelen=510;
hBuf->changesnum=0;
hBuf->valid=0;
hBuf->fresh=1;
hBuf->file=fopen(filename,"rb");
memcpy(hBuf->filename,filename,filenamelen+1);
hBuf->filename[511]=0;
if (hBuf->file)
{
hBuf->valid=1;
hBuf->filesize=getfilesize(hBuf->file);
hBuf->bufsize=hBuf->filesize;
hBuf->bufferpos=-1;
return RETOK;
} else return RETNOK;
}
tUInt32 readbuf(tBuffer* hBuf,tInt64 pos)
{
tBool havetoread=0;
tInt32 bytesread;
if (hBuf->fresh || pos<hBuf->bufferpos || pos>(hBuf->bufferpos+BUFFERSIZE))
{
havetoread=1;
hBuf->bufferpos=pos&(~(BUFFERSIZE-1)); // floor
}
else if ((hBuf->bufferpos+BUFFERMARGIN)>pos && hBuf->bufferpos>=(BUFFERSIZE/2))
{
havetoread=1;
hBuf->bufferpos-=(BUFFERSIZE/2);
}
else if ((hBuf->bufferpos+BUFFERSIZE-BUFFERMARGIN)<pos && (hBuf->bufferpos+(BUFFERSIZE/2))<hBuf->bufsize && hBuf->bufsize>BUFFERSIZE)
{
havetoread=1;
hBuf->bufferpos+=(BUFFERSIZE/2);
}
if (havetoread)
{
hBuf->fresh=0;
if (hBuf->filesize>hBuf->bufferpos)
{
if (setfilepos(hBuf->file,hBuf->bufferpos)!=RETOK)
{
return RETNOK;
}
bytesread=fread(hBuf->data,sizeof(tUInt8),BUFFERSIZE,hBuf->file);
if (bytesread!=BUFFERSIZE && ferror(hBuf->file))
{
return RETNOK;
}
if (bytesread!=BUFFERSIZE)
{
memset(&hBuf->data[bytesread],0,sizeof(tUInt8)*(BUFFERSIZE-bytesread)); // fill the rest with 0
}
} else {
memset(hBuf->data,0,sizeof(tUInt8)*BUFFERSIZE);
}
}
return RETOK;
}
tInt32 getbufferidx(tBuffer* hBuf,tInt64 pos)
{
tInt32 retval=RETOK;
if ((pos<(hBuf->bufferpos+BUFFERMARGIN)) || (pos>(hBuf->bufferpos+BUFFERSIZE-BUFFERMARGIN)))
{
retval=readbuf(hBuf,pos);
}
if (retval==RETOK)
{
retval=pos-(hBuf->bufferpos);
}
return retval;
}
tInt8 savechanges(tBuffer* hBuf)
{
int i;
size_t bytes_written;
// Close the file temporarily
fclose(hBuf->file);
if (hBuf->changesnum)
{
// Try to open for writing
hBuf->file = fopen(hBuf->filename, "r+b");
if (hBuf->file == NULL) {
// Failed to open for writing, try to reopen for reading
hBuf->file = fopen(hBuf->filename, "rb");
return RETNOK;
}
for (i = 0; i < hBuf->changesnum; i++)
{
if (setfilepos(hBuf->file, hBuf->changes[i].pos) == RETNOK)
{
fclose(hBuf->file);
// Try to reopen for reading
hBuf->file = fopen(hBuf->filename, "rb");
return RETNOK;
}
bytes_written = fwrite(&(hBuf->changes[i].after), sizeof(tUInt8), 1, hBuf->file);
if (bytes_written != 1)
{
fclose(hBuf->file);
// Try to reopen for reading
hBuf->file = fopen(hBuf->filename, "rb");
return RETNOK;
}
}
if (fclose(hBuf->file) == EOF)
{
// Try to reopen for reading
hBuf->file = fopen(hBuf->filename, "rb");
return RETNOK;
}
}
// Reopen for reading
hBuf->file = fopen(hBuf->filename, "rb");
if (hBuf->file == NULL) {
return RETNOK;
}
return RETOK;
}
|