#include "segmentsFile.h" #include "../common/platform.h" void fileSegmentInit(file_segment_t *segment, int fd, int pos, int len, char access) { //set basic information segment->fd=fd; segment->access=access; segment->filePos=pos; //enable caching one PC #if defined(PC) segment->cacheOff=-1; segment->cacheLen=0; segment->cacheWritten=0; #endif //enlarge the file if needed int fileSize=File_length(fd); if(fileSize+posfileSize=fileSize; } //enable cache on PC #if defined(PC) void fileSegmentRead(int pos, char* value, void *opaque) { //get the segment information file_segment_t *segment=(file_segment_t*) opaque; //make sure we have cache for this if(!fileSegmentLoad(segment, pos)) return; if(poscacheOff||pos>=segment->cacheOff+segment->cacheLen) return; //read from cache *value=segment->cache[pos-segment->cacheOff]; } void fileSegmentWrite(int pos, char value, void *opaque) { //get the segment information file_segment_t *segment=(file_segment_t*) opaque; //make sure we have cache for this if(!fileSegmentLoad(segment, pos)) return; if(poscacheOff||pos>=segment->cacheOff+segment->cacheLen) return; //write to cache segment->cache[pos-segment->cacheOff]=value; segment->cacheWritten=1; } int fileSegmentFlush(file_segment_t *segment) { //check if we have write access and we have an actual cache if(!(segment->access&MMU_ACCESS_w)) return 0; if(segment->cacheOff==-1||segment->cacheLen==0) return 1; //check if we have written if(!segment->cacheWritten) return 1; //flush to disk return File_write(segment->fd, segment->cacheOff+segment->filePos, segment->cache, segment->cacheLen); } int fileSegmentLoad(file_segment_t *segment, int pos) { //determine the aligned offset, and don't load if it's already loaded pos-=pos/CACHE_LEN; if(segment->cacheOff==pos) return 1; //determine length to cache int len=CACHE_LEN; if(pos+len+segment->filePos>segment->fileSize) len=segment->fileSize-pos; //flush if we need to if(segment->access&MMU_ACCESS_w) { if(!fileSegmentFlush(segment)) return 0; } //invalidate the cache segment->cacheOff=-1; segment->cacheLen=0; //read the file len=File_read(segment->fd, pos+segment->filePos, segment->cache, len); //update the cache segment->cacheOff=pos; segment->cacheLen=len; segment->cacheWritten=0; return 1; } //direct access to underlying file cache on casio #else void fileSegmentRead(int pos, char* value, void *opaque) { //get the segment information file_segment_t *segment=(file_segment_t*) opaque; //get offset into disk int offset=pos+segment->filePos; //read from file, the file will check for access itself File_read(segment->fd, offset, value, 1); } void fileSegmentWrite(int pos, char value, void *opaque) { //get the segment information file_segment_t *segment=(file_segment_t*) opaque; //get offset into disk int offset=pos+segment->filePos; //write into file, the file will check for access itself File_write(segment->fd, offset, &value, 1); } #endif