reference-Storage.rst
Author: Arvid Norberg, arvid@libtorrent.org

| libtorrent

Author: | Arvid Norberg, arvid@libtorrent.org
Version: | 1.2.9

home

# Storage

Table of contents

- Storage
  - storage_params
  - file_slice
  - file_storage
  - default_storage_constructor()
  - disabled_storage_constructor()
  - zero_storage_constructor()
  - enum storage_mode_t
  - enum status_t
  - enum move_flags_t

[report issue]

## storage_params

Declared in "libtorrent/storage_defs.hpp"

    struct storage_params
    {
       storage_params (file_storage const& f, file_storage const* mf
          , std::string const& sp, storage_mode_t const sm
          , aux::vector<download_priority_t, file_index_t> const& prio
          , sha1_hash const& ih);

       file_storage const& files;
       file_storage const* mapped_files  = nullptr;
       std::string const& path;
       storage_mode_t mode {storage_mode_sparse};
       aux::vector<download_priority_t, file_index_t> const& priorities;
       sha1_hash const& info_hash;
    };

[report issue]

## file_slice

Declared in "libtorrent/file_storage.hpp"

represents a window of a file in a torrent.

The `file_index` refers to the index of the file (in the torrent_info). To get the path and filename, use `file_path()` and give the `file_index` 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.

    struct file_slice
    {
       file_index_t file_index;
       std::int64_t offset;
       std::int64_t size;
    };

[report issue]

file_index
  the index of the file

[report issue]

offset
  the offset from the start of the file, in bytes

[report issue]

size
  the size of the window, in bytes

[report issue]

## file_storage

Declared in "libtorrent/file_storage.hpp"

The `file_storage` class represents a file list and the piece size. Everything necessary to interpret a regular bittorrent storage file structure.

    class file_storage
    {
       bool is_valid () const;
       void reserve (int num_files);
       void add_file (std::string const& path, std::int64_t file_size
          , file_flags_t file_flags = {}
          , std::time_t mtime = 0, string_view symlink_path = string_view());
       void add_file_borrow (string_view filename
          , std::string const& path, std::int64_t file_size
          , file_flags_t file_flags = {}, char const* filehash = nullptr
          , std::int64_t mtime = 0, string_view symlink_path = string_view());
       void rename_file (file_index_t index, std::string const& new_filename);
       std::vector<file_slice> map_block (piece_index_t piece, std::int64_t offset
          , int size) const;
       peer_request map_file (file_index_t file, std::int64_t offset, int size) const;
       int num_files () const noexcept;
       file_index_t end_file () const noexcept;
       index_range<file_index_t> file_range () const noexcept;
       std::int64_t total_size () const;
       void set_num_pieces (int n);
       int num_pieces () const;
       piece_index_t end_piece () const;
       piece_index_t last_piece () const;
       index_range<piece_index_t> piece_range () const noexcept;
       int piece_length () const;
       void set_piece_length (int l);
       int piece_size (piece_index_t index) const;
       std::string const& name () const;
       void set_name (std::string const& n);
       void swap (file_storage& ti) noexcept;
       void optimize (int pad_file_limit = -1, int alignment = -1
          , bool tail_padding = false);
       std::string const& symlink (file_index_t index) const;
       bool pad_file_at (file_index_t index) const;
       std::time_t mtime (file_index_t index) const;
       std::int64_t file_offset (file_index_t index) const;
       std::int64_t file_size (file_index_t index) const;
       string_view file_name (file_index_t index) const;
       sha1_hash hash (file_index_t index) const;
       std::string file_path (file_index_t index, std::string const& save_path = "") const;
       std::uint32_t file_path_hash (file_index_t index, std::string const& save_path) const;
       void all_path_hashes (std::unordered_set<std::uint32_t>& table) const;
       std::vector<std::string> const& paths () const;
       file_flags_t file_flags (file_index_t index) const;
       bool file_absolute_path (file_index_t index) const;
       file_index_t file_index_at_offset (std::int64_t offset) const;
       int file_name_len (file_index_t index) const;
       char const* file_name_ptr (file_index_t index) const;
       void apply_pointer_offset (std::ptrdiff_t off);
       void sanitize_symlinks ();

       static constexpr file_flags_t flag_pad_file  = 0_bit;
       static constexpr file_flags_t flag_hidden  = 1_bit;
       static constexpr file_flags_t flag_executable  = 2_bit;
       static constexpr file_flags_t flag_symlink  = 3_bit;
    };

[report issue]

### is_valid()

    bool is_valid () const;

returns true if the piece length has been initialized on the file_storage. This is typically taken as a proxy of whether the file_storage as a whole is initialized or not.

[report issue]

### reserve()

    void reserve (int num_files);

allocates space for `num_files` in the internal file list. This can be used to avoid reallocating the internal file list when the number of files to be added is known up-front.

[report issue]

### add_file_borrow() add_file()

    void add_file (std::string const& path, std::int64_t file_size
          , file_flags_t file_flags = {}
          , std::time_t mtime = 0, string_view symlink_path = string_view());
    void add_file_borrow (string_view filename
          , std::string const& path, std::int64_t file_size
          , file_flags_t file_flags = {}, char const* filehash = nullptr
          , std::int64_t mtime = 0, string_view symlink_path = string_view());

Adds a file to the file storage. The `add_file_borrow` version expects that `filename` is the file name (without a path) of the file that's being added. This memory is borrowed, i.e. it is the caller's responsibility to make sure it stays valid throughout the lifetime of this file_storage object or any copy of it. The same thing applies to `filehash`, which is an optional pointer to a 20 byte binary SHA-1 hash of the file.

if `filename` is empty, the filename from `path` is used and not borrowed.

The `path` argument is the full path (in the torrent file) to the file to add. Note that this is not supposed to be an absolute path, but it is expected to include the name of the torrent as the first path element.

`file_size` is the size of the file in bytes.

The `file_flags` argument sets attributes on the file. The file attributes is an extension and may not work in all bittorrent clients.

For possible file attributes, see file_storage::flags_t.

The `mtime` argument is optional and can be set to 0. If non-zero, it is the posix time of the last modification time of this file.

`symlink_path` is the path the file is a symlink to. To make this a symlink you also need to set the file_storage::flag_symlink file flag.

If more files than one are added, certain restrictions to their paths apply. In a multi-file file storage (torrent), all files must share the same root directory.

That is, the first path element of all files must be the same. This shared path element is also set to the name of the torrent. It can be changed by calling `set_name`.

[report issue]

### rename_file()

    void rename_file (file_index_t index, std::string const& new_filename);

renames the file at `index` to `new_filename`. Keep in mind that filenames are expected to be UTF-8 encoded.

[report issue]

### map_block()

    std::vector<file_slice> map_block (piece_index_t piece, std::int64_t offset
          , int size) const;

returns a list of file_slice objects representing the portions of files the specified piece index, byte offset and size range overlaps. this is the inverse mapping of map_file().

Preconditions of this function is that the input range is within the torrents address space. `piece` may not be negative and

> `piece` * piece_size + `offset` + `size`

may not exceed the total size of the torrent.

[report issue]

### map_file()

    peer_request map_file (file_index_t file, std::int64_t offset, int size) const;

returns a peer_request representing the piece index, byte offset and size the specified file range overlaps. This is the inverse mapping over map_block(). Note that the `peer_request` return type is meant to hold bittorrent block requests, which may not be larger than 16 kiB. Mapping a range larger than that may return an overflown integer.

[report issue]

### num_files()

    int num_files () const noexcept;

returns the number of files in the file_storage

[report issue]

### end_file()

    file_index_t end_file () const noexcept;

returns the index of the one-past-end file in the file storage

[report issue]

### file_range()

    index_range<file_index_t> file_range () const noexcept;

returns an implementation-defined type that can be used as the container in a range-for loop. Where the values are the indices of all files in the file_storage.

[report issue]

### total_size()

    std::int64_t total_size () const;

returns the total number of bytes all the files in this torrent spans

[report issue]

### num_pieces() set_num_pieces()

    void set_num_pieces (int n);
    int num_pieces () const;

set and get the number of pieces in the torrent

[report issue]

### end_piece()

    piece_index_t end_piece () const;

returns the index of the one-past-end piece in the file storage

[report issue]

### last_piece()

    piece_index_t last_piece () const;

returns the index of the last piece in the torrent. The last piece is special in that it may be smaller than the other pieces (and the other pieces are all the same size).

[report issue]

### piece_range()

    index_range<piece_index_t> piece_range () const noexcept;

returns an implementation-defined type that can be used as the container in a range-for loop. Where the values are the indices of all pieces in the file_storage.

[report issue]

### set_piece_length() piece_length()

    int piece_length () const;
    void set_piece_length (int l);

set and get the size of each piece in this torrent. This size is typically an even power of 2. It doesn't have to be though. It should be divisible by 16 kiB however.

[report issue]

### piece_size()

    int piece_size (piece_index_t index) const;

returns the piece size of `index`. This will be the same as piece_length(), except for the last piece, which may be shorter.

[report issue]

### name() set_name()

    std::string const& name () const;
    void set_name (std::string const& n);

set and get the name of this torrent. For multi-file torrents, this is also the name of the root directory all the files are stored in.

[report issue]

### swap()

    void swap (file_storage& ti) noexcept;

swap all content of this with ti.

[report issue]

### optimize()

    void optimize (int pad_file_limit = -1, int alignment = -1
          , bool tail_padding = false);

if pad_file_limit >= 0, files larger than that limit will be padded, default is to not add any padding (-1). The alignment specifies the alignment files should be padded to. This defaults to the piece size (-1) but it may also make sense to set it to 16 kiB, or something divisible by 16 kiB. If pad_file_limit is 0, every file will be padded (except empty ones). `tail_padding` indicates whether aligned files also are padded at the end to make them end aligned. This is required for mutable torrents, since piece hashes are compared

[report issue]

### file_size() mtime() file_path() file_name() hash() file_offset() pad_file_at() symlink()

    std::string const& symlink (file_index_t index) const;
    bool pad_file_at (file_index_t index) const;
    std::time_t mtime (file_index_t index) const;
    std::int64_t file_offset (file_index_t index) const;
    std::int64_t file_size (file_index_t index) const;
    string_view file_name (file_index_t index) const;
    sha1_hash hash (file_index_t index) const;
    std::string file_path (file_index_t index, std::string const& save_path = "") const;

These functions are used to query attributes of files at a given index.

The `hash()` is a SHA-1 hash of the file, or 0 if none was provided in the torrent file. This can potentially be used to join a bittorrent network with other file sharing networks.

The `mtime()` is the modification time is the posix time when a file was last modified when the torrent was created, or 0 if it was not included in the torrent file.

`file_path()` returns the full path to a file.

`file_size()` returns the size of a file.

`pad_file_at()` returns true if the file at the given index is a pad-file.

`file_name()` returns just the name of the file, whereas `file_path()` returns the path (inside the torrent file) with the filename appended.

`file_offset()` returns the byte offset within the torrent file where this file starts. It can be used to map the file to a piece index (given the piece size).

[report issue]

### file_path_hash()

    std::uint32_t file_path_hash (file_index_t index, std::string const& save_path) const;

returns the crc32 hash of file_path(index)

[report issue]

### all_path_hashes()

    void all_path_hashes (std::unordered_set<std::uint32_t>& table) const;

this will add the CRC32 hash of all directory entries to the table. No filename will be included, just directories. Every depth of directories are added separately to allow test for collisions with files at all levels. i.e. if one path in the torrent is `foo/bar/baz`, the CRC32 hashes for `foo`, `foo/bar` and `foo/bar/baz` will be added to the set.

[report issue]

### paths()

    std::vector<std::string> const& paths () const;

returns all directories used in the torrent. Files in the torrent are located in one of these directories. This is not a tree, it's a flat list of all leaf directories. i.e. the union of the parent paths of all files.

[report issue]

### file_flags()

    file_flags_t file_flags (file_index_t index) const;

returns a bitmask of flags from file_flags_t that apply to file at `index`.

[report issue]

### file_absolute_path()

    bool file_absolute_path (file_index_t index) const;

returns true if the file at the specified index has been renamed to have an absolute path, i.e. is not anchored in the save path of the torrent.

[report issue]

### file_index_at_offset()

    file_index_t file_index_at_offset (std::int64_t offset) const;

returns the index of the file at the given offset in the torrent

[report issue]

### file_name_len() file_name_ptr()

    int file_name_len (file_index_t index) const;
    char const* file_name_ptr (file_index_t index) const;

low-level function. returns a pointer to the internal storage for the filename. This string may not be 0-terminated! the `file_name_len()` function returns the length of the filename. prefer to use `file_name()` instead, which returns a `string_view`.

[report issue]

### apply_pointer_offset()

    void apply_pointer_offset (std::ptrdiff_t off);

if the backing buffer changed for this storage, this is the pointer offset to add to any pointers to make them point into the new buffer

[report issue]

### sanitize_symlinks()

    void sanitize_symlinks ();

validate any symlinks, to ensure they all point to other files or directories inside this storage. Any invalid symlinks are updated to point to themselves.

[report issue]

flag_pad_file
  the file is a pad file. It's required to contain zeros at it will not be saved to disk. Its purpose is to make the following file start on a piece boundary.

[report issue]

flag_hidden
  this file has the hidden attribute set. This is primarily a windows attribute

[report issue]

flag_executable
  this file has the executable attribute set.

[report issue]

flag_symlink
  this file is a symbolic link. It should have a link target string associated with it.

[report issue]

## default_storage_constructor()

Declared in "libtorrent/storage_defs.hpp"

    storage_interface* default_storage_constructor (storage_params const&
       , file_pool& p);

the constructor function for the regular file storage. This is the default value for add_torrent_params::storage.

[report issue]

## disabled_storage_constructor()

Declared in "libtorrent/storage_defs.hpp"

    storage_interface* disabled_storage_constructor (storage_params const&, file_pool&);

the constructor function for the disabled storage. This can be used for testing and benchmarking. It will throw away any data written to it and return garbage for anything read from it.

[report issue]

## zero_storage_constructor()

Declared in "libtorrent/storage_defs.hpp"

    storage_interface* zero_storage_constructor (storage_params const&, file_pool&);

the constructor function for the "zero" storage. This will always read zeros and ignore all writes.

[report issue]

## enum storage_mode_t

Declared in "libtorrent/storage_defs.hpp"

name | value | description
--- | --- | ---
storage_mode_allocate | 0 | All pieces will be written to their final position, all files will be allocated in full when the torrent is first started. This is done with `fallocate()` and similar calls. This mode minimizes fragmentation.
storage_mode_sparse | 1 | All pieces will be written to the place where they belong and sparse files will be used. This is the recommended, and default mode.

[report issue]

## enum status_t

Declared in "libtorrent/storage_defs.hpp"

name | value | description
--- | --- | ---
no_error | 0 |
fatal_disk_error | 1 |
need_full_check | 2 |
file_exist | 3 |

[report issue]

## enum move_flags_t

Declared in "libtorrent/storage_defs.hpp"

name | value | description
--- | --- | ---
always_replace_files | 0 | replace any files in the destination when copying or moving the storage
fail_if_exist | 1 | if any files that we want to copy exist in the destination exist, fail the whole operation and don't perform any copy or move. There is an inherent race condition in this mode. The files are checked for existence before the operation starts. In between the check and performing the copy, the destination files may be created, in which case they are replaced.
dont_replace | 2 | if any file exist in the target, take those files instead of the ones we may have in the source.