blob: 4c7caf9d9ba729b5f96e7409969244d08a8e8703 [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/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 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
25#include "../common.hpp"
26
27#include "../encoding/block.hpp"
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070028#include "../encoding/buffer-stream.hpp"
Yingdi Yuf50098d2014-02-26 14:26:29 -080029
Yingdi Yuf50098d2014-02-26 14:26:29 -080030#include <iostream>
31#include <fstream>
Junxiao Shi482ccc52014-03-31 13:05:24 -070032#include "../security/cryptopp.hpp"
Yingdi Yuf50098d2014-02-26 14:26:29 -080033
34
35namespace ndn {
36namespace io {
37
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070038class Error : public std::runtime_error
39{
40public:
41 explicit
42 Error(const std::string& what)
43 : std::runtime_error(what)
44 {
45 }
46};
Yingdi Yuf50098d2014-02-26 14:26:29 -080047
48enum IoEncoding {
49 NO_ENCODING,
50 BASE_64,
51 HEX
52};
53
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070054template<typename T>
55shared_ptr<T>
Yingdi Yuf50098d2014-02-26 14:26:29 -080056load(std::istream& is, IoEncoding encoding = BASE_64)
57{
58 typedef typename T::Error TypeError;
59 try
60 {
61 using namespace CryptoPP;
62
63 shared_ptr<T> object = make_shared<T>();
64
65 OBufferStream os;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070066
67 switch (encoding)
68 {
69 case NO_ENCODING:
70 {
71 FileSource ss(is, true, new FileSink(os));
72 break;
73 }
74 case BASE_64:
75 {
76 FileSource ss(is, true, new Base64Decoder(new FileSink(os)));
77 break;
78 }
79 case HEX:
80 {
81 FileSource ss(is, true, new HexDecoder(new FileSink(os)));
82 break;
83 }
84 default:
85 return shared_ptr<T>();
86 }
Yingdi Yuf50098d2014-02-26 14:26:29 -080087
88 object->wireDecode(Block(os.buf()));
89 return object;
90 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070091 catch (CryptoPP::Exception& e)
Yingdi Yuf50098d2014-02-26 14:26:29 -080092 {
93 return shared_ptr<T>();
94 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060095 catch (tlv::Error& e)
Yingdi Yuf50098d2014-02-26 14:26:29 -080096 {
97 return shared_ptr<T>();
98 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070099 catch (TypeError& e)
Yingdi Yuf50098d2014-02-26 14:26:29 -0800100 {
101 return shared_ptr<T>();
102 }
103}
104
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700105template<typename T>
106shared_ptr<T>
Yingdi Yuf50098d2014-02-26 14:26:29 -0800107load(const std::string& file, IoEncoding encoding = BASE_64)
108{
109 std::ifstream is(file.c_str());
110 return load<T>(is, encoding);
111}
112
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700113template<typename T>
Yingdi Yuf50098d2014-02-26 14:26:29 -0800114void
115save(const T& object, std::ostream& os, IoEncoding encoding = BASE_64)
116{
117 typedef typename T::Error TypeError;
118 try
119 {
120 using namespace CryptoPP;
121
122 Block block = object.wireEncode();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700123
124 switch (encoding)
125 {
126 case NO_ENCODING:
127 {
128 StringSource ss(block.wire(), block.size(), true,
129 new FileSink(os));
130 break;
131 }
132 case BASE_64:
133 {
134 StringSource ss(block.wire(), block.size(), true,
135 new Base64Encoder(new FileSink(os), true, 64));
136 break;
137 }
138 case HEX:
139 {
140 StringSource ss(block.wire(), block.size(), true,
141 new HexEncoder(new FileSink(os)));
142 break;
143 }
144 default:
145 return;
146 }
Yingdi Yuf50098d2014-02-26 14:26:29 -0800147 return;
148 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700149 catch (CryptoPP::Exception& e)
Yingdi Yuf50098d2014-02-26 14:26:29 -0800150 {
151 throw Error(e.what());
152 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600153 catch (tlv::Error& e)
Yingdi Yuf50098d2014-02-26 14:26:29 -0800154 {
155 throw Error(e.what());
156 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700157 catch (TypeError& e)
Yingdi Yuf50098d2014-02-26 14:26:29 -0800158 {
159 throw Error(e.what());
160 }
161}
162
163template<typename T>
164void
165save(const T& object, const std::string& file, IoEncoding encoding = BASE_64)
166{
167 std::ofstream os(file.c_str());
168 save(object, os, encoding);
169}
170
171} // namespace io
172} // namespace ndn
173
174#endif // NDN_UTIL_IO_HPP