util: add io::loadBuffer and io::saveBuffer
Change-Id: Ifa9d3bc44bba5dd8e2bd5d419629763936f355d4
diff --git a/tests/unit/util/io.t.cpp b/tests/unit/util/io.t.cpp
index f8595c9..9340279 100644
--- a/tests/unit/util/io.t.cpp
+++ b/tests/unit/util/io.t.cpp
@@ -25,21 +25,88 @@
#include "tests/identity-management-fixture.hpp"
#include <boost/filesystem.hpp>
+#include <boost/mpl/vector.hpp>
namespace ndn {
namespace tests {
-class IoFixture
+BOOST_AUTO_TEST_SUITE(Util)
+BOOST_AUTO_TEST_SUITE(TestIo)
+
+struct NoEncoding
+{
+ const io::IoEncoding encoding{io::NO_ENCODING};
+ const std::vector<uint8_t> blob{0xd1, 0x0, 0xb0, 0x1a};
+ std::istringstream stream{std::string("\xd1\x00\xb0\x1a", 4), std::ios_base::binary};
+};
+
+struct Base64Encoding
+{
+ const io::IoEncoding encoding = io::BASE64;
+ const std::vector<uint8_t> blob{0x42, 0x61, 0x73, 0x65, 0x36, 0x34, 0x45, 0x6e, 0x63};
+ std::istringstream stream{"QmFzZTY0RW5j\n", std::ios_base::binary};
+};
+
+struct HexEncoding
+{
+ const io::IoEncoding encoding = io::HEX;
+ const std::vector<uint8_t> blob{0x48, 0x65, 0x78, 0x45, 0x6e, 0x63};
+ std::istringstream stream{"486578456E63", std::ios_base::binary};
+};
+
+using Encodings = boost::mpl::vector<NoEncoding, Base64Encoding, HexEncoding>;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(LoadBuffer, T, Encodings)
+{
+ T t;
+ shared_ptr<Buffer> buf = io::loadBuffer(t.stream, t.encoding);
+ BOOST_CHECK_EQUAL_COLLECTIONS(buf->begin(), buf->end(), t.blob.begin(), t.blob.end());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(SaveBuffer, T, Encodings)
+{
+ T t;
+ std::ostringstream os(std::ios_base::binary);
+ io::saveBuffer(t.blob.data(), t.blob.size(), os, t.encoding);
+ BOOST_CHECK_EQUAL(os.str(), t.stream.str());
+}
+
+BOOST_AUTO_TEST_CASE(LoadBufferException)
+{
+ std::ifstream in("this-file-does-not-exist", std::ios_base::binary);
+ BOOST_CHECK_THROW(io::loadBuffer(in, io::NO_ENCODING), io::Error);
+}
+
+BOOST_AUTO_TEST_CASE(SaveBufferException)
+{
+ class NullStreambuf : public std::streambuf
+ {
+ };
+
+ NullStreambuf nullbuf;
+ std::ostream out(&nullbuf);
+ const Buffer buffer(1);
+ BOOST_CHECK_THROW(io::saveBuffer(buffer.data(), buffer.size(), out, io::NO_ENCODING), io::Error);
+}
+
+BOOST_AUTO_TEST_CASE(UnknownIoEncoding)
+{
+ std::stringstream ss;
+ BOOST_CHECK_THROW(io::loadBuffer(ss, static_cast<io::IoEncoding>(5)), std::invalid_argument);
+ BOOST_CHECK_THROW(io::saveBuffer(nullptr, 0, ss, static_cast<io::IoEncoding>(5)), std::invalid_argument);
+}
+
+class FileIoFixture
{
protected:
- IoFixture()
- : filepath(boost::filesystem::path(UNIT_TEST_CONFIG_PATH) /= "TestIo")
+ FileIoFixture()
+ : filepath(boost::filesystem::path(UNIT_TEST_CONFIG_PATH) / "TestIo")
, filename(filepath.string())
{
boost::filesystem::create_directories(filepath.parent_path());
}
- ~IoFixture()
+ ~FileIoFixture()
{
boost::system::error_code ec;
boost::filesystem::remove(filepath, ec); // ignore error
@@ -53,28 +120,29 @@
boost::filesystem::create_directory(filepath);
}
- template<typename Container, typename CharT = typename Container::value_type>
+ template<typename Container>
Container
readFile() const
{
Container container;
std::ifstream fs(filename, std::ios_base::binary);
+ BOOST_REQUIRE_MESSAGE(fs, "error opening file");
char ch;
while (fs.get(ch)) {
- container.push_back(static_cast<CharT>(ch));
+ container.push_back(static_cast<typename Container::value_type>(ch));
}
return container;
}
- template<typename Container, typename CharT = typename Container::value_type>
+ template<typename Container>
void
writeFile(const Container& content) const
{
std::ofstream fs(filename, std::ios_base::binary);
- for (CharT ch : content) {
+ BOOST_REQUIRE_MESSAGE(fs, "error opening file");
+ for (auto ch : content) {
fs.put(static_cast<char>(ch));
}
- fs.close();
BOOST_REQUIRE_MESSAGE(fs, "error writing file");
}
@@ -83,8 +151,7 @@
const std::string filename;
};
-BOOST_AUTO_TEST_SUITE(Util)
-BOOST_FIXTURE_TEST_SUITE(TestIo, IoFixture)
+BOOST_FIXTURE_TEST_SUITE(FileIo, FileIoFixture)
class EncodableType
{
@@ -104,7 +171,7 @@
bool shouldThrow = false;
};
-template<bool SHOULD_THROW = false>
+template<bool SHOULD_THROW>
class DecodableTypeTpl
{
public:
@@ -119,7 +186,7 @@
void
wireDecode(const Block& block)
{
- if (m_shouldThrow) {
+ if (SHOULD_THROW) {
NDN_THROW(tlv::Error("decode error"));
}
@@ -128,13 +195,10 @@
BOOST_REQUIRE_EQUAL(block.value_size(), 1);
BOOST_CHECK_EQUAL(block.value()[0], 0xEE);
}
-
-private:
- bool m_shouldThrow = SHOULD_THROW;
};
-typedef DecodableTypeTpl<false> DecodableType;
-typedef DecodableTypeTpl<true> DecodableTypeThrow;
+using DecodableType = DecodableTypeTpl<false>;
+using DecodableTypeThrow = DecodableTypeTpl<true>;
BOOST_AUTO_TEST_CASE(LoadNoEncoding)
{
@@ -260,7 +324,9 @@
BOOST_CHECK_THROW(io::save(encoded, filename, io::NO_ENCODING), io::Error);
}
-class IdCertFixture : public IoFixture
+BOOST_AUTO_TEST_SUITE_END() // FileIo
+
+class IdCertFixture : public FileIoFixture
, public IdentityManagementFixture
{
};