blob: 8366db247bffac448e1b35901001d83af0bd97b3 [file] [log] [blame]
Mickey Sweatt3b0bea62016-01-25 22:12:27 -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#ifndef INCLUDED_FILE_MANIFEST_HPP
22#define INCLUDED_FILE_MANIFEST_HPP
23
24#include <cstring>
Mickey Sweatt3b0bea62016-01-25 22:12:27 -080025#include <memory>
26#include <string>
Mickey Sweattebc01952016-02-19 11:38:30 -080027#include <utility>
Mickey Sweatt3b0bea62016-01-25 22:12:27 -080028#include <vector>
29
30#include <ndn-cxx/data.hpp>
31#include <ndn-cxx/name.hpp>
32
33namespace ndn {
34namespace ntorrent {
35
36class FileManifest : public Data {
37/**
38* \class FileManifest
39*
40* \brief A value semantic type for File manifests
41*
42*/
43 public:
44 // TYPES
45 class Error : public Data::Error
46 {
47 public:
48 explicit
49 Error(const std::string& what)
50 : Data::Error(what)
51 {
52 }
53 };
54
55 public:
Mickey Sweattebc01952016-02-19 11:38:30 -080056 // CLASS METHODS
57 static std::vector<FileManifest>
58 generate(const std::string& filePath,
59 const ndn::Name& manifestPrefix,
60 size_t subManifestSize,
61 size_t dataPacketSize);
62
63
64 static std::pair<std::vector<FileManifest>, std::vector<Data>>
65 generate(const std::string& filePath,
66 const ndn::Name& manifestPrefix,
67 size_t subManifestSize,
68 size_t dataPacketSize,
69 bool returnData);
70 /**
71 * \brief Generates the FileManifest(s) and Data packets for the file at the specified 'filePath'
72 *
73 * @param filePath The path to the file for which we are to create a manifest
74 * @param manifestPrefix The prefix to be used for the name of this manifest
75 * @param subManifestSize The maximum number of data packets to be included in a sub-manifest
76 * @param dataPacketSize The maximum number of bytes per Data packet packets for the file
77 * @param returnData If true also return the Data
78 *
79 * @throws Error if there is any I/O issue when trying to read the filePath.
80 *
81 * Generates the FileManfiest(s) for the file at the specified 'filePath', splitting the manifest
82 * into sub-manifests of size at most the specified 'subManifestSize'. Each sub-manifest is
83 * composed of a catalog of Data packets of at most the specified 'dataPacketSize'. Returns all
84 * of the manifests that were created in order. The behavior is undefined unless the
85 * trailing component of of the manifestPrefix is a subComponent filePath and
86 '* O < subManifestSize' and '0 < dataPacketSize'.
87 */
88
Mickey Sweatt3b0bea62016-01-25 22:12:27 -080089 // CREATORS
Mickey Sweatt6de5dde2016-03-15 16:44:56 -070090 FileManifest() = default;
Mickey Sweatt3b0bea62016-01-25 22:12:27 -080091
92 ~FileManifest() = default;
93 /// Destroy this object
94
95 FileManifest(const Name& name,
96 size_t dataPacketSize,
97 const Name& commonPrefix,
98 const std::vector<Name>& catalog = std::vector<Name>(),
99 std::shared_ptr<Name> subManifestPtr = nullptr);
100 /**
101 * \brief Creates a new FileManifest with the specified values
102 *
103 * @param name The Name of this FileManifest
104 * @param dataPacketSize The size (except the last) of each data packet in this FileManifest
105 * @param commonPrefix The common prefix used for all named in the catalog
106 * @param catalog The collection of Names for this FileManifest
107 * @param subManifestPtr (optional) The Name for the sub-manifest in this for this file
108 */
109
110 FileManifest(const Name& name,
111 size_t dataPacketSize,
112 const Name& catalogPrefix,
113 std::vector<Name>&& catalog,
114 std::shared_ptr<Name> subManifestPtr = nullptr);
115 /**
116 * \brief Creates a new FileManifest with the specified values
117 *
118 * @param name The Name of this FileManifest
119 * @param dataPacketSize The size (except the last) of each data packet in this FileManifest
120 * @param catalogPrefix the common prefix used for all named in the catalog
121 * @param catalog The collection of Names for this FileManifest
122 * @param subManifestPtr (optional) The Name for the sub-manifest in this for this file
123 */
124
125 explicit
126 FileManifest(const Block& block);
127
128 FileManifest(const FileManifest& other) = default;
129 /// Creates a new FileManifest with same value as the specified 'other'
130
131 // ACCESSORS
132 const Name&
133 name() const;
134 /// Returns the 'name' of this FileManifest
135
136 const Name&
137 catalog_prefix() const;
138 /// Returns the 'catalogPrefix' of this FileManfiest.
139
140 size_t
141 data_packet_size() const;
142 /// Returns the 'data_packet_size' of this FileManifest
143
Mickey Sweatt599bfef2016-04-05 19:11:20 -0700144 size_t
145 submanifest_number() const;
146 /// Return the submanifest number for this FileManifest
147
148 std::string
149 file_name() const;
150 /// Return the file name for this FileManifest
151
Mickey Sweatt3b0bea62016-01-25 22:12:27 -0800152 std::shared_ptr<Name>
153 submanifest_ptr() const;
154 /// Returns the 'submanifest_ptr' of this FileManifest, or 'nullptr' is none exists
155
156 const std::vector<Name>&
157 catalog() const;
158 /// Returns an unmodifiable reference to the 'catalog' of this FileManifest
159
160 private:
161 template<encoding::Tag TAG>
162 size_t
163 encodeContent(EncodingImpl<TAG>& encoder) const;
164 /// Encodes the contents of this object and append the contents to the 'encoder'
165
166 public:
167 // MANIPULATORS
168 FileManifest&
169 operator=(const FileManifest& rhs) = default;
170 /// Assigns the value of the specific 'rhs' object to this object.
171
172 void
Mickey Sweattebc01952016-02-19 11:38:30 -0800173 set_submanifest_ptr(std::shared_ptr<Name> subManifestPtr);
174 /// Sets the sub-manifest pointer of manifest to the specified 'subManifestPtr'
175
176 void
Mickey Sweatt3b0bea62016-01-25 22:12:27 -0800177 push_back(const Name& name);
178 /// Appends a Name to the catalog
179
Mickey Sweattebc01952016-02-19 11:38:30 -0800180 void
181 reserve(size_t capacity);
182 /// Reserve memory in the catalog adequate to hold at least 'capacity' Names.
183
Mickey Sweatt3b0bea62016-01-25 22:12:27 -0800184 bool
185 remove(const Name& name);
186 /// If 'name' in catalog, removes first instance and returns 'true', otherwise returns 'false'.
187
188 void
189 wireDecode(const Block& wire);
190 /**
191 * \brief Decodes the wire and assign its contents to this FileManifest
192 *
193 * @param wire the write to be decoded
194 * @throws Error if decoding fails
195 */
Mickey Sweatta768b242016-02-29 20:08:05 -0800196
197 void
198 finalize();
199 /*
200 * \brief Performs all final processing on this manifest
201 *
202 * This method should be called once this manifest is populated and *must* be called before
203 * signing it or calling wireEncode().
204 */
Mickey Sweatt3b0bea62016-01-25 22:12:27 -0800205
206private:
207 void
208 decodeContent();
209 /// Decodes the contents of this Data packet, assigning its contents to this FileManifest.
210
211 void
212 encodeContent();
213 /// Encodes the contents of this FileManifest into the content section of its Data packet.
214
215// DATA
216 private:
217 size_t m_dataPacketSize;
218 Name m_catalogPrefix;
219 std::vector<Name> m_catalog;
220 std::shared_ptr<Name> m_submanifestPtr;
221};
222
223/// Non-member functions
224bool operator==(const FileManifest& lhs, const FileManifest& rhs);
225/// Returns 'true' if 'lhs' and 'rhs' have the same value, 'false' otherwise.
226
227bool operator!=(const FileManifest& lhs, const FileManifest& rhs);
228/// Returns 'true' if 'lhs' and 'rhs' have different values, and 'false' otherwise.
229
230inline
Mickey Sweattebc01952016-02-19 11:38:30 -0800231std::vector<FileManifest>
232FileManifest::generate(const std::string& filePath,
233 const ndn::Name& manifestPrefix,
234 size_t subManifestSize,
235 size_t dataPacketSize)
236{
237 return generate(filePath, manifestPrefix, subManifestSize, dataPacketSize, false).first;
238}
239
240inline
Mickey Sweatt3b0bea62016-01-25 22:12:27 -0800241FileManifest::FileManifest(
242 const Name& name,
243 size_t dataPacketSize,
244 const Name& catalogPrefix,
245 const std::vector<Name>& catalog,
246 std::shared_ptr<Name> subManifestPtr)
247: Data(name)
248, m_dataPacketSize(dataPacketSize)
249, m_catalogPrefix(catalogPrefix)
250, m_catalog(catalog)
251, m_submanifestPtr(subManifestPtr)
252{
253}
254
Mickey Sweattebc01952016-02-19 11:38:30 -0800255
Mickey Sweatt3b0bea62016-01-25 22:12:27 -0800256inline
257FileManifest::FileManifest(
258 const Name& name,
259 size_t dataPacketSize,
260 const Name& catalogPrefix,
261 std::vector<Name>&& catalog,
262 std::shared_ptr<Name> subManifestPtr)
263: Data(name)
264, m_dataPacketSize(dataPacketSize)
265, m_catalogPrefix(catalogPrefix)
266, m_catalog(catalog)
267, m_submanifestPtr(subManifestPtr)
268{
269}
270
271inline
272FileManifest::FileManifest(const Block& block)
Mickey Sweatta768b242016-02-29 20:08:05 -0800273: Data()
274, m_dataPacketSize(0)
275, m_catalogPrefix("")
276, m_catalog()
277, m_submanifestPtr(nullptr)
Mickey Sweatt3b0bea62016-01-25 22:12:27 -0800278{
279 wireDecode(block);
280}
281
282inline const Name&
283FileManifest::name() const
284{
285 return getName();
286}
287
288inline size_t
289FileManifest::data_packet_size() const
290{
291 return m_dataPacketSize;
292}
293
294inline const Name&
295FileManifest::catalog_prefix() const
296{
297 return m_catalogPrefix;
298}
299
300inline const std::vector<Name>&
301FileManifest::catalog() const
302{
303 return m_catalog;
304}
305
306inline std::shared_ptr<Name>
307FileManifest::submanifest_ptr() const
308{
309 return m_submanifestPtr;
310}
311
Mickey Sweatt599bfef2016-04-05 19:11:20 -0700312inline std::string
313FileManifest::file_name() const
314{
315 return name().getSubName(1, name().size() - 2).toUri();
316}
317
318
319inline size_t
320FileManifest::submanifest_number() const
321{
322 return name().get(name().size() - 1).toSequenceNumber();
323}
324
Mickey Sweattebc01952016-02-19 11:38:30 -0800325inline void
326FileManifest::set_submanifest_ptr(std::shared_ptr<Name> subManifestPtr)
327{
328 m_submanifestPtr = subManifestPtr;
329}
330
331inline void
332FileManifest::reserve(size_t capacity)
333{
334 m_catalog.reserve(capacity);
335}
336
Mickey Sweatt3b0bea62016-01-25 22:12:27 -0800337} // end ntorrent
338} // end ndn
339
340#endif // INCLUDED_FILE_MANIFEST_HPP