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