initial fix to enable mapping files in torrents to other files on disk. see torrent_info::remap_files

This commit is contained in:
Arvid Norberg 2007-08-25 18:26:43 +00:00
parent b6ee4fddbf
commit 2b0197e810
6 changed files with 388 additions and 188 deletions

View File

@ -58,122 +58,123 @@
<li><a class="reference" href="#id3" id="id43" name="id43">torrent_info()</a></li>
<li><a class="reference" href="#set-comment-set-piece-size-set-creator-set-hash-add-tracker-add-file" id="id44" name="id44">set_comment() set_piece_size() set_creator() set_hash() add_tracker() add_file()</a></li>
<li><a class="reference" href="#create-torrent" id="id45" name="id45">create_torrent()</a></li>
<li><a class="reference" href="#begin-files-end-files-rbegin-files-rend-files" id="id46" name="id46">begin_files() end_files() rbegin_files() rend_files()</a></li>
<li><a class="reference" href="#num-files-file-at" id="id47" name="id47">num_files() file_at()</a></li>
<li><a class="reference" href="#map-block" id="id48" name="id48">map_block()</a></li>
<li><a class="reference" href="#map-file" id="id49" name="id49">map_file()</a></li>
<li><a class="reference" href="#url-seeds-add-url-seed" id="id50" name="id50">url_seeds() add_url_seed()</a></li>
<li><a class="reference" href="#print" id="id51" name="id51">print()</a></li>
<li><a class="reference" href="#trackers" id="id52" name="id52">trackers()</a></li>
<li><a class="reference" href="#total-size-piece-length-piece-size-num-pieces" id="id53" name="id53">total_size() piece_length() piece_size() num_pieces()</a></li>
<li><a class="reference" href="#hash-for-piece-info-hash" id="id54" name="id54">hash_for_piece() info_hash()</a></li>
<li><a class="reference" href="#name-comment-creation-date-creator" id="id55" name="id55">name() comment() creation_date() creator()</a></li>
<li><a class="reference" href="#priv-set-priv" id="id56" name="id56">priv() set_priv()</a></li>
<li><a class="reference" href="#nodes" id="id57" name="id57">nodes()</a></li>
<li><a class="reference" href="#add-node" id="id58" name="id58">add_node()</a></li>
<li><a class="reference" href="#remap-files" id="id46" name="id46">remap_files()</a></li>
<li><a class="reference" href="#begin-files-end-files-rbegin-files-rend-files" id="id47" name="id47">begin_files() end_files() rbegin_files() rend_files()</a></li>
<li><a class="reference" href="#num-files-file-at" id="id48" name="id48">num_files() file_at()</a></li>
<li><a class="reference" href="#map-block" id="id49" name="id49">map_block()</a></li>
<li><a class="reference" href="#map-file" id="id50" name="id50">map_file()</a></li>
<li><a class="reference" href="#url-seeds-add-url-seed" id="id51" name="id51">url_seeds() add_url_seed()</a></li>
<li><a class="reference" href="#print" id="id52" name="id52">print()</a></li>
<li><a class="reference" href="#trackers" id="id53" name="id53">trackers()</a></li>
<li><a class="reference" href="#total-size-piece-length-piece-size-num-pieces" id="id54" name="id54">total_size() piece_length() piece_size() num_pieces()</a></li>
<li><a class="reference" href="#hash-for-piece-info-hash" id="id55" name="id55">hash_for_piece() info_hash()</a></li>
<li><a class="reference" href="#name-comment-creation-date-creator" id="id56" name="id56">name() comment() creation_date() creator()</a></li>
<li><a class="reference" href="#priv-set-priv" id="id57" name="id57">priv() set_priv()</a></li>
<li><a class="reference" href="#nodes" id="id58" name="id58">nodes()</a></li>
<li><a class="reference" href="#add-node" id="id59" name="id59">add_node()</a></li>
</ul>
</li>
<li><a class="reference" href="#torrent-handle" id="id59" name="id59">torrent_handle</a><ul>
<li><a class="reference" href="#piece-priority-prioritize-pieces-piece-priorities-prioritize-files" id="id60" name="id60">piece_priority() prioritize_pieces() piece_priorities() prioritize_files()</a></li>
<li><a class="reference" href="#file-progress" id="id61" name="id61">file_progress()</a></li>
<li><a class="reference" href="#save-path" id="id62" name="id62">save_path()</a></li>
<li><a class="reference" href="#move-storage" id="id63" name="id63">move_storage()</a></li>
<li><a class="reference" href="#force-reannounce" id="id64" name="id64">force_reannounce()</a></li>
<li><a class="reference" href="#connect-peer" id="id65" name="id65">connect_peer()</a></li>
<li><a class="reference" href="#name" id="id66" name="id66">name()</a></li>
<li><a class="reference" href="#set-ratio" id="id67" name="id67">set_ratio()</a></li>
<li><a class="reference" href="#set-upload-limit-set-download-limit-upload-limit-download-limit" id="id68" name="id68">set_upload_limit() set_download_limit() upload_limit() download_limit()</a></li>
<li><a class="reference" href="#set-sequenced-download-threshold" id="id69" name="id69">set_sequenced_download_threshold()</a></li>
<li><a class="reference" href="#set-peer-upload-limit-set-peer-download-limit" id="id70" name="id70">set_peer_upload_limit() set_peer_download_limit()</a></li>
<li><a class="reference" href="#pause-resume-is-paused" id="id71" name="id71">pause() resume() is_paused()</a></li>
<li><a class="reference" href="#resolve-countries" id="id72" name="id72">resolve_countries()</a></li>
<li><a class="reference" href="#is-seed" id="id73" name="id73">is_seed()</a></li>
<li><a class="reference" href="#has-metadata" id="id74" name="id74">has_metadata()</a></li>
<li><a class="reference" href="#set-tracker-login" id="id75" name="id75">set_tracker_login()</a></li>
<li><a class="reference" href="#trackers-replace-trackers" id="id76" name="id76">trackers() replace_trackers()</a></li>
<li><a class="reference" href="#add-url-seed-remove-url-seed-url-seeds" id="id77" name="id77">add_url_seed() remove_url_seed() url_seeds()</a></li>
<li><a class="reference" href="#use-interface" id="id78" name="id78">use_interface()</a></li>
<li><a class="reference" href="#info-hash" id="id79" name="id79">info_hash()</a></li>
<li><a class="reference" href="#id5" id="id80" name="id80">set_max_uploads() set_max_connections()</a></li>
<li><a class="reference" href="#write-resume-data" id="id81" name="id81">write_resume_data()</a></li>
<li><a class="reference" href="#id6" id="id82" name="id82">status()</a></li>
<li><a class="reference" href="#get-download-queue" id="id83" name="id83">get_download_queue()</a></li>
<li><a class="reference" href="#get-peer-info" id="id84" name="id84">get_peer_info()</a></li>
<li><a class="reference" href="#get-torrent-info" id="id85" name="id85">get_torrent_info()</a></li>
<li><a class="reference" href="#is-valid" id="id86" name="id86">is_valid()</a></li>
<li><a class="reference" href="#torrent-handle" id="id60" name="id60">torrent_handle</a><ul>
<li><a class="reference" href="#piece-priority-prioritize-pieces-piece-priorities-prioritize-files" id="id61" name="id61">piece_priority() prioritize_pieces() piece_priorities() prioritize_files()</a></li>
<li><a class="reference" href="#file-progress" id="id62" name="id62">file_progress()</a></li>
<li><a class="reference" href="#save-path" id="id63" name="id63">save_path()</a></li>
<li><a class="reference" href="#move-storage" id="id64" name="id64">move_storage()</a></li>
<li><a class="reference" href="#force-reannounce" id="id65" name="id65">force_reannounce()</a></li>
<li><a class="reference" href="#connect-peer" id="id66" name="id66">connect_peer()</a></li>
<li><a class="reference" href="#name" id="id67" name="id67">name()</a></li>
<li><a class="reference" href="#set-ratio" id="id68" name="id68">set_ratio()</a></li>
<li><a class="reference" href="#set-upload-limit-set-download-limit-upload-limit-download-limit" id="id69" name="id69">set_upload_limit() set_download_limit() upload_limit() download_limit()</a></li>
<li><a class="reference" href="#set-sequenced-download-threshold" id="id70" name="id70">set_sequenced_download_threshold()</a></li>
<li><a class="reference" href="#set-peer-upload-limit-set-peer-download-limit" id="id71" name="id71">set_peer_upload_limit() set_peer_download_limit()</a></li>
<li><a class="reference" href="#pause-resume-is-paused" id="id72" name="id72">pause() resume() is_paused()</a></li>
<li><a class="reference" href="#resolve-countries" id="id73" name="id73">resolve_countries()</a></li>
<li><a class="reference" href="#is-seed" id="id74" name="id74">is_seed()</a></li>
<li><a class="reference" href="#has-metadata" id="id75" name="id75">has_metadata()</a></li>
<li><a class="reference" href="#set-tracker-login" id="id76" name="id76">set_tracker_login()</a></li>
<li><a class="reference" href="#trackers-replace-trackers" id="id77" name="id77">trackers() replace_trackers()</a></li>
<li><a class="reference" href="#add-url-seed-remove-url-seed-url-seeds" id="id78" name="id78">add_url_seed() remove_url_seed() url_seeds()</a></li>
<li><a class="reference" href="#use-interface" id="id79" name="id79">use_interface()</a></li>
<li><a class="reference" href="#info-hash" id="id80" name="id80">info_hash()</a></li>
<li><a class="reference" href="#id5" id="id81" name="id81">set_max_uploads() set_max_connections()</a></li>
<li><a class="reference" href="#write-resume-data" id="id82" name="id82">write_resume_data()</a></li>
<li><a class="reference" href="#id6" id="id83" name="id83">status()</a></li>
<li><a class="reference" href="#get-download-queue" id="id84" name="id84">get_download_queue()</a></li>
<li><a class="reference" href="#get-peer-info" id="id85" name="id85">get_peer_info()</a></li>
<li><a class="reference" href="#get-torrent-info" id="id86" name="id86">get_torrent_info()</a></li>
<li><a class="reference" href="#is-valid" id="id87" name="id87">is_valid()</a></li>
</ul>
</li>
<li><a class="reference" href="#torrent-status" id="id87" name="id87">torrent_status</a></li>
<li><a class="reference" href="#peer-info" id="id88" name="id88">peer_info</a></li>
<li><a class="reference" href="#session-settings" id="id89" name="id89">session_settings</a></li>
<li><a class="reference" href="#pe-settings" id="id90" name="id90">pe_settings</a></li>
<li><a class="reference" href="#proxy-settings" id="id91" name="id91">proxy_settings</a></li>
<li><a class="reference" href="#ip-filter" id="id92" name="id92">ip_filter</a><ul>
<li><a class="reference" href="#id9" id="id93" name="id93">ip_filter()</a></li>
<li><a class="reference" href="#add-rule" id="id94" name="id94">add_rule()</a></li>
<li><a class="reference" href="#access" id="id95" name="id95">access()</a></li>
<li><a class="reference" href="#export-filter" id="id96" name="id96">export_filter()</a></li>
<li><a class="reference" href="#torrent-status" id="id88" name="id88">torrent_status</a></li>
<li><a class="reference" href="#peer-info" id="id89" name="id89">peer_info</a></li>
<li><a class="reference" href="#session-settings" id="id90" name="id90">session_settings</a></li>
<li><a class="reference" href="#pe-settings" id="id91" name="id91">pe_settings</a></li>
<li><a class="reference" href="#proxy-settings" id="id92" name="id92">proxy_settings</a></li>
<li><a class="reference" href="#ip-filter" id="id93" name="id93">ip_filter</a><ul>
<li><a class="reference" href="#id9" id="id94" name="id94">ip_filter()</a></li>
<li><a class="reference" href="#add-rule" id="id95" name="id95">add_rule()</a></li>
<li><a class="reference" href="#access" id="id96" name="id96">access()</a></li>
<li><a class="reference" href="#export-filter" id="id97" name="id97">export_filter()</a></li>
</ul>
</li>
<li><a class="reference" href="#big-number" id="id97" name="id97">big_number</a></li>
<li><a class="reference" href="#hasher" id="id98" name="id98">hasher</a></li>
<li><a class="reference" href="#fingerprint" id="id99" name="id99">fingerprint</a></li>
<li><a class="reference" href="#free-functions" id="id100" name="id100">free functions</a><ul>
<li><a class="reference" href="#identify-client" id="id101" name="id101">identify_client()</a></li>
<li><a class="reference" href="#client-fingerprint" id="id102" name="id102">client_fingerprint()</a></li>
<li><a class="reference" href="#bdecode-bencode" id="id103" name="id103">bdecode() bencode()</a></li>
<li><a class="reference" href="#supports-sparse-files" id="id104" name="id104">supports_sparse_files()</a></li>
<li><a class="reference" href="#big-number" id="id98" name="id98">big_number</a></li>
<li><a class="reference" href="#hasher" id="id99" name="id99">hasher</a></li>
<li><a class="reference" href="#fingerprint" id="id100" name="id100">fingerprint</a></li>
<li><a class="reference" href="#free-functions" id="id101" name="id101">free functions</a><ul>
<li><a class="reference" href="#identify-client" id="id102" name="id102">identify_client()</a></li>
<li><a class="reference" href="#client-fingerprint" id="id103" name="id103">client_fingerprint()</a></li>
<li><a class="reference" href="#bdecode-bencode" id="id104" name="id104">bdecode() bencode()</a></li>
<li><a class="reference" href="#supports-sparse-files" id="id105" name="id105">supports_sparse_files()</a></li>
</ul>
</li>
<li><a class="reference" href="#alerts" id="id105" name="id105">alerts</a><ul>
<li><a class="reference" href="#listen-failed-alert" id="id106" name="id106">listen_failed_alert</a></li>
<li><a class="reference" href="#portmap-error-alert" id="id107" name="id107">portmap_error_alert</a></li>
<li><a class="reference" href="#portmap-alert" id="id108" name="id108">portmap_alert</a></li>
<li><a class="reference" href="#file-error-alert" id="id109" name="id109">file_error_alert</a></li>
<li><a class="reference" href="#tracker-announce-alert" id="id110" name="id110">tracker_announce_alert</a></li>
<li><a class="reference" href="#tracker-alert" id="id111" name="id111">tracker_alert</a></li>
<li><a class="reference" href="#tracker-reply-alert" id="id112" name="id112">tracker_reply_alert</a></li>
<li><a class="reference" href="#tracker-warning-alert" id="id113" name="id113">tracker_warning_alert</a></li>
<li><a class="reference" href="#url-seed-alert" id="id114" name="id114">url_seed_alert</a></li>
<li><a class="reference" href="#hash-failed-alert" id="id115" name="id115">hash_failed_alert</a></li>
<li><a class="reference" href="#peer-ban-alert" id="id116" name="id116">peer_ban_alert</a></li>
<li><a class="reference" href="#peer-error-alert" id="id117" name="id117">peer_error_alert</a></li>
<li><a class="reference" href="#invalid-request-alert" id="id118" name="id118">invalid_request_alert</a></li>
<li><a class="reference" href="#torrent-finished-alert" id="id119" name="id119">torrent_finished_alert</a></li>
<li><a class="reference" href="#metadata-failed-alert" id="id120" name="id120">metadata_failed_alert</a></li>
<li><a class="reference" href="#metadata-received-alert" id="id121" name="id121">metadata_received_alert</a></li>
<li><a class="reference" href="#fastresume-rejected-alert" id="id122" name="id122">fastresume_rejected_alert</a></li>
<li><a class="reference" href="#peer-blocked-alert" id="id123" name="id123">peer_blocked_alert</a></li>
<li><a class="reference" href="#storage-moved-alert" id="id124" name="id124">storage_moved_alert</a></li>
<li><a class="reference" href="#torrent-paused-alert" id="id125" name="id125">torrent_paused_alert</a></li>
<li><a class="reference" href="#dispatcher" id="id126" name="id126">dispatcher</a></li>
<li><a class="reference" href="#alerts" id="id106" name="id106">alerts</a><ul>
<li><a class="reference" href="#listen-failed-alert" id="id107" name="id107">listen_failed_alert</a></li>
<li><a class="reference" href="#portmap-error-alert" id="id108" name="id108">portmap_error_alert</a></li>
<li><a class="reference" href="#portmap-alert" id="id109" name="id109">portmap_alert</a></li>
<li><a class="reference" href="#file-error-alert" id="id110" name="id110">file_error_alert</a></li>
<li><a class="reference" href="#tracker-announce-alert" id="id111" name="id111">tracker_announce_alert</a></li>
<li><a class="reference" href="#tracker-alert" id="id112" name="id112">tracker_alert</a></li>
<li><a class="reference" href="#tracker-reply-alert" id="id113" name="id113">tracker_reply_alert</a></li>
<li><a class="reference" href="#tracker-warning-alert" id="id114" name="id114">tracker_warning_alert</a></li>
<li><a class="reference" href="#url-seed-alert" id="id115" name="id115">url_seed_alert</a></li>
<li><a class="reference" href="#hash-failed-alert" id="id116" name="id116">hash_failed_alert</a></li>
<li><a class="reference" href="#peer-ban-alert" id="id117" name="id117">peer_ban_alert</a></li>
<li><a class="reference" href="#peer-error-alert" id="id118" name="id118">peer_error_alert</a></li>
<li><a class="reference" href="#invalid-request-alert" id="id119" name="id119">invalid_request_alert</a></li>
<li><a class="reference" href="#torrent-finished-alert" id="id120" name="id120">torrent_finished_alert</a></li>
<li><a class="reference" href="#metadata-failed-alert" id="id121" name="id121">metadata_failed_alert</a></li>
<li><a class="reference" href="#metadata-received-alert" id="id122" name="id122">metadata_received_alert</a></li>
<li><a class="reference" href="#fastresume-rejected-alert" id="id123" name="id123">fastresume_rejected_alert</a></li>
<li><a class="reference" href="#peer-blocked-alert" id="id124" name="id124">peer_blocked_alert</a></li>
<li><a class="reference" href="#storage-moved-alert" id="id125" name="id125">storage_moved_alert</a></li>
<li><a class="reference" href="#torrent-paused-alert" id="id126" name="id126">torrent_paused_alert</a></li>
<li><a class="reference" href="#dispatcher" id="id127" name="id127">dispatcher</a></li>
</ul>
</li>
<li><a class="reference" href="#exceptions" id="id127" name="id127">exceptions</a><ul>
<li><a class="reference" href="#invalid-handle" id="id128" name="id128">invalid_handle</a></li>
<li><a class="reference" href="#duplicate-torrent" id="id129" name="id129">duplicate_torrent</a></li>
<li><a class="reference" href="#invalid-encoding" id="id130" name="id130">invalid_encoding</a></li>
<li><a class="reference" href="#type-error" id="id131" name="id131">type_error</a></li>
<li><a class="reference" href="#invalid-torrent-file" id="id132" name="id132">invalid_torrent_file</a></li>
<li><a class="reference" href="#exceptions" id="id128" name="id128">exceptions</a><ul>
<li><a class="reference" href="#invalid-handle" id="id129" name="id129">invalid_handle</a></li>
<li><a class="reference" href="#duplicate-torrent" id="id130" name="id130">duplicate_torrent</a></li>
<li><a class="reference" href="#invalid-encoding" id="id131" name="id131">invalid_encoding</a></li>
<li><a class="reference" href="#type-error" id="id132" name="id132">type_error</a></li>
<li><a class="reference" href="#invalid-torrent-file" id="id133" name="id133">invalid_torrent_file</a></li>
</ul>
</li>
<li><a class="reference" href="#fast-resume" id="id133" name="id133">fast resume</a><ul>
<li><a class="reference" href="#file-format" id="id134" name="id134">file format</a></li>
<li><a class="reference" href="#fast-resume" id="id134" name="id134">fast resume</a><ul>
<li><a class="reference" href="#file-format" id="id135" name="id135">file format</a></li>
</ul>
</li>
<li><a class="reference" href="#threads" id="id135" name="id135">threads</a></li>
<li><a class="reference" href="#storage-allocation" id="id136" name="id136">storage allocation</a><ul>
<li><a class="reference" href="#full-allocation" id="id137" name="id137">full allocation</a></li>
<li><a class="reference" href="#compact-allocation" id="id138" name="id138">compact allocation</a></li>
<li><a class="reference" href="#threads" id="id136" name="id136">threads</a></li>
<li><a class="reference" href="#storage-allocation" id="id137" name="id137">storage allocation</a><ul>
<li><a class="reference" href="#full-allocation" id="id138" name="id138">full allocation</a></li>
<li><a class="reference" href="#compact-allocation" id="id139" name="id139">compact allocation</a></li>
</ul>
</li>
<li><a class="reference" href="#extensions" id="id139" name="id139">extensions</a><ul>
<li><a class="reference" href="#metadata-from-peers" id="id140" name="id140">metadata from peers</a></li>
<li><a class="reference" href="#http-seeding" id="id141" name="id141">HTTP seeding</a></li>
<li><a class="reference" href="#extensions" id="id140" name="id140">extensions</a><ul>
<li><a class="reference" href="#metadata-from-peers" id="id141" name="id141">metadata from peers</a></li>
<li><a class="reference" href="#http-seeding" id="id142" name="id142">HTTP seeding</a></li>
</ul>
</li>
<li><a class="reference" href="#filename-checks" id="id142" name="id142">filename checks</a></li>
<li><a class="reference" href="#acknowledgments" id="id143" name="id143">acknowledgments</a></li>
<li><a class="reference" href="#filename-checks" id="id143" name="id143">filename checks</a></li>
<li><a class="reference" href="#acknowledgments" id="id144" name="id144">acknowledgments</a></li>
</ul>
</div>
<div class="section">
@ -549,7 +550,11 @@ versions is the payload download only.</p>
<p><tt class="docutils literal"><span class="pre">total_download</span></tt> and <tt class="docutils literal"><span class="pre">total_upload</span></tt> are the total number of bytes downloaded and
uploaded to and from all torrents. <tt class="docutils literal"><span class="pre">total_payload_download</span></tt> and <tt class="docutils literal"><span class="pre">total_payload_upload</span></tt>
are the same thing but where only the payload is considered.</p>
<p><tt class="docutils literal"><span class="pre">num_peers</span></tt> is the total number of peer connections this session have.</p>
<p><tt class="docutils literal"><span class="pre">num_peers</span></tt> is the total number of peer connections this session has. This includes
incoming connections that still hasn't sent their handshake or outgoing connections
that still hasn't completed the TCP connection. This number may be slightly higher
than the sum of all peers of all torrents because the incoming connections may not
be assigned a torrent yet.</p>
<p><tt class="docutils literal"><span class="pre">dht_nodes</span></tt>, <tt class="docutils literal"><span class="pre">dht_cache_nodes</span></tt> and <tt class="docutils literal"><span class="pre">dht_torrents</span></tt> are only available when
built with DHT support. They are all set to 0 if the DHT isn't running. When
the DHT is running, <tt class="docutils literal"><span class="pre">dht_nodes</span></tt> is set to the number of nodes in the routing
@ -951,18 +956,18 @@ public:
typedef std::vector&lt;file_entry&gt;::const_reverse_iterator
reverse_file_iterator;
file_iterator begin_files() const;
file_iterator end_files() const;
reverse_file_iterator rbegin_files() const;
reverse_file_iterator rend_files() const;
file_iterator begin_files(bool storage = false) const;
file_iterator end_files(bool storage = false) const;
reverse_file_iterator rbegin_files(bool storage = false) const;
reverse_file_iterator rend_files(bool storage = false) const;
int num_files() const;
file_entry const&amp; file_at(int index) const;
int num_files(bool storage = false) const;
file_entry const&amp; file_at(int index, bool storage = false) const;
std::vector&lt;file_slice&gt; map_block(int piece, size_type offset
, int size) const;
, int size, bool storage = false) const;
peer_request map_file(int file_index, size_type file_offset
, int size) const;
, int size, bool storage = false) const;
std::vector&lt;announce_entry&gt; const&amp; trackers() const;
@ -1064,19 +1069,48 @@ object.</p>
least one tracker url or at least one DHT node.</p>
</div>
<div class="section">
<h2><a id="remap-files" name="remap-files">remap_files()</a></h2>
<blockquote>
<pre class="literal-block">
bool remap_files(std::vector&lt;std::string, libtorrent::size_type&gt; const&amp; map);
</pre>
</blockquote>
<p>This call will create a new mapping of the data in this torrent to other files. The
<tt class="docutils literal"><span class="pre">torrent_info</span></tt> maintains 2 views of the file storage. One that is true to the torrent
file, and one that represents what is actually saved on disk. This call will change
what the files on disk are called.</p>
<p>The return value indicates if the remap was successful or not. True means success and
false means failure. The only reason for failure is if the sum of all the files passed
in through <tt class="docutils literal"><span class="pre">map</span></tt> has to be exactly the same as the total_size of the torrent.</p>
</div>
<div class="section">
<h2><a id="begin-files-end-files-rbegin-files-rend-files" name="begin-files-end-files-rbegin-files-rend-files">begin_files() end_files() rbegin_files() rend_files()</a></h2>
<blockquote>
<pre class="literal-block">
file_iterator begin_files() const;
file_iterator end_files() const;
reverse_file_iterator rbegin_files() const;
reverse_file_iterator rend_files() const;
file_iterator begin_files(bool storage = false) const;
file_iterator end_files(bool storage = false) const;
reverse_file_iterator rbegin_files(bool storage = false) const;
reverse_file_iterator rend_files(bool storage = false) const;
</pre>
</blockquote>
<p>This class will need some explanation. First of all, to get a list of all files
in the torrent, you can use <tt class="docutils literal"><span class="pre">begin_files()</span></tt>, <tt class="docutils literal"><span class="pre">end_files()</span></tt>,
<tt class="docutils literal"><span class="pre">rbegin_files()</span></tt> and <tt class="docutils literal"><span class="pre">rend_files()</span></tt>. These will give you standard vector
iterators with the type <tt class="docutils literal"><span class="pre">file_entry</span></tt>.</p>
<p>The <tt class="docutils literal"><span class="pre">storage</span></tt> parameter specifies which view of the files you want. The default
is false, which means you will see the content of the torrent file. If set to
true, you will see the file that the storage class uses to save the files to
disk. Typically these views are the same, but in case the files have been
remapped, they may differ. For more info, see <a class="reference" href="#remap-files">remap_files()</a>.</p>
<pre class="literal-block">
struct file_entry
{
boost::filesystem::path path;
size_type offset;
size_type size;
boost::shared_ptr&lt;const boost::filesystem::path&gt; orig_path;
};
</pre>
<p>The <tt class="docutils literal"><span class="pre">path</span></tt> is the full (relative) path of each file. i.e. if it is a multi-file
torrent, all the files starts with a directory with the same name as <tt class="docutils literal"><span class="pre">torrent_info::name()</span></tt>.
The filenames are encoded with UTF-8.</p>
@ -1089,33 +1123,29 @@ incorrectly encoded, and had to be fixed in order to be acceptable utf-8,
the original string is preserved in <tt class="docutils literal"><span class="pre">orig_path</span></tt>. The reason to keep it
is to be able to reproduce the info-section exactly, with the correct
info-hash.</p>
<pre class="literal-block">
struct file_entry
{
boost::filesystem::path path;
size_type offset;
size_type size;
boost::shared_ptr&lt;const boost::filesystem::path&gt; orig_path;
};
</pre>
</div>
<div class="section">
<h2><a id="num-files-file-at" name="num-files-file-at">num_files() file_at()</a></h2>
<blockquote>
<pre class="literal-block">
int num_files() const;
file_entry const&amp; file_at(int index) const;
int num_files(bool storage = false) const;
file_entry const&amp; file_at(int index, bool storage = false) const;
</pre>
</blockquote>
<p>If you need index-access to files you can use the <tt class="docutils literal"><span class="pre">num_files()</span></tt> and <tt class="docutils literal"><span class="pre">file_at()</span></tt>
to access files using indices.</p>
<p>The <tt class="docutils literal"><span class="pre">storage</span></tt> parameter specifies which view of the files you want. The default
is false, which means you will see the content of the torrent file. If set to
true, you will see the file that the storage class uses to save the files to
disk. Typically these views are the same, but in case the files have been
remapped, they may differ. For more info, see <a class="reference" href="#remap-files">remap_files()</a>.</p>
</div>
<div class="section">
<h2><a id="map-block" name="map-block">map_block()</a></h2>
<blockquote>
<pre class="literal-block">
std::vector&lt;file_slice&gt; map_block(int piece, size_type offset
, int size) const;
, int size, bool storage = false) const;
</pre>
</blockquote>
<p>This function will map a piece index, a byte offset within that piece and
@ -1135,13 +1165,18 @@ To get the path and filename, use <tt class="docutils literal"><span class="pre"
as argument. The <tt class="docutils literal"><span class="pre">offset</span></tt> is the byte offset in the file where the range
starts, and <tt class="docutils literal"><span class="pre">size</span></tt> is the number of bytes this range is. The size + offset
will never be greater than the file size.</p>
<p>The <tt class="docutils literal"><span class="pre">storage</span></tt> parameter specifies which view of the files you want. The default
is false, which means you will see the content of the torrent file. If set to
true, you will see the file that the storage class uses to save the files to
disk. Typically these views are the same, but in case the files have been
remapped, they may differ. For more info, see <a class="reference" href="#remap-files">remap_files()</a>.</p>
</div>
<div class="section">
<h2><a id="map-file" name="map-file">map_file()</a></h2>
<blockquote>
<pre class="literal-block">
peer_request map_file(int file_index, size_type file_offset
, int size) const;
, int size, bool storage = false) const;
</pre>
</blockquote>
<p>This function will map a range in a specific file into a range in the torrent.
@ -1176,6 +1211,11 @@ void add_url_seed(std::string const&amp; url);
vector of those urls. If you're creating a torrent file, <tt class="docutils literal"><span class="pre">add_url_seed()</span></tt>
adds one url to the list of url-seeds. Currently, the only transport protocol
supported for the url is http.</p>
<p>The <tt class="docutils literal"><span class="pre">storage</span></tt> parameter specifies which view of the files you want. The default
is false, which means you will see the content of the torrent file. If set to
true, you will see the file that the storage class uses to save the files to
disk. Typically these views are the same, but in case the files have been
remapped, they may differ. For more info, see <a class="reference" href="#remap-files">remap_files()</a>.</p>
<p>See <a class="reference" href="#http-seeding">HTTP seeding</a> for more information.</p>
</div>
<div class="section">
@ -1887,6 +1927,13 @@ struct torrent_status
float distributed_copies;
int block_size;
int num_uploads;
int num_connections;
int uploads_limit;
int connections_limit;
bool compact_mode;
};
</pre>
<p><tt class="docutils literal"><span class="pre">progress</span></tt> is a value in the range [0, 1], that represents the progress of the
@ -2004,6 +2051,14 @@ is the number of bytes that each piece request asks for and the number of
bytes that each bit in the <tt class="docutils literal"><span class="pre">partial_piece_info</span></tt>'s bitset represents
(see <a class="reference" href="#get-download-queue">get_download_queue()</a>). This is typically 16 kB, but it may be
larger if the pieces are larger.</p>
<p><tt class="docutils literal"><span class="pre">num_uploads</span></tt> is the number of unchoked peers in this torrent.</p>
<p><tt class="docutils literal"><span class="pre">num_connections</span></tt> is the number of peer connections this torrent has, including
half-open connections that hasn't completed the bittorrent handshake yet. This is
always &lt;= <tt class="docutils literal"><span class="pre">num_peers</span></tt>.</p>
<p><tt class="docutils literal"><span class="pre">uploads_limit</span></tt> is the set limit of upload slots (unchoked peers) for this torrent.</p>
<p><tt class="docutils literal"><span class="pre">connections_limit</span></tt> is the set limit of number of connections for this torrent.</p>
<p><tt class="docutils literal"><span class="pre">compact_mode</span></tt> is true if this torrent was started with compact allocation mode
for its storage. False means it was started in full allocation mode.</p>
</div>
<div class="section">
<h1><a id="peer-info" name="peer-info">peer_info</a></h1>

View File

@ -855,18 +855,18 @@ The ``torrent_info`` has the following synopsis::
typedef std::vector<file_entry>::const_reverse_iterator
reverse_file_iterator;
file_iterator begin_files() const;
file_iterator end_files() const;
reverse_file_iterator rbegin_files() const;
reverse_file_iterator rend_files() const;
file_iterator begin_files(bool storage = false) const;
file_iterator end_files(bool storage = false) const;
reverse_file_iterator rbegin_files(bool storage = false) const;
reverse_file_iterator rend_files(bool storage = false) const;
int num_files() const;
file_entry const& file_at(int index) const;
int num_files(bool storage = false) const;
file_entry const& file_at(int index, bool storage = false) const;
std::vector<file_slice> map_block(int piece, size_type offset
, int size) const;
, int size, bool storage = false) const;
peer_request map_file(int file_index, size_type file_offset
, int size) const;
, int size, bool storage = false) const;
std::vector<announce_entry> const& trackers() const;
@ -982,21 +982,54 @@ Note that a torrent file must include at least one file, and it must have at
least one tracker url or at least one DHT node.
remap_files()
-------------
::
bool remap_files(std::vector<std::string, libtorrent::size_type> const& map);
This call will create a new mapping of the data in this torrent to other files. The
``torrent_info`` maintains 2 views of the file storage. One that is true to the torrent
file, and one that represents what is actually saved on disk. This call will change
what the files on disk are called.
The return value indicates if the remap was successful or not. True means success and
false means failure. The only reason for failure is if the sum of all the files passed
in through ``map`` has to be exactly the same as the total_size of the torrent.
begin_files() end_files() rbegin_files() rend_files()
-----------------------------------------------------
::
file_iterator begin_files() const;
file_iterator end_files() const;
reverse_file_iterator rbegin_files() const;
reverse_file_iterator rend_files() const;
file_iterator begin_files(bool storage = false) const;
file_iterator end_files(bool storage = false) const;
reverse_file_iterator rbegin_files(bool storage = false) const;
reverse_file_iterator rend_files(bool storage = false) const;
This class will need some explanation. First of all, to get a list of all files
in the torrent, you can use ``begin_files()``, ``end_files()``,
``rbegin_files()`` and ``rend_files()``. These will give you standard vector
iterators with the type ``file_entry``.
The ``storage`` parameter specifies which view of the files you want. The default
is false, which means you will see the content of the torrent file. If set to
true, you will see the file that the storage class uses to save the files to
disk. Typically these views are the same, but in case the files have been
remapped, they may differ. For more info, see `remap_files()`_.
::
struct file_entry
{
boost::filesystem::path path;
size_type offset;
size_type size;
boost::shared_ptr<const boost::filesystem::path> orig_path;
};
The ``path`` is the full (relative) path of each file. i.e. if it is a multi-file
torrent, all the files starts with a directory with the same name as ``torrent_info::name()``.
The filenames are encoded with UTF-8.
@ -1012,15 +1045,6 @@ the original string is preserved in ``orig_path``. The reason to keep it
is to be able to reproduce the info-section exactly, with the correct
info-hash.
::
struct file_entry
{
boost::filesystem::path path;
size_type offset;
size_type size;
boost::shared_ptr<const boost::filesystem::path> orig_path;
};
num_files() file_at()
@ -1028,20 +1052,27 @@ num_files() file_at()
::
int num_files() const;
file_entry const& file_at(int index) const;
int num_files(bool storage = false) const;
file_entry const& file_at(int index, bool storage = false) const;
If you need index-access to files you can use the ``num_files()`` and ``file_at()``
to access files using indices.
The ``storage`` parameter specifies which view of the files you want. The default
is false, which means you will see the content of the torrent file. If set to
true, you will see the file that the storage class uses to save the files to
disk. Typically these views are the same, but in case the files have been
remapped, they may differ. For more info, see `remap_files()`_.
map_block()
-----------
::
std::vector<file_slice> map_block(int piece, size_type offset
, int size) const;
, int size, bool storage = false) const;
This function will map a piece index, a byte offset within that piece and
a size (in bytes) into the corresponding files with offsets where that data
@ -1063,6 +1094,12 @@ as argument. The ``offset`` is the byte offset in the file where the range
starts, and ``size`` is the number of bytes this range is. The size + offset
will never be greater than the file size.
The ``storage`` parameter specifies which view of the files you want. The default
is false, which means you will see the content of the torrent file. If set to
true, you will see the file that the storage class uses to save the files to
disk. Typically these views are the same, but in case the files have been
remapped, they may differ. For more info, see `remap_files()`_.
map_file()
----------
@ -1070,7 +1107,7 @@ map_file()
::
peer_request map_file(int file_index, size_type file_offset
, int size) const;
, int size, bool storage = false) const;
This function will map a range in a specific file into a range in the torrent.
The ``file_offset`` parameter is the offset in the file, given in bytes, where
@ -1107,6 +1144,12 @@ vector of those urls. If you're creating a torrent file, ``add_url_seed()``
adds one url to the list of url-seeds. Currently, the only transport protocol
supported for the url is http.
The ``storage`` parameter specifies which view of the files you want. The default
is false, which means you will see the content of the torrent file. If set to
true, you will see the file that the storage class uses to save the files to
disk. Typically these views are the same, but in case the files have been
remapped, they may differ. For more info, see `remap_files()`_.
See `HTTP seeding`_ for more information.

View File

@ -71,7 +71,7 @@ namespace libtorrent
size_type offset; // the offset of this file inside the torrent
size_type size; // the size of this file
// if the path was incorrectly encoded, this is
// the origianal corrupt encoded string. It is
// the original corrupt encoded string. It is
// preserved in order to be able to reproduce
// the correct info-hash
boost::shared_ptr<const fs::path> orig_path;
@ -115,8 +115,12 @@ namespace libtorrent
void add_file(fs::path file, size_type size);
void add_url_seed(std::string const& url);
std::vector<file_slice> map_block(int piece, size_type offset, int size) const;
peer_request map_file(int file, size_type offset, int size) const;
bool remap_files(std::vector<std::pair<std::string, libtorrent::size_type> > const& map);
std::vector<file_slice> map_block(int piece, size_type offset
, int size, bool storage = false) const;
peer_request map_file(int file, size_type offset, int size
, bool storage = false) const;
std::vector<std::string> const& url_seeds() const
{
@ -128,15 +132,60 @@ namespace libtorrent
typedef std::vector<file_entry>::const_reverse_iterator reverse_file_iterator;
// list the files in the torrent file
file_iterator begin_files() const { return m_files.begin(); }
file_iterator end_files() const { return m_files.end(); }
reverse_file_iterator rbegin_files() const { return m_files.rbegin(); }
reverse_file_iterator rend_files() const { return m_files.rend(); }
file_iterator begin_files(bool storage = false) const
{
if (!storage || m_remapped_files.empty())
return m_files.begin();
else
return m_remapped_files.begin();
}
int num_files() const
{ assert(m_piece_length > 0); return (int)m_files.size(); }
const file_entry& file_at(int index) const
{ assert(index >= 0 && index < (int)m_files.size()); return m_files[index]; }
file_iterator end_files(bool storage = false) const
{
if (!storage || m_remapped_files.empty())
return m_files.end();
else
return m_remapped_files.end();
}
reverse_file_iterator rbegin_files(bool storage = false) const
{
if (!storage || m_remapped_files.empty())
return m_files.rbegin();
else
return m_remapped_files.rbegin();
}
reverse_file_iterator rend_files(bool storage = false) const
{
if (!storage || m_remapped_files.empty())
return m_files.rend();
else
return m_remapped_files.rend();
}
int num_files(bool storage = false) const
{
assert(m_piece_length > 0);
if (!storage || m_remapped_files.empty())
return (int)m_files.size();
else
return (int)m_remapped_files.size();
}
const file_entry& file_at(int index, bool storage = false) const
{
if (!storage || m_remapped_files.empty())
{
assert(index >= 0 && index < (int)m_files.size());
return m_files[index];
}
else
{
assert(index >= 0 && index < (int)m_remapped_files.size());
return m_remapped_files[index];
}
}
const std::vector<announce_entry>& trackers() const { return m_urls; }
@ -218,6 +267,13 @@ namespace libtorrent
// the list of files that this torrent consists of
std::vector<file_entry> m_files;
// this vector is typically empty. If it is not
// empty, it means the user has re-mapped the
// files in this torrent to diffefrent names
// on disk. This is only used when reading and
// writing the disk.
std::vector<file_entry> m_remapped_files;
nodes_t m_nodes;
// the sum of all filesizes

View File

@ -247,8 +247,8 @@ namespace libtorrent
{
p = complete(p);
std::vector<std::pair<size_type, std::time_t> > sizes;
for (torrent_info::file_iterator i = t.begin_files();
i != t.end_files(); ++i)
for (torrent_info::file_iterator i = t.begin_files(true);
i != t.end_files(true); ++i)
{
size_type size = 0;
std::time_t time = 0;
@ -287,7 +287,7 @@ namespace libtorrent
, bool compact_mode
, std::string* error)
{
if ((int)sizes.size() != t.num_files())
if ((int)sizes.size() != t.num_files(true))
{
if (error) *error = "mismatching number of files";
return false;
@ -296,8 +296,8 @@ namespace libtorrent
std::vector<std::pair<size_type, std::time_t> >::const_iterator s
= sizes.begin();
for (torrent_info::file_iterator i = t.begin_files();
i != t.end_files(); ++i, ++s)
for (torrent_info::file_iterator i = t.begin_files(true);
i != t.end_files(true); ++i, ++s)
{
size_type size = 0;
std::time_t time = 0;
@ -349,7 +349,7 @@ namespace libtorrent
: m_info(info)
, m_files(fp)
{
assert(info.begin_files() != info.end_files());
assert(info.begin_files(true) != info.end_files(true));
m_save_path = fs::complete(path);
assert(m_save_path.is_complete());
}
@ -412,8 +412,8 @@ namespace libtorrent
{
// first, create all missing directories
fs::path last_path;
for (torrent_info::file_iterator file_iter = m_info.begin_files(),
end_iter = m_info.end_files(); file_iter != end_iter; ++file_iter)
for (torrent_info::file_iterator file_iter = m_info.begin_files(true),
end_iter = m_info.end_files(true); file_iter != end_iter; ++file_iter)
{
fs::path dir = (m_save_path / file_iter->path).branch_path();
@ -510,11 +510,11 @@ namespace libtorrent
if (seed)
{
if (m_info.num_files() != (int)file_sizes.size())
if (m_info.num_files(true) != (int)file_sizes.size())
{
error = "the number of files does not match the torrent (num: "
+ boost::lexical_cast<std::string>(file_sizes.size()) + " actual: "
+ boost::lexical_cast<std::string>(m_info.num_files()) + ")";
+ boost::lexical_cast<std::string>(m_info.num_files(true)) + ")";
return false;
}
@ -522,8 +522,8 @@ namespace libtorrent
fs = file_sizes.begin();
// the resume data says we have the entire torrent
// make sure the file sizes are the right ones
for (torrent_info::file_iterator i = m_info.begin_files()
, end(m_info.end_files()); i != end; ++i, ++fs)
for (torrent_info::file_iterator i = m_info.begin_files(true)
, end(m_info.end_files(true)); i != end; ++i, ++fs)
{
if (i->size != fs->first)
{
@ -688,7 +688,7 @@ namespace libtorrent
#ifndef NDEBUG
std::vector<file_slice> slices
= m_info.map_block(slot, offset, size);
= m_info.map_block(slot, offset, size, true);
assert(!slices.empty());
#endif
@ -699,7 +699,7 @@ namespace libtorrent
size_type file_offset = start;
std::vector<file_entry>::const_iterator file_iter;
for (file_iter = m_info.begin_files();;)
for (file_iter = m_info.begin_files(true);;)
{
if (file_offset < file_iter->size)
break;
@ -757,7 +757,7 @@ namespace libtorrent
assert(int(slices.size()) > counter);
size_type slice_size = slices[counter].size;
assert(slice_size == read_bytes);
assert(m_info.file_at(slices[counter].file_index).path
assert(m_info.file_at(slices[counter].file_index, true).path
== file_iter->path);
#endif
@ -813,7 +813,7 @@ namespace libtorrent
#ifndef NDEBUG
std::vector<file_slice> slices
= m_info.map_block(slot, offset, size);
= m_info.map_block(slot, offset, size, true);
assert(!slices.empty());
#endif
@ -823,14 +823,14 @@ namespace libtorrent
size_type file_offset = start;
std::vector<file_entry>::const_iterator file_iter;
for (file_iter = m_info.begin_files();;)
for (file_iter = m_info.begin_files(true);;)
{
if (file_offset < file_iter->size)
break;
file_offset -= file_iter->size;
++file_iter;
assert(file_iter != m_info.end_files());
assert(file_iter != m_info.end_files(true));
}
fs::path p(m_save_path / file_iter->path);
@ -874,7 +874,7 @@ namespace libtorrent
{
assert(int(slices.size()) > counter);
assert(slices[counter].size == write_bytes);
assert(m_info.file_at(slices[counter].file_index).path
assert(m_info.file_at(slices[counter].file_index, true).path
== file_iter->path);
assert(buf_pos >= 0);
@ -902,7 +902,7 @@ namespace libtorrent
#endif
++file_iter;
assert(file_iter != m_info.end_files());
assert(file_iter != m_info.end_files(true));
fs::path p = m_save_path / file_iter->path;
file_offset = 0;
out = m_files.open_file(
@ -1866,8 +1866,8 @@ namespace libtorrent
// find the file that failed, and skip all the blocks in that file
size_type file_offset = 0;
size_type current_offset = m_current_slot * m_info.piece_length();
for (torrent_info::file_iterator i = m_info.begin_files();
i != m_info.end_files(); ++i)
for (torrent_info::file_iterator i = m_info.begin_files(true);
i != m_info.end_files(true); ++i)
{
file_offset += i->size;
if (file_offset > current_offset) break;

View File

@ -824,8 +824,33 @@ namespace libtorrent
m_nodes.push_back(node);
}
bool torrent_info::remap_files(std::vector<std::pair<std::string
, libtorrent::size_type> > const& map)
{
typedef std::vector<std::pair<std::string, size_type> > files_t;
size_type offset = 0;
m_remapped_files.resize(map.size());
for (int i = 0; i < int(map.size()); ++i)
{
file_entry& fe = m_remapped_files[i];
fe.path = map[i].first;
fe.offset = offset;
fe.size = map[i].second;
offset += fe.size;
}
if (offset != total_size())
{
m_remapped_files.clear();
return false;
}
return true;
}
std::vector<file_slice> torrent_info::map_block(int piece, size_type offset
, int size) const
, int size, bool storage) const
{
assert(num_files() > 0);
std::vector<file_slice> ret;
@ -839,9 +864,9 @@ namespace libtorrent
std::vector<file_entry>::const_iterator file_iter;
int counter = 0;
for (file_iter = begin_files();; ++counter, ++file_iter)
for (file_iter = begin_files(storage);; ++counter, ++file_iter)
{
assert(file_iter != end_files());
assert(file_iter != end_files(storage));
if (file_offset < file_iter->size)
{
file_slice f;
@ -862,11 +887,11 @@ namespace libtorrent
}
peer_request torrent_info::map_file(int file_index, size_type file_offset
, int size) const
, int size, bool storage) const
{
assert(file_index < (int)m_files.size());
assert(file_index < num_files(storage));
assert(file_index >= 0);
size_type offset = file_offset + m_files[file_index].offset;
size_type offset = file_offset + file_at(file_index, storage).offset;
peer_request ret;
ret.piece = offset / piece_length();

View File

@ -142,12 +142,31 @@ int test_main()
run_storage_tests(info);
// make sure the files have the correct size
std::cerr << file_size(initial_path() / "temp_storage" / "test1.tmp") << std::endl;
TEST_CHECK(file_size(initial_path() / "temp_storage" / "test1.tmp") == 17);
std::cerr << file_size(initial_path() / "temp_storage" / "test2.tmp") << std::endl;
TEST_CHECK(file_size(initial_path() / "temp_storage" / "test2.tmp") == 31);
TEST_CHECK(exists("temp_storage/test3.tmp"));
TEST_CHECK(exists("temp_storage/test4.tmp"));
remove_all(initial_path() / "temp_storage");
// ==============================================
// make sure remap_files works
std::vector<std::pair<std::string, libtorrent::size_type> > map;
map.push_back(std::make_pair(std::string("temp_storage/test.tmp"), 17 + 612 + 1));
bool ret = info.remap_files(map);
TEST_CHECK(ret);
run_storage_tests(info, false);
std::cerr << file_size(initial_path() / "temp_storage" / "test.tmp") << std::endl;
TEST_CHECK(file_size(initial_path() / "temp_storage" / "test.tmp") == 17 + 612 + 1);
remove_all(initial_path() / "temp_storage");
// ==============================================
info = torrent_info();
info.set_piece_size(piece_size);
info.add_file("temp_storage/test1.tmp", 17 + 612 + 1);
@ -158,6 +177,8 @@ int test_main()
TEST_CHECK(file_size(initial_path() / "temp_storage" / "test1.tmp") == 48);
remove_all(initial_path() / "temp_storage");
// ==============================================
// make sure full allocation mode actually allocates the files
// and creates the directories
run_storage_tests(info, false);