putchunks: use ndn-cxx's Segmenter
Change-Id: I2a2bdac2983cce45c6e6d8f5b41a5609b4a98c48
diff --git a/tools/chunks/putchunks/producer.cpp b/tools/chunks/putchunks/producer.cpp
index 24565c0..6b305cd 100644
--- a/tools/chunks/putchunks/producer.cpp
+++ b/tools/chunks/putchunks/producer.cpp
@@ -31,6 +31,7 @@
#include "producer.hpp"
#include <ndn-cxx/metadata-object.hpp>
+#include <ndn-cxx/util/segmenter.hpp>
namespace ndn::chunks {
@@ -49,12 +50,13 @@
m_versionedPrefix = Name(m_prefix).appendVersion();
}
- populateStore(is);
+ if (!m_options.isQuiet) {
+ std::cerr << "Loading input ...\n";
+ }
+ util::Segmenter segmenter(m_keyChain, m_options.signingInfo);
+ m_store = segmenter.segment(is, m_versionedPrefix, m_options.maxSegmentSize, m_options.freshnessPeriod);
- if (m_options.wantShowVersion)
- std::cout << m_versionedPrefix[-1] << "\n";
-
- // register m_prefix without interest handler
+ // register m_prefix without Interest handler
m_face.registerPrefix(m_prefix, nullptr, [this] (const Name& prefix, const auto& reason) {
std::cerr << "ERROR: Failed to register prefix '" << prefix << "' (" << reason << ")\n";
m_face.shutdown();
@@ -76,8 +78,13 @@
processDiscoveryInterest(interest);
});
- if (!m_options.isQuiet)
- std::cerr << "Data published with name: " << m_versionedPrefix << "\n";
+ if (m_options.wantShowVersion) {
+ std::cout << m_versionedPrefix[-1] << "\n";
+ }
+ if (!m_options.isQuiet) {
+ std::cerr << "Published " << m_store.size() << " Data packet" << (m_store.size() > 1 ? "s" : "")
+ << " with prefix " << m_versionedPrefix << "\n";
+ }
}
void
@@ -93,8 +100,9 @@
std::cerr << "Discovery Interest: " << interest << "\n";
if (!interest.getCanBePrefix()) {
- if (m_options.isVerbose)
+ if (m_options.isVerbose) {
std::cerr << "Discovery Interest lacks CanBePrefix, sending Nack\n";
+ }
m_face.put(lp::Nack(interest));
return;
}
@@ -103,7 +111,7 @@
mobject.setVersionedName(m_versionedPrefix);
// make a metadata packet based on the received discovery Interest name
- Data mdata(mobject.makeData(interest.getName(), m_keyChain, m_options.signingInfo));
+ auto mdata = mobject.makeData(interest.getName(), m_keyChain, m_options.signingInfo);
if (m_options.isVerbose)
std::cerr << "Sending metadata: " << mdata << "\n";
@@ -135,53 +143,17 @@
}
if (data != nullptr) {
- if (m_options.isVerbose)
+ if (m_options.isVerbose) {
std::cerr << "Data: " << *data << "\n";
-
+ }
m_face.put(*data);
}
else {
- if (m_options.isVerbose)
+ if (m_options.isVerbose) {
std::cerr << "Interest cannot be satisfied, sending Nack\n";
+ }
m_face.put(lp::Nack(interest));
}
}
-void
-Producer::populateStore(std::istream& is)
-{
- BOOST_ASSERT(m_store.empty());
-
- if (!m_options.isQuiet)
- std::cerr << "Loading input ...\n";
-
- std::vector<uint8_t> buffer(m_options.maxSegmentSize);
- while (is.good()) {
- is.read(reinterpret_cast<char*>(buffer.data()), buffer.size());
- const auto nCharsRead = is.gcount();
-
- if (nCharsRead > 0) {
- auto data = make_shared<Data>(Name(m_versionedPrefix).appendSegment(m_store.size()));
- data->setFreshnessPeriod(m_options.freshnessPeriod);
- data->setContent(make_span(buffer).first(nCharsRead));
- m_store.push_back(data);
- }
- }
-
- if (m_store.empty()) {
- auto data = make_shared<Data>(Name(m_versionedPrefix).appendSegment(0));
- data->setFreshnessPeriod(m_options.freshnessPeriod);
- m_store.push_back(data);
- }
-
- auto finalBlockId = name::Component::fromSegment(m_store.size() - 1);
- for (const auto& data : m_store) {
- data->setFinalBlock(finalBlockId);
- m_keyChain.sign(*data, m_options.signingInfo);
- }
-
- if (!m_options.isQuiet)
- std::cerr << "Created " << m_store.size() << " chunks for prefix " << m_prefix << "\n";
-}
-
} // namespace ndn::chunks
diff --git a/tools/chunks/putchunks/producer.hpp b/tools/chunks/putchunks/producer.hpp
index 7000bd7..afacabd 100644
--- a/tools/chunks/putchunks/producer.hpp
+++ b/tools/chunks/putchunks/producer.hpp
@@ -35,7 +35,7 @@
namespace ndn::chunks {
/**
- * @brief Segmented & versioned data publisher
+ * @brief Segmented & versioned data publisher.
*
* Packetizes and publishes data from an input stream as `/prefix/<version>/<segment number>`.
* Unless another value is provided, the current time is used as the version number.
@@ -54,9 +54,8 @@
bool wantShowVersion = false;
};
-public:
/**
- * @brief Create the producer
+ * @brief Create the producer.
* @param prefix prefix used to publish data; if the last component is not a valid
* version number, the current system time is used as version number.
*/
@@ -64,33 +63,20 @@
const Options& opts);
/**
- * @brief Run the producer
+ * @brief Run the producer.
*/
void
run();
private:
/**
- * @brief Split the input stream in data packets and save them to the store
- *
- * Create data packets reading all the characters from the input stream until EOF or an
- * error occurs. Each data packet has a maximum payload size of `m_options.maxSegmentSize`
- * bytes and is stored in the vector `m_store`. An empty data packet is created and stored
- * if the input stream is empty.
- *
- * @return Number of data packets contained in the store after the operation
- */
- void
- populateStore(std::istream& is);
-
- /**
- * @brief Respond with a metadata packet containing the versioned content name
+ * @brief Respond with a metadata packet containing the versioned content name.
*/
void
processDiscoveryInterest(const Interest& interest);
/**
- * @brief Respond with the requested segment of content
+ * @brief Respond with the requested segment of content.
*/
void
processSegmentInterest(const Interest& interest);