Program Listing for File ofile_pos.hpp

Return to documentation for file (/tmp/ws/src/ecl_core/ecl_devices/include/ecl/devices/ofile_pos.hpp)

/*****************************************************************************
** Ifdefs
*****************************************************************************/

#ifndef ECL_DEVICES_OFILE_POS_HPP_
#define ECL_DEVICES_OFILE_POS_HPP_

/*****************************************************************************
** Cross Platform Functionality
*****************************************************************************/

#include <ecl/config/ecl.hpp>
#if defined(ECL_IS_POSIX)

/*****************************************************************************
** Includes
*****************************************************************************/

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <cstdio> // FILE calls
#include <string>
#include <ecl/concepts/containers.hpp>
#include <ecl/exceptions/macros.hpp>
#include <ecl/exceptions/standard_exception.hpp>
#include "detail/exception_handler_pos.hpp"
#include "modes.hpp"
#include "traits.hpp"

/*****************************************************************************
** Namespaces
*****************************************************************************/

namespace ecl {

/*****************************************************************************
** Interface [Output File]
*****************************************************************************/
class OFile {
public:
    /*********************
    ** C&D
    **********************/
    OFile();
    OFile(const std::string &file_name, const WriteMode &mode = New);

    virtual ~OFile();

    /*********************
    ** Open/Close
    **********************/
    virtual bool open() { return ( file != NULL ) ? true : false; }

    virtual bool open(const std::string &file_name, const WriteMode &mode = New);

    virtual bool close();

    /*********************
    ** Utility Methods
    **********************/
    virtual const std::string& filename() const { return name; }


    /*********************
    ** Output Methods
    **********************/
    virtual long write(const char &c);
    long write(const char* s, unsigned long n);

    template <typename ByteArray>
    long write(const ByteArray &byte_array);
    virtual bool flush();

    const Error& error() const { return error_handler; }

private:
    /*********************
    ** Variables
    **********************/
    int file_descriptor;
    FILE *file;
    std::string name;
    Error error_handler;
};

/*****************************************************************************
** Template Implementation
*****************************************************************************/

template <typename ByteArray>
long OFile::write(const ByteArray&byte_array) {

    ecl_compile_time_concept_check(ecl::ByteContainerConcept<ByteArray>);
    if ( !open() ) {
        ecl_debug_throw(ecl::StandardException(LOC, OpenError, std::string("File ") + name + std::string(" is not open for writing.")));
        error_handler = OpenError;
        return -1;
    }
    size_t written = fwrite(&byte_array[0],byte_array.size(),1,file);
    if ( written == 0) {
        ecl_debug_throw(ecl::StandardException(LOC, WriteError, std::string("Could not write to ") + name + std::string(".")));
        error_handler = WriteError;
        return -1;
    }
    error_handler = NoError;
    return byte_array.size()*written; // fwrite returns the number of 'items' written, not bytes!
}


/*****************************************************************************
** Traits [OFile]
*****************************************************************************/

template <>
class is_sink<OFile> : public True {};

} // namespace ecl


#endif /* ECL_IS_POSIX */
#endif /* ECL_DEVICES_OFILE_POS_HPP_ */