125 lines · 4.1 KB · C
RawDownload
//// Dis VM// File: buffered_reader.h// Author: arr// #ifndef _DISVM_SRC_VM_BUFFERED_READER_H_#define _DISVM_SRC_VM_BUFFERED_READER_H_ #include <cstdint>#include <cassert>#include <vector>#include <tuple>#include <iosfwd> namespace disvm{    namespace util    {        class buffered_reader_t        {        private: // static            static const std::size_t buffer_size = 64 * 1024; // 64k is an optimization for the Windows filesystem manager         public:            buffered_reader_t(std::istream &stream)                : _buffer(buffered_reader_t::buffer_size)                , _current_index{ 0 }                , _current_size{ 0 }                , _stream{ stream }            {                assert(!stream.fail());            }             buffered_reader_t(const buffered_reader_t&) = delete;            buffered_reader_t& operator=(const buffered_reader_t&) = delete;             // Get the next 'n' number of bytes.            // Returns the number of bytes retrieved.            uint32_t get_next_bytes(uint32_t bytes_requested, uint8_t *buffer)            {                if (bytes_requested == 0)                    return 0;                 assert(buffer != nullptr);                 auto bytes_requested_acc = uint32_t{0};                std::size_t amount_in_buffer;                 for (;;)                {                    bool success = check_buffer_content(amount_in_buffer);                    if (!success || amount_in_buffer == 0)                        return 0;                     // Buffer contains requested amount                    if (bytes_requested <= amount_in_buffer)                    {                        std::memcpy(buffer, (_buffer.data() + _current_index), bytes_requested);                        _current_index += bytes_requested;                        bytes_requested_acc += bytes_requested;                        return bytes_requested_acc;                    }                    else                    {                        // Buffer does not contain all the data requested                        std::memcpy(buffer, (_buffer.data() + _current_index), amount_in_buffer);                        _current_index += amount_in_buffer;                         // Subtract the bytes consumed                        bytes_requested -= amount_in_buffer;                         bytes_requested_acc += amount_in_buffer;                        buffer += amount_in_buffer;                    }                }            }             // Get the next byte in the buffer.            // Returns success and the byte.            std::tuple<bool, uint8_t> get_next_byte()            {                std::size_t amount_in_buffer;                bool success = check_buffer_content(amount_in_buffer);                if (!success || amount_in_buffer == 0)                    return std::make_tuple(false, 0);                 return std::make_tuple(true, _buffer[_current_index++]);            }         private:            bool check_buffer_content(std::size_t &amount_in_buffer)            {                // Signed so checking for underflow is easier.                amount_in_buffer = 0;                auto amount_in_buffer_local = _current_size - _current_index;                if (amount_in_buffer_local <= 0)                {                    _current_index = 0;                    _current_size = 0;                     if (_stream.fail())                        return false;                     _stream.read(_buffer.data(), buffered_reader_t::buffer_size);                    _current_size = _stream.fail() ? static_cast<std::size_t>(_stream.gcount()) : buffered_reader_t::buffer_size;                                        // Reset amount in buffer                    amount_in_buffer_local = buffered_reader_t::buffer_size;                }                 amount_in_buffer = amount_in_buffer_local;                return true;            }         private:            std::istream &_stream;            std::size_t _current_index;            std::size_t _current_size;            std::vector<char> _buffer;        };    }} #endif // _DISVM_SRC_VM_BUFFERED_READER_H_

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t