1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <sys/types.h> 5 #include <sys/stat.h> 6 7 #include "block_file_accessor.h" 8 9 10 11 BlockFileAccessor::BlockFileAccessor(const char *path, fileid_t fileid) 12 : Accessor(fileid) 13 { 14 /* Obtain the size of the file. */ 15 16 struct stat buf; 17 18 if (stat(path, &buf)) 19 { 20 _size = 0; 21 return; 22 } 23 24 /* Allocate memory. */ 25 26 _size = buf.st_size; 27 _data = (char *) malloc(_size); 28 29 if (_data == NULL) 30 return; 31 32 /* Load the file into memory and initialise the size. */ 33 34 FILE *fp = fopen(path, "r"); 35 36 if (fp == NULL) 37 { 38 free(_data); 39 return; 40 } 41 42 _size = fread(_data, sizeof(char), _size, fp); 43 44 fclose(fp); 45 } 46 47 /* Update the size of the file. */ 48 49 void BlockFileAccessor::set_size(offset_t size) 50 { 51 void *new_data = realloc(_data, size); 52 53 if (new_data != NULL) 54 { 55 _data = (char *) new_data; 56 57 if (size > _size) 58 memset(_data + _size, 0, size - _size); 59 60 Accessor::set_size(size); 61 } 62 } 63 64 /* Data transfer helper methods. */ 65 66 /* Fill the populated portion of a flexpage. */ 67 68 void BlockFileAccessor::fill_populated(Flexpage *flexpage) 69 { 70 offset_t filepos = flexpage->base_offset; 71 address_t addr = flexpage->base_addr; 72 offset_t populated_size = _size - filepos; 73 74 if (populated_size > flexpage->size) 75 populated_size = flexpage->size; 76 77 /* Tag the region with file state. */ 78 79 flexpage->region->fill(fileid, filepos); 80 81 /* Fill the region with file content. */ 82 83 memcpy((void *) addr, _data + filepos, populated_size); 84 85 /* Pad the flexpage with zero. */ 86 87 if (populated_size < flexpage->size) 88 memset((void *) (addr + populated_size), 0, flexpage->size - populated_size); 89 } 90 91 /* Flush the populated portion of a flexpage. */ 92 93 void BlockFileAccessor::flush_populated(Flexpage *flexpage) 94 { 95 offset_t filepos = flexpage->base_offset; 96 address_t addr = flexpage->base_addr; 97 offset_t populated_size = _size - filepos; 98 99 if (populated_size > flexpage->size) 100 populated_size = flexpage->size; 101 102 /* Remove the file state tag from the region. */ 103 104 flexpage->region->flush(); 105 106 /* Copy the populated region to the block memory. */ 107 108 memcpy((void *) (_data + filepos), (const void *) addr, populated_size); 109 } 110 111 // vim: tabstop=4 expandtab shiftwidth=4