Class: QuartzTorrent::ExtendedMetaInfo
- Inherits:
-
Extended
- Object
- PeerWireMessage
- Extended
- QuartzTorrent::ExtendedMetaInfo
- Defined in:
- lib/quartz_torrent/peermsg.rb
Overview
An Extended Metainfo message. Used to request metadata pieces, or provide responses to those requests.
Constant Summary
Constants inherited from PeerWireMessage
PeerWireMessage::MessageBitfield, PeerWireMessage::MessageCancel, PeerWireMessage::MessageChoke, PeerWireMessage::MessageExtended, PeerWireMessage::MessageHave, PeerWireMessage::MessageInterested, PeerWireMessage::MessageKeepAlive, PeerWireMessage::MessagePiece, PeerWireMessage::MessageRequest, PeerWireMessage::MessageUnchoke, PeerWireMessage::MessageUninterested
Instance Attribute Summary collapse
-
#data ⇒ Object
This field is only set if the msgType is :piece.
-
#dict ⇒ Object
Returns the value of attribute dict.
-
#msgType ⇒ Object
Message type as a symbol.
-
#piece ⇒ Object
Returns the value of attribute piece.
-
#totalSize ⇒ Object
This field is only set if the msgType is :piece.
Attributes inherited from Extended
Attributes inherited from PeerWireMessage
Instance Method Summary collapse
-
#initialize ⇒ ExtendedMetaInfo
constructor
A new instance of ExtendedMetaInfo.
- #serializeTo(io) ⇒ Object
- #unserialize(payload) ⇒ Object
Methods inherited from Extended
Methods inherited from PeerWireMessage
#length, #payloadLength, #to_s
Constructor Details
#initialize ⇒ ExtendedMetaInfo
Returns a new instance of ExtendedMetaInfo.
407 408 409 410 411 412 413 414 415 |
# File 'lib/quartz_torrent/peermsg.rb', line 407 def initialize super() @extendedMessageId = 0 @msgType = nil @piece = nil @totalSize = nil @data = nil @dict = {} end |
Instance Attribute Details
#data ⇒ Object
This field is only set if the msgType is :piece. It contains the data for the piece.
424 425 426 |
# File 'lib/quartz_torrent/peermsg.rb', line 424 def data @data end |
#dict ⇒ Object
Returns the value of attribute dict.
417 418 419 |
# File 'lib/quartz_torrent/peermsg.rb', line 417 def dict @dict end |
#msgType ⇒ Object
Message type as a symbol. One of :request, :data, or :reject
419 420 421 |
# File 'lib/quartz_torrent/peermsg.rb', line 419 def msgType @msgType end |
#piece ⇒ Object
Returns the value of attribute piece.
420 421 422 |
# File 'lib/quartz_torrent/peermsg.rb', line 420 def piece @piece end |
#totalSize ⇒ Object
This field is only set if the msgType is :piece
422 423 424 |
# File 'lib/quartz_torrent/peermsg.rb', line 422 def totalSize @totalSize end |
Instance Method Details
#serializeTo(io) ⇒ Object
470 471 472 473 474 475 476 |
# File 'lib/quartz_torrent/peermsg.rb', line 470 def serializeTo(io) super(io) updateDictFromProps io.write @dict.bencode raise "Extended metainfo piece messages must have piece data. This one's data was nil" if ! @data && dict['msg_type'] == 1 io.write @data if dict['msg_type'] == 1 end |
#unserialize(payload) ⇒ Object
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 |
# File 'lib/quartz_torrent/peermsg.rb', line 426 def unserialize(payload) # Unserialize extended message id super(payload) # Rest of the message is a bencoded dictionary. # Piece messages of this class are encoded in an interesting way: the bencoded dictionary # is concatenated with the arbitrary binary data of the piece at the end. To decode this # we need to know the position of when we've finished reading the dictionary. We do this by # using a Parser object from the bencode library which maintains a stream object which happens # to know the current offset of the parsing. payload = payload[1,payload.length] parser = BEncode::Parser.new payload begin @dict = parser.parse! rescue e = RuntimeError.new("Error bdecoding payload '#{payload}' (payload length = #{payload.length})") e.set_backtrace($!.backtrace) raise e end @msgType = @dict['msg_type'] raise "Extended Metainfo message contained no 'msg_type' key." if ! @msgType if @msgType == 0 @msgType = :request elsif @msgType == 1 @msgType = :piece elsif @msgType == 2 @msgType = :reject else raise "Unknown message type '#{@msgType}' in Extended Metainfo message" end @piece = @dict['piece'] raise "Extended Metainfo message contained no 'piece' key." if ! @piece @totalSize = @dict['total_size'] if @msgType == :piece # If this is a piece message, read the data after the dictionary. @data = parser.stream.read if @msgType == :piece end |