diff --git a/Makefile.am b/Makefile.am index 6f107dc3ea..b94df52b84 100755 --- a/Makefile.am +++ b/Makefile.am @@ -738,7 +738,6 @@ include_bitcoin_system_streamdir = ${includedir}/bitcoin/system/stream include_bitcoin_system_stream_HEADERS = \ include/bitcoin/system/stream/binary.hpp \ include/bitcoin/system/stream/device.hpp \ - include/bitcoin/system/stream/iostream.hpp \ include/bitcoin/system/stream/make_stream.hpp \ include/bitcoin/system/stream/make_streamer.hpp \ include/bitcoin/system/stream/stream.hpp \ @@ -753,6 +752,12 @@ include_bitcoin_system_stream_devices_HEADERS = \ include/bitcoin/system/stream/devices/flip_sink.hpp \ include/bitcoin/system/stream/devices/push_sink.hpp +include_bitcoin_system_stream_iostreamdir = ${includedir}/bitcoin/system/stream/iostream +include_bitcoin_system_stream_iostream_HEADERS = \ + include/bitcoin/system/stream/iostream/iostream.hpp \ + include/bitcoin/system/stream/iostream/istream.hpp \ + include/bitcoin/system/stream/iostream/ostream.hpp + include_bitcoin_system_stream_streamersdir = ${includedir}/bitcoin/system/stream/streamers include_bitcoin_system_stream_streamers_HEADERS = \ include/bitcoin/system/stream/streamers/bit_flipper.hpp \ diff --git a/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj b/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj index 619323cece..8de69ea583 100644 --- a/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj +++ b/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj @@ -407,7 +407,9 @@ - + + + diff --git a/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj.filters index 8e504d94c8..7c4c4016a5 100644 --- a/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj.filters +++ b/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj.filters @@ -124,38 +124,41 @@ {39F60708-FF48-4C22-0000-000000000005} - + {39F60708-FF48-4C22-0000-000000000006} - + {39F60708-FF48-4C22-0000-000000000007} + + {39F60708-FF48-4C22-0000-000000000008} + {39F60708-FF48-4C22-0000-000000000011} - {39F60708-FF48-4C22-0000-000000000008} + {39F60708-FF48-4C22-0000-000000000009} {39F60708-FF48-4C22-0000-0000000000A2} - {39F60708-FF48-4C22-0000-000000000009} + {39F60708-FF48-4C22-0000-000000000010} - {39F60708-FF48-4C22-0000-000000000010} + {39F60708-FF48-4C22-0000-000000000011} - {39F60708-FF48-4C22-0000-000000000011} + {39F60708-FF48-4C22-0000-000000000012} {39F60708-FF48-4C22-0000-0000000000B2} - {39F60708-FF48-4C22-0000-000000000012} + {39F60708-FF48-4C22-0000-000000000013} - {39F60708-FF48-4C22-0000-000000000013} + {39F60708-FF48-4C22-0000-0000000000A4} {39F60708-FF48-4C22-0000-000000000000} @@ -1097,8 +1100,14 @@ include\bitcoin\system\stream\devices - - include\bitcoin\system\stream + + include\bitcoin\system\stream\iostream + + + include\bitcoin\system\stream\iostream + + + include\bitcoin\system\stream\iostream include\bitcoin\system\stream diff --git a/include/bitcoin/system.hpp b/include/bitcoin/system.hpp index 687f3f649b..069a910c94 100755 --- a/include/bitcoin/system.hpp +++ b/include/bitcoin/system.hpp @@ -177,7 +177,6 @@ #include #include #include -#include #include #include #include @@ -188,6 +187,9 @@ #include #include #include +#include +#include +#include #include #include #include diff --git a/include/bitcoin/system/impl/stream/iostream/iostream.ipp b/include/bitcoin/system/impl/stream/iostream/iostream.ipp index 3d22521ed9..64066b822c 100644 --- a/include/bitcoin/system/impl/stream/iostream/iostream.ipp +++ b/include/bitcoin/system/impl/stream/iostream/iostream.ipp @@ -26,8 +26,9 @@ namespace system { BC_PUSH_WARNING(NO_POINTER_ARITHMETIC) -template -INLINE iostream::iostream(Buffer& buffer) NOEXCEPT +template +template +INLINE iostream::iostream(Buffer& buffer) NOEXCEPT : position_(buffer.data()), begin_(position_), end_(begin_ + buffer.size()), @@ -35,8 +36,8 @@ INLINE iostream::iostream(Buffer& buffer) NOEXCEPT { } -template -INLINE iostream::iostream(uint8_t* begin, +template +INLINE iostream::iostream(uint8_t* begin, ptrdiff_t size) NOEXCEPT : position_(begin), begin_(position_), @@ -45,31 +46,165 @@ INLINE iostream::iostream(uint8_t* begin, { } -template -INLINE typename iostream::iostate -iostream::rdstate() const NOEXCEPT +template +INLINE typename iostream::iostate +iostream::rdstate() const NOEXCEPT { return state_; } -template +template INLINE void -iostream::setstate(iostate state) NOEXCEPT +iostream::setstate(iostate state) NOEXCEPT { state_ |= state; } -template +template INLINE void -iostream::clear(iostate state) NOEXCEPT +iostream::clear(iostate state) NOEXCEPT { state_ = state; } + +template +INLINE typename iostream::pos_type +iostream::tellg() const NOEXCEPT +{ + return static_cast(position_ - begin_); +} + +template +INLINE typename iostream::pos_type +iostream::tellp() const NOEXCEPT +{ + return static_cast(position_ - begin_); +} + +template +INLINE iostream& +iostream::seekg(off_type offset, seekdir direction) NOEXCEPT +{ + if (state_ != goodbit) + return *this; + + using namespace system; + switch (direction) + { + case beg: + { + if (is_negative(offset) || (offset > (end_ - begin_))) + { + setstate(badbit); + break; + } + + position_ = begin_ + offset; + break; + } + case cur: + { + if ((is_negative(offset) && (offset < (begin_ - position_))) || + (is_positive(offset) && (offset > (end_ - position_)))) + { + setstate(badbit); + break; + } + + position_ = position_ + offset; + break; + } + case end: + { + if (is_positive(offset) || (offset < (begin_ - end_))) + { + setstate(badbit); + break; + } + + position_ = end_ + offset; + break; + } + default: + { + setstate(failbit); + break; + } + } + + return *this; +} + +template +INLINE typename iostream::int_type +iostream::peek() NOEXCEPT +{ + constexpr auto eof = std::char_traits::eof(); + + if (is_overflow(1)) + { + setstate(badbit); + return eof; + } + + const uint8_t value = *position_; + return system::sign_cast(value); +} + +template +INLINE void +iostream::read(char_type* data, pos_type size) NOEXCEPT +{ + if (is_overflow(size)) + { + setstate(badbit); + return; + } + + BC_PUSH_WARNING(NO_UNSAFE_COPY_N) + std::copy_n(position_, size, data); + BC_POP_WARNING() + + position_ += size; +} + +template +INLINE void +iostream::write(const char_type* data, + pos_type size) NOEXCEPT +{ + if (is_overflow(size)) + { + setstate(badbit); + return; + } + + BC_PUSH_WARNING(NO_UNSAFE_COPY_N) + std::copy_n(data, size, position_); + BC_POP_WARNING() + + position_ += size; +} + +template +INLINE void +iostream::flush() NOEXCEPT +{ +} + +// private +template +constexpr bool +iostream::is_positive(off_type value) NOEXCEPT +{ + return !is_zero(value) && !system::is_negative(value); +} + // private -template +template INLINE bool -iostream::is_overflow(pos_type size) const NOEXCEPT +iostream::is_overflow(pos_type size) const NOEXCEPT { return (state_ != goodbit) || (size > (end_ - position_)); } diff --git a/include/bitcoin/system/impl/stream/iostream/istream.ipp b/include/bitcoin/system/impl/stream/iostream/istream.ipp index e0bd6939d2..56692b8f44 100644 --- a/include/bitcoin/system/impl/stream/iostream/istream.ipp +++ b/include/bitcoin/system/impl/stream/iostream/istream.ipp @@ -28,16 +28,57 @@ namespace system { BC_PUSH_WARNING(NO_POINTER_ARITHMETIC) -template -INLINE typename iostream::pos_type -iostream::tellg() const NOEXCEPT +template +template +INLINE istream::istream(const Buffer& buffer) NOEXCEPT + : position_(buffer.data()), + begin_(position_), + end_(begin_ + buffer.size()), + state_(goodbit) +{ +} + +template +INLINE istream::istream(const uint8_t* begin, + ptrdiff_t size) NOEXCEPT + : position_(begin), + begin_(position_), + end_(begin_ + size), + state_(goodbit) +{ +} + +template +INLINE typename istream::iostate +istream::rdstate() const NOEXCEPT +{ + return state_; +} + +template +INLINE void +istream::setstate(iostate state) NOEXCEPT +{ + state_ |= state; +} + +template +INLINE void +istream::clear(iostate state) NOEXCEPT +{ + state_ = state; +} + +template +INLINE typename istream::pos_type +istream::tellg() const NOEXCEPT { return static_cast(position_ - begin_); } -template -INLINE iostream& -iostream::seekg(off_type offset, seekdir direction) NOEXCEPT +template +INLINE istream& +istream::seekg(off_type offset, seekdir direction) NOEXCEPT { if (state_ != goodbit) return *this; @@ -89,9 +130,9 @@ iostream::seekg(off_type offset, seekdir direction) NOEXCEPT return *this; } -template -INLINE typename iostream::int_type -iostream::peek() NOEXCEPT +template +INLINE typename istream::int_type +istream::peek() NOEXCEPT { constexpr auto eof = std::char_traits::eof(); @@ -105,9 +146,9 @@ iostream::peek() NOEXCEPT return system::sign_cast(value); } -template +template INLINE void -iostream::read(char_type* data, pos_type size) NOEXCEPT +istream::read(char_type* data, pos_type size) NOEXCEPT { if (is_overflow(size)) { @@ -123,13 +164,21 @@ iostream::read(char_type* data, pos_type size) NOEXCEPT } // private -template +template constexpr bool -iostream::is_positive(off_type value) NOEXCEPT +istream::is_positive(off_type value) NOEXCEPT { return !is_zero(value) && !system::is_negative(value); } +// private +template +INLINE bool +istream::is_overflow(pos_type size) const NOEXCEPT +{ + return (state_ != goodbit) || (size > (end_ - position_)); +} + BC_POP_WARNING() } // namespace system diff --git a/include/bitcoin/system/impl/stream/iostream/ostream.ipp b/include/bitcoin/system/impl/stream/iostream/ostream.ipp index 3dce8ffa09..db7c49f3f6 100644 --- a/include/bitcoin/system/impl/stream/iostream/ostream.ipp +++ b/include/bitcoin/system/impl/stream/iostream/ostream.ipp @@ -27,16 +27,58 @@ namespace system { BC_PUSH_WARNING(NO_POINTER_ARITHMETIC) -template -INLINE typename iostream::pos_type -iostream::tellp() const NOEXCEPT +template +template +ostream::ostream(Buffer& buffer) NOEXCEPT + : position_(buffer.data()), + begin_(position_), + end_(begin_ + buffer.size()), + state_(goodbit) +{ +} + +template +ostream::ostream(uint8_t* begin, + ptrdiff_t size) NOEXCEPT + : position_(begin), + begin_(position_), + end_(begin_ + size), + state_(goodbit) +{ +} + +template +INLINE typename ostream::iostate +ostream::rdstate() const NOEXCEPT +{ + return state_; +} + +template +INLINE void +ostream::setstate(iostate state) NOEXCEPT +{ + state_ |= state; +} + +template +INLINE void +ostream::clear(iostate state) NOEXCEPT +{ + state_ = state; +} + +template +INLINE typename ostream::pos_type +ostream::tellp() const NOEXCEPT { return static_cast(position_ - begin_); } -template +template INLINE void -iostream::write(const char_type* data, pos_type size) NOEXCEPT +ostream::write(const char_type* data, + pos_type size) NOEXCEPT { if (is_overflow(size)) { @@ -51,10 +93,18 @@ iostream::write(const char_type* data, pos_type size) NOEXCEP position_ += size; } -template +template INLINE void -iostream::flush() NOEXCEPT +ostream::flush() NOEXCEPT +{ +} + +// private +template +INLINE bool +ostream::is_overflow(pos_type size) const NOEXCEPT { + return (state_ != goodbit) || (size > (end_ - position_)); } BC_POP_WARNING() diff --git a/include/bitcoin/system/stream/iostream.hpp b/include/bitcoin/system/stream/iostream/iostream.hpp similarity index 92% rename from include/bitcoin/system/stream/iostream.hpp rename to include/bitcoin/system/stream/iostream/iostream.hpp index 7e5fc98c19..579b727847 100644 --- a/include/bitcoin/system/stream/iostream.hpp +++ b/include/bitcoin/system/stream/iostream/iostream.hpp @@ -16,8 +16,8 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -#ifndef LIBBITCOIN_SYSTEM_STREAM_IOSTREAM_HPP -#define LIBBITCOIN_SYSTEM_STREAM_IOSTREAM_HPP +#ifndef LIBBITCOIN_SYSTEM_STREAM_IOSTREAM_IOSTREAM_HPP +#define LIBBITCOIN_SYSTEM_STREAM_IOSTREAM_IOSTREAM_HPP #include #include @@ -26,7 +26,7 @@ namespace libbitcoin { namespace system { /// Support for high level input/output operations on a byte buffer. -template +template class iostream { public: @@ -50,6 +50,7 @@ class iostream static constexpr seekdir end = 2; /// Construct the object. + template INLINE iostream(Buffer& buffer) NOEXCEPT; INLINE iostream(uint8_t* begin, ptrdiff_t size) NOEXCEPT; @@ -97,7 +98,5 @@ class iostream } // namespace libbitcoin #include -#include -#include #endif diff --git a/include/bitcoin/system/stream/iostream/istream.hpp b/include/bitcoin/system/stream/iostream/istream.hpp new file mode 100644 index 0000000000..10d9fd37b2 --- /dev/null +++ b/include/bitcoin/system/stream/iostream/istream.hpp @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) + * + * This file is part of libbitcoin. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#ifndef LIBBITCOIN_SYSTEM_STREAM_IOSTREAM_ISTREAM_HPP +#define LIBBITCOIN_SYSTEM_STREAM_IOSTREAM_ISTREAM_HPP + +#include +#include + +namespace libbitcoin { +namespace system { + +/// Support for high level input/output operations on a byte buffer. +template +class istream +{ +public: + DEFAULT_COPY_MOVE_DESTRUCT(istream); + + using char_type = Character; + using int_type = typename std::basic_ios::int_type; + using off_type = typename std::basic_ios::off_type; + using pos_type = typename std::basic_ios::pos_type; + using failure = typename std::ios_base::failure; + + using iostate = uint8_t; + static constexpr iostate goodbit = 0; + static constexpr iostate eofbit = 1; + static constexpr iostate failbit = 2; + static constexpr iostate badbit = 4; + + using seekdir = uint8_t; + static constexpr seekdir beg = 0; + static constexpr seekdir cur = 1; + static constexpr seekdir end = 2; + + /// Construct the object. + template + INLINE istream(const Buffer& buffer) NOEXCEPT; + INLINE istream(const uint8_t* begin, ptrdiff_t size) NOEXCEPT; + + /// Return state flags. + virtual INLINE iostate rdstate() const NOEXCEPT; + + /// Set the stream error flags state in addition to currently set flags. + virtual INLINE void setstate(iostate state) NOEXCEPT; + + /// Set the stream error state flags by assigning the state value. + virtual INLINE void clear(iostate state=goodbit) NOEXCEPT; + + /// Return the relative input position indicator (zero-based). + virtual INLINE pos_type tellg() const NOEXCEPT; + + /// Set the relative input position indicator (zero-based). + virtual INLINE istream& seekg(off_type offset, seekdir direction) NOEXCEPT; + + /// Read the next character without advancing, sets badbit on underflow. + virtual INLINE int_type peek() NOEXCEPT; + + /// Read a block of characters, sets badbit on underflow. + virtual INLINE void read(char_type* data, pos_type size) NOEXCEPT; + +private: + static constexpr bool is_positive(off_type value) NOEXCEPT; + INLINE bool is_overflow(pos_type size) const NOEXCEPT; + + const uint8_t* position_; + const uint8_t* begin_; + const uint8_t* end_; + iostate state_; +}; + +} // namespace system +} // namespace libbitcoin + +#include + +#endif diff --git a/include/bitcoin/system/stream/iostream/ostream.hpp b/include/bitcoin/system/stream/iostream/ostream.hpp new file mode 100644 index 0000000000..37ba85f03e --- /dev/null +++ b/include/bitcoin/system/stream/iostream/ostream.hpp @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS) + * + * This file is part of libbitcoin. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +#ifndef LIBBITCOIN_SYSTEM_STREAM_IOSTREAM_OSTREAM_HPP +#define LIBBITCOIN_SYSTEM_STREAM_IOSTREAM_OSTREAM_HPP + +#include +#include + +namespace libbitcoin { +namespace system { + +/// Support for high level input/output operations on a byte buffer. +template +class ostream +{ +public: + DEFAULT_COPY_MOVE_DESTRUCT(ostream); + + using char_type = Character; + using int_type = typename std::basic_ios::int_type; + using off_type = typename std::basic_ios::off_type; + using pos_type = typename std::basic_ios::pos_type; + using failure = typename std::ios_base::failure; + + using iostate = uint8_t; + static constexpr iostate goodbit = 0; + static constexpr iostate eofbit = 1; + static constexpr iostate failbit = 2; + static constexpr iostate badbit = 4; + + /// Construct the object. + template + INLINE ostream(Buffer& buffer) NOEXCEPT; + INLINE ostream(uint8_t* begin, ptrdiff_t size) NOEXCEPT; + + /// Return state flags. + virtual INLINE iostate rdstate() const NOEXCEPT; + + /// Set the stream error flags state in addition to currently set flags. + virtual INLINE void setstate(iostate state) NOEXCEPT; + + /// Set the stream error state flags by assigning the state value. + virtual INLINE void clear(iostate state=goodbit) NOEXCEPT; + + /// Return the relative output position indicator (zero-based). + virtual INLINE pos_type tellp() const NOEXCEPT; + + /// Write a block of characters, sets badbit on overflow. + virtual INLINE void write(const char_type* data, pos_type size) NOEXCEPT; + + /// Synchronize with the underlying storage device (no-op). + virtual INLINE void flush() NOEXCEPT; + +private: + INLINE bool is_overflow(pos_type size) const NOEXCEPT; + + uint8_t* position_; + uint8_t* begin_; + uint8_t* end_; + iostate state_; +}; + +} // namespace system +} // namespace libbitcoin + +#include + +#endif diff --git a/include/bitcoin/system/stream/stream.hpp b/include/bitcoin/system/stream/stream.hpp index 494fa10353..301699bb7e 100644 --- a/include/bitcoin/system/stream/stream.hpp +++ b/include/bitcoin/system/stream/stream.hpp @@ -27,7 +27,9 @@ #include #include #include -#include +#include +#include +#include #include #include #include diff --git a/src/chain/header.cpp b/src/chain/header.cpp index 9e055cd4a3..56d024be73 100644 --- a/src/chain/header.cpp +++ b/src/chain/header.cpp @@ -231,7 +231,8 @@ hash_digest header::hash() const NOEXCEPT return *hash_; hash_digest digest{}; - hash::sha256x2::copy sink(digest); + ostream stream{ digest }; + sha256x2_writer sink{ stream }; to_data(sink); sink.flush(); return digest; diff --git a/src/chain/transaction.cpp b/src/chain/transaction.cpp index 7ef8f9a005..f8f6f79657 100644 --- a/src/chain/transaction.cpp +++ b/src/chain/transaction.cpp @@ -428,8 +428,9 @@ hash_digest transaction::hash(bool witness) const NOEXCEPT BC_PUSH_WARNING(LOCAL_VARIABLE_NOT_INITIALIZED) hash_digest digest; BC_POP_WARNING() - - hash::sha256x2::copy sink(digest); + + ostream stream{ digest }; + sha256x2_writer sink{ stream }; to_data(sink, witness); sink.flush(); return digest; @@ -485,8 +486,9 @@ hash_digest transaction::outputs_hash() const NOEXCEPT BC_PUSH_WARNING(LOCAL_VARIABLE_NOT_INITIALIZED) hash_digest digest; BC_POP_WARNING() - - hash::sha256x2::copy sink(digest); + + ostream stream{ digest }; + sha256x2_writer sink{ stream }; const auto& outs = *outputs_; for (const auto& output: outs) @@ -502,7 +504,8 @@ hash_digest transaction::points_hash() const NOEXCEPT hash_digest digest; BC_POP_WARNING() - hash::sha256x2::copy sink(digest); + ostream stream{ digest }; + sha256x2_writer sink{ stream }; const auto& ins = *inputs_; for (const auto& input: ins) @@ -518,7 +521,8 @@ hash_digest transaction::sequences_hash() const NOEXCEPT hash_digest digest; BC_POP_WARNING() - hash::sha256x2::copy sink(digest); + ostream stream{ digest }; + sha256x2_writer sink{ stream }; const auto& ins = *inputs_; for (const auto& input: ins) @@ -722,7 +726,8 @@ hash_digest transaction::unversioned_signature_hash( hash_digest digest; BC_POP_WARNING() - hash::sha256x2::copy sink(digest); + ostream stream{ digest }; + sha256x2_writer sink{ stream }; switch (flag) { @@ -790,7 +795,8 @@ hash_digest transaction::output_hash(const input_iterator& input) const NOEXCEPT hash_digest digest; BC_POP_WARNING() - hash::sha256x2::copy sink(digest); + ostream stream{ digest }; + sha256x2_writer sink{ stream }; outputs_->at(index)->to_data(sink); sink.flush(); return digest; @@ -818,7 +824,8 @@ hash_digest transaction::version_0_signature_hash(const input_iterator& input, hash_digest digest; BC_POP_WARNING() - hash::sha256x2::copy sink(digest); + ostream stream{ digest }; + sha256x2_writer sink{ stream }; // Create signature hash. sink.write_little_endian(version_); diff --git a/test/stream/iostream/iostream.cpp b/test/stream/iostream/iostream.cpp index ba98dce2be..148b2e6ecd 100644 --- a/test/stream/iostream/iostream.cpp +++ b/test/stream/iostream/iostream.cpp @@ -20,69 +20,393 @@ BOOST_AUTO_TEST_SUITE(iostream_tests) -using iostream_chunk = iostream; +using seekdir = typename iostream<>::seekdir; +using pos_type = typename iostream<>::pos_type; +using iostate = typename iostream<>::iostate; -// setstate/clear +// setstate/rdstate/clear BOOST_AUTO_TEST_CASE(iostream__setstate__goodbit__goodbit) { data_chunk empty{}; - iostream_chunk stream{ empty }; - stream.setstate(iostream_chunk::goodbit); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + iostream<> stream{ empty }; + stream.setstate(iostream<>::goodbit); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); } BOOST_AUTO_TEST_CASE(iostream__setstate__eofbit__eofbit) { auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; - stream.setstate(iostream_chunk::eofbit); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::eofbit); + iostream<> stream{ chunk }; + stream.setstate(iostream<>::eofbit); + BOOST_REQUIRE(stream.rdstate() == iostream<>::eofbit); stream.clear(); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); } BOOST_AUTO_TEST_CASE(iostream__setstate__failbit__failbit) { data_chunk empty{}; - iostream_chunk stream{ empty }; - stream.setstate(iostream_chunk::failbit); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::failbit); + iostream<> stream{ empty }; + stream.setstate(iostream<>::failbit); + BOOST_REQUIRE(stream.rdstate() == iostream<>::failbit); stream.clear(); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); } BOOST_AUTO_TEST_CASE(iostream__setstate__badbit__badbit) { data_chunk empty{}; - iostream_chunk stream{ empty }; - stream.setstate(iostream_chunk::badbit); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::badbit); + iostream<> stream{ empty }; + stream.setstate(iostream<>::badbit); + BOOST_REQUIRE(stream.rdstate() == iostream<>::badbit); stream.clear(); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); } BOOST_AUTO_TEST_CASE(iostream__setstate__badbit_failbit__badbit_failbit) { - constexpr auto badfail = iostream_chunk::failbit | iostream_chunk::badbit; + constexpr auto badfail = iostream<>::failbit | iostream<>::badbit; auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; - stream.setstate(iostream_chunk::badbit); - stream.setstate(iostream_chunk::failbit); + iostream<> stream{ chunk }; + stream.setstate(iostream<>::badbit); + stream.setstate(iostream<>::failbit); BOOST_REQUIRE(stream.rdstate() == badfail); - stream.clear(iostream_chunk::badbit); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::badbit); + stream.clear(iostream<>::badbit); + BOOST_REQUIRE(stream.rdstate() == iostream<>::badbit); - stream.clear(iostream_chunk::failbit); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::failbit); + stream.clear(iostream<>::failbit); + BOOST_REQUIRE(stream.rdstate() == iostream<>::failbit); - stream.clear(iostream_chunk::goodbit); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + stream.clear(iostream<>::goodbit); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +// istream +// ---------------------------------------------------------------------------- + +// tellg + +BOOST_AUTO_TEST_CASE(iostream__tellg__empty__zero_goodbit) +{ + data_chunk empty{}; + iostream<> stream{ empty }; + BOOST_REQUIRE(is_zero(stream.tellg())); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +BOOST_AUTO_TEST_CASE(iostream__tellg__initial__zero_goodbit) +{ + auto chunk = base16_chunk("00010203040506070809"); + const iostream<> stream{ chunk }; + BOOST_REQUIRE(is_zero(stream.tellg())); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +// iostream<>::beg + +BOOST_AUTO_TEST_CASE(iostream__seekg__zero_from_begin__tellg_zero_goodbit) +{ + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream<>::beg).tellg(), 3); + BOOST_REQUIRE(is_zero(stream.seekg(0, iostream<>::beg).tellg())); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +BOOST_AUTO_TEST_CASE(iostream__seekg__three_from_begin__tellg_three_goodbit) +{ + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream<>::beg).tellg(), 3); + BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream<>::beg).tellg(), 3); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +BOOST_AUTO_TEST_CASE(iostream__seekg__size_from_begin__tellg_size_goodbit) +{ + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream<>::beg).tellg(), 3); + BOOST_REQUIRE_EQUAL(stream.seekg(chunk.size(), iostream<>::beg).tellg(), to_signed(chunk.size())); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +BOOST_AUTO_TEST_CASE(iostream__seekg__overflow_from_begin__unchanged_badbit) +{ + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + BOOST_REQUIRE(is_zero(stream.seekg(add1(chunk.size()), iostream<>::beg).tellg())); + BOOST_REQUIRE(stream.rdstate() == iostream<>::badbit); +} + +// iostream<>::cur + +BOOST_AUTO_TEST_CASE(iostream__seekg__zero_from_three_current__tellg_three_goodbit) +{ + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream<>::beg).tellg(), 3); + BOOST_REQUIRE_EQUAL(stream.seekg(0, iostream<>::cur).tellg(), 3); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +BOOST_AUTO_TEST_CASE(iostream__seekg__three_from_three_current__tellg_six_goodbit) +{ + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream<>::beg).tellg(), 3); + BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream<>::cur).tellg(), 6); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +BOOST_AUTO_TEST_CASE(iostream__seekg__size_from_zero_current__tellg_size_goodbit) +{ + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(chunk.size(), iostream<>::cur).tellg(), to_signed(chunk.size())); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +BOOST_AUTO_TEST_CASE(iostream__seekg__overflow_from_three_current__unchanged_badbit) +{ + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream<>::beg).tellg(), 3); + BOOST_REQUIRE(stream.seekg(chunk.size(), iostream<>::cur).tellg() == 3); + BOOST_REQUIRE(stream.rdstate() == iostream<>::badbit); +} + +// iostream<>::end + +BOOST_AUTO_TEST_CASE(iostream__seekg__zero_from_end__tellg_size_goodbit) +{ + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream<>::beg).tellg(), 3); + BOOST_REQUIRE_EQUAL(stream.seekg(0, iostream<>::end).tellg(), to_signed(chunk.size())); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +BOOST_AUTO_TEST_CASE(iostream__seekg__negative_three_from_end__tellg_size_less_three_goodbit) +{ + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream<>::beg).tellg(), 3); + BOOST_REQUIRE_EQUAL(stream.seekg(-3, iostream<>::end).tellg(), to_signed(chunk.size()) - 3); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +BOOST_AUTO_TEST_CASE(iostream__seekg__negative_size_from_end__tellg_zero_goodbit) +{ + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + BOOST_REQUIRE(is_zero(stream.seekg(-to_signed(chunk.size()), iostream<>::end).tellg())); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +BOOST_AUTO_TEST_CASE(iostream__seekg__underflow_from_end__unchanged_badbit) +{ + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + BOOST_REQUIRE(is_zero(stream.seekg(add1(chunk.size()), iostream<>::end).tellg())); + BOOST_REQUIRE(stream.rdstate() == iostream<>::badbit); +} + +// peek + +BOOST_AUTO_TEST_CASE(iostream__peek__empty__eof_badbit) +{ + constexpr auto eof = std::char_traits::eof(); + data_chunk empty{}; + iostream<> stream{ empty }; + BOOST_REQUIRE_EQUAL(stream.peek(), eof); + BOOST_REQUIRE(stream.rdstate() == iostream<>::badbit); +} + +BOOST_AUTO_TEST_CASE(iostream__peek__chunk__no_advance_expected_goodbit) +{ + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.peek(), 0x00); + BOOST_REQUIRE(is_zero(stream.tellg())); + BOOST_REQUIRE_EQUAL(stream.peek(), 0x00); + BOOST_REQUIRE(is_zero(stream.tellg())); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +BOOST_AUTO_TEST_CASE(iostream__peek__end__eof_badbit) +{ + constexpr auto eof = std::char_traits::eof(); + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(0, iostream<>::end).tellg(), to_signed(chunk.size())); + BOOST_REQUIRE_EQUAL(stream.peek(), eof); + BOOST_REQUIRE(stream.rdstate() == iostream<>::badbit); +} + +BOOST_AUTO_TEST_CASE(iostream__peek__chunk__advance_expected_goodbit) +{ + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.peek(), 0x00); + BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream<>::cur).tellg(), 1); + BOOST_REQUIRE_EQUAL(stream.peek(), 0x01); + BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream<>::cur).tellg(), 2); + BOOST_REQUIRE_EQUAL(stream.peek(), 0x02); + BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream<>::cur).tellg(), 3); + BOOST_REQUIRE_EQUAL(stream.peek(), 0x03); + BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream<>::cur).tellg(), 4); + BOOST_REQUIRE_EQUAL(stream.peek(), 0x04); + BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream<>::cur).tellg(), 5); + BOOST_REQUIRE_EQUAL(stream.peek(), 0x05); + BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream<>::cur).tellg(), 6); + BOOST_REQUIRE_EQUAL(stream.peek(), 0x06); + BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream<>::cur).tellg(), 7); + BOOST_REQUIRE_EQUAL(stream.peek(), 0x07); + BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream<>::cur).tellg(), 8); + BOOST_REQUIRE_EQUAL(stream.peek(), 0x08); + BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream<>::cur).tellg(), 9); + BOOST_REQUIRE_EQUAL(stream.peek(), 0x09); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +// read + +BOOST_AUTO_TEST_CASE(iostream__read__none_empty__goodbit) +{ + data_chunk buffer{}; + data_chunk empty{}; + iostream<> stream{ empty }; + stream.read(system::pointer_cast(buffer.data()), buffer.size()); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +BOOST_AUTO_TEST_CASE(iostream__read__underflow_empty__badbit) +{ + auto buffer = base16_chunk("00000000000000000000"); + data_chunk empty{}; + iostream<> stream{ empty }; + stream.read(system::pointer_cast(buffer.data()), buffer.size()); + BOOST_REQUIRE(stream.rdstate() == iostream<>::badbit); +} + +BOOST_AUTO_TEST_CASE(iostream__read__underflow_nonempty__badbit) +{ + auto buffer = base16_chunk("00000000000000000000000000"); + auto chunk = base16_chunk("00010203040506070809"); + iostream<> stream{ chunk }; + stream.read(system::pointer_cast(buffer.data()), add1(chunk.size())); + BOOST_REQUIRE(stream.rdstate() == iostream<>::badbit); +} + +BOOST_AUTO_TEST_CASE(iostream__read__full_buffer__goodbit) +{ + auto buffer = base16_chunk("00000000000000000000000000"); + auto chunk = base16_chunk("00010203040506070809"); + BOOST_REQUIRE_GE(buffer.size(), chunk.size()); + BOOST_REQUIRE_NE(buffer, chunk); + + iostream<> stream{ chunk }; + stream.read(system::pointer_cast(buffer.data()), chunk.size()); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); + buffer.resize(chunk.size()); + BOOST_REQUIRE_EQUAL(buffer, chunk); +} + +// reader + +BOOST_AUTO_TEST_CASE(iostream__reader__read_8_bytes_big_endian__exected_goodbit) +{ + auto chunk = base16_chunk("010203040506070809"); + iostream<> stream{ chunk }; + byte_reader> reader{ stream }; + BOOST_REQUIRE_EQUAL(reader.read_8_bytes_big_endian(), 0x0102030405060708_u64); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +// ostream +// ---------------------------------------------------------------------------- + +const auto chunk = base16_chunk("00010203040506070809"); + +// tellp + +BOOST_AUTO_TEST_CASE(iostream__tellp__empty__zero_goodbit) +{ + data_chunk empty{}; + iostream<> stream{ empty }; + BOOST_REQUIRE(is_zero(stream.tellp())); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +BOOST_AUTO_TEST_CASE(iostream__tellp__initial__zero_goodbit) +{ + data_chunk empty{}; + iostream<> stream{ empty }; + BOOST_REQUIRE(is_zero(stream.tellp())); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +// write + +BOOST_AUTO_TEST_CASE(iostream__write__none_empty__goodbit) +{ + const data_chunk buffer{}; + data_chunk empty{}; + iostream<> stream{ empty }; + stream.write(system::pointer_cast(buffer.data()), buffer.size()); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); +} + +BOOST_AUTO_TEST_CASE(iostream__write__overflow_empty__badbit) +{ + const auto buffer = base16_chunk("00010203040506070809"); + data_chunk empty{}; + iostream<> stream{ empty }; + stream.write(system::pointer_cast(buffer.data()), buffer.size()); + BOOST_REQUIRE(stream.rdstate() == iostream<>::badbit); +} + +BOOST_AUTO_TEST_CASE(iostream__write__overflow_nonempty__badbit) +{ + const auto buffer = base16_chunk("00010203040506070809"); + auto chunk = base16_chunk("000000000000"); + iostream<> stream{ chunk }; + stream.write(system::pointer_cast(buffer.data()), buffer.size()); + BOOST_REQUIRE(stream.rdstate() == iostream<>::badbit); +} + +BOOST_AUTO_TEST_CASE(iostream__write__full_buffer__goodbit) +{ + const auto buffer = base16_chunk("00010203040506070809"); + auto chunk = base16_chunk("00000000000000000000000000"); + BOOST_REQUIRE_GE(chunk.size(), buffer.size()); + BOOST_REQUIRE_NE(buffer, chunk); + + iostream<> stream{ chunk }; + stream.write(system::pointer_cast(buffer.data()), buffer.size()); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); + chunk.resize(buffer.size()); + BOOST_REQUIRE_EQUAL(buffer, chunk); +} + +// writer + +BOOST_AUTO_TEST_CASE(iostream__writer__write_8_bytes_big_endian__exected_goodbit) +{ + const auto expected = base16_chunk("010203040506070800"); + auto chunk = base16_chunk("000000000000000000"); + iostream<> stream{ chunk }; + byte_writer> writer{ stream }; + writer.write_8_bytes_big_endian(0x0102030405060708_u64); + BOOST_REQUIRE(stream.rdstate() == iostream<>::goodbit); + BOOST_REQUIRE_EQUAL(chunk, expected); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/stream/iostream/istream.cpp b/test/stream/iostream/istream.cpp index 1d2b0c0a81..f2c608c406 100644 --- a/test/stream/iostream/istream.cpp +++ b/test/stream/iostream/istream.cpp @@ -18,251 +18,250 @@ */ #include "../../test.hpp" -BOOST_AUTO_TEST_SUITE(iostream_tests) +BOOST_AUTO_TEST_SUITE(istream_tests) -using iostream_chunk = iostream; -using seekdir = typename iostream_chunk::seekdir; -using pos_type = typename iostream_chunk::pos_type; -using iostate = typename iostream_chunk::iostate; +using seekdir = typename istream<>::seekdir; +using pos_type = typename istream<>::pos_type; +using iostate = typename istream<>::iostate; // tellg -BOOST_AUTO_TEST_CASE(iostream__tellg__empty__zero_goodbit) +BOOST_AUTO_TEST_CASE(istream__tellg__empty__zero_goodbit) { data_chunk empty{}; - iostream_chunk stream{ empty }; + istream<> stream{ empty }; BOOST_REQUIRE(is_zero(stream.tellg())); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); } -BOOST_AUTO_TEST_CASE(iostream__tellg__initial__zero_goodbit) +BOOST_AUTO_TEST_CASE(istream__tellg__initial__zero_goodbit) { auto chunk = base16_chunk("00010203040506070809"); - const iostream_chunk stream{ chunk }; + const istream<> stream{ chunk }; BOOST_REQUIRE(is_zero(stream.tellg())); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); } -// iostream_chunk::beg +// istream<>::beg -BOOST_AUTO_TEST_CASE(iostream__seekg__zero_from_begin__tellg_zero_goodbit) +BOOST_AUTO_TEST_CASE(istream__seekg__zero_from_begin__tellg_zero_goodbit) { auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; - BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream_chunk::beg).tellg(), 3); - BOOST_REQUIRE(is_zero(stream.seekg(0, iostream_chunk::beg).tellg())); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + istream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, istream<>::beg).tellg(), 3); + BOOST_REQUIRE(is_zero(stream.seekg(0, istream<>::beg).tellg())); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); } -BOOST_AUTO_TEST_CASE(iostream__seekg__three_from_begin__tellg_three_goodbit) +BOOST_AUTO_TEST_CASE(istream__seekg__three_from_begin__tellg_three_goodbit) { auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; - BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream_chunk::beg).tellg(), 3); - BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream_chunk::beg).tellg(), 3); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + istream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, istream<>::beg).tellg(), 3); + BOOST_REQUIRE_EQUAL(stream.seekg(3, istream<>::beg).tellg(), 3); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); } -BOOST_AUTO_TEST_CASE(iostream__seekg__size_from_begin__tellg_size_goodbit) +BOOST_AUTO_TEST_CASE(istream__seekg__size_from_begin__tellg_size_goodbit) { auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; - BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream_chunk::beg).tellg(), 3); - BOOST_REQUIRE_EQUAL(stream.seekg(chunk.size(), iostream_chunk::beg).tellg(), to_signed(chunk.size())); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + istream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, istream<>::beg).tellg(), 3); + BOOST_REQUIRE_EQUAL(stream.seekg(chunk.size(), istream<>::beg).tellg(), to_signed(chunk.size())); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); } -BOOST_AUTO_TEST_CASE(iostream__seekg__overflow_from_begin__unchanged_badbit) +BOOST_AUTO_TEST_CASE(istream__seekg__overflow_from_begin__unchanged_badbit) { auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; - BOOST_REQUIRE(is_zero(stream.seekg(add1(chunk.size()), iostream_chunk::beg).tellg())); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::badbit); + istream<> stream{ chunk }; + BOOST_REQUIRE(is_zero(stream.seekg(add1(chunk.size()), istream<>::beg).tellg())); + BOOST_REQUIRE(stream.rdstate() == istream<>::badbit); } -// iostream_chunk::cur +// istream<>::cur -BOOST_AUTO_TEST_CASE(iostream__seekg__zero_from_three_current__tellg_three_goodbit) +BOOST_AUTO_TEST_CASE(istream__seekg__zero_from_three_current__tellg_three_goodbit) { auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; - BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream_chunk::beg).tellg(), 3); - BOOST_REQUIRE_EQUAL(stream.seekg(0, iostream_chunk::cur).tellg(), 3); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + istream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, istream<>::beg).tellg(), 3); + BOOST_REQUIRE_EQUAL(stream.seekg(0, istream<>::cur).tellg(), 3); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); } -BOOST_AUTO_TEST_CASE(iostream__seekg__three_from_three_current__tellg_six_goodbit) +BOOST_AUTO_TEST_CASE(istream__seekg__three_from_three_current__tellg_six_goodbit) { auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; - BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream_chunk::beg).tellg(), 3); - BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream_chunk::cur).tellg(), 6); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + istream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, istream<>::beg).tellg(), 3); + BOOST_REQUIRE_EQUAL(stream.seekg(3, istream<>::cur).tellg(), 6); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); } -BOOST_AUTO_TEST_CASE(iostream__seekg__size_from_zero_current__tellg_size_goodbit) +BOOST_AUTO_TEST_CASE(istream__seekg__size_from_zero_current__tellg_size_goodbit) { auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; - BOOST_REQUIRE_EQUAL(stream.seekg(chunk.size(), iostream_chunk::cur).tellg(), to_signed(chunk.size())); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + istream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(chunk.size(), istream<>::cur).tellg(), to_signed(chunk.size())); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); } -BOOST_AUTO_TEST_CASE(iostream__seekg__overflow_from_three_current__unchanged_badbit) +BOOST_AUTO_TEST_CASE(istream__seekg__overflow_from_three_current__unchanged_badbit) { auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; - BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream_chunk::beg).tellg(), 3); - BOOST_REQUIRE(stream.seekg(chunk.size(), iostream_chunk::cur).tellg() == 3); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::badbit); + istream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, istream<>::beg).tellg(), 3); + BOOST_REQUIRE(stream.seekg(chunk.size(), istream<>::cur).tellg() == 3); + BOOST_REQUIRE(stream.rdstate() == istream<>::badbit); } -// iostream_chunk::end +// istream<>::end -BOOST_AUTO_TEST_CASE(iostream__seekg__zero_from_end__tellg_size_goodbit) +BOOST_AUTO_TEST_CASE(istream__seekg__zero_from_end__tellg_size_goodbit) { auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; - BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream_chunk::beg).tellg(), 3); - BOOST_REQUIRE_EQUAL(stream.seekg(0, iostream_chunk::end).tellg(), to_signed(chunk.size())); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + istream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, istream<>::beg).tellg(), 3); + BOOST_REQUIRE_EQUAL(stream.seekg(0, istream<>::end).tellg(), to_signed(chunk.size())); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); } -BOOST_AUTO_TEST_CASE(iostream__seekg__negative_three_from_end__tellg_size_less_three_goodbit) +BOOST_AUTO_TEST_CASE(istream__seekg__negative_three_from_end__tellg_size_less_three_goodbit) { auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; - BOOST_REQUIRE_EQUAL(stream.seekg(3, iostream_chunk::beg).tellg(), 3); - BOOST_REQUIRE_EQUAL(stream.seekg(-3, iostream_chunk::end).tellg(), to_signed(chunk.size()) - 3); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + istream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(3, istream<>::beg).tellg(), 3); + BOOST_REQUIRE_EQUAL(stream.seekg(-3, istream<>::end).tellg(), to_signed(chunk.size()) - 3); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); } -BOOST_AUTO_TEST_CASE(iostream__seekg__negative_size_from_end__tellg_zero_goodbit) +BOOST_AUTO_TEST_CASE(istream__seekg__negative_size_from_end__tellg_zero_goodbit) { auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; - BOOST_REQUIRE(is_zero(stream.seekg(-to_signed(chunk.size()), iostream_chunk::end).tellg())); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + istream<> stream{ chunk }; + BOOST_REQUIRE(is_zero(stream.seekg(-to_signed(chunk.size()), istream<>::end).tellg())); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); } -BOOST_AUTO_TEST_CASE(iostream__seekg__underflow_from_end__unchanged_badbit) +BOOST_AUTO_TEST_CASE(istream__seekg__underflow_from_end__unchanged_badbit) { auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; - BOOST_REQUIRE(is_zero(stream.seekg(add1(chunk.size()), iostream_chunk::end).tellg())); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::badbit); + istream<> stream{ chunk }; + BOOST_REQUIRE(is_zero(stream.seekg(add1(chunk.size()), istream<>::end).tellg())); + BOOST_REQUIRE(stream.rdstate() == istream<>::badbit); } // peek -BOOST_AUTO_TEST_CASE(iostream__peek__empty__eof_badbit) +BOOST_AUTO_TEST_CASE(istream__peek__empty__eof_badbit) { constexpr auto eof = std::char_traits::eof(); data_chunk empty{}; - iostream_chunk stream{ empty }; + istream<> stream{ empty }; BOOST_REQUIRE_EQUAL(stream.peek(), eof); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::badbit); + BOOST_REQUIRE(stream.rdstate() == istream<>::badbit); } -BOOST_AUTO_TEST_CASE(iostream__peek__chunk__no_advance_expected_goodbit) +BOOST_AUTO_TEST_CASE(istream__peek__chunk__no_advance_expected_goodbit) { auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; + istream<> stream{ chunk }; BOOST_REQUIRE_EQUAL(stream.peek(), 0x00); BOOST_REQUIRE(is_zero(stream.tellg())); BOOST_REQUIRE_EQUAL(stream.peek(), 0x00); BOOST_REQUIRE(is_zero(stream.tellg())); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); } -BOOST_AUTO_TEST_CASE(iostream__peek__end__eof_badbit) +BOOST_AUTO_TEST_CASE(istream__peek__end__eof_badbit) { constexpr auto eof = std::char_traits::eof(); auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; - BOOST_REQUIRE_EQUAL(stream.seekg(0, iostream_chunk::end).tellg(), to_signed(chunk.size())); + istream<> stream{ chunk }; + BOOST_REQUIRE_EQUAL(stream.seekg(0, istream<>::end).tellg(), to_signed(chunk.size())); BOOST_REQUIRE_EQUAL(stream.peek(), eof); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::badbit); + BOOST_REQUIRE(stream.rdstate() == istream<>::badbit); } -BOOST_AUTO_TEST_CASE(iostream__peek__chunk__advance_expected_goodbit) +BOOST_AUTO_TEST_CASE(istream__peek__chunk__advance_expected_goodbit) { auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; + istream<> stream{ chunk }; BOOST_REQUIRE_EQUAL(stream.peek(), 0x00); - BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream_chunk::cur).tellg(), 1); + BOOST_REQUIRE_EQUAL(stream.seekg(1, istream<>::cur).tellg(), 1); BOOST_REQUIRE_EQUAL(stream.peek(), 0x01); - BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream_chunk::cur).tellg(), 2); + BOOST_REQUIRE_EQUAL(stream.seekg(1, istream<>::cur).tellg(), 2); BOOST_REQUIRE_EQUAL(stream.peek(), 0x02); - BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream_chunk::cur).tellg(), 3); + BOOST_REQUIRE_EQUAL(stream.seekg(1, istream<>::cur).tellg(), 3); BOOST_REQUIRE_EQUAL(stream.peek(), 0x03); - BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream_chunk::cur).tellg(), 4); + BOOST_REQUIRE_EQUAL(stream.seekg(1, istream<>::cur).tellg(), 4); BOOST_REQUIRE_EQUAL(stream.peek(), 0x04); - BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream_chunk::cur).tellg(), 5); + BOOST_REQUIRE_EQUAL(stream.seekg(1, istream<>::cur).tellg(), 5); BOOST_REQUIRE_EQUAL(stream.peek(), 0x05); - BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream_chunk::cur).tellg(), 6); + BOOST_REQUIRE_EQUAL(stream.seekg(1, istream<>::cur).tellg(), 6); BOOST_REQUIRE_EQUAL(stream.peek(), 0x06); - BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream_chunk::cur).tellg(), 7); + BOOST_REQUIRE_EQUAL(stream.seekg(1, istream<>::cur).tellg(), 7); BOOST_REQUIRE_EQUAL(stream.peek(), 0x07); - BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream_chunk::cur).tellg(), 8); + BOOST_REQUIRE_EQUAL(stream.seekg(1, istream<>::cur).tellg(), 8); BOOST_REQUIRE_EQUAL(stream.peek(), 0x08); - BOOST_REQUIRE_EQUAL(stream.seekg(1, iostream_chunk::cur).tellg(), 9); + BOOST_REQUIRE_EQUAL(stream.seekg(1, istream<>::cur).tellg(), 9); BOOST_REQUIRE_EQUAL(stream.peek(), 0x09); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); } // read -BOOST_AUTO_TEST_CASE(iostream__read__none_empty__goodbit) +BOOST_AUTO_TEST_CASE(istream__read__none_empty__goodbit) { data_chunk buffer{}; data_chunk empty{}; - iostream_chunk stream{ empty }; + istream<> stream{ empty }; stream.read(system::pointer_cast(buffer.data()), buffer.size()); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); } -BOOST_AUTO_TEST_CASE(iostream__read__underflow_empty__badbit) +BOOST_AUTO_TEST_CASE(istream__read__underflow_empty__badbit) { auto buffer = base16_chunk("00000000000000000000"); data_chunk empty{}; - iostream_chunk stream{ empty }; + istream<> stream{ empty }; stream.read(system::pointer_cast(buffer.data()), buffer.size()); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::badbit); + BOOST_REQUIRE(stream.rdstate() == istream<>::badbit); } -BOOST_AUTO_TEST_CASE(iostream__read__underflow_nonempty__badbit) +BOOST_AUTO_TEST_CASE(istream__read__underflow_nonempty__badbit) { auto buffer = base16_chunk("00000000000000000000000000"); auto chunk = base16_chunk("00010203040506070809"); - iostream_chunk stream{ chunk }; + istream<> stream{ chunk }; stream.read(system::pointer_cast(buffer.data()), add1(chunk.size())); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::badbit); + BOOST_REQUIRE(stream.rdstate() == istream<>::badbit); } -BOOST_AUTO_TEST_CASE(iostream__read__full_buffer__goodbit) +BOOST_AUTO_TEST_CASE(istream__read__full_buffer__goodbit) { auto buffer = base16_chunk("00000000000000000000000000"); auto chunk = base16_chunk("00010203040506070809"); BOOST_REQUIRE_GE(buffer.size(), chunk.size()); BOOST_REQUIRE_NE(buffer, chunk); - iostream_chunk stream{ chunk }; + istream<> stream{ chunk }; stream.read(system::pointer_cast(buffer.data()), chunk.size()); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); buffer.resize(chunk.size()); BOOST_REQUIRE_EQUAL(buffer, chunk); } // reader -BOOST_AUTO_TEST_CASE(iostream__reader__read_8_bytes_big_endian__exected_goodbit) +BOOST_AUTO_TEST_CASE(istream__reader__read_8_bytes_big_endian__exected_goodbit) { auto chunk = base16_chunk("010203040506070809"); - iostream_chunk stream{ chunk }; - byte_reader reader{ stream }; + istream<> stream{ chunk }; + byte_reader> reader{ stream }; BOOST_REQUIRE_EQUAL(reader.read_8_bytes_big_endian(), 0x0102030405060708_u64); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + BOOST_REQUIRE(stream.rdstate() == istream<>::goodbit); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/stream/iostream/ostream.cpp b/test/stream/iostream/ostream.cpp index 7a465ef86d..98fa373ef8 100644 --- a/test/stream/iostream/ostream.cpp +++ b/test/stream/iostream/ostream.cpp @@ -18,84 +18,83 @@ */ #include "../../test.hpp" -BOOST_AUTO_TEST_SUITE(iostream_tests) +BOOST_AUTO_TEST_SUITE(ostream_tests) -using iostream_chunk = iostream; -using pos_type = typename iostream_chunk::pos_type; -using iostate = typename iostream_chunk::iostate; +using pos_type = typename ostream<>::pos_type; +using iostate = typename ostream<>::iostate; const auto chunk = base16_chunk("00010203040506070809"); // tellp -BOOST_AUTO_TEST_CASE(iostream__tellp__empty__zero_goodbit) +BOOST_AUTO_TEST_CASE(ostream__tellp__empty__zero_goodbit) { data_chunk empty{}; - iostream_chunk stream{ empty }; + ostream<> stream{ empty }; BOOST_REQUIRE(is_zero(stream.tellp())); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + BOOST_REQUIRE(stream.rdstate() == ostream<>::goodbit); } -BOOST_AUTO_TEST_CASE(iostream__tellp__initial__zero_goodbit) +BOOST_AUTO_TEST_CASE(ostream__tellp__initial__zero_goodbit) { data_chunk empty{}; - iostream_chunk stream{ empty }; + ostream<> stream{ empty }; BOOST_REQUIRE(is_zero(stream.tellp())); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + BOOST_REQUIRE(stream.rdstate() == ostream<>::goodbit); } // write -BOOST_AUTO_TEST_CASE(iostream__write__none_empty__goodbit) +BOOST_AUTO_TEST_CASE(ostream__write__none_empty__goodbit) { const data_chunk buffer{}; data_chunk empty{}; - iostream_chunk stream{ empty }; + ostream<> stream{ empty }; stream.write(system::pointer_cast(buffer.data()), buffer.size()); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + BOOST_REQUIRE(stream.rdstate() == ostream<>::goodbit); } -BOOST_AUTO_TEST_CASE(iostream__write__overflow_empty__badbit) +BOOST_AUTO_TEST_CASE(ostream__write__overflow_empty__badbit) { const auto buffer = base16_chunk("00010203040506070809"); data_chunk empty{}; - iostream_chunk stream{ empty }; + ostream<> stream{ empty }; stream.write(system::pointer_cast(buffer.data()), buffer.size()); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::badbit); + BOOST_REQUIRE(stream.rdstate() == ostream<>::badbit); } -BOOST_AUTO_TEST_CASE(iostream__write__overflow_nonempty__badbit) +BOOST_AUTO_TEST_CASE(ostream__write__overflow_nonempty__badbit) { const auto buffer = base16_chunk("00010203040506070809"); auto chunk = base16_chunk("000000000000"); - iostream_chunk stream{ chunk }; + ostream<> stream{ chunk }; stream.write(system::pointer_cast(buffer.data()), buffer.size()); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::badbit); + BOOST_REQUIRE(stream.rdstate() == ostream<>::badbit); } -BOOST_AUTO_TEST_CASE(iostream__write__full_buffer__goodbit) +BOOST_AUTO_TEST_CASE(ostream__write__full_buffer__goodbit) { const auto buffer = base16_chunk("00010203040506070809"); auto chunk = base16_chunk("00000000000000000000000000"); BOOST_REQUIRE_GE(chunk.size(), buffer.size()); BOOST_REQUIRE_NE(buffer, chunk); - iostream_chunk stream{ chunk }; + ostream<> stream{ chunk }; stream.write(system::pointer_cast(buffer.data()), buffer.size()); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + BOOST_REQUIRE(stream.rdstate() == ostream<>::goodbit); chunk.resize(buffer.size()); BOOST_REQUIRE_EQUAL(buffer, chunk); } // writer -BOOST_AUTO_TEST_CASE(iostream__writer__write_8_bytes_big_endian__exected_goodbit) +BOOST_AUTO_TEST_CASE(ostream__writer__write_8_bytes_big_endian__exected_goodbit) { const auto expected = base16_chunk("010203040506070800"); auto chunk = base16_chunk("000000000000000000"); - iostream_chunk stream{ chunk }; - byte_writer writer{ stream }; + ostream<> stream{ chunk }; + byte_writer> writer{ stream }; writer.write_8_bytes_big_endian(0x0102030405060708_u64); - BOOST_REQUIRE(stream.rdstate() == iostream_chunk::goodbit); + BOOST_REQUIRE(stream.rdstate() == ostream<>::goodbit); BOOST_REQUIRE_EQUAL(chunk, expected); }