blob: d32ac65e8e255b97560fa24b2e80e795fba5f22b [file] [log] [blame]
Mickey Sweattfcbfb3d2016-04-13 17:05:17 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3* Copyright (c) 2016 Regents of the University of California.
4*
5* This file is part of the nTorrent codebase.
6*
7* nTorrent 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* nTorrent 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 nTorrent, e.g., in COPYING.md file. If not, see
17* <http://www.gnu.org/licenses/>.
18*
19* See AUTHORS for complete list of nTorrent authors and contributors.
20*/
21
22#ifndef INCLUDED_UTIL_IO_UTIL_H
23#define INCLUDED_UTIL_IO_UTIL_H
24
25#include <boost/filesystem.hpp>
26#include <boost/filesystem/fstream.hpp>
27
28#include <ndn-cxx/data.hpp>
29#include <ndn-cxx/name.hpp>
30#include <ndn-cxx/util/io.hpp>
31
32#include <set>
33#include <string>
34#include <vector>
35
36namespace fs = boost::filesystem;
37
38namespace ndn {
39namespace ntorrent {
40
41class TorrentFile;
42class FileManifest;
43
44class IoUtil {
45 public:
46 /*
47 * An enum used to identify the type of content to which a name refers
48 */
49 enum NAME_TYPE
50 {
51 FILE_MANIFEST,
52 TORRENT_FILE,
53 DATA_PACKET,
54 UNKNOWN
55 };
56
57 template<typename T>
58 static std::vector<T>
59 load_directory(const std::string& dirPath,
60 ndn::io::IoEncoding encoding = ndn::io::IoEncoding::BASE_64);
61
62 static std::vector<ndn::Data>
63 packetize_file(const fs::path& filePath,
64 const ndn::Name& commonPrefix,
65 size_t dataPacketSize,
66 size_t subManifestSize,
67 size_t subManifestNum);
68
69 /*
70 * @brief Write the @p segment torrent segment to disk at the specified path.
71 * @param segment The torrent file segment to be written to disk
72 * @param path The path at which to write the torrent file segment
73 * Write the segment to disk, return 'true' if data successfully written to disk 'false'
74 * otherwise. Behavior is undefined unless @segment is a correct segment for the torrent file of
75 * this manager and @p path is the directory used for all segments of this torrent file.
76 */
77 static bool
78 writeTorrentSegment(const TorrentFile& segment, const std::string& path);
79
80 /*
81 * @brief Write the @p manifest file manifest to disk at the specified @p path.
82 * @param manifest The file manifest to be written to disk
83 * @param path The path at which to write the file manifest
84 * Write the file manifest to disk, return 'true' if data successfully written to disk 'false'
85 * otherwise. Behavior is undefined unless @manifest is a correct file manifest for a file in the
86 * torrent file of this manager and @p path is the directory used for all file manifests of this
87 * torrent file.
88 */
89 static bool
90 writeFileManifest(const FileManifest& manifest, const std::string& path);
91
92 /*
93 * @brief Write @p packet composed of torrent date to disk.
94 * @param packet The data packet to be written to the disk
95 * @param os The output stream to which to write
96 * Write the Data packet to disk, return 'true' if data successfully written to disk 'false'
97 * otherwise. Behavior is undefined unless the corresponding file manifest has already been
98 * downloaded.
99 */
100 static bool
101 writeData(const Data& packet,
102 const FileManifest& manifest,
103 size_t subManifestSize,
104 fs::fstream& os);
105
106 /*
107 * @brief Read a data packet from the provided stream
108 * @param packetFullName The fullname of the expected Data packet
109 * @param manifest The file manifest for the requested Data packet
110 * @param subManifestSize The number of Data packets in each catalog for this Data packet
111 * @param is The stream from which to read the packet
112 * Read the data packet from the @p is stream, validate it against the provided @p packetFullName
113 * and @p manifest, if successful return a pointer to the packet, otherwise return nullptr.
114 */
115 static std::shared_ptr<Data>
116 readDataPacket(const Name& packetFullName,
117 const FileManifest& manifest,
118 size_t subManifestSize,
119 fs::fstream& is);
120
121 /*
122 * @brief Return the type of the specified name
123 */
124 static IoUtil::NAME_TYPE
125 findType(const Name& name);
126
127};
128
129template<typename T>
130inline std::vector<T>
131IoUtil::load_directory(const std::string& dirPath,
132 ndn::io::IoEncoding encoding) {
133 std::vector<T> structures;
134 std::set<std::string> fileNames;
135 if (fs::exists(dirPath)) {
136 for(fs::recursive_directory_iterator it(dirPath);
137 it != fs::recursive_directory_iterator();
138 ++it)
139 {
140 fileNames.insert(it->path().string());
141 }
142 for (const auto& f : fileNames) {
143 auto data_ptr = ndn::io::load<T>(f, encoding);
144 if (nullptr != data_ptr) {
145 structures.push_back(*data_ptr);
146 }
147 }
148 }
149 structures.shrink_to_fit();
150 return structures;
151}
152
153} // namespace ntorrent
154} // namespace ndn
155
156#endif // INCLUDED_UTIL_IO_UTIL_H