Class: RubyTorrent::Message

Inherits:
Object show all
Defined in:
lib/rubytorrent/message.rb

Constant Summary collapse

WIRE_IDS =
[:choke, :unchoke, :interested, :uninterested, :have, :bitfield,
:request, :piece, :cancel]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id, args = nil) ⇒ Message

Returns a new instance of Message.



55
56
57
58
# File 'lib/rubytorrent/message.rb', line 55

def initialize(id, args=nil)
  @id = id
  @args = args
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth) ⇒ Object



60
61
62
63
64
65
66
# File 'lib/rubytorrent/message.rb', line 60

def method_missing(meth)
  if @args.has_key? meth
    @args[meth]
  else
    raise %{no such argument "#{meth}" to message #{self.to_s}}
  end
end

Instance Attribute Details

#idObject

Returns the value of attribute id.



53
54
55
# File 'lib/rubytorrent/message.rb', line 53

def id
  @id
end

Class Method Details

.from_wire_form(idnum, argstr) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/rubytorrent/message.rb', line 89

def self.from_wire_form(idnum, argstr)
  type = WIRE_IDS[idnum]

  case type
  when :choke, :unchoke, :interested, :uninterested
    raise ProtocolError, "invalid length #{argstr.length} for #{type} message" unless argstr.nil? or (argstr.length == 0)
    Message.new(type)

  when :have
    raise ProtocolError, "invalid length #{str.length} for #{type} message" unless argstr.length == 4
    Message.new(type, {:index => argstr[0,4].from_fbbe})
    
  when :bitfield
    Message.new(type, {:bitfield => argstr})

  when :request, :cancel
    raise ProtocolError, "invalid length #{argstr.length} for #{type} message" unless argstr.length == 12
    Message.new(type, {:index => argstr[0,4].from_fbbe,
                       :begin => argstr[4,4].from_fbbe,
                       :length => argstr[8,4].from_fbbe})
  when :piece
    raise ProtocolError, "invalid length #{argstr.length} for #{type} message" unless argstr.length == 8
    Message.new(type, {:index => argstr[0,4].from_fbbe,
                       :begin => argstr[4,4].from_fbbe})
  else
    raise "unknown message #{type.inspect}"
  end
end

Instance Method Details

#to_sObject



118
119
120
121
122
123
124
125
# File 'lib/rubytorrent/message.rb', line 118

def to_s
  case @id
  when :bitfield
    %{bitfield <#{@args[:bitfield].extend(StringExpandBits).expand_bits}>}
  else
    %{#@id#{@args.nil? ? "" : "(" + @args.map { |k, v| "#{k}=#{v.to_s.inspect}" }.join(", ") + ")"}}
  end
end

#to_wire_formObject



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/rubytorrent/message.rb', line 68

def to_wire_form
  case @id
  when :keepalive
    0.to_fbbe
  when :choke, :unchoke, :interested, :uninterested
    1.to_fbbe + WIRE_IDS.index(@id).chr
  when :have
    5.to_fbbe + 4.chr + @args[:index].to_fbbe
  when :bitfield
    (@args[:bitfield].length + 1).to_fbbe + 5.chr + @args[:bitfield]
  when :request, :cancel
    13.to_fbbe + WIRE_IDS.index(@id).chr + @args[:index].to_fbbe +
      @args[:begin].to_fbbe + @args[:length].to_fbbe
  when :piece
    (@args[:length] + 9).to_fbbe + 7.chr + @args[:index].to_fbbe +
      @args[:begin].to_fbbe
  else
    raise "unknown message type #{id}"
  end
end