class QuartzTorrent::Metainfo::Info

The ‘info’ property of the torrent metainfo.

Attributes

files[RW]

Array of FileInfo objects

name[RW]

Suggested file or directory name

pieceLen[RW]

Length of each piece in bytes. The last piece may be shorter than this.

pieces[RW]

Array of SHA1 digests of all peices. These digests are in binary format.

private[RW]

True if no external peer source is allowed.

source[RW]

Optional source

Public Class Methods

createFromBdecode(infoDict) click to toggle source

Create a FileInfo object from a bdecoded structure.

# File lib/quartz_torrent/metainfo.rb, line 83
def self.createFromBdecode(infoDict)
  result = Info.new
  result.pieceLen = infoDict['piece length']
  result.private = infoDict['private']
  result.source = infoDict['source']
  result.pieces = parsePieces(Metainfo.valueOrException(infoDict['pieces'], "Torrent metainfo is missing the pieces property."))
  result.name = Metainfo.valueOrException(infoDict['name'], "Torrent metainfo is missing the name property.")

  if infoDict.has_key? 'files'
    # This is a multi-file torrent
    infoDict['files'].each do |file|
      result.files.push FileInfo.createFromBdecode(file)
      result.files.last.path = result.name + File::SEPARATOR + result.files.last.path
    end
  else
    # This is a single-file torrent
    length = Metainfo.valueOrException(infoDict['length'], "Torrent metainfo listed a single file, but it is missing the length property.")
    result.files.push FileInfo.new(length, result.name)
  end

  result
end
new() click to toggle source
# File lib/quartz_torrent/metainfo.rb, line 51
def initialize
  @pieceLen = nil
  @pieces = nil
  @private = nil
  # Suggested file or directory name
  @name = nil
  # List of file info for files in the torrent. These include the directory name if this is a
  # multi-file download. For a single-file download the
  @files = []
  @logger = LogManager.getLogger("metainfo")
  @source = nil
end

Private Class Methods

parsePieces(p) click to toggle source

Parse the pieces of the torrent out of the metainfo.

# File lib/quartz_torrent/metainfo.rb, line 134
def self.parsePieces(p)
  # Break into 20-byte portions.
  if p.length % 20 != 0
    @logger.error "Torrent metainfo contained a pieces property that was not a multiple of 20 bytes long."
    raise "Invalid torrent metainfo"
  end

  result = []
  index = 0
  while index < p.length
    result.push p[index,20].unpack("a20")[0]
    index += 20
  end
  result
end

Public Instance Methods

bencode() click to toggle source

BEncode this info and return the result.

# File lib/quartz_torrent/metainfo.rb, line 107
def bencode
  hash = {}
    
  raise "Cannot encode Info object with nil pieceLen" if ! @pieceLen
  raise "Cannot encode Info object with nil name" if ! @name
  raise "Cannot encode Info object with nil pieces" if ! @pieces
  raise "Cannot encode Info object with nil files or empty files" if ! @files || @files.empty?

  hash['piece length'] = @pieceLen
  hash['private'] = @private if @private
  hash['source'] = @source if @source
  hash['name'] = @name
  hash['pieces'] = @pieces.join

  if @files.length > 1
    # This is a multi-file torrent
    # When we loaded the torrent, we prepended the 'name' element of the info hash to the path. We need to remove this
    # name element to end up with the same result.
    hash['files'] = @files.collect{ |file| {'length' => file.length, 'path' => file.path.split(File::SEPARATOR).drop(1) }  }
  else
    hash['length'] = @files.first.length
  end
  hash.bencode
end
dataLength() click to toggle source

Total length of the torrent data in bytes.

# File lib/quartz_torrent/metainfo.rb, line 78
def dataLength
  files.reduce(0){ |memo,f| memo + f.length}
end