java.lang.Object
org.klomp.snark.MetaInfo

public class MetaInfoextends Object
Holds all information extracted from a torrent file.

This class parses and stores the metadata from .torrent files, including:

  • Tracker announce URLs
  • Info hash for torrent identification
  • File names, sizes, and structure
  • Piece length and piece hashes for integrity verification

Note: This class has a known limitation where it doesn't propagate custom meta fields into the bencoded info data, and from there to the info_hash. However, it currently works with torrents created by I2P-BT, I2PRufus and Azureus.

  • Field Details

    • _log

      private final Log _log
      Logger for the torrent metadata.
    • announce

      private final String announce
      The announce URL of the tracker.
    • info_hash

      private final byte[] info_hash
      The SHA-1 hash of the info dictionary.
    • name

      private final String name
      The suggested name of the download.
    • files

      private final List<List<String>> files
      The file paths and lengths of a multi file torrent.
    • attributes

      private final List<String> attributes
      The file attributes, path components first.
    • lengths

      private final List<Long> lengths
      The file lengths, in bytes.
    • piece_length

      private final int piece_length
      The piece length, in bytes.
    • piece_hashes

      private final byte[] piece_hashes
      The SHA-1 hash of each piece.
    • _fileEnds

      private volatile long[] _fileEnds
      Cumulative exclusive end offset of each file, lazily computed; null for single-file.
    • length

      private final long length
      The total length, in bytes.
    • privateTorrent

      private final int privateTorrent
      1 if the private flag is set, -1 if cleared, 0 if absent.
    • announce_list

      private final List<List<String>> announce_list
      The DHT and tracker announce groups.
    • comment

      private final String comment
      The comment from the torrent file.
    • created_by

      private final String created_by
      The program that created the torrent.
    • creation_date

      private final long creation_date
      When the torrent was created, epoch seconds.
    • url_list

      private final List<String> url_list
      Extra web seeds, HTTP URLs.
    • infoMap

      private Map<String,BEValue> infoMap
      Original bencoded info dictionary, preserved to keep infohash consistent on re-encode.
    • infoBytesLength

      private int infoBytesLength
      Length of the serialized info dictionary in bytes, cached after first computation.
  • Constructor Details

    • MetaInfo

      public MetaInfo(String announce, String name, String nameUtf8, List<List<String>> files, List<Long> lengths, List<String> attributes, int pieceLength, byte[] pieceHashes, long length, boolean privateTorrent, List<List<String>> announceList, String createdBy, List<String> urlList, String comment)
      Called by Storage when creating a new torrent from local data.
      Parameters:
      announce - the tracker announce URL, may be null
      name - the file or top-level directory name
      nameUtf8 - unused, retained for API compatibility
      files - list of file path components per file, null for single-file torrent
      lengths - list of file sizes in bytes, null for single-file torrent
      attributes - per-file attribute strings (BEP 47 "p" marks padding files), may be null
      pieceLength - the length of each data piece in bytes
      pieceHashes - concatenated 20-byte SHA1 hashes of all pieces
      length - total torrent size in bytes
      privateTorrent - whether the tracker restricts peer sharing to the swarm
      announceList - tiered list of alternate announce URLs, may be null
      createdBy - application name that created the torrent, may be null
      urlList - web seed URLs for BEP 19 HTTP seeding, may be null
      comment - free-form user comment, may be null
    • MetaInfo

      public MetaInfo(String announce, String name, String nameUtf8, List<List<String>> files, List<Long> lengths, int pieceLength, byte[] pieceHashes, long length, int privateTorrent, List<List<String>> announceList, String createdBy, List<String> urlList, String comment)
      Preserves privateTorrent int value, for use by main(String[]).
      Parameters:
      announce - the tracker announce URL, may be null
      name - the file or top-level directory name
      nameUtf8 - unused, retained for API compatibility
      files - list of file path components per file, null for single-file torrent
      lengths - list of file sizes in bytes, null for single-file torrent
      pieceLength - the length of each data piece in bytes
      pieceHashes - concatenated 20-byte SHA1 hashes of all pieces
      length - total torrent size in bytes
      privateTorrent - 0 = not present, 1 = private, -1 = explicitly not private
      announceList - tiered list of alternate announce URLs, may be null
      createdBy - application name that created the torrent, may be null
      urlList - web seed URLs for BEP 19 HTTP seeding, may be null
      comment - free-form user comment, may be null
    • MetaInfo

      public MetaInfo(MetaInfo old, String newAnnounce, List<List<String>> newAnnounceList, String newComment, String newCreatedBy, List<String> newUrlList)
      Will not change infohash. Retains creation date of old MetaInfo if nonzero.
      Parameters:
      old - the source MetaInfo whose infohash, name, files, and hashes are reused
      newAnnounce - the replacement announce URL, may be null
      newAnnounceList - tiered list of replacement announce URLs, may be null
      newComment - replacement comment string, may be null
      newCreatedBy - replacement created-by string, may be null
      newUrlList - replacement web seed URLs, may be null
    • MetaInfo

      public MetaInfo(InputStream in) throws IOException, Throwable
      Creates a new MetaInfo from the given InputStream. The InputStream must start with a correctly bencoded dictionary describing the torrent. Caller must close the stream.
      Parameters:
      in - the stream containing the bencoded torrent data
      Throws:
      IOException - if the stream cannot be read or the bencoded data is malformed
      Throwable
    • MetaInfo

      private MetaInfo(BDecoder be) throws IOException, Throwable
      Creates a new MetaInfo from the given BDecoder. The BDecoder must have a complete dictionary describing the torrent.
      Parameters:
      be - the decoder holding the torrent dictionary
      Throws:
      IOException - if the stream cannot be read
      Throwable - if the dictionary is malformed or a field has the wrong type
    • MetaInfo

      public MetaInfo(Map<String,BEValue> m) throws InvalidBEncodingException
      Creates a new MetaInfo from a Map of BEValues and the SHA1 over the original bencoded info dictionary (this is a hack, we could reconstruct the bencoded stream and recalculate the hash). Will NOT throw a InvalidBEncodingException if the given map does not contain a valid announce string. WILL throw a InvalidBEncodingException if the given map does not contain a valid info dictionary.
      Parameters:
      m - the parsed bencoded dictionary as a map of keys to BEValues
      Throws:
      InvalidBEncodingException - if the info dictionary is missing or malformed
  • Method Details

    • getNameAndInfoHash

      public static String getNameAndInfoHash(InputStream in, byte[] infoHashOut) throws IOException
      Efficiently returns the name and the 20 byte SHA1 hash of the info dictionary in a torrent file. Caller must close the stream.
      Parameters:
      in - the stream containing the bencoded torrent data
      infoHashOut - 20-byte array that receives the info hash
      Returns:
      the name field from the info dictionary
      Throws:
      IOException - if the stream cannot be read or the data is malformed
    • getAnnounce

      public String getAnnounce()
      Returns the string representing the URL of the tracker for this torrent.
      Returns:
      may be null!
    • getAnnounceList

      public List<List<String>> getAnnounceList()
      The tracker announce URLs grouped into tiers, each tier a set of equivalent trackers, per BEP 12.
      Returns:
      tiered announce URLs per BEP 12, or null if none were specified
    • getWebSeedURLs

      public List<String> getWebSeedURLs()
      Returns the web seed URLs for BEP 19 HTTP seeding.
      Returns:
      list of web seed URLs, or null if none were specified
    • getInfoHash

      public byte[] getInfoHash()
      Returns the original 20 byte SHA1 hash over the bencoded info map.
      Returns:
      not a copy, do not modify
    • getPieceHashes

      public byte[] getPieceHashes()
      The 20-byte SHA1 hash of each piece, concatenated.
      Returns:
      not a copy, do not modify
    • getName

      public String getName()
      Returns the requested name for the file or toplevel directory. If it is a toplevel directory name getFiles() will return a non-null List of file name hierarchy name.
      Returns:
      the name the torrent requests for the file, or for the toplevel directory when getFiles() returns a file hierarchy
    • isPrivate

      public boolean isPrivate()
      Is it a private torrent?
      Returns:
      true if the private flag is present and set; false if it is absent or explicitly 0
    • getPrivateTrackerStatus

      public int getPrivateTrackerStatus()
      The private tracker flag: 0 (default), 1 (set to 1), -1 (set to 0).
      Returns:
      0 (default), 1 (set to 1), -1 (set to 0)
    • getFiles

      public List<List<String>> getFiles()
      Returns a list of lists of file name hierarchies or null if it is a single name. It has the same size as the list returned by getLengths().
      Returns:
      the per-file name hierarchies, or null for a single-file torrent
    • isPaddingFile

      public boolean isPaddingFile(int filenum)
      Is this file a padding file?
      Parameters:
      filenum - the index of the file in the files list
      Returns:
      true if the file has the padding attribute set
    • isRangePadding

      public boolean isRangePadding(long offset, int length)
      True if every byte in the given range lies within BEP 47 padding files.

      Padding bytes are all zeros and are never stored on disk, so chunks or pieces entirely within padding need not be requested from peers (BEP 47).

      Parameters:
      offset - global byte offset into the torrent
      length - number of bytes
      Returns:
      true if the whole range is covered by padding files
    • fileIndex

      int fileIndex(long pos)
      Index of the first file whose cumulative exclusive end offset is above the given position, mapping a torrent byte offset to the file containing it. A position exactly on a file boundary maps to the following file. Single-file torrents always return 0.
      Parameters:
      pos - torrent byte offset
      Returns:
      the index into getFiles() and getLengths(), which is the file count if the position is past the end
    • fileEnds

      long[] fileEnds()
      Cumulative exclusive end offset of each file; single-file torrents return null.
      Returns:
      one offset per file, in torrent order, or null when the torrent has no per-file length list
    • getLengths

      public List<Long> getLengths()
      Returns a list of Longs indication the size of the individual files, or null if it is a single file. It has the same size as the list returned by getFiles().
      Returns:
      the file sizes in bytes, or null if it is a single file
    • getComment

      public String getComment()
      The comment string or null. Not available for locally-created torrents.
      Returns:
      the comment, or null if the torrent carries none
    • getCreatedBy

      public String getCreatedBy()
      The created-by string or null. Not available for locally-created torrents.
      Returns:
      the created by
    • getCreationDate

      public long getCreationDate()
      The creation date (ms) or zero. As of 0.9.19, available for locally-created torrents.
      Returns:
      the creation date
    • getPieces

      public int getPieces()
      Returns the number of pieces in the torrent.
      Returns:
      the piece count computed from the hash array length divided by 20
    • getPieceLength

      public int getPieceLength(int piece)
      Return the length of a piece. All pieces are of equal length except for the last one ( getPieces()-1).
      Parameters:
      piece - zero-based piece index, from 0 to getPieces() - 1
      Returns:
      the piece length
      Throws:
      IndexOutOfBoundsException - when piece is equal to or greater then the number of pieces in the torrent.
    • checkPiece

      public boolean checkPiece(int piece, byte[] bs, int off, int length)
      Checks that the given piece has the same SHA1 hash as the given byte array. Returns random results or IndexOutOfBoundsExceptions when the piece number is unknown.
      Parameters:
      piece - the piece index
      bs - the byte array containing the piece data
      off - the offset within the byte array where the piece data starts
      length - the number of bytes in the piece
      Returns:
      true if the computed SHA1 hash matches the stored hash for that piece
      Throws:
      IndexOutOfBoundsException - if the piece index is out of range
    • fast_checkPiece

      private boolean fast_checkPiece(int piece, byte[] bs, int off, int length)
      Fast path for piece hash verification. Computes SHA1 of the given data and compares it against the stored piece hash.
      Parameters:
      piece - the piece index
      bs - the byte array containing the piece data
      off - the offset within the byte array where the piece data starts
      length - the number of bytes in the piece
      Returns:
      true if the computed hash matches the stored hash
    • checkPiece

      boolean checkPiece(PartialPiece pp)
      Checks a piece against the stored hashes using a PartialPiece.
      Parameters:
      pp - the PartialPiece containing the piece data and hash
      Returns:
      true if the hash embedded in the PartialPiece matches the stored hash for that piece
    • getTotalLength

      public long getTotalLength()
      Returns the total length of the torrent in bytes. This includes any padding files.
      Returns:
      the torrent size in bytes, padding included
    • getDataLength

      public long getDataLength()
      Returns the total length of the non-padding files in this torrent, or getTotalLength() if there are no padding files. The projected downloaded size.
      Returns:
      the length of all non-padding files
    • toString

      public String toString()
      Returns a human-readable summary of this torrent's metadata.
      Overrides:
      toString in class Object
      Returns:
      string containing name, infohash, announce URL, size, file count, and piece count
    • reannounce

      public MetaInfo reannounce(String announce) throws InvalidBEncodingException
      Creates a copy of this MetaInfo that shares everything except the announce URL. Drops any announce-list. Preserves infohash and info map, including any non-standard fields.
      Parameters:
      announce - may be null
      Returns:
      the copy, sharing the same infohash and info map
      Throws:
      InvalidBEncodingException - if the info dictionary built from this torrent is missing or malformed
    • getTorrentData

      public byte[] getTorrentData()
      Returns the bencoded torrent file data. Used by the servlet when saving a torrent generated from local data.
      Returns:
      the bencoded byte array representing the complete torrent file
    • getInfoBytes

      public byte[] getInfoBytes()
      Side effect: Caches infoBytesLength.
      Returns:
      the info bytes
    • getInfoBytesLength

      public int getInfoBytesLength()
      The size of getInfoBytes(). Cached.
      Returns:
      the info bytes length
    • createInfoMap

      private Map<String,BEValue> createInfoMap()
      An unmodifiable view of the info map.
      Returns:
      an unmodifiable view of the Map
    • calculateInfoHash

      private byte[] calculateInfoHash()
      Computes the 20-byte SHA1 hash over the bencoded info dictionary. Creates the info map if it has not been built yet.
      Returns:
      the 20-byte info hash used as the torrent identifier
    • main

      public static void main(String[] args)
      Command-line utility to inspect and optionally modify torrent file metadata. Usage: MetaInfo [-a announceURL] [-c created-by] [-m comment] [-w webseed-url]* file.torrent [file2.torrent...].
      Parameters:
      args - the options in Usage above, followed by the torrent files