java.lang.Object
org.klomp.snark.MagnetState

class MagnetStateextends Object
Simple state for the download of the metainfo, shared between Peer and ExtensionHandler.

Nothing is synchronized here! Caller must synchronize on this for everything!

Reference: BEP 9

  • Field Summary

    Modifier and Type
    Field
    Description
    static final int
    Chunk size for magnet metadata fetches (16 KB).
    private boolean
    True once the metadata is fully fetched.
    private BitField
    Which metadata pieces have arrived.
    private final byte[]
    The torrent's info hash.
    private boolean
    If false, nothing below is valid.
    private MetaInfo
    Only valid when finished.
    private byte[]
    Bitfield for the metainfo.
    private int
    Total size of the metadata, in bytes.
    private BitField
    Bitfield for the metainfo chunks; remains null if we start out complete.
    private int
    Number of metadata pieces.
  • Constructor Summary

    Constructors
    Constructor
    Description
    MagnetState(byte[] iHash, MetaInfo meta)
    Creates a new MagnetState for the given info hash.
  • Method Summary

    Modifier and Type
    Method
    Description
    private MetaInfo
    Builds a MetaInfo from the collected metadata bytes.
    int
    chunkSize(int chunk)
    The size of a specific chunk.
    int
    The number of chunks remaining to be downloaded.
    byte[]
    getChunk(int chunk)
    The data for a specific chunk.
    Returns the MetaInfo for this magnet state.
    int
    The next chunk number to request.
    int
    Returns the total metadata size in bytes.
    void
    initialize(int size)
    Initializes the magnet state with the given metadata size.
    boolean
    Check if the magnet download is complete.
    boolean
    Check if the magnet state has been initialized.
    boolean
    saveChunk(int chunk, byte[] data, int off, int length)
    Save a chunk of data to the magnet state.
    void
    Store the MetaInfo for a completed magnet download.

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • CHUNK_SIZE

      public static final int CHUNK_SIZE
      Chunk size for magnet metadata fetches (16 KB).
      See Also:
    • infohash

      private final byte[] infohash
      The torrent's info hash.
    • complete

      private boolean complete
      True once the metadata is fully fetched.
    • isInitialized

      private boolean isInitialized
      If false, nothing below is valid.
    • metaSize

      private int metaSize
      Total size of the metadata, in bytes.
    • totalChunks

      private int totalChunks
      Number of metadata pieces.
    • requested

      private BitField requested
      Bitfield for the metainfo chunks; remains null if we start out complete.
    • have

      private BitField have
      Which metadata pieces have arrived.
    • metainfoBytes

      private byte[] metainfoBytes
      Bitfield for the metainfo.
    • metainfo

      private MetaInfo metainfo
      Only valid when finished.
  • Constructor Details

    • MagnetState

      public MagnetState(byte[] iHash, MetaInfo meta)
      Creates a new MagnetState for the given info hash.
      Parameters:
      iHash - the 20-byte info hash
      meta - the MetaInfo if already available, or null for a new magnet download
  • Method Details

    • initialize

      public void initialize(int size)
      Initializes the magnet state with the given metadata size. Must only be called once.
      Parameters:
      size - the metadata size in bytes
      Throws:
      IllegalArgumentException - if already initialized
    • setMetaInfo

      public void setMetaInfo(MetaInfo meta)
      Store the MetaInfo for a completed magnet download.
      Parameters:
      meta - the completed MetaInfo
    • getMetaInfo

      public MetaInfo getMetaInfo()
      Returns the MetaInfo for this magnet state.
      Returns:
      the MetaInfo built from the gathered pieces
      Throws:
      IllegalArgumentException - if not complete
    • getSize

      public int getSize()
      Returns the total metadata size in bytes.
      Returns:
      the metadata size
      Throws:
      IllegalArgumentException - if not initialized
    • isInitialized

      public boolean isInitialized()
      Check if the magnet state has been initialized.
      Returns:
      true if initialized, false otherwise
    • isComplete

      public boolean isComplete()
      Check if the magnet download is complete.
      Returns:
      true if complete, false otherwise
    • chunkSize

      public int chunkSize(int chunk)
      The size of a specific chunk.
      Parameters:
      chunk - the chunk number
      Returns:
      the size of the chunk in bytes
    • chunksRemaining

      public int chunksRemaining()
      The number of chunks remaining to be downloaded.
      Returns:
      the number of chunks remaining
      Throws:
      IllegalArgumentException - if not initialized
    • getNextRequest

      public int getNextRequest()
      The next chunk number to request. Uses a random selection algorithm to avoid requesting the same chunks repeatedly.
      Returns:
      the next chunk number to request
      Throws:
      IllegalArgumentException - if not initialized or complete
    • getChunk

      public byte[] getChunk(int chunk)
      The data for a specific chunk.
      Parameters:
      chunk - the chunk number to retrieve
      Returns:
      the chunk data as a byte array
      Throws:
      IllegalArgumentException - if not complete or chunk number is invalid
    • saveChunk

      public boolean saveChunk(int chunk, byte[] data, int off, int length) throws Throwable
      Save a chunk of data to the magnet state.
      Parameters:
      chunk - the chunk number to save
      data - the byte array containing the chunk data
      off - the offset in the data array where the chunk starts
      length - the byte count to copy, which must equal the chunk size in a complete file
      Returns:
      true if this was the last piece, false otherwise
      Throws:
      IllegalArgumentException - if not initialized, chunk number is invalid, or length is incorrect
      Exception - if there's an error building the MetaInfo
      StackOverflowError - if the received metadata nests lists or maps deeply enough to exhaust the decoder's recursion
      Throwable
    • buildMetaInfo

      private MetaInfo buildMetaInfo() throws Throwable
      Builds a MetaInfo from the collected metadata bytes. Verifies the info hash matches.
      Returns:
      the built MetaInfo
      Throws:
      IOException - if the info hash doesn't match or data is corrupt
      Exception - if there's an error parsing the metadata
      StackOverflowError - if the bencoded metadata is nested too deeply for the decoder
      Throwable