util: Add helper method to load/save object from/to file.
Change-Id: I7417bbf85865e15c02e5dec170265bcdd3f2bae4
diff --git a/src/util/io.hpp b/src/util/io.hpp
new file mode 100644
index 0000000..3d39feb
--- /dev/null
+++ b/src/util/io.hpp
@@ -0,0 +1,150 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_UTIL_IO_HPP
+#define NDN_UTIL_IO_HPP
+
+#include "../common.hpp"
+
+#include "../encoding/block.hpp"
+
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <cryptopp/files.h>
+#include <cryptopp/base64.h>
+#include <cryptopp/hex.h>
+
+
+namespace ndn {
+namespace io {
+
+struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+enum IoEncoding {
+ NO_ENCODING,
+ BASE_64,
+ HEX
+};
+
+template<typename T>
+shared_ptr<T>
+load(std::istream& is, IoEncoding encoding = BASE_64)
+{
+ typedef typename T::Error TypeError;
+ try
+ {
+ using namespace CryptoPP;
+
+ shared_ptr<T> object = make_shared<T>();
+
+ OBufferStream os;
+
+ switch(encoding)
+ {
+ case NO_ENCODING:
+ {
+ FileSource ss(is, true, new FileSink(os));
+ break;
+ }
+ case BASE_64:
+ {
+ FileSource ss(is, true, new Base64Decoder(new FileSink(os)));
+ break;
+ }
+ case HEX:
+ {
+ FileSource ss(is, true, new HexDecoder(new FileSink(os)));
+ break;
+ }
+ default:
+ return shared_ptr<T>();
+ }
+
+ object->wireDecode(Block(os.buf()));
+ return object;
+ }
+ catch(CryptoPP::Exception& e)
+ {
+ return shared_ptr<T>();
+ }
+ catch(Block::Error& e)
+ {
+ return shared_ptr<T>();
+ }
+ catch(TypeError& e)
+ {
+ return shared_ptr<T>();
+ }
+}
+
+template<typename T>
+shared_ptr<T>
+load(const std::string& file, IoEncoding encoding = BASE_64)
+{
+ std::ifstream is(file.c_str());
+ return load<T>(is, encoding);
+}
+
+template<typename T>
+void
+save(const T& object, std::ostream& os, IoEncoding encoding = BASE_64)
+{
+ typedef typename T::Error TypeError;
+ try
+ {
+ using namespace CryptoPP;
+
+ Block block = object.wireEncode();
+
+ switch(encoding)
+ {
+ case NO_ENCODING:
+ {
+ StringSource ss(block.wire(), block.size(), true, new FileSink(os));
+ break;
+ }
+ case BASE_64:
+ {
+ StringSource ss(block.wire(), block.size(), true, new Base64Encoder(new FileSink(os), true, 64));
+ break;
+ }
+ case HEX:
+ {
+ StringSource ss(block.wire(), block.size(), true, new HexEncoder(new FileSink(os)));
+ break;
+ }
+ default:
+ return;
+ }
+ return;
+ }
+ catch(CryptoPP::Exception& e)
+ {
+ throw Error(e.what());
+ }
+ catch(Block::Error& e)
+ {
+ throw Error(e.what());
+ }
+ catch(TypeError& e)
+ {
+ throw Error(e.what());
+ }
+}
+
+template<typename T>
+void
+save(const T& object, const std::string& file, IoEncoding encoding = BASE_64)
+{
+ std::ofstream os(file.c_str());
+ save(object, os, encoding);
+}
+
+} // namespace io
+} // namespace ndn
+
+#endif // NDN_UTIL_IO_HPP
+
diff --git a/tests/util/test-io.cpp b/tests/util/test-io.cpp
new file mode 100644
index 0000000..acbdc38
--- /dev/null
+++ b/tests/util/test-io.cpp
@@ -0,0 +1,36 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#include <boost/test/unit_test.hpp>
+
+#include "util/io.hpp"
+#include "security/key-chain.hpp"
+
+namespace ndn {
+
+BOOST_AUTO_TEST_SUITE(TestIO)
+
+BOOST_AUTO_TEST_CASE (Basic)
+{
+ KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> keychain;
+
+ Name identity("/TestIO/Basic/" + boost::lexical_cast<std::string>(time::now()));
+ Name certName;
+ BOOST_REQUIRE_NO_THROW(certName = keychain.createIdentity(identity));
+ shared_ptr<IdentityCertificate> idCert;
+ BOOST_REQUIRE_NO_THROW(idCert = keychain.getCertificate(certName));
+
+ std::string file("/tmp/TestIO-Basic");
+ io::save(*idCert, file);
+ shared_ptr<IdentityCertificate> readCert = io::load<IdentityCertificate>(file);
+
+ BOOST_CHECK(static_cast<bool>(readCert));
+ BOOST_CHECK(idCert->getName() == readCert->getName());
+ keychain.deleteIdentity(identity);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace ndn