blob: 8e81acae6ace53ea6b6e08a3a86ef082ee6d0494 [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
30#include <string>
31#include <iostream>
32#include <fstream>
Junxiao Shi482ccc52014-03-31 13:05:24 -070033#include "../security/cryptopp.hpp"
Yingdi Yuf50098d2014-02-26 14:26:29 -080034
35
36namespace ndn {
37namespace io {
38
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070039class Error : public std::runtime_error
40{
41public:
42 explicit
43 Error(const std::string& what)
44 : std::runtime_error(what)
45 {
46 }
47};
Yingdi Yuf50098d2014-02-26 14:26:29 -080048
49enum IoEncoding {
50 NO_ENCODING,
51 BASE_64,
52 HEX
53};
54
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070055template<typename T>
56shared_ptr<T>
Yingdi Yuf50098d2014-02-26 14:26:29 -080057load(std::istream& is, IoEncoding encoding = BASE_64)
58{
59 typedef typename T::Error TypeError;
60 try
61 {
62 using namespace CryptoPP;
63
64 shared_ptr<T> object = make_shared<T>();
65
66 OBufferStream os;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070067
68 switch (encoding)
69 {
70 case NO_ENCODING:
71 {
72 FileSource ss(is, true, new FileSink(os));
73 break;
74 }
75 case BASE_64:
76 {
77 FileSource ss(is, true, new Base64Decoder(new FileSink(os)));
78 break;
79 }
80 case HEX:
81 {
82 FileSource ss(is, true, new HexDecoder(new FileSink(os)));
83 break;
84 }
85 default:
86 return shared_ptr<T>();
87 }
Yingdi Yuf50098d2014-02-26 14:26:29 -080088
89 object->wireDecode(Block(os.buf()));
90 return object;
91 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070092 catch (CryptoPP::Exception& e)
Yingdi Yuf50098d2014-02-26 14:26:29 -080093 {
94 return shared_ptr<T>();
95 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070096 catch (Tlv::Error& e)
Yingdi Yuf50098d2014-02-26 14:26:29 -080097 {
98 return shared_ptr<T>();
99 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700100 catch (TypeError& e)
Yingdi Yuf50098d2014-02-26 14:26:29 -0800101 {
102 return shared_ptr<T>();
103 }
104}
105
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700106template<typename T>
107shared_ptr<T>
Yingdi Yuf50098d2014-02-26 14:26:29 -0800108load(const std::string& file, IoEncoding encoding = BASE_64)
109{
110 std::ifstream is(file.c_str());
111 return load<T>(is, encoding);
112}
113
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700114template<typename T>
Yingdi Yuf50098d2014-02-26 14:26:29 -0800115void
116save(const T& object, std::ostream& os, IoEncoding encoding = BASE_64)
117{
118 typedef typename T::Error TypeError;
119 try
120 {
121 using namespace CryptoPP;
122
123 Block block = object.wireEncode();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700124
125 switch (encoding)
126 {
127 case NO_ENCODING:
128 {
129 StringSource ss(block.wire(), block.size(), true,
130 new FileSink(os));
131 break;
132 }
133 case BASE_64:
134 {
135 StringSource ss(block.wire(), block.size(), true,
136 new Base64Encoder(new FileSink(os), true, 64));
137 break;
138 }
139 case HEX:
140 {
141 StringSource ss(block.wire(), block.size(), true,
142 new HexEncoder(new FileSink(os)));
143 break;
144 }
145 default:
146 return;
147 }
Yingdi Yuf50098d2014-02-26 14:26:29 -0800148 return;
149 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700150 catch (CryptoPP::Exception& e)
Yingdi Yuf50098d2014-02-26 14:26:29 -0800151 {
152 throw Error(e.what());
153 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700154 catch (Tlv::Error& e)
Yingdi Yuf50098d2014-02-26 14:26:29 -0800155 {
156 throw Error(e.what());
157 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700158 catch (TypeError& e)
Yingdi Yuf50098d2014-02-26 14:26:29 -0800159 {
160 throw Error(e.what());
161 }
162}
163
164template<typename T>
165void
166save(const T& object, const std::string& file, IoEncoding encoding = BASE_64)
167{
168 std::ofstream os(file.c_str());
169 save(object, os, encoding);
170}
171
172} // namespace io
173} // namespace ndn
174
175#endif // NDN_UTIL_IO_HPP