binaryfile.hpp

Back to BinaryFile class

pastel/sys/binaryfile/

#ifndef PASTELSYS_BINARYFILE_HPP
#define PASTELSYS_BINARYFILE_HPP

#include "pastel/sys/binaryfile.h"
#include "pastel/sys/ensure.h"
#include "pastel/sys/endian.h"

#include <fstream>

namespace Pastel
{

    inline BinaryFile::BinaryFile()
        : stream_()
        , littleEndian_(true)
    {
    }

    inline BinaryFile::BinaryFile(const std::string& fileName, bool read, bool write)
        : stream_()
        , littleEndian_(true)
    {
        open(fileName, read, write);
    }

    inline BinaryFile::~BinaryFile()
    {
        close();
    }

    inline void BinaryFile::open(const std::string& fileName, bool read, bool write)
    {
        if (fileName.empty())
        {
            return;
        }

        std::ios_base::openmode mode = std::ios_base::binary;

        if (write)
        {
            if (read)
            {
                mode |=
                    std::ios_base::in |
                    std::ios_base::out;
            }
            else
            {
                mode |=
                    std::ios_base::out |
                    std::ios_base::trunc;
            }
        }
        else
        {
            if (read)
            {
                mode |=
                    std::ios_base::in;
            }
            else
            {
            }
        }

        stream_.open(fileName.c_str(), mode);
    }

    inline void BinaryFile::close()
    {
        if (stream_.is_open())
        {
            stream_.close();
        }
    }

    inline void BinaryFile::setEndian(bool littleEndian)
    {
        littleEndian_ = littleEndian;
    }

    inline bool BinaryFile::isOpen()
    {
        return stream_.is_open();
    }

    inline bool BinaryFile::isInEnd() const
    {
        return stream_.eof();
    }

    inline BinaryFile& BinaryFile::operator>>(int8& value)
    {
        read((char*)&value, 1);

        return *this;
    }

    inline BinaryFile& BinaryFile::operator>>(uint8& value)
    {
        read((char*)&value, 1);

        return *this;
    }

    inline BinaryFile& BinaryFile::operator>>(int16& value)
    {
        int8 data[2];
        read(&data[0], 2);

        if (littleEndian_)
        {
            value = littleEndian((int16&)data[0]);
        }
        else
        {
            value = bigEndian((int16&)data[0]);
        }

        return *this;
    }

    inline BinaryFile& BinaryFile::operator>>(uint16& value)
    {
        int8 data[2];
        read(&data[0], 2);

        if (littleEndian_)
        {
            value = littleEndian((uint16&)data[0]);
        }
        else
        {
            value = bigEndian((uint16&)data[0]);
        }

        return *this;
    }

    inline BinaryFile& BinaryFile::operator>>(int32& value)
    {
        int8 data[4];
        read(&data[0], 4);

        if (littleEndian_)
        {
            value = littleEndian((int32&)data[0]);
        }
        else
        {
            value = bigEndian((int32&)data[0]);
        }

        return *this;
    }

    inline BinaryFile& BinaryFile::operator>>(uint32& value)
    {
        int8 data[4];
        read(&data[0], 4);

        if (littleEndian_)
        {
            value = littleEndian((uint32&)data[0]);
        }
        else
        {
            value = bigEndian((uint32&)data[0]);
        }

        return *this;
    }

    inline BinaryFile& BinaryFile::operator>>(real32& value)
    {
        int8 data[4];
        read(&data[0], 4);

        if (littleEndian_)
        {
            value = littleEndian((real32&)data[0]);
        }
        else
        {
            value = bigEndian((real32&)data[0]);
        }

        return *this;
    }

    inline BinaryFile& BinaryFile::operator>>(real64& value)
    {
        int8 data[8];
        read(&data[0], 8);

        if (littleEndian_)
        {
            value = littleEndian((real64&)data[0]);
        }
        else
        {
            value = bigEndian((real64&)data[0]);
        }

        return *this;
    }

    inline BinaryFile& BinaryFile::operator<<(int8 value)
    {
        write((char*)&value, 1);
        return *this;
    }

    inline BinaryFile& BinaryFile::operator<<(uint8 value)
    {
        write((int8*)&value, 1);
        return *this;
    }

    inline BinaryFile& BinaryFile::operator<<(int16 value)
    {
        if (littleEndian_)
        {
            value = littleEndian(value);
        }
        else
        {
            value = bigEndian(value);
        }

        write((int8*)&value, 2);
        return *this;
    }

    inline BinaryFile& BinaryFile::operator<<(uint16 value)
    {
        if (littleEndian_)
        {
            value = littleEndian(value);
        }
        else
        {
            value = bigEndian(value);
        }

        write((int8*)&value, 2);
        return *this;
    }

    inline BinaryFile& BinaryFile::operator<<(int32 value)
    {
        if (littleEndian_)
        {
            value = littleEndian(value);
        }
        else
        {
            value = bigEndian(value);
        }

        write((int8*)&value, 4);
        return *this;
    }

    inline BinaryFile& BinaryFile::operator<<(uint32 value)
    {

        if (littleEndian_)
        {
            value = littleEndian(value);
        }
        else
        {
            value = bigEndian(value);
        }

        write((int8*)&value, 4);
        return *this;
    }

    inline BinaryFile& BinaryFile::operator<<(real32 value)
    {
        if (littleEndian_)
        {
            value = littleEndian(value);
        }
        else
        {
            value = bigEndian(value);
        }

        write((int8*)&value, 4);
        return *this;
    }

    inline BinaryFile& BinaryFile::operator<<(real64 value)
    {
        if (littleEndian_)
        {
            value = littleEndian(value);
        }
        else
        {
            value = bigEndian(value);
        }

        write((int8*)&value, 8);
        return *this;
    }

    inline BinaryFile& BinaryFile::operator<<(const std::string& text)
    {
        write(&text[0], text.size());

        return *this;
    }

    inline BinaryFile& BinaryFile::operator<<(const char* nullString)
    {
        char symbol = 0;
        integer index = 0;
        do
        {
            symbol = nullString[index];
            (*this) << symbol;
        }
        while (symbol != 0);

        return *this;
    }

    inline BinaryFile& BinaryFile::operator<<(void (*callBack)(BinaryFile&))
    {
        ENSURE(callBack);

        callBack(*this);

        return *this;
    }

    inline void BinaryFile::ignore(integer count)
    {
        ENSURE_OP(count, >=, 0);

        stream_.ignore(count);
    }

    inline void BinaryFile::flush()
    {
        stream_.flush();
    }

    inline void BinaryFile::write(const char* str, integer count)
    {
        ENSURE_OP(count, >=, 0);

        if (!str)
        {
            return;
        }

        stream_.write(str, count);
    }

    inline void BinaryFile::read(char* str, integer count)
    {
        ENSURE_OP(count, >=, 0);
        if (!str)
        {
            return;
        }

        stream_.read(str, count);
    }

    inline void BinaryFile::setOffset(integer offset)
    {
        if (offset < 0)
        {
            stream_.seekg(offset, std::ios::end);
        }
        else
        {
            stream_.seekg(offset, std::ios::beg);
        }
    }

    inline integer BinaryFile::getOffset()
    {
        return stream_.tellg();
    }

    // Helpers

    inline void binaryLittleEndian(BinaryFile& file)
    {
        file.setEndian(true);
    }

    inline void binaryBigEndian(BinaryFile& file)
    {
        file.setEndian(false);
    }

}

#endif