#include "File.h" #include #include #include #include #include #ifndef free_ptr #define free_ptr(ptr) { free(ptr); ptr = NULL; } #endif const size_t INITIAL_BUFFER_SIZE = 4096; const size_t BUFFER_INCREASE_FACTOR = 4; File::File() : file(NULL) , filename(NULL) , mode(NULL) , buffer(NULL) , bufferSize(0) { } File::File(const char* filename, const char* mode) : file(NULL) , filename(NULL) , mode(NULL) , buffer(NULL) , bufferSize(0) { open(filename, mode); } File::File(FILE *openFile) : file(openFile) , filename(NULL) , mode(NULL) , buffer(NULL) , bufferSize(0) { assert(openFile); } File::~File() { close(); } bool File::open(const char* filename, const char* mode) { assert(filename && mode); close(); this->filename = strdup(filename); this->mode = strdup(mode); file = fopen(filename, mode); return file; } bool File::close() { // If no filename and file is not null, this object was working with a file // opened by somebody else, keep it open bool shouldCloseFile = filename; free_ptr(filename); free_ptr(mode); free_ptr(buffer); return file && shouldCloseFile ? fclose(file) != EOF : false; } bool File::printf(const char* format, ...) { assert(file); va_list list; va_start(list, format); int result = vfprintf(file, format, list); va_end(list); return result >= 0; } bool File::scanf(const char* format, ...) { assert(file); va_list list; va_start(list, format); int result = vfscanf(file, format, list); va_end(list); return result != EOF; } int File::getc() { assert(file); return fgetc(file); } bool File::putc(int ch) { assert(file); return fputc(ch, file) != EOF; } const char* File::readLine(size_t* length) { assert(file); if ( eof() ) return NULL; size_t dummy = 0; if ( ! length ) length = &dummy; else *length = 0; for ( int ch = getc(); ch != '\n' && ch != EOF; ch = getc() ) { if ( bufferSize <= *length + 1 && ! increaseBufferCapacity() ) { ungetc(ch, file); return NULL; } buffer[ (*length)++ ] = ch; } buffer[ *length ] = '\0'; return buffer; } bool File::increaseBufferCapacity() { size_t newSize = bufferSize ? BUFFER_INCREASE_FACTOR * bufferSize : INITIAL_BUFFER_SIZE; char* newBuffer = (char*) realloc(buffer, newSize); if ( ! newBuffer ) return false; buffer = newBuffer; bufferSize = newSize; return true; } bool File::gets(char* buffer, size_t size) { assert(file); return fgets(buffer, size, file); } bool File::puts(const char* str) { assert(file); return fputs(str, file) != EOF; } size_t File::read(void *arr, size_t elementSize, size_t elementCount) { assert(file); return fread(arr, elementSize, elementCount, file); } size_t File::write(const void *arr, size_t elementSize, size_t elementCount) { assert(file); return fwrite(arr, elementSize, elementCount, file); } bool File::flush() { assert(file); return fflush(file) != EOF; } long File::tell() const { assert(file); return ftell(file); } bool File::seek(long position, FileOrigin origin) { assert(file); return fseek(file, position, origin) == 0; } bool File::rewind() { assert(file); errno = 0; ::rewind(file); return errno == 0; } bool File::eof() const { assert(file); return feof(file); } bool File::error() const { assert(file); return ferror(file); } void File::clearerr() { assert(file); ::clearerr(file); } File& File::operator<<(bool value) { assert(file); fprintf(file, "%i", value); return *this; } File& File::operator<<(char ch) { assert(file); putc(ch); return *this; } File& File::operator<<(int value) { assert(file); fprintf(file, "%i", value); return *this; } File& File::operator<<(unsigned int value) { assert(file); fprintf(file, "%u", value); return *this; } File& File::operator<<(long value) { assert(file); fprintf(file, "%li", value); return *this; } File& File::operator<<(unsigned long int value) { assert(file); fprintf(file, "%lu", value); return *this; } File& File::operator<<(long long value) { assert(file); fprintf(file, "%lli", value); return *this; } File& File::operator<<(unsigned long long int value) { assert(file); fprintf(file, "%llu", value); return *this; } File& File::operator<<(double value) { assert(file); fprintf(file, "%g", value); return *this; } File& File::operator<<(const char* str) { assert(file); puts(str); return *this; } File& File::operator>>(bool& value) { assert(file); int temp = 0; *this >> temp; value = temp; return *this; } File& File::operator>>(char& ch) { assert(file); ch = getc(); return *this; } File& File::operator>>(int& value) { assert(file); fscanf(file, "%i", &value); return *this; } File& File::operator>>(unsigned int& value) { assert(file); fscanf(file, "%u", &value); return *this; } File& File::operator>>(long int& value) { assert(file); fscanf(file, "%li", &value); return *this; } File& File::operator>>(unsigned long int& value) { assert(file); fscanf(file, "%lu", &value); return *this; } File& File::operator>>(long long int& value) { assert(file); fscanf(file, "%lli", &value); return *this; } File& File::operator>>(unsigned long long int& value) { assert(file); fscanf(file, "%llu", &value); return *this; } File& File::operator>>(double& value) { assert(file); fscanf(file, "%lg", &value); return *this; } bool File::remove(const char* filename) { return ::remove(filename) == 0; } bool File::rename(const char* oldFilename, const char* newFilename) { return ::rename(oldFilename, newFilename) == 0; }