I found such code in: https://github.com/mojombo/proxymachine/
proxy do |data|
return if data.size < 9
v, c, port, o1, o2, o3, o4, user = data.unpack("CCnC4a*")
return { :close => "\0\x5b\0\0\0\0\0\0" } if v != 4 or c != 1
return if ! idx = user.index("\0")
{ :remote => "#{[o1,o2,o3,o4]*'.'}:#{port}",
:reply => "\0\x5a\0\0\0\0\0\0",
:data => data[idx+9..-1] }
end
What does this code do? Especially these lines:
data.unpack("CCnC4a*")
return { :close => "\0\x5b\0\0\0\0\0\0" } if v != 4 or c != 1
:reply => "\0\x5a\0\0\0\0\0\0",
:data => data[idx+9..-1] }
I am not asking for ruby idioms, but for the functional side.
Assuming data
is a String, the unpack
method is defined in String#unpack
.
v, c, port, o1, o2, o3, o4, user = data.unpack("CCnC4a*")
This converts a String (throug reading the bytes, not interpreting the string as a text) into an array following these rules:
C
: read 8-bit as an unsigned charC
: read 8-bit as an unsigned charn
: read 16-bit unsigned integer (in big-endian format)C4
: read 8-bit as an unsigned char (4 times)a*
: read all the remaining bytes as an arbitrary stringSo we get an array containing 8 entries (7 integers, one string). Each of those entries in the array is assigned to the variables v
, c
, port
, o1
, o2
, o3
, o4
, user
.
return { :close => "\0\x5b\0\0\0\0\0\0" } if v != 4 or c != 1
When v
is not 4
and c
is not 1
, return the hash { :close => "\0\x5b\0\0\0\0\0\0" }
.
A method returns the result of its last statement. The last statement of your method is
{ :remote => "#{[o1,o2,o3,o4]*'.'}:#{port}",
:reply => "\0\x5a\0\0\0\0\0\0",
:data => data[idx+9..-1] }
It is a hash containing three keys (:remote
, :reply
, :data
). In an earlier statement we assigned idx
so that it contains the position of the first null-byte ("\0"
) in the data
string.
data[idx+9..-1]
returns the part of the data
string beginning at 9 bytes after the first null-byte until the end of the string.