Created
September 8, 2015 09:33
-
-
Save Redchards/bebd526f544fa0f36133 to your computer and use it in GitHub Desktop.
Simple C++ wrapper around C functions. Sometimes easier to use that C++standard file streaming function.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <File.hxx> | |
File::File(const std::string& pathName, const char* openMode) : fileInfos_(initPath(pathName)), | |
filePtr_(nullptr), | |
openMode_(openMode) | |
{ | |
init(); | |
} | |
File::File(std::string&& pathName, const char* openMode) : fileInfos_(initPath(std::move(pathName))), | |
filePtr_(nullptr), | |
openMode_(openMode) | |
{ | |
init(); | |
} | |
File::File(const File& other) : fileInfos_(other.fileInfos_.getFilePath()), | |
filePtr_(nullptr), | |
openMode_(other.openMode_) | |
{ | |
init(); | |
} | |
File::File(File&& other) : fileInfos_(std::move(other.fileInfos_.getFilePath())) | |
{ | |
std::swap(filePtr_, other.filePtr_); | |
other.filePtr_ = nullptr; | |
std::swap(openMode_, other.openMode_); | |
other.openMode_ = 0; | |
init(); | |
} | |
File::~File() | |
{ | |
std::fclose(filePtr_); | |
} | |
bool File::operator==(const File& rhs) const noexcept | |
{ | |
return ((filePtr_ == rhs.filePtr_) && (fileInfos_ == rhs.fileInfos_)); | |
} | |
File::operator bool() | |
{ | |
return fileInfos_.exists(); | |
} | |
FileInfos File::getFileInfos() const noexcept | |
{ | |
return fileInfos_; | |
} | |
size_t File::getCursorPosition() const noexcept | |
{ | |
return std::ftell(filePtr_); | |
} | |
void File::setCursorPosition(size_t pos) const noexcept | |
{ | |
std::fseek(filePtr_, pos, SEEK_SET); | |
} | |
char File::readByte() const | |
{ | |
char tmp = std::fgetc(filePtr_); | |
if(tmp == EOF) | |
{ | |
checkForReadError(); | |
} | |
return tmp; | |
} | |
std::unique_ptr<char[]> File::read(size_t byteNum) const | |
{ | |
// Set this to debug, to see if we attempt to read furhter than the EOF | |
/*if(bytes > fileInfos_.getFileSize() - ftell(filePtr_)) | |
{ | |
throw IOException(fileInfos_.getFilePath(), IOAction::READ); | |
}*/ | |
std::unique_ptr<char[]> buf{ new char[byteNum] }; | |
size_t result = std::fread(buf.get(), 1, byteNum, filePtr_); | |
if(result < byteNum) | |
{ | |
checkForReadError(); | |
} | |
return buf; | |
} | |
void File::writeByte(char byte) const | |
{ | |
char tmp = std::fputc(byte, filePtr_); | |
if(tmp == EOF) | |
{ | |
checkForWriteError(); | |
} | |
} | |
void File::writeBuffer(const char* buf, size_t byteNum) const | |
{ | |
size_t result = std::fwrite(buf, 1, byteNum, filePtr_); | |
if(result < byteNum) | |
{ | |
checkForWriteError(); | |
} | |
} | |
void File::rewind() | |
{ | |
std::fseek(filePtr_, 0, SEEK_SET); | |
} | |
File File::create(const std::string& filePath, const char* openMode) | |
{ | |
auto last = filePath.find_last_of(FileInfos::pathDelimiter); | |
struct stat s; | |
auto err = stat(filePath.substr(0, last).data(), &s); | |
std::cout << filePath.substr(0, last).data() << std::endl; | |
if(err != 0) | |
{ | |
throw CStatException(err, filePath); | |
} | |
std::ofstream ff(filePath, std::ios::out); | |
ff.close(); | |
File newFile(filePath, openMode); | |
newFile.fileInfos_.updateFileInfos(); | |
newFile.init(); | |
return newFile; | |
} | |
void File::init() | |
{ | |
filePtr_ = std::fopen((fileInfos_.exists() ? fileInfos_.getFilePath().c_str() : ""), openMode_); | |
if(filePtr_ == nullptr) | |
{ | |
throw IOException(fileInfos_.getFilePath(), IOAction::OPEN); | |
} | |
} | |
void File::checkForReadError() const | |
{ | |
if((ferror(filePtr_) != 0)) | |
{ | |
throw IOException(fileInfos_.getFilePath(), IOAction::READ); | |
} | |
} | |
void File::checkForWriteError() const | |
{ | |
if((ferror(filePtr_) != 0)) | |
{ | |
throw IOException(fileInfos_.getFilePath(), IOAction::WRITE); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef UZIP_FILE | |
#define UZIP_FILE | |
#include <FileInfos.hxx> | |
#include <cstring> | |
#include <fstream> | |
// NOTE : Should I reimplement it with stl instead of c lib ? | |
class File | |
{ | |
public: | |
File(const std::string& pathName, const char* openMode = "rw"); | |
File(std::string&& pathName, const char* openMode = "rw"); | |
File(const File& other); | |
File(File&& other); | |
~File(); | |
bool operator==(const File&) const noexcept; | |
operator bool(); | |
FileInfos getFileInfos() const noexcept; | |
size_t getCursorPosition() const noexcept; | |
void setCursorPosition(size_t pos) const noexcept; | |
char readByte() const; | |
std::unique_ptr<char[]> read(size_t byteNum) const; | |
void writeByte(char byte) const; | |
void writeBuffer(const char* buf, size_t byteNum) const; | |
void rewind(); | |
static File create(const std::string& filePath, const char* openMode = "rw"); | |
private: | |
void init(); | |
template<class T> | |
std::string initPath(T&& pathName) const; | |
void checkForReadError() const; | |
void checkForWriteError() const; | |
FileInfos fileInfos_; | |
FILE* filePtr_; | |
const char* openMode_; | |
}; | |
template<class T> | |
std::string File::initPath(T&& pathName) const | |
{ | |
if(pathName[0] == FileInfos::pathDelimiter) | |
{ | |
return std::move(std::string(pathName)); | |
} | |
std::string f(std::forward<T>(pathName)); | |
auto last = f.find_last_of(FileInfos::pathDelimiter); | |
char* tmp{ get_current_dir_name() }; | |
std::string retval = ""; | |
if(last != std::string::npos) | |
{ | |
retval = std::string(tmp + f.substr(last, f.length() - 1)); | |
free(tmp); | |
return retval; | |
} | |
retval = std::string(tmp) + FileInfos::pathDelimiter + std::string(std::move(f)); | |
free(tmp); | |
return retval; | |
} | |
#endif // UZIP_FILE |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <FileInfos.hxx> | |
char FileInfos::pathDelimiter = '/'; | |
bool FileInfos::operator==(const FileInfos& rhs) const noexcept | |
{ | |
return (filePath_ == rhs.filePath_); | |
} | |
const std::string& FileInfos::getFilePath() const noexcept | |
{ | |
return filePath_; | |
} | |
const std::string FileInfos::getFileName() const noexcept | |
{ | |
auto last = filePath_.find_last_of(pathDelimiter); | |
return filePath_.substr(last, filePath_.length() - 1); | |
} | |
uint64 FileInfos::getFileSize() noexcept | |
{ | |
updateFileInfos(); | |
return fileStat_.st_size; | |
} | |
bool FileInfos::exists() noexcept | |
{ | |
updateFileInfos(); | |
return exists_; | |
} | |
std::unique_ptr<tm> FileInfos::getLastAccessTime() noexcept | |
{ | |
updateFileInfos(); | |
return std::unique_ptr<tm>{ gmtime(&(fileStat_.st_atime)) }; | |
} | |
std::unique_ptr<tm> FileInfos::getLastModificationTime() noexcept | |
{ | |
updateFileInfos(); | |
return std::unique_ptr<tm>{ gmtime(&(fileStat_.st_mtime)) }; | |
} | |
void FileInfos::updateFileInfos() | |
{ | |
auto err = stat(filePath_.data(), &fileStat_); | |
if(err != 0) | |
{ | |
if(err != ENOENT && err != ENOTDIR) | |
{ | |
exists_ = false; | |
} | |
else | |
{ | |
throw CStatException(err, filePath_); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef UZIP_FILE_INFOS | |
#define UZIP_FILE_INFOS | |
#include <CommonTypes.hxx> | |
#include <Exceptions.hxx> | |
#include <Platform.hxx> | |
#include <climits> | |
#include <ctime> | |
#include <unistd.h> | |
#include <sys/stat.h> | |
#include <memory> | |
#include <string> | |
#include <iostream> | |
class FileInfos | |
{ | |
public: | |
template<class T> | |
FileInfos(T&& filePath) : | |
filePath_(filePath[0] == '/' ? std::forward<T>(filePath) : ""), | |
exists_(true), | |
fileStat_{} | |
{ | |
updateFileInfos(); | |
} | |
bool operator==(const FileInfos& rhs) const noexcept; | |
const std::string& getFilePath() const noexcept; | |
const std::string getFileName() const noexcept; | |
uint64 getFileSize() noexcept; | |
bool exists() noexcept; | |
std::unique_ptr<tm> getLastAccessTime() noexcept; | |
std::unique_ptr<tm> getLastModificationTime() noexcept; | |
void updateFileInfos(); | |
static char pathDelimiter; | |
private: | |
const std::string filePath_; | |
bool exists_; | |
struct stat fileStat_; | |
// To change on other systems | |
}; | |
#endif // UZIP_FILE_INFOS |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment