NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.3: 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; -*- */
22 #include "base64-encode.hpp"
23 #include "../../encoding/buffer.hpp"
24 #include "../detail/openssl.hpp"
25 
26 namespace ndn {
27 namespace security {
28 namespace transform {
29 
35 {
36 public:
37  Impl()
38  : m_base64(BIO_new(BIO_f_base64()))
39  , m_sink(BIO_new(BIO_s_mem()))
40  {
41  // connect base64 transform to the data sink.
42  BIO_push(m_base64, m_sink);
43  }
44 
46  {
47  BIO_free_all(m_base64);
48  }
49 
50 public:
51  BIO* m_base64;
52  BIO* m_sink; // BIO_f_base64 alone does not work without a sink
53 };
54 
56  : m_impl(new Impl)
57 {
58  if (!needBreak)
59  BIO_set_flags(m_impl->m_base64, BIO_FLAGS_BASE64_NO_NL);
60 }
61 
62 void
63 Base64Encode::preTransform()
64 {
65  fillOutputBuffer();
66 }
67 
68 size_t
69 Base64Encode::convert(const uint8_t* data, size_t dataLen)
70 {
71  if (dataLen == 0)
72  return 0;
73 
74  int wLen = BIO_write(m_impl->m_base64, data, dataLen);
75 
76  if (wLen <= 0) { // fail to write data
77  if (!BIO_should_retry(m_impl->m_base64)) {
78  // we haven't written everything but some error happens, and we cannot retry
79  BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to accept more input"));
80  }
81  return 0;
82  }
83  else { // update number of bytes written
84  fillOutputBuffer();
85  return wLen;
86  }
87 }
88 
89 void
90 Base64Encode::finalize()
91 {
92  if (BIO_flush(m_impl->m_base64) != 1)
93  BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to flush"));
94 
95  while (!isConverterEmpty()) {
96  fillOutputBuffer();
97  while (!isOutputBufferEmpty()) {
99  }
100  }
101 }
102 
103 void
104 Base64Encode::fillOutputBuffer()
105 {
106  int nRead = BIO_pending(m_impl->m_sink);
107  if (nRead <= 0)
108  return;
109 
110  // there is something to read from BIO
111  auto buffer = make_unique<OBuffer>(nRead);
112  int rLen = BIO_read(m_impl->m_sink, &(*buffer)[0], nRead);
113  if (rLen < 0)
114  return;
115 
116  if (rLen < nRead)
117  buffer->erase(buffer->begin() + rLen, buffer->end());
118  setOutputBuffer(std::move(buffer));
119 }
120 
121 bool
122 Base64Encode::isConverterEmpty()
123 {
124  return (BIO_pending(m_impl->m_sink) <= 0);
125 }
126 
127 unique_ptr<Transform>
128 base64Encode(bool needBreak)
129 {
130  return make_unique<Base64Encode>(needBreak);
131 }
132 
133 } // namespace transform
134 } // namespace security
135 } // 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.
Base class of transformation error.
void flushOutputBuffer()
Read the content from output buffer and write it into next module.
unique_ptr< Transform > base64Encode(bool needBreak)