00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <sys/types.h>
00034 #include <sys/stat.h>
00035 #include <inttypes.h>
00036
00037
00038 #include <assert.h>
00039
00040 #include "Log.h"
00041 #include "FileBlockManager.h"
00042
00043 using namespace std;
00044
00045 FileBlockManager::FileBlockManager() :
00046 isOpenFlag(false), path("(null)"), fp(NULL) {
00047 }
00048
00049 FileBlockManager::~FileBlockManager() {
00050 close();
00051 }
00052
00053 const string& FileBlockManager::getPath() const {
00054 return path;
00055 }
00056
00057 string FileBlockManager::getFileName() const {
00058 if(path.find("/") != string::npos) {
00059 return path.substr(path.rfind("/")+1);
00060 }
00061 else {
00062 return path;
00063 }
00064 }
00065
00066 string FileBlockManager::getBlock(uint64_t index) {
00067 assert(isOpen());
00068 if (fp == 0) {
00069 fprintf(stderr,
00070 "FileBlockManager::getBlock: attempt to read block for null file pointer\n");
00071 exit(-1);
00072 }
00073
00074 size_t offset = index * blockSize;
00075 char buf[blockSize];
00076
00077 if (fseek(fp, offset, SEEK_SET) < 0) {
00078 perror("FileBlockManager::getBlock: fseek");
00079 exit(-1);
00080 }
00081
00082 int read = fread(buf, 1, blockSize, fp);
00083 if (ferror(fp)) {
00084 perror("FileBlockManager::getBlock: fread");
00085 exit(-1);
00086 }
00087 if ((read == 0) && (feof(fp))) {
00088 clearerr(fp);
00089 fprintf(stderr, "FileBlockManager::getBlock: read 0 sized block for EOF\n");
00090 exit(-1);
00091
00092
00093 }
00094 else if (read <= 0) {
00095 perror("FileBlockManager::getBlock: fread");
00096 exit(-1);
00097 }
00098
00099 return string(buf, read);
00100 }
00101
00102 size_t FileBlockManager::setBlock(uint64_t index, const string& buf) {
00103 assert(isOpen());
00104 if (fp == 0) {
00105 fprintf(stderr,
00106 "FileBlockManager::setBlock: attempt to write block for null file pointer\n");
00107 exit(-1);
00108 }
00109
00110 size_t offset = index * blockSize;
00111 if (fseek(fp, offset, SEEK_SET) < 0) {
00112 perror("FileBlockManager::setBlock: fseek");
00113 exit(-1);
00114 }
00115 size_t r = fwrite(buf.data(), 1, buf.size(), fp);
00116 if (r != buf.size()) {
00117 perror("FileBlockManager::setBlock: fwrite");
00118 exit(-1);
00119 }
00120 return r;
00121 }
00122
00123 int FileBlockManager::open(const std::string& p, const char* mode) {
00124 if (isOpen()) {
00125 return 0;
00126 }
00127 Log::logf("FileBlockManager::open", "path=%s mode=%s", p.c_str(), mode);
00128
00129 fp = fopen(p.c_str(), mode);
00130 if (fp == 0) {
00131 perror("FileBlockManager: fopen");
00132 exit(-1);
00133
00134 }
00135
00136 isOpenFlag = true;
00137 path = p;
00138
00139
00140 struct stat sbuf;
00141 if (fstat(fileno(fp), &sbuf) != 0) {
00142 perror("FileBlockManager::open: fstat");
00143 exit(-1);
00144
00145 }
00146
00147 size = sbuf.st_size;
00148 blockCount = size / blockSize;
00149 if ((size % blockSize) != 0) {
00150 blockCount++;
00151 }
00152
00153 Log::logf("FileBlockManager::open",
00154 "opened file %d size=%" PRIu64 " blockSize=%zu blockCount=%"
00155 PRIu64 , fileno(fp), size, blockSize, blockCount);
00156
00157 return 0;
00158 }
00159
00160 bool FileBlockManager::isOpen() const {
00161 return isOpenFlag;
00162 }
00163
00164 int FileBlockManager::close() {
00165 if (!isOpen()) {
00166 return 0;
00167 }
00168 isOpenFlag = false;
00169 Log::logf("FileBlockManager::close", "closing file %d", fileno(fp));
00170 int r = fclose(fp);
00171 return r;
00172 }
00173
00174 int FileBlockManager::flush() {
00175 if (!isOpen()) {
00176 return 0;
00177 }
00178
00179 int r = fflush(fp);
00180 return r;
00181 }