impress/vendor/gems/RocketAMF-1.0.0/lib/rocketamf/pure/remoting.rb

117 lines
3.9 KiB
Ruby
Raw Permalink Normal View History

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