io.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2022 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * 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.
20  */
21 
22 #ifndef NDN_CXX_UTIL_IO_HPP
23 #define NDN_CXX_UTIL_IO_HPP
24 
28 
29 #include <fstream>
30 
31 namespace ndn {
32 namespace io {
33 
34 class Error : public std::runtime_error
35 {
36 public:
37  using std::runtime_error::runtime_error;
38 };
39 
42 enum IoEncoding {
46 
53 
58  HEX,
59 };
60 
61 namespace detail {
62 
63 template<typename T>
64 static void
65 checkNestedError(typename T::Error*)
66 {
67  static_assert(std::is_convertible<typename T::Error*, tlv::Error*>::value,
68  "T::Error, if defined, must be a subclass of ndn::tlv::Error");
69 }
70 
71 template<typename T>
72 static void
73 checkNestedError(...)
74 {
75  // T::Error is not defined
76 }
77 
78 } // namespace detail
79 
86 shared_ptr<Buffer>
87 loadBuffer(std::istream& is, IoEncoding encoding = BASE64);
88 
96 template<typename T>
97 T
98 loadTlv(std::istream& is, IoEncoding encoding = BASE64)
99 {
100  BOOST_CONCEPT_ASSERT((WireDecodable<T>));
101 
102  auto buf = loadBuffer(is, encoding);
103  try {
104  return T(Block(buf));
105  }
106  catch (const std::exception& e) {
107  NDN_THROW_NESTED(Error("Decode error during load: "s + e.what()));
108  }
109 }
110 
118 template<typename T>
119 shared_ptr<T>
120 load(std::istream& is, IoEncoding encoding = BASE64)
121 {
122  BOOST_CONCEPT_ASSERT((WireDecodable<T>));
123  detail::checkNestedError<T>(nullptr);
124 
125  Block block;
126  try {
127  block = Block(loadBuffer(is, encoding));
128  }
129  catch (const std::invalid_argument&) {
130  return nullptr;
131  }
132  catch (const std::runtime_error&) {
133  return nullptr;
134  }
135 
136  try {
137  return make_shared<T>(block);
138  }
139  catch (const tlv::Error&) {
140  return nullptr;
141  }
142 }
143 
151 template<typename T>
152 shared_ptr<T>
153 load(const std::string& filename, IoEncoding encoding = BASE64)
154 {
155  std::ifstream is(filename);
156  return load<T>(is, encoding);
157 }
158 
164 void
165 saveBuffer(span<const uint8_t> buf, std::ostream& os, IoEncoding encoding = BASE64);
166 
173 template<typename T>
174 void
175 save(const T& obj, std::ostream& os, IoEncoding encoding = BASE64)
176 {
177  BOOST_CONCEPT_ASSERT((WireEncodable<T>));
178  detail::checkNestedError<T>(nullptr);
179 
180  Block block;
181  try {
182  block = obj.wireEncode();
183  }
184  catch (const tlv::Error& e) {
185  NDN_THROW_NESTED(Error("Encode error during save: "s + e.what()));
186  }
187 
188  saveBuffer({block.wire(), block.size()}, os, encoding);
189 }
190 
197 template<typename T>
198 void
199 save(const T& obj, const std::string& filename, IoEncoding encoding = BASE64)
200 {
201  std::ofstream os(filename);
202  save(obj, os, encoding);
203 }
204 
205 } // namespace io
206 } // namespace ndn
207 
208 #endif // NDN_CXX_UTIL_IO_HPP
Represents a TLV element of the NDN packet format.
Definition: block.hpp:45
const uint8_t * wire() const
Return a raw pointer to the beginning of the encoded wire.
Definition: block.cpp:296
size_t size() const
Return the size of the encoded wire, i.e.
Definition: block.cpp:305
a concept check for TLV abstraction with .wireDecode method and constructible from Block
Definition: concepts.hpp:81
a concept check for TLV abstraction with .wireEncode method
Definition: concepts.hpp:45
represents an error in TLV encoding or decoding
Definition: tlv.hpp:53
#define NDN_THROW_NESTED(e)
Definition: exception.hpp:71
T loadTlv(std::istream &is, IoEncoding encoding=BASE64)
Reads a TLV element of type T from a stream.
Definition: io.hpp:98
void save(const T &obj, std::ostream &os, IoEncoding encoding=BASE64)
Writes a TLV element to a stream.
Definition: io.hpp:175
shared_ptr< T > load(std::istream &is, IoEncoding encoding=BASE64)
Reads a TLV element from a stream.
Definition: io.hpp:120
void saveBuffer(span< const uint8_t > buf, std::ostream &os, IoEncoding encoding)
Writes a sequence of bytes to a stream.
Definition: io.cpp:63
IoEncoding
Indicates how a file or stream of bytes is encoded.
Definition: io.hpp:42
@ NO_ENCODING
Raw binary, without encoding.
Definition: io.hpp:45
@ HEX
Hexadecimal encoding.
Definition: io.hpp:58
@ BASE64
Base64 encoding.
Definition: io.hpp:52
shared_ptr< Buffer > loadBuffer(std::istream &is, IoEncoding encoding)
Reads bytes from a stream until EOF.
Definition: io.cpp:37
Definition: data.cpp:25