blob: 7f6414580cf1c61e7acf2b9577e28d0fe5a76691 [file] [log] [blame]
Yingdi Yu3168c302015-07-04 16:45:40 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2016 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_SECURITY_TRANSFORM_BASE_HPP
23#define NDN_CXX_SECURITY_TRANSFORM_BASE_HPP
24
25#include "../../common.hpp"
26
27namespace ndn {
28namespace security {
29namespace transform {
30
31/**
32 * @file transform-base.hpp
33 *
34 * There are three types of module in a transformation chain: Source, Transform, and Sink.
35 * The ideal usage of the transformation would be:
36 *
37 * source(...) >> transform1(...) >> transform2(...) >> sink(...);
38 *
39 * When error happens in a module, the module will throw out a transform::Error, one
40 * can get the location of the module through the getIndex() method of transform::Error.
41 */
42
43/**
44 * @brief Base class of transformation error
45 */
46class Error : public std::runtime_error
47{
48public:
49 Error(size_t index, const std::string& what);
50
51 size_t
52 getIndex() const
53 {
54 return m_index;
55 }
56
57private:
58 size_t m_index;
59};
60
61/**
62 * @brief The downstream interface of a transformation module
63 *
64 * A module can accept input through this interface
65 */
66class Downstream
67{
68public:
69 /**
70 * @brief Accept input data and perform transformation.
71 *
72 * An upstream module should call this method to write data into this module.
73 * The written data will be transformed and the result will be written into the next
74 * downstream module.
75 *
76 * An upstream module can keep calling this method to until end() is called, which
77 * indicates the end of input. After that, calling this method will cause Error.
78 *
79 * If a Downstream implementation expects structured input (e.g., hex decoding requires byte-pair),
80 * it should not return less than size if final portion of input is not a complete record.
81 *
82 * @return number of bytes that has been written into this module
83 * @throws Error if this module is closed or transformation error happens.
84 */
85 size_t
86 write(const uint8_t* buf, size_t size);
87
88 /**
89 * @brief Close the input interface of a module.
90 *
91 * This method will notify this module that there is no more input and that the module
92 * should finalize transformation.
93 *
94 * Although end() can be invoked multiple times, only the first invocation takes effect.
95 */
96 void
97 end();
98
99 /**
100 * @brief Check if the input interface of a module is closed.
101 */
102 bool
103 isEnd() const
104 {
105 return m_isEnd;
106 }
107
108 /**
109 * @brief Set the module index.
110 */
111 void
112 setIndex(size_t index)
113 {
114 m_index = index;
115 }
116
117 /**
118 * @brief Get the module index.
119 */
120 size_t
121 getIndex() const
122 {
123 return m_index;
124 }
125
126protected:
127 Downstream();
128
129private:
130 /**
131 * @brief Internal implementation of write method
132 */
133 virtual size_t
134 doWrite(const uint8_t* buf, size_t size) = 0;
135
136 /**
137 * @brief Internal implementation of end method
138 */
139 virtual void
140 doEnd() = 0;
141
142private:
143 bool m_isEnd;
144 size_t m_index;
145};
146
147/**
148 * @brief The upstream interface of a transformation module
149 *
150 * A module can construct subsequent transformation chain through this interface.
151 */
152class Upstream
153{
154protected:
155 Upstream();
156
157protected:
158 /**
159 * @brief connect to next transformation module
160 */
161 void
162 appendChain(unique_ptr<Downstream> tail);
163
164 Downstream*
165 getNext()
166 {
167 return m_next.get();
168 }
169
170protected:
171 unique_ptr<Downstream> m_next;
172};
173
174/**
175 * @brief Abstraction of an intermediate transformation module
176 */
177class Transform : public Upstream,
178 public Downstream,
179 noncopyable
180{
181};
182
183/**
184 * @brief Abstraction of the transformation sink module
185 *
186 * This module does not have next module and can only accept input data
187 */
188class Sink : public Downstream,
189 noncopyable
190{
191};
192
193/**
194 * @brief Abstraction of the transformation source module
195 *
196 * This module can only accept input data from constructor
197 */
198class Source : public Upstream,
199 noncopyable
200{
201public:
202 /**
203 * @brief Connect to an intermediate transformation module.
204 */
205 Source&
206 operator>>(unique_ptr<Transform> transform);
207
208 /**
209 * @brief Connect to the last transformation module.
210 *
211 * This method will trigger the source to pump data into the transformation pipeline.
212 */
213 void
214 operator>>(unique_ptr<Sink> sink);
215
216protected:
217 Source();
218
219 /**
220 * @brief Pump all data into next transformation module.
221 */
222 void
223 pump();
224
225 /**
226 * @brief Get the source module index (should always be 0).
227 */
228 size_t
229 getIndex() const
230 {
231 return 0;
232 }
233
234private:
235 /**
236 * @brief Internal implementation of pump().
237 */
238 virtual void
239 doPump() = 0;
240
241private:
242 size_t m_nModules; // count of modules in the chain starting from this Source
243};
244
245} // namespace transform
246} // namespace security
247} // namespace ndn
248
249#endif // NDN_CXX_SECURITY_TRANSFORM_BASE_HPP