MASA-Core
SpecialRowFile.cpp
Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Copyright (c) 2010-2015   Edans Sandes
00004  *
00005  * This file is part of MASA-Core.
00006  * 
00007  * MASA-Core is free software: you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation, either version 3 of the License, or
00010  * (at your option) any later version.
00011  * 
00012  * MASA-Core is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with MASA-Core.  If not, see <http://www.gnu.org/licenses/>.
00019  *
00020  ******************************************************************************/
00021 
00022 #include "SpecialRowFile.hpp"
00023 
00024 #include <unistd.h>
00025 #include <sys/types.h>
00026 #include <sys/stat.h>
00027 #include <stdlib.h>
00028 
00029 #define DEBUG (0)
00030 
00031 /*
00032  * @see description on header file
00033  */
00034 SpecialRowFile::SpecialRowFile(string* path, string filename)
00035 {
00036         this->path = path;
00037         this->filename = filename;
00038         this->file = NULL;
00039         int id = -1;
00040         if (filename.length() == 8) {
00041                 sscanf(filename.c_str(), "%X", &id);
00042         } else if (filename.length() == 8 + 4 && filename.compare(filename.length()-4, 4, ".tmp") == 0) {
00043                 string fullFile = ((*path) + "/" + filename);
00044                 //printf("Removing Temporary File: %s\n", fullFile.c_str());
00045                 remove(fullFile.c_str());
00046         }
00047         setId(id);
00048 }
00049 
00050 /*
00051  * @see description on header file
00052  */
00053 SpecialRowFile::SpecialRowFile(string* path, int id)
00054 {
00055         this->path = path;
00056         this->file = NULL;
00057         setId(id);
00058 
00059         char str[256];
00060         sprintf(str, "%08X", id);
00061         this->filename = string(str);
00062 
00063 }
00064 
00065 /*
00066  * @see description on header file
00067  */
00068 SpecialRowFile::~SpecialRowFile()
00069 {
00070         close();
00071 }
00072 
00073 /*
00074  * @see description on header file
00075  */
00076 void SpecialRowFile::initialize(bool readOnly, int length) {
00077         string filename = getFullFilename(!readOnly);
00078         file = fopen(filename.c_str(), readOnly ? "rb" : "wb");
00079         if (file == NULL) {
00080                 fprintf(stderr, "Could not %s special row: %s\n", readOnly?"open":"create",
00081                                 filename.c_str());
00082                 perror("fopen()");
00083                 exit(1);
00084         }
00085         if (!readOnly) {
00086                 truncate(filename.c_str(), length*sizeof(cell_t));
00087         }
00088 }
00089 
00090 /*
00091  * @see description on header file
00092  */
00093 void SpecialRowFile::close() {
00094         if (file != NULL) {
00095                 fclose(file);
00096                 file = NULL;
00097                 string filenameTmp = getFullFilename(true);
00098                 string filenameDef = getFullFilename(false);
00099                 rename(filenameTmp.c_str(), filenameDef.c_str());
00100                 //printf("Closed %s\n", filename.c_str());
00101         }
00102 }
00103 
00104 /*
00105  * @see description on header file
00106  */
00107 void SpecialRowFile::truncateRow(int size) {
00108         string filenameDef = getFullFilename(false);
00109         if (size == 0) {
00110                 remove(filenameDef.c_str());
00111                 //printf("Removed %s\n", filenameDef.c_str());
00112         } else {
00113                 struct stat st;
00114                 stat(filenameDef.c_str(), &st);
00115                 if (size*sizeof(cell_t) < st.st_size) {
00116                         truncate(filenameDef.c_str(), size*sizeof(cell_t));
00117                         //printf("Truncated[%d bytes] %s\n", st.st_size - size*sizeof(cell_t), filenameDef.c_str());
00118                 }
00119         }
00120 }
00121 
00122 /*
00123  * @see description on header file
00124  */
00125 int SpecialRowFile::write(const cell_t* buf, int offset, int len) {
00126         return fwrite(buf, sizeof(cell_t), len, file);
00127 }
00128 
00129 /*
00130  * @see description on header file
00131  */
00132 int SpecialRowFile::read(cell_t* buf, int offset, int len) {
00133         if (DEBUG) printf("SpecialRowFile::read(%p, %d, %d): %s\n", buf, offset, len, filename.c_str());
00134         fseek(file, offset*sizeof(cell_t), SEEK_SET);
00135         int pos = 0;
00136         while (pos<len) {
00137                 int ret = fread(buf, sizeof(cell_t), len-pos, file);
00138                 if (ret == 0) {
00139                         return pos;
00140                 }
00141                 pos += ret;
00142         }
00143         return pos;
00144 }
00145 
00146 string SpecialRowFile::getFullFilename(bool temp) {
00147         if (temp) {
00148                 return (*path) + "/" + filename + ".tmp";
00149         } else {
00150                 return (*path) + "/" + filename;
00151         }
00152 }