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-2023 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 
27 
28 #include <fstream>
29 
30 namespace ndn::io {
31 
32 class Error : public std::runtime_error
33 {
34 public:
35  using std::runtime_error::runtime_error;
36 };
37 
40 enum IoEncoding {
44 
51 
56  HEX,
57 };
58 
59 namespace detail {
60 
61 template<typename T>
62 static void
63 checkNestedError(typename T::Error*)
64 {
65  static_assert(std::is_convertible_v<typename T::Error*, tlv::Error*>,
66  "T::Error, if defined, must be a subclass of ndn::tlv::Error");
67 }
68 
69 template<typename T>
70 static void
71 checkNestedError(...)
72 {
73  // T::Error is not defined
74 }
75 
76 } // namespace detail
77 
84 shared_ptr<Buffer>
85 loadBuffer(std::istream& is, IoEncoding encoding = BASE64);
86 
94 template<typename T>
95 T
96 loadTlv(std::istream& is, IoEncoding encoding = BASE64)
97 {
98  BOOST_CONCEPT_ASSERT((WireDecodable<T>));
99 
100  auto buf = loadBuffer(is, encoding);
101  try {
102  return T(Block(buf));
103  }
104  catch (const std::exception& e) {
105  NDN_THROW_NESTED(Error("Decode error during load: "s + e.what()));
106  }
107 }
108 
116 template<typename T>
117 shared_ptr<T>
118 load(std::istream& is, IoEncoding encoding = BASE64)
119 {
120  BOOST_CONCEPT_ASSERT((WireDecodable<T>));
121  detail::checkNestedError<T>(nullptr);
122 
123  Block block;
124  try {
125  block = Block(loadBuffer(is, encoding));
126  }
127  catch (const std::invalid_argument&) {
128  return nullptr;
129  }
130  catch (const std::runtime_error&) {
131  return nullptr;
132  }
133 
134  try {
135  return make_shared<T>(block);
136  }
137  catch (const tlv::Error&) {
138  return nullptr;
139  }
140 }
141 
149 template<typename T>
150 shared_ptr<T>
151 load(const std::string& filename, IoEncoding encoding = BASE64)
152 {
153  std::ifstream is(filename);
154  return load<T>(is, encoding);
155 }
156 
162 void
163 saveBuffer(span<const uint8_t> buf, std::ostream& os, IoEncoding encoding = BASE64);
164 
171 template<typename T>
172 void
173 save(const T& obj, std::ostream& os, IoEncoding encoding = BASE64)
174 {
175  BOOST_CONCEPT_ASSERT((WireEncodable<T>));
176  detail::checkNestedError<T>(nullptr);
177 
178  Block block;
179  try {
180  block = obj.wireEncode();
181  }
182  catch (const tlv::Error& e) {
183  NDN_THROW_NESTED(Error("Encode error during save: "s + e.what()));
184  }
185 
186  saveBuffer(block, os, encoding);
187 }
188 
195 template<typename T>
196 void
197 save(const T& obj, const std::string& filename, IoEncoding encoding = BASE64)
198 {
199  std::ofstream os(filename);
200  save(obj, os, encoding);
201 }
202 
203 } // namespace ndn::io
204 
205 #endif // NDN_CXX_UTIL_IO_HPP
Represents a TLV element of the NDN packet format.
Definition: block.hpp:45
A concept check for TLV abstraction with a wireDecode(Block) method and constructible from Block.
Definition: concepts.hpp:82
A concept check for TLV abstraction with a wireEncode() method.
Definition: concepts.hpp:46
Represents an error in TLV encoding or decoding.
Definition: tlv.hpp:54
#define NDN_THROW_NESTED(e)
Definition: exception.hpp:65
Definition: io.cpp:33
T loadTlv(std::istream &is, IoEncoding encoding=BASE64)
Reads a TLV element of type T from a stream.
Definition: io.hpp:96
void save(const T &obj, std::ostream &os, IoEncoding encoding=BASE64)
Writes a TLV element to a stream.
Definition: io.hpp:173
shared_ptr< T > load(std::istream &is, IoEncoding encoding=BASE64)
Reads a TLV element from a stream.
Definition: io.hpp:118
void saveBuffer(span< const uint8_t > buf, std::ostream &os, IoEncoding encoding)
Writes a sequence of bytes to a stream.
Definition: io.cpp:62
IoEncoding
Indicates how a file or stream of bytes is encoded.
Definition: io.hpp:40
@ NO_ENCODING
Raw binary, without encoding.
Definition: io.hpp:43
@ HEX
Hexadecimal encoding.
Definition: io.hpp:56
@ BASE64
Base64 encoding.
Definition: io.hpp:50
shared_ptr< Buffer > loadBuffer(std::istream &is, IoEncoding encoding)
Reads bytes from a stream until EOF.
Definition: io.cpp:36