java.lang.Object
org.klomp.snark.MetaInfo
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 Summary
FieldsModifier and TypeFieldDescriptionprivate long[]Cumulative exclusive end offset of each file, lazily computed; null for single-file.private final LogLogger for the torrent metadata.private final StringThe announce URL of the tracker.The DHT and tracker announce groups.The file attributes, path components first.private final StringThe comment from the torrent file.private final StringThe program that created the torrent.private final longWhen the torrent was created, epoch seconds.The file paths and lengths of a multi file torrent.private final byte[]The SHA-1 hash of the info dictionary.private intLength of the serialized info dictionary in bytes, cached after first computation.Original bencoded info dictionary, preserved to keep infohash consistent on re-encode.private final longThe total length, in bytes.The file lengths, in bytes.private final StringThe suggested name of the download.private final byte[]The SHA-1 hash of each piece.private final intThe piece length, in bytes.private final int1 if the private flag is set, -1 if cleared, 0 if absent.Extra web seeds, HTTP URLs.Constructor Summary
ModifierConstructorDescriptionMetaInfo(InputStream in) Creates a new MetaInfo from the given InputStream.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 bymain(String[]).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.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).privateCreates a new MetaInfo from the given BDecoder.MetaInfo(MetaInfo old, String newAnnounce, List<List<String>> newAnnounceList, String newComment, String newCreatedBy, List<String> newUrlList) Will not change infohash.Method Summary
Modifier and TypeMethodDescriptionprivate byte[]Computes the 20-byte SHA1 hash over the bencoded info dictionary.booleancheckPiece(int piece, byte[] bs, int off, int length) Checks that the given piece has the same SHA1 hash as the given byte array.(package private) booleanChecks a piece against the stored hashes using a PartialPiece.An unmodifiable view of the info map.private booleanfast_checkPiece(int piece, byte[] bs, int off, int length) Fast path for piece hash verification.(package private) long[]fileEnds()Cumulative exclusive end offset of each file; single-file torrents return null.(package private) intfileIndex(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.Returns the string representing the URL of the tracker for this torrent.The tracker announce URLs grouped into tiers, each tier a set of equivalent trackers, per BEP 12.The comment string or null.The created-by string or null.longThe creation date (ms) or zero.longReturns the total length of the non-padding files in this torrent, orgetTotalLength()if there are no padding files.getFiles()Returns a list of lists of file name hierarchies or null if it is a single name.byte[]Side effect: Caches infoBytesLength.intThe size ofgetInfoBytes().byte[]Returns the original 20 byte SHA1 hash over the bencoded info map.Returns a list of Longs indication the size of the individual files, or null if it is a single file.getName()Returns the requested name for the file or toplevel directory.static StringgetNameAndInfoHash(InputStream in, byte[] infoHashOut) Efficiently returns the name and the 20 byte SHA1 hash of the info dictionary in a torrent file.byte[]The 20-byte SHA1 hash of each piece, concatenated.intgetPieceLength(int piece) Return the length of a piece.intReturns the number of pieces in the torrent.intThe private tracker flag: 0 (default), 1 (set to 1), -1 (set to 0).byte[]Returns the bencoded torrent file data.longReturns the total length of the torrent in bytes.Returns the web seed URLs for BEP 19 HTTP seeding.booleanisPaddingFile(int filenum) Is this file a padding file?booleanIs it a private torrent?booleanisRangePadding(long offset, int length) True if every byte in the given range lies within BEP 47 padding files.static voidCommand-line utility to inspect and optionally modify torrent file metadata.reannounce(String announce) Creates a copy of this MetaInfo that shares everything except the announce URL.toString()Returns a human-readable summary of this torrent's metadata.
Field Details
_log
Logger for the torrent metadata.announce
The announce URL of the tracker.info_hash
private final byte[] info_hashThe SHA-1 hash of the info dictionary.name
The suggested name of the download.files
attributes
lengths
piece_length
private final int piece_lengthThe piece length, in bytes.piece_hashes
private final byte[] piece_hashesThe SHA-1 hash of each piece._fileEnds
private volatile long[] _fileEndsCumulative exclusive end offset of each file, lazily computed; null for single-file.length
private final long lengthThe total length, in bytes.privateTorrent
private final int privateTorrent1 if the private flag is set, -1 if cleared, 0 if absent.announce_list
comment
The comment from the torrent file.created_by
The program that created the torrent.creation_date
private final long creation_dateWhen the torrent was created, epoch seconds.url_list
infoMap
infoBytesLength
private int infoBytesLengthLength 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 nullname- the file or top-level directory namenameUtf8- unused, retained for API compatibilityfiles- list of file path components per file, null for single-file torrentlengths- list of file sizes in bytes, null for single-file torrentattributes- per-file attribute strings (BEP 47 "p" marks padding files), may be nullpieceLength- the length of each data piece in bytespieceHashes- concatenated 20-byte SHA1 hashes of all pieceslength- total torrent size in bytesprivateTorrent- whether the tracker restricts peer sharing to the swarmannounceList- tiered list of alternate announce URLs, may be nullcreatedBy- application name that created the torrent, may be nullurlList- web seed URLs for BEP 19 HTTP seeding, may be nullcomment- 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 bymain(String[]).- Parameters:
announce- the tracker announce URL, may be nullname- the file or top-level directory namenameUtf8- unused, retained for API compatibilityfiles- list of file path components per file, null for single-file torrentlengths- list of file sizes in bytes, null for single-file torrentpieceLength- the length of each data piece in bytespieceHashes- concatenated 20-byte SHA1 hashes of all pieceslength- total torrent size in bytesprivateTorrent- 0 = not present, 1 = private, -1 = explicitly not privateannounceList- tiered list of alternate announce URLs, may be nullcreatedBy- application name that created the torrent, may be nullurlList- web seed URLs for BEP 19 HTTP seeding, may be nullcomment- 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 reusednewAnnounce- the replacement announce URL, may be nullnewAnnounceList- tiered list of replacement announce URLs, may be nullnewComment- replacement comment string, may be nullnewCreatedBy- replacement created-by string, may be nullnewUrlList- replacement web seed URLs, may be null
MetaInfo
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 malformedThrowable
MetaInfo
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 readThrowable- if the dictionary is malformed or a field has the wrong type
MetaInfo
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
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 datainfoHashOut- 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
Returns the string representing the URL of the tracker for this torrent.- Returns:
- may be null!
getAnnounceList
getWebSeedURLs
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
Returns the requested name for the file or toplevel directory. If it is a toplevel directory namegetFiles()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
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 bygetLengths().- 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 torrentlength- 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()andgetLengths(), 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
getComment
The comment string or null. Not available for locally-created torrents.- Returns:
- the comment, or null if the torrent carries none
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 togetPieces()- 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 indexbs- the byte array containing the piece dataoff- the offset within the byte array where the piece data startslength- 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 indexbs- the byte array containing the piece dataoff- the offset within the byte array where the piece data startslength- the number of bytes in the piece- Returns:
- true if the computed hash matches the stored hash
checkPiece
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, orgetTotalLength()if there are no padding files. The projected downloaded size.- Returns:
- the length of all non-padding files
toString
reannounce
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
createInfoMap
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
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 inUsageabove, followed by the torrent files