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