117 lines
3.9 KiB
Ruby
117 lines
3.9 KiB
Ruby
|
|
require 'rocketamf/pure/io_helpers'
|
||
|
|
|
||
|
|
module RocketAMF
|
||
|
|
module Pure
|
||
|
|
# Included into RocketAMF::Envelope, this module replaces the
|
||
|
|
# populate_from_stream and serialize methods with actual working versions
|
||
|
|
module Envelope
|
||
|
|
# Included into RocketAMF::Envelope, this method handles deserializing an
|
||
|
|
# AMF request/response into the envelope
|
||
|
|
def populate_from_stream stream, class_mapper=nil
|
||
|
|
stream = StringIO.new(stream) unless StringIO === stream
|
||
|
|
des = Deserializer.new(class_mapper || RocketAMF::ClassMapper.new)
|
||
|
|
des.source = stream
|
||
|
|
|
||
|
|
# Initialize
|
||
|
|
@amf_version = 0
|
||
|
|
@headers = {}
|
||
|
|
@messages = []
|
||
|
|
|
||
|
|
# Read AMF version
|
||
|
|
@amf_version = read_word16_network stream
|
||
|
|
|
||
|
|
# Read in headers
|
||
|
|
header_count = read_word16_network stream
|
||
|
|
0.upto(header_count-1) do
|
||
|
|
name = stream.read(read_word16_network(stream))
|
||
|
|
name.force_encoding("UTF-8") if name.respond_to?(:force_encoding)
|
||
|
|
|
||
|
|
must_understand = read_int8(stream) != 0
|
||
|
|
|
||
|
|
length = read_word32_network stream
|
||
|
|
data = des.deserialize(0, nil)
|
||
|
|
|
||
|
|
@headers[name] = RocketAMF::Header.new(name, must_understand, data)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Read in messages
|
||
|
|
message_count = read_word16_network stream
|
||
|
|
0.upto(message_count-1) do
|
||
|
|
target_uri = stream.read(read_word16_network(stream))
|
||
|
|
target_uri.force_encoding("UTF-8") if target_uri.respond_to?(:force_encoding)
|
||
|
|
|
||
|
|
response_uri = stream.read(read_word16_network(stream))
|
||
|
|
response_uri.force_encoding("UTF-8") if response_uri.respond_to?(:force_encoding)
|
||
|
|
|
||
|
|
length = read_word32_network stream
|
||
|
|
data = des.deserialize(0, nil)
|
||
|
|
if data.is_a?(Array) && data.length == 1 && data[0].is_a?(::RocketAMF::Values::AbstractMessage)
|
||
|
|
data = data[0]
|
||
|
|
end
|
||
|
|
|
||
|
|
@messages << RocketAMF::Message.new(target_uri, response_uri, data)
|
||
|
|
end
|
||
|
|
|
||
|
|
self
|
||
|
|
end
|
||
|
|
|
||
|
|
# Included into RocketAMF::Envelope, this method handles serializing an
|
||
|
|
# AMF request/response into a string
|
||
|
|
def serialize class_mapper=nil
|
||
|
|
ser = Serializer.new(class_mapper || RocketAMF::ClassMapper.new)
|
||
|
|
stream = ser.stream
|
||
|
|
|
||
|
|
# Write version
|
||
|
|
stream << pack_int16_network(@amf_version)
|
||
|
|
|
||
|
|
# Write headers
|
||
|
|
stream << pack_int16_network(@headers.length) # Header count
|
||
|
|
@headers.each_value do |h|
|
||
|
|
# Write header name
|
||
|
|
name_str = h.name
|
||
|
|
name_str.encode!("UTF-8").force_encoding("ASCII-8BIT") if name_str.respond_to?(:encode)
|
||
|
|
stream << pack_int16_network(name_str.bytesize)
|
||
|
|
stream << name_str
|
||
|
|
|
||
|
|
# Write must understand flag
|
||
|
|
stream << pack_int8(h.must_understand ? 1 : 0)
|
||
|
|
|
||
|
|
# Serialize data
|
||
|
|
stream << pack_word32_network(-1) # length of data - -1 if you don't know
|
||
|
|
ser.serialize(0, h.data)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Write messages
|
||
|
|
stream << pack_int16_network(@messages.length) # Message count
|
||
|
|
@messages.each do |m|
|
||
|
|
# Write target_uri
|
||
|
|
uri_str = m.target_uri
|
||
|
|
uri_str.encode!("UTF-8").force_encoding("ASCII-8BIT") if uri_str.respond_to?(:encode)
|
||
|
|
stream << pack_int16_network(uri_str.bytesize)
|
||
|
|
stream << uri_str
|
||
|
|
|
||
|
|
# Write response_uri
|
||
|
|
uri_str = m.response_uri
|
||
|
|
uri_str.encode!("UTF-8").force_encoding("ASCII-8BIT") if uri_str.respond_to?(:encode)
|
||
|
|
stream << pack_int16_network(uri_str.bytesize)
|
||
|
|
stream << uri_str
|
||
|
|
|
||
|
|
# Serialize data
|
||
|
|
stream << pack_word32_network(-1) # length of data - -1 if you don't know
|
||
|
|
if @amf_version == 3
|
||
|
|
stream << AMF0_AMF3_MARKER
|
||
|
|
ser.serialize(3, m.data)
|
||
|
|
else
|
||
|
|
ser.serialize(0, m.data)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
stream
|
||
|
|
end
|
||
|
|
|
||
|
|
private
|
||
|
|
include RocketAMF::Pure::ReadIOHelpers
|
||
|
|
include RocketAMF::Pure::WriteIOHelpers
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|