Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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());
    }
}
share|improve this question
Should add the header file also. – avip Nov 8 '12 at 7:14
One hint: If you want to test the behavior, you could just (temporarily) use a very small file size and see what happens. – leemes Nov 8 '12 at 10:26

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.