blob: 8d7b2a92191cfafeef2f64c6be5d704850136aa4 [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2016 Regents of the University of California.
*
* This file is part of the nTorrent codebase.
*
* nTorrent is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* nTorrent is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with nTorrent, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS for complete list of nTorrent authors and contributors.
*/
#ifndef INCLUDED_UTIL_IO_UTIL_H
#define INCLUDED_UTIL_IO_UTIL_H
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <ndn-cxx/data.hpp>
#include <ndn-cxx/name.hpp>
#include <ndn-cxx/util/io.hpp>
#include <set>
#include <string>
#include <vector>
namespace fs = boost::filesystem;
namespace ndn {
namespace ntorrent {
class TorrentFile;
class FileManifest;
class IoUtil {
public:
/*
* An enum used to identify the type of content to which a name refers
*/
enum NAME_TYPE
{
TORRENT_FILE,
FILE_MANIFEST,
DATA_PACKET,
UNKNOWN
};
template<typename T>
static std::vector<T>
load_directory(const std::string& dirPath,
ndn::io::IoEncoding encoding = ndn::io::IoEncoding::BASE64);
static std::vector<ndn::Data>
packetize_file(const fs::path& filePath,
const ndn::Name& commonPrefix,
size_t dataPacketSize,
size_t subManifestSize,
size_t subManifestNum);
/*
* @brief Write the @p segment torrent segment to disk at the specified path.
* @param segment The torrent file segment to be written to disk
* @param path The path at which to write the torrent file segment
* Write the segment to disk, return 'true' if data successfully written to disk 'false'
* otherwise. Behavior is undefined unless @segment is a correct segment for the torrent file of
* this manager and @p path is the directory used for all segments of this torrent file.
*/
static bool
writeTorrentSegment(const TorrentFile& segment, const std::string& path);
/*
* @brief Write the @p manifest file manifest to disk at the specified @p path.
* @param manifest The file manifest to be written to disk
* @param path The path at which to write the file manifest
* Write the file manifest to disk, return 'true' if data successfully written to disk 'false'
* otherwise. Behavior is undefined unless @manifest is a correct file manifest for a file in the
* torrent file of this manager and @p path is the directory used for all file manifests of this
* torrent file.
*/
static bool
writeFileManifest(const FileManifest& manifest, const std::string& path);
/*
* @brief Write @p packet composed of torrent date to disk.
* @param packet The data packet to be written to the disk
* @param os The output stream to which to write
* Write the Data packet to disk, return 'true' if data successfully written to disk 'false'
* otherwise. Behavior is undefined unless the corresponding file manifest has already been
* downloaded.
*/
static bool
writeData(const Data& packet,
const FileManifest& manifest,
size_t subManifestSize,
fs::fstream& os);
/*
* @brief Read a data packet from the provided stream
* @param packetFullName The fullname of the expected Data packet
* @param manifest The file manifest for the requested Data packet
* @param subManifestSize The number of Data packets in each catalog for this Data packet
* @param is The stream from which to read the packet
* Read the data packet from the @p is stream, validate it against the provided @p packetFullName
* and @p manifest, if successful return a pointer to the packet, otherwise return nullptr.
*/
static std::shared_ptr<Data>
readDataPacket(const Name& packetFullName,
const FileManifest& manifest,
size_t subManifestSize,
fs::fstream& is);
/*
* @brief Return the type of the specified name
*/
static IoUtil::NAME_TYPE
findType(const Name& name);
};
template<typename T>
inline std::vector<T>
IoUtil::load_directory(const std::string& dirPath,
ndn::io::IoEncoding encoding) {
std::vector<T> structures;
std::set<std::string> fileNames;
if (fs::exists(dirPath)) {
for(fs::recursive_directory_iterator it(dirPath);
it != fs::recursive_directory_iterator();
++it)
{
fileNames.insert(it->path().string());
}
for (const auto& f : fileNames) {
auto data_ptr = ndn::io::load<T>(f, encoding);
if (nullptr != data_ptr) {
structures.push_back(*data_ptr);
}
}
}
structures.shrink_to_fit();
return structures;
}
} // namespace ntorrent
} // namespace ndn
#endif // INCLUDED_UTIL_IO_UTIL_H