This is a log file writer that appends binary data to an existing or non existing log file. It will only write to a file up to 2 gigs. Upon exceeding 2 gigs it would open another log file by simply icrementing a log file number.
Could I do anything better? Where am I going wrong?
#include "loggerfileconnector.h"
enum { MaxBytes = 0x7FFFFFFF }; //2 Gigs;
LoggerFileConnector::LoggerFileConnector(std::string filename_,
bool appendMode_):
mLogFilename(filename_) {
boost::algorithm::trim(filename_);
if (filename_.compare("") == 0) {
throw std::runtime_error("You cannot pass me an empty file name"
" says the File Logger");
}
if (appendMode_){
OpenCorrectFileToAppend(filename_);
} else {
mLogFilename = filename_;
mFileOut.open(mLogFilename.c_str(),
std::ios::out | std::ios_base::binary);
}
}
LoggerFileConnector::~LoggerFileConnector(void){
if (mFileOut.is_open()){
mFileOut.close();
}
}
std::ios::pos_type LoggerFileConnector::FileSize() {
return mFileOut.tellp();
}
void LoggerFileConnector::OpenCorrectFileToAppend(std::string &filename_) {
// Check to see if user tried to append his own file type
std::vector<std::string> pathTokens;
boost::split(pathTokens, filename_, boost::is_any_of("."));
// Take file file name and start of at version 0 of the file.
filename_ = pathTokens[0];
filename_ += std::string(".");
filename_ += std::string("0");
filename_ += std::string(".log");
// Open the requested file starting at number 0
mFileOut.open(filename_.c_str(),
std::ios::app | std::ios_base::binary);
// Get the file size
mFileOut.seekp(0, std::ifstream::end);
std::ios::pos_type size = FileSize();
// Close the file because we might open and close it in the loop below
// to determine the file number.
mFileOut.close();
// If file size larger than MaxBytes (see top of source file) then we need
// to increment the file number untill we find one that is not full. Or
// untill we hit the 100th version of the file.
uint32_t i = 1;
while (size >= MaxBytes && i < 100) {
pathTokens.clear();
boost::split(pathTokens, filename_, boost::is_any_of("."));
filename_ = pathTokens[0];
filename_ += std::string(".");
filename_ += boost::lexical_cast<std::string>(i);
filename_ += std::string(".log");
// Open the requested file starting at base 0
mLogFilename = filename_;
mFileOut.open(filename_.c_str(),
std::ios::app | std::ios_base::binary);
// Get the file size
mFileOut.seekp(0, std::ifstream::end);
size = FileSize();
mFileOut.close();
}
// Finally set the file name for this.
mLogFilename = filename_;
mFileOut.open(mLogFilename.c_str(),
std::ios::app | std::ios_base::binary);
}
void LoggerFileConnector::Append(std::vector<unsigned char> output){
boost::lock_guard<boost::mutex>
guard(MutexControl::GetInstance().GetMutex(MutexControl::LOGGER_MUTEX));
if (mFileOut.is_open()){
if (static_cast<uint32_t>(FileSize()) + output.size() > MaxBytes) {
OpenCorrectFileToAppend(mLogFilename);
}
mFileOut.write((char*)&output[0], output.size());
}
}
void LoggerFileConnector::AppendNoMutex(std::vector<unsigned char> output){
if (mFileOut.is_open()){
mFileOut.write((char*)&output[0], output.size());
}
}