transform-base.cpp
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 
23 
24 namespace ndn {
25 namespace security {
26 namespace transform {
27 
28 Error::Error(size_t index, const std::string& what)
29  : std::runtime_error("Error in module " + to_string(index) + ": " + what)
30  , m_index(index)
31 {
32 }
33 
34 size_t
35 Downstream::write(span<const uint8_t> buf)
36 {
37  if (m_isEnd)
38  NDN_THROW(Error(getIndex(), "Module is closed, no more input"));
39 
40  size_t nBytesWritten = doWrite(buf);
41  BOOST_ASSERT(nBytesWritten <= buf.size());
42  return nBytesWritten;
43 }
44 
45 void
47 {
48  if (m_isEnd)
49  return;
50 
51  m_isEnd = true;
52  doEnd();
53 }
54 
55 void
56 Upstream::appendChain(unique_ptr<Downstream> tail)
57 {
58  if (m_next == nullptr) {
59  m_next = std::move(tail);
60  }
61  else {
62  BOOST_ASSERT(dynamic_cast<Transform*>(m_next.get()) != nullptr);
63  static_cast<Transform*>(m_next.get())->appendChain(std::move(tail));
64  }
65 }
66 
67 void
69 {
70  if (isOutputBufferEmpty())
71  return;
72 
73  size_t nWritten = m_next->write(make_span(*m_oBuffer).subspan(m_outputOffset));
74  m_outputOffset += nWritten;
75 }
76 
77 void
79 {
80  while (!isOutputBufferEmpty()) {
82  }
83 }
84 
85 void
86 Transform::setOutputBuffer(unique_ptr<OBuffer> buffer)
87 {
88  BOOST_ASSERT(isOutputBufferEmpty());
89  m_oBuffer = std::move(buffer);
90  m_outputOffset = 0;
91 }
92 
93 bool
95 {
96  return m_oBuffer == nullptr || m_oBuffer->size() == m_outputOffset;
97 }
98 
99 size_t
100 Transform::doWrite(span<const uint8_t> data)
101 {
103  if (!isOutputBufferEmpty())
104  return 0;
105 
106  preTransform();
108  if (!isOutputBufferEmpty())
109  return 0;
110 
111  size_t nConverted = convert(data);
113  return nConverted;
114 }
115 
116 void
117 Transform::doEnd()
118 {
119  finalize();
120  m_next->end();
121 }
122 
123 void
124 Transform::preTransform()
125 {
126 }
127 
128 void
129 Transform::finalize()
130 {
131  flushAllOutput();
132 }
133 
134 void
136 {
137  doPump();
138 }
139 
140 Source&
141 Source::operator>>(unique_ptr<Transform> transform)
142 {
143  transform->setIndex(m_nModules);
144  m_nModules++;
145  appendChain(std::move(transform));
146 
147  return *this;
148 }
149 
150 void
151 Source::operator>>(unique_ptr<Sink> sink)
152 {
153  sink->setIndex(m_nModules);
154  m_nModules++;
155  appendChain(std::move(sink));
156 
157  pump();
158 }
159 
160 } // namespace transform
161 } // namespace security
162 } // namespace ndn
size_t getIndex() const
Get the module index.
void end()
Close the input interface of a module.
size_t write(span< const uint8_t > buf)
Accept input data and perform transformation.
Base class of transformation error.
Error(size_t index, const std::string &what)
Abstraction of the transformation source module.
Source & operator>>(unique_ptr< Transform > transform)
Connect to an intermediate transformation module.
void pump()
Pump all data into next transformation module.
Abstraction of an intermediate transformation module.
void setOutputBuffer(unique_ptr< OBuffer > buffer)
Set output buffer to buffer.
void flushAllOutput()
Read the all the content from output buffer and write it into next module.
bool isOutputBufferEmpty() const
Check if output buffer is empty.
void flushOutputBuffer()
Read the content from output buffer and write it into next module.
void appendChain(unique_ptr< Downstream > tail)
Connect to the next transformation module.
unique_ptr< Downstream > m_next
#define NDN_THROW(e)
Definition: exception.hpp:61
std::string to_string(const errinfo_stacktrace &x)
Definition: exception.cpp:31
Definition: data.cpp:25
There are three types of module in a transformation chain: Source, Transform, and Sink.