From d9a4020a92db3fdc92163fa1bdb8b46ce13fae86 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 1 Dec 2021 12:31:21 +0100 Subject: [PATCH] Function to read a number of bytes from an input stream. --- libsolutil/CommonIO.cpp | 11 +++++++++++ libsolutil/CommonIO.h | 4 ++++ test/libsolutil/CommonIO.cpp | 9 +++++++++ 3 files changed, 24 insertions(+) diff --git a/libsolutil/CommonIO.cpp b/libsolutil/CommonIO.cpp index 9da5b2422..6089f4db6 100644 --- a/libsolutil/CommonIO.cpp +++ b/libsolutil/CommonIO.cpp @@ -79,6 +79,17 @@ string solidity::util::readUntilEnd(istream& _stdin) return ss.str(); } +string solidity::util::readBytes(istream& _input, size_t _length) +{ + string output; + output.resize(_length); + _input.read(output.data(), static_cast(_length)); + // If read() reads fewer bytes it sets failbit in addition to eofbit. + if (_input.fail()) + output.resize(static_cast(_input.gcount())); + return output; +} + #if defined(_WIN32) class DisableConsoleBuffering { diff --git a/libsolutil/CommonIO.h b/libsolutil/CommonIO.h index ab0000f86..e6cd0c161 100644 --- a/libsolutil/CommonIO.h +++ b/libsolutil/CommonIO.h @@ -57,6 +57,10 @@ std::string readFileAsString(boost::filesystem::path const& _file); /// Retrieves and returns the whole content of the specified input stream (until EOF). std::string readUntilEnd(std::istream& _stdin); +/// Tries to read exactly @a _length bytes from @a _input. +/// Returns a string containing as much data as has been read. +std::string readBytes(std::istream& _input, size_t _length); + /// Retrieves and returns a character from standard input (without waiting for EOL). int readStandardInputChar(); diff --git a/test/libsolutil/CommonIO.cpp b/test/libsolutil/CommonIO.cpp index ce1a24a41..8b8c3d326 100644 --- a/test/libsolutil/CommonIO.cpp +++ b/test/libsolutil/CommonIO.cpp @@ -90,6 +90,15 @@ BOOST_AUTO_TEST_CASE(readUntilEnd_empty) BOOST_TEST(readUntilEnd(inputStream) == ""); } +BOOST_AUTO_TEST_CASE(readBytes_past_end) +{ + istringstream inputStream("abc"); + BOOST_CHECK_EQUAL(readBytes(inputStream, 0), ""); + BOOST_CHECK_EQUAL(readBytes(inputStream, 1), "a"); + BOOST_CHECK_EQUAL(readBytes(inputStream, 20), "bc"); + BOOST_CHECK_EQUAL(readBytes(inputStream, 20), ""); +} + BOOST_AUTO_TEST_SUITE_END() } // namespace solidity::util::test