blob: 0536c17b9999af968e172f83dcbafa0771897695 [file] [log] [blame]
spirosmastorakisa6057f52016-01-28 13:34:41 -08001/* -*- 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 TORRENT_FILE_HPP
23#define TORRENT_FILE_HPP
24
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -080025#include "file-manifest.hpp"
26
spirosmastorakisa6057f52016-01-28 13:34:41 -080027#include <ndn-cxx/name.hpp>
28#include <ndn-cxx/encoding/block.hpp>
29#include <ndn-cxx/data.hpp>
30
31#include <memory>
32
33namespace ndn {
34
35namespace ntorrent {
36
37class TorrentFile : public Data {
38public:
39 class Error : public Data::Error
40 {
41 public:
42 explicit
43 Error(const std::string& what)
44 : Data::Error(what)
45 {
46 }
47 };
48
49 /**
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -080050 * @brief Create a new empty TorrentFile.
spirosmastorakisa6057f52016-01-28 13:34:41 -080051 */
52 TorrentFile() = default;
53
54 /**
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -080055 * @brief Create a new TorrentFile.
56 * @param torrentFileName The name of the torrent-file
57 * @param torrentFilePtr A pointer (name) to the next segment of the torrent-file
spirosmastorakisa6057f52016-01-28 13:34:41 -080058 * @param commonPrefix The common name prefix of the manifest file names included in the catalog
59 * @param catalog The catalog containing the name of each file manifest
60 */
61 TorrentFile(const Name& torrentFileName,
62 const Name& torrentFilePtr,
63 const Name& commonPrefix,
64 const std::vector<ndn::Name>& catalog);
65
66 /**
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -080067 * @brief Create a new TorrentFile.
68 * @param torrentFileName The name of the torrent-file
spirosmastorakisa6057f52016-01-28 13:34:41 -080069 * @param commonPrefix The common name prefix of the manifest file names included in the catalog
70 * @param catalog The catalog containing the name of each file manifest
71 */
72 TorrentFile(const Name& torrentFileName,
73 const Name& commonPrefix,
74 const std::vector<ndn::Name>& catalog);
75
76 /**
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -080077 * @brief Create a new TorrentFile
78 * @param block The block format of the torrent-file
spirosmastorakisa6057f52016-01-28 13:34:41 -080079 */
80 explicit
81 TorrentFile(const Block& block);
82
83 /**
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -080084 * @brief Get the name of the TorrentFile
spirosmastorakisa6057f52016-01-28 13:34:41 -080085 */
86 const Name&
87 getName() const;
88
89 /**
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -080090 * @brief Get the common prefix of the file manifest names of this torrent-file
spirosmastorakisa6057f52016-01-28 13:34:41 -080091 */
92 const Name&
93 getCommonPrefix() const;
94
95 /**
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -080096 * @brief Get a shared pointer to the name of the next segment of the torrent-file.
spirosmastorakisa6057f52016-01-28 13:34:41 -080097 *
98 * If there is no next segment, it returns a nullptr
99 */
100 shared_ptr<Name>
101 getTorrentFilePtr() const;
102
103 /**
104 * @brief Get the catalog of names of the file manifests
105 */
106 const std::vector<Name>&
107 getCatalog() const;
108
109 /**
Mickey Sweatt599bfef2016-04-05 19:11:20 -0700110 * @brief Get the segment number for this torrent file
111 */
112 size_t
113 getSegmentNumber() const;
114
115 /**
116 * @brief Get the directory name for this torrent file
117 */
118 std::string
119 getTorrentFilePath() const;
120
121 /**
spirosmastorakisa6057f52016-01-28 13:34:41 -0800122 * @brief Decode from wire format
123 */
124 void
125 wireDecode(const Block& wire);
126
127 /**
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -0800128 * @brief Finalize torrent-file before signing the data packet
spirosmastorakis6d4300f2016-02-29 20:18:43 -0800129 *
130 * This method has to be called (every time) right before signing or encoding
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -0800131 * the torrent-file
spirosmastorakisa6057f52016-01-28 13:34:41 -0800132 */
spirosmastorakis6d4300f2016-02-29 20:18:43 -0800133 void
134 finalize();
spirosmastorakisa6057f52016-01-28 13:34:41 -0800135
136 /**
137 * @brief Insert a name to the catalog of file manifest names
138 */
139 void
140 insert(const Name& name);
141
142 /**
143 * @brief Erase a name from the catalog of file manifest names
144 */
145 bool
146 erase(const Name& name);
147
148 /**
149 * @brief Get the size of the catalog of file manifest names
150 */
151 size_t
152 catalogSize() const;
153
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -0800154 /**
155 * @brief Given a directory path for the torrent file, it generates the torrent file
156 *
157 * @param directoryPath The path to the directory for which we are to create a torrent-file
158 * @param torrentFilePrefix The prefix to be used for the name of this torrent-file
159 * @param namesPerSegment The number of manifest names to be included in each segment of the
160 * torrent-file
161 * @param returnData Determines whether the data would be returned in memory or it will be
162 * stored on disk without being returned
163 *
164 * Generates the torrent-file for the directory at the specified 'directoryPath',
165 * splitting the torrent-file into multiple segments, each one of which contains
166 * at most 'namesPerSegment' number of manifest names
167 *
168 **/
169 static std::pair<std::vector<TorrentFile>,
170 std::vector<std::pair<std::vector<FileManifest>,
171 std::vector<Data>>>>
172 generate(const std::string& directoryPath,
173 size_t namesPerSegment,
174 size_t subManifestSize,
175 size_t dataPacketSize,
176 bool returnData = false);
177
spirosmastorakisa6057f52016-01-28 13:34:41 -0800178protected:
179 /**
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -0800180 * @brief prepend torrent file as a Content block to the encoder
spirosmastorakisa6057f52016-01-28 13:34:41 -0800181 */
182 template<encoding::Tag TAG>
183 size_t
184 encodeContent(EncodingImpl<TAG>& encoder) const;
185
186 void
187 encodeContent();
188
189 void
190 decodeContent();
191
192private:
193 /**
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -0800194 * @brief Check whether the torrent-file has a pointer to the next segment
spirosmastorakisa6057f52016-01-28 13:34:41 -0800195 */
196 bool
197 hasTorrentFilePtr() const;
198
199 /**
200 * @brief Create a catalog of suffixes for the names of the file manifests
201 *
202 * To optimize encoding and decoding, we encode the name of the file manifests
203 * as suffixes along with their common prefix.
204 *
205 */
206 void
207 createSuffixCatalog();
208
209 /**
210 * @brief Construct the catalog of long names from a catalog of suffixes for the file
211 * manifests' name
212 *
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -0800213 * After decoding a torrent-file from its wire format, we construct the catalog of
spirosmastorakisa6057f52016-01-28 13:34:41 -0800214 * long names from the decoded common prefix and suffixes
215 *
216 */
217 void
218 constructLongNames();
219
220 /**
221 * @brief Insert a suffix to the suffix catalog
222 */
223 void
224 insertToSuffixCatalog(const PartialName& suffix);
225
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -0800226 /**
227 * @brief Set the pointer of the current torrent-file segment to the next segment
228 */
229 void
230 setTorrentFilePtr(const Name& ptrName);
231
spirosmastorakisa6057f52016-01-28 13:34:41 -0800232private:
233 Name m_commonPrefix;
234 Name m_torrentFilePtr;
235 std::vector<ndn::Name> m_suffixCatalog;
236 std::vector<ndn::Name> m_catalog;
237};
238
239inline bool
240TorrentFile::hasTorrentFilePtr() const
241{
242 return !m_torrentFilePtr.empty();
243}
244
245inline const std::vector<Name>&
246TorrentFile::getCatalog() const
247{
248 return m_catalog;
249}
250
251inline size_t
252TorrentFile::catalogSize() const
253{
254 return m_catalog.size();
255}
256
257inline void
258TorrentFile::insert(const Name& name)
259{
260 m_catalog.push_back(name);
261}
262
263inline void
264TorrentFile::insertToSuffixCatalog(const PartialName& suffix)
265{
266 m_suffixCatalog.push_back(suffix);
267}
268
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -0800269inline void
270TorrentFile::setTorrentFilePtr(const Name& ptrName)
271{
272 m_torrentFilePtr = ptrName;
273}
274
275inline const Name&
276TorrentFile::getName() const
277{
278 return Data::getName();
279}
280
281inline const Name&
282TorrentFile::getCommonPrefix() const
283{
284 return m_commonPrefix;
285}
286
Mickey Sweatt599bfef2016-04-05 19:11:20 -0700287inline std::string
288TorrentFile::getTorrentFilePath() const
289{
290 return (0 == getSegmentNumber() ? getFullName().get(-3) : getFullName().get(-4)).toUri();
291}
292
293inline size_t
294TorrentFile::getSegmentNumber() const
295{
296 const auto& lastComponent = getName().get(getName().size() - 1);
297 return lastComponent.isSequenceNumber() ? lastComponent.toSequenceNumber() : 0;
298}
299
spirosmastorakisf5d1b6c2016-02-25 12:49:56 -0800300
spirosmastorakisa6057f52016-01-28 13:34:41 -0800301} // namespace ntorrent
302
303} // namespace ndn
304
305#endif // TORRENT_FILE_HPP