NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
base64-encode.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2017 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 #include "base64-encode.hpp"
23 #include "../detail/openssl.hpp"
24 
25 namespace ndn {
26 namespace security {
27 namespace transform {
28 
34 {
35 public:
36  Impl()
37  : m_base64(BIO_new(BIO_f_base64()))
38  , m_sink(BIO_new(BIO_s_mem()))
39  {
40  // connect base64 transform to the data sink.
41  BIO_push(m_base64, m_sink);
42  }
43 
45  {
46  BIO_free_all(m_base64);
47  }
48 
49 public:
50  BIO* m_base64;
51  BIO* m_sink; // BIO_f_base64 alone does not work without a sink
52 };
53 
55  : m_impl(make_unique<Impl>())
56 {
57  if (!needBreak)
58  BIO_set_flags(m_impl->m_base64, BIO_FLAGS_BASE64_NO_NL);
59 }
60 
61 Base64Encode::~Base64Encode() = default;
62 
63 void
64 Base64Encode::preTransform()
65 {
66  fillOutputBuffer();
67 }
68 
69 size_t
70 Base64Encode::convert(const uint8_t* data, size_t dataLen)
71 {
72  if (dataLen == 0)
73  return 0;
74 
75  int wLen = BIO_write(m_impl->m_base64, data, dataLen);
76 
77  if (wLen <= 0) { // fail to write data
78  if (!BIO_should_retry(m_impl->m_base64)) {
79  // we haven't written everything but some error happens, and we cannot retry
80  BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to accept more input"));
81  }
82  return 0;
83  }
84  else { // update number of bytes written
85  fillOutputBuffer();
86  return wLen;
87  }
88 }
89 
90 void
91 Base64Encode::finalize()
92 {
93  if (BIO_flush(m_impl->m_base64) != 1)
94  BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to flush"));
95 
96  while (!isConverterEmpty()) {
97  fillOutputBuffer();
98  while (!isOutputBufferEmpty()) {
100  }
101  }
102 }
103 
104 void
105 Base64Encode::fillOutputBuffer()
106 {
107  int nRead = BIO_pending(m_impl->m_sink);
108  if (nRead <= 0)
109  return;
110 
111  // there is something to read from BIO
112  auto buffer = make_unique<OBuffer>(nRead);
113  int rLen = BIO_read(m_impl->m_sink, buffer->data(), nRead);
114  if (rLen < 0)
115  return;
116 
117  if (rLen < nRead)
118  buffer->erase(buffer->begin() + rLen, buffer->end());
119  setOutputBuffer(std::move(buffer));
120 }
121 
122 bool
123 Base64Encode::isConverterEmpty()
124 {
125  return (BIO_pending(m_impl->m_sink) <= 0);
126 }
127 
128 unique_ptr<Transform>
129 base64Encode(bool needBreak)
130 {
131  return make_unique<Base64Encode>(needBreak);
132 }
133 
134 } // namespace transform
135 } // namespace security
136 } // namespace ndn
Copyright (c) 2011-2015 Regents of the University of California.
size_t getIndex() const
Get the module index.
bool isOutputBufferEmpty() const
Check if output buffer is empty.
The implementation class which contains the internal state of the filter which includes openssl speci...
void setOutputBuffer(unique_ptr< OBuffer > buffer)
Set output buffer to buffer.
Base64Encode(bool needBreak=true)
Create a base64 encoding module.
void flushOutputBuffer()
Read the content from output buffer and write it into next module.
unique_ptr< T > make_unique(Args &&... args)
Definition: backports.hpp:73
unique_ptr< Transform > base64Encode(bool needBreak)