blob: 96cd74976d3cc4d76f2f3039af6de3ec62de5100 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Yingdi Yuf50098d2014-02-26 14:26:29 -08002/**
Junxiao Shi2d4be252016-08-17 04:29:00 +00003 * Copyright (c) 2013-2016 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Yingdi Yuf50098d2014-02-26 14:26:29 -080020 */
21
22#ifndef NDN_UTIL_IO_HPP
23#define NDN_UTIL_IO_HPP
24
Yingdi Yuf50098d2014-02-26 14:26:29 -080025#include "../encoding/block.hpp"
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070026#include "../encoding/buffer-stream.hpp"
Junxiao Shi2d4be252016-08-17 04:29:00 +000027#include "../security/cryptopp.hpp"
Yingdi Yuf50098d2014-02-26 14:26:29 -080028
Yingdi Yuf50098d2014-02-26 14:26:29 -080029#include <iostream>
30#include <fstream>
Yingdi Yuf50098d2014-02-26 14:26:29 -080031
32
33namespace ndn {
34namespace io {
35
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070036class Error : public std::runtime_error
37{
38public:
39 explicit
40 Error(const std::string& what)
41 : std::runtime_error(what)
42 {
43 }
44};
Yingdi Yuf50098d2014-02-26 14:26:29 -080045
46enum IoEncoding {
47 NO_ENCODING,
48 BASE_64,
49 HEX
50};
51
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070052template<typename T>
53shared_ptr<T>
Yingdi Yuf50098d2014-02-26 14:26:29 -080054load(std::istream& is, IoEncoding encoding = BASE_64)
55{
56 typedef typename T::Error TypeError;
Junxiao Shi2d4be252016-08-17 04:29:00 +000057 try {
58 using namespace CryptoPP;
Yingdi Yuf50098d2014-02-26 14:26:29 -080059
Junxiao Shi2d4be252016-08-17 04:29:00 +000060 shared_ptr<T> object = make_shared<T>();
Yingdi Yuf50098d2014-02-26 14:26:29 -080061
Junxiao Shi2d4be252016-08-17 04:29:00 +000062 OBufferStream os;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070063
Junxiao Shi2d4be252016-08-17 04:29:00 +000064 switch (encoding) {
65 case NO_ENCODING: {
66 FileSource ss(is, true, new FileSink(os));
67 break;
68 }
69 case BASE_64: {
70 FileSource ss(is, true, new Base64Decoder(new FileSink(os)));
71 break;
72 }
73 case HEX: {
74 FileSource ss(is, true, new HexDecoder(new FileSink(os)));
75 break;
76 }
77 default:
78 return nullptr;
79 }
Yingdi Yuf50098d2014-02-26 14:26:29 -080080
Junxiao Shi2d4be252016-08-17 04:29:00 +000081 object->wireDecode(Block(os.buf()));
82 return object;
83 }
84 catch (const TypeError& e) {
85 return nullptr;
86 }
87 catch (const CryptoPP::Exception& e) {
88 return nullptr;
89 }
90 catch (const tlv::Error& e) {
91 return nullptr;
92 }
Yingdi Yuf50098d2014-02-26 14:26:29 -080093}
94
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070095template<typename T>
96shared_ptr<T>
Yingdi Yuf50098d2014-02-26 14:26:29 -080097load(const std::string& file, IoEncoding encoding = BASE_64)
98{
99 std::ifstream is(file.c_str());
100 return load<T>(is, encoding);
101}
102
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700103template<typename T>
Yingdi Yuf50098d2014-02-26 14:26:29 -0800104void
105save(const T& object, std::ostream& os, IoEncoding encoding = BASE_64)
106{
107 typedef typename T::Error TypeError;
Junxiao Shi2d4be252016-08-17 04:29:00 +0000108 try {
109 using namespace CryptoPP;
Yingdi Yuf50098d2014-02-26 14:26:29 -0800110
Junxiao Shi2d4be252016-08-17 04:29:00 +0000111 Block block = object.wireEncode();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700112
Junxiao Shi2d4be252016-08-17 04:29:00 +0000113 switch (encoding) {
114 case NO_ENCODING: {
115 StringSource ss(block.wire(), block.size(), true, new FileSink(os));
116 break;
117 }
118 case BASE_64: {
119 StringSource ss(block.wire(), block.size(), true,
120 new Base64Encoder(new FileSink(os), true, 64));
121 break;
122 }
123 case HEX: {
124 StringSource ss(block.wire(), block.size(), true,
125 new HexEncoder(new FileSink(os)));
126 break;
127 }
128 default:
129 return;
Yingdi Yuf50098d2014-02-26 14:26:29 -0800130 }
Junxiao Shi2d4be252016-08-17 04:29:00 +0000131 return;
132 }
133 catch (const TypeError& e) {
134 BOOST_THROW_EXCEPTION(Error(e.what()));
135 }
136 catch (const CryptoPP::Exception& e) {
137 BOOST_THROW_EXCEPTION(Error(e.what()));
138 }
139 catch (const tlv::Error& e) {
140 BOOST_THROW_EXCEPTION(Error(e.what()));
141 }
Yingdi Yuf50098d2014-02-26 14:26:29 -0800142}
143
144template<typename T>
145void
146save(const T& object, const std::string& file, IoEncoding encoding = BASE_64)
147{
148 std::ofstream os(file.c_str());
149 save(object, os, encoding);
150}
151
152} // namespace io
153} // namespace ndn
154
155#endif // NDN_UTIL_IO_HPP