Skip to content
Snippets Groups Projects
binary_stream.cpp 3.59 KiB
Newer Older
  • Learn to ignore specific revisions
  • theazgra's avatar
    theazgra committed
    #include "binary_stream.h"
    #include <iterator>
    
    
    BinaryStream::BinaryStream()
    {
        this->isOpen = false;
    }
    
    
    theazgra's avatar
    theazgra committed
    BinaryStream::BinaryStream(const std::string &file)
    {
    
        this->isOpen = false;
        open_stream(file);
    }
    
    theazgra's avatar
    theazgra committed
    
    
    void BinaryStream::open_stream(const std::string &file)
    {
        assert(!this->isOpen);
    
        this->fileStream = std::ifstream(file, std::ios::binary | std::ios::in | std::ios::ate);
    
    theazgra's avatar
    theazgra committed
        assert(this->fileStream.is_open());
    
    
        this->isOpen = true;
    
        this->fileStream.unsetf(std::ios::skipws);
    
    theazgra's avatar
    theazgra committed
        this->fileSize = fileStream.tellg();
    
        fileStream.seekg(std::ios::beg);
    }
    
    void BinaryStream::close_stream()
    {
        if (this->isOpen)
        {
            this->fileStream.close();
            this->isOpen = false;
        }
    
    theazgra's avatar
    theazgra committed
    }
    
    BinaryStream::~BinaryStream()
    {
    
        close_stream();
    
    theazgra's avatar
    theazgra committed
    }
    
    
    long BinaryStream::get_size() const
    
    theazgra's avatar
    theazgra committed
    {
    
        assert(this->isOpen);
    
    theazgra's avatar
    theazgra committed
        return this->fileSize;
    }
    
    
    long BinaryStream::get_position()
    {
        assert(this->isOpen);
        return (long)(this->fileStream.tellg());
    }
    
    
    theazgra's avatar
    theazgra committed
    void BinaryStream::move_to(const long position)
    {
    
        assert(this->isOpen);
    
    theazgra's avatar
    theazgra committed
        this->fileStream.seekg(position);
    }
    
    void BinaryStream::move_to_beginning()
    {
    
        assert(this->isOpen);
    
    theazgra's avatar
    theazgra committed
        this->fileStream.seekg(std::ios::beg);
    }
    
    void BinaryStream::move_to_end()
    {
    
        assert(this->isOpen);
    
    theazgra's avatar
    theazgra committed
        this->fileStream.seekg(std::ios::end);
    }
    
    
    void BinaryStream::move_by(const long distance)
    {
        assert(this->isOpen);
        auto currentPosition = this->fileStream.tellg();
        auto requiredPosition = currentPosition + distance;
        this->fileStream.seekg(requiredPosition);
    }
    
    byte BinaryStream::consume_byte()
    {
        assert(this->isOpen);
        char readedChar;
        this->fileStream.read(&readedChar, 1);
        byte result = (byte)readedChar;
        return result;
    }
    
    
    bool BinaryStream::consume_bool(const short byteCount)
    {
        assert(this->isOpen);
        auto bytes = consume_bytes(byteCount);
        int sum = 0;
    
        for (size_t i = 0; i < byteCount; i++)
            sum |= bytes[i];
    
        return (sum != 0);
    }
    
    
    short BinaryStream::consume_short()
    {
        assert(this->isOpen);
        return bytes_to_short(consume_bytes(2));
    }
    
    int BinaryStream::consume_int()
    {
        assert(this->isOpen);
        return bytes_to_int(consume_bytes(4));
    }
    
    long BinaryStream::consume_long()
    {
        assert(this->isOpen);
        return bytes_to_long(consume_bytes(8));
    }
    
    
    float BinaryStream::consume_float()
    {
        assert(this->isOpen);
        return bytes_to_float(consume_bytes(4));
    }
    
    double BinaryStream::consume_double()
    {
        assert(this->isOpen);
        return bytes_to_double(consume_bytes(8));
    }
    
    
    std::vector<byte> BinaryStream::consume_whole_file()
    {
        assert(this->isOpen);
        std::vector<byte> result;
        this->fileStream.seekg(std::ios::beg);
        result.insert(result.begin(), std::istream_iterator<byte>(this->fileStream), std::istream_iterator<byte>());
        return result;
    }
    
    std::vector<byte> BinaryStream::consume_rest_of_file()
    
    theazgra's avatar
    theazgra committed
    {
    
        assert(this->isOpen);
        std::vector<byte> result;
        result.insert(result.begin(), std::istream_iterator<byte>(this->fileStream), std::istream_iterator<byte>());
        return result;
    
    theazgra's avatar
    theazgra committed
    }
    
    std::vector<byte> BinaryStream::consume_bytes(const long byteCount)
    {
    
        assert(this->isOpen);
    
    theazgra's avatar
    theazgra committed
    
    
        //TODO: Can this be made faster?
        std::vector<byte> result;
    
    theazgra's avatar
    theazgra committed
        auto readIterator = std::istream_iterator<byte>(fileStream);
    
        result.resize(byteCount);
    
    
        for (size_t i = 0; i < byteCount - 1; i++)
    
    theazgra's avatar
    theazgra committed
        {
            result[i] = *readIterator++;
        }
    
        result[byteCount - 1] = *readIterator;
    
    theazgra's avatar
    theazgra committed
        return result;
    }
    
    
    std::vector<byte> BinaryStream::move_and_consume_bytes(const long position, const long byteCount)
    
    theazgra's avatar
    theazgra committed
    {
    
        assert(this->isOpen);
        move_to(position);
        return consume_bytes(byteCount);
    
    theazgra's avatar
    theazgra committed
    }