lib/rocketamf/pure/deserializer.rb in mrpin-rocketamf-1.0.2 vs lib/rocketamf/pure/deserializer.rb in mrpin-rocketamf-1.0.3
- old
+ new
@@ -7,133 +7,139 @@
attr_accessor :source
# Pass in the class mapper instance to use when deserializing. This
# enables better caching behavior in the class mapper and allows
# one to change mappings between deserialization attempts.
- def initialize class_mapper
+ def initialize(class_mapper)
@class_mapper = class_mapper
end
# Deserialize the source using AMF0 or AMF3. Source should either
# be a string or StringIO object. If you pass a StringIO object,
# it will have its position updated to the end of the deserialized
# data.
- def deserialize version, source
- raise ArgumentError, "unsupported version #{version}" unless [0,3].include?(version)
+ def deserialize(version, source)
+ result = []
+
@version = version
- if StringIO === source
+ if source.is_a?(StringIO)
@source = source
elsif source
@source = StringIO.new(source)
elsif @source.nil?
- raise AMFError, "no source to deserialize"
+ raise AMFError, 'no source to deserialize'
end
- if @version == 0
- @ref_cache = []
- return amf0_deserialize
- else
- @string_cache = []
- @object_cache = []
- @trait_cache = []
- return amf3_deserialize
+ case @version
+ when 0
+ until @source.eof?
+ @ref_cache = []
+ result << amf0_deserialize
+ end
+ when 3
+ until @source.eof?
+ @string_cache = []
+ @object_cache = []
+ @trait_cache = []
+ result << amf3_deserialize
+ end
+ else
+ raise ArgumentError, "unsupported version #{version}"
end
+
+ result
end
# Reads an object from the deserializer's stream and returns it.
def read_object
- if @version == 0
- return amf0_deserialize
- else
- return amf3_deserialize
- end
+ @version == 0 ? amf0_deserialize : amf3_deserialize
end
private
include RocketAMF::Pure::ReadIOHelpers
- def amf0_deserialize type=nil
+ def amf0_deserialize(type = nil)
type = read_int8 @source unless type
case type
- when AMF0_NUMBER_MARKER
- amf0_read_number
- when AMF0_BOOLEAN_MARKER
- amf0_read_boolean
- when AMF0_STRING_MARKER
- amf0_read_string
- when AMF0_OBJECT_MARKER
- amf0_read_object
- when AMF0_NULL_MARKER
- nil
- when AMF0_UNDEFINED_MARKER
- nil
- when AMF0_REFERENCE_MARKER
- amf0_read_reference
- when AMF0_HASH_MARKER
- amf0_read_hash
- when AMF0_STRICT_ARRAY_MARKER
- amf0_read_array
- when AMF0_DATE_MARKER
- amf0_read_date
- when AMF0_LONG_STRING_MARKER
- amf0_read_string true
- when AMF0_UNSUPPORTED_MARKER
- nil
- when AMF0_XML_MARKER
- amf0_read_string true
- when AMF0_TYPED_OBJECT_MARKER
- amf0_read_typed_object
- when AMF0_AMF3_MARKER
- deserialize(3, nil)
- else
- raise AMFError, "Invalid type: #{type}"
+ when AMF0_NUMBER_MARKER
+ amf0_read_number
+ when AMF0_BOOLEAN_MARKER
+ amf0_read_boolean
+ when AMF0_STRING_MARKER
+ amf0_read_string
+ when AMF0_OBJECT_MARKER
+ amf0_read_object
+ when AMF0_NULL_MARKER
+ nil
+ when AMF0_UNDEFINED_MARKER
+ nil
+ when AMF0_REFERENCE_MARKER
+ amf0_read_reference
+ when AMF0_HASH_MARKER
+ amf0_read_hash
+ when AMF0_STRICT_ARRAY_MARKER
+ amf0_read_array
+ when AMF0_DATE_MARKER
+ amf0_read_date
+ when AMF0_LONG_STRING_MARKER
+ amf0_read_string true
+ when AMF0_UNSUPPORTED_MARKER
+ nil
+ when AMF0_XML_MARKER
+ amf0_read_string true
+ when AMF0_TYPED_OBJECT_MARKER
+ amf0_read_typed_object
+ when AMF0_AMF3_MARKER
+ deserialize(3, nil)
+ else
+ raise AMFError, "Invalid type: #{type}"
end
end
def amf0_read_number
- res = read_double @source
- (res.is_a?(Float) && res.nan?) ? nil : res # check for NaN and convert them to nil
+ result = read_double @source
+ (result.is_a?(Float) && result.nan?) ? nil : result # check for NaN and convert them to nil
end
def amf0_read_boolean
read_int8(@source) != 0
end
- def amf0_read_string long=false
- len = long ? read_word32_network(@source) : read_word16_network(@source)
- str = @source.read(len)
- str.force_encoding("UTF-8") if str.respond_to?(:force_encoding)
- str
+ def amf0_read_string(long=false)
+ len = long ? read_word32_network(@source) : read_word16_network(@source)
+ result = @source.read(len)
+ result.force_encoding('UTF-8') if result.respond_to?(:force_encoding)
+ result
end
def amf0_read_reference
index = read_word16_network(@source)
@ref_cache[index]
end
def amf0_read_array
- len = read_word32_network(@source)
- array = []
- @ref_cache << array
+ len = read_word32_network(@source)
+ result = []
+ @ref_cache << result
0.upto(len - 1) do
- array << amf0_deserialize
+ result << amf0_deserialize
end
- array
+ result
end
def amf0_read_date
seconds = read_double(@source).to_f/1000
- time = Time.at(seconds)
- tz = read_word16_network(@source) # Unused
+ time = Time.at(seconds)
+ tz = read_word16_network(@source) # Unused
time
end
- def amf0_read_props obj={}
+ def amf0_read_props(obj = {})
while true
- key = amf0_read_string
+ key = amf0_read_string
type = read_int8 @source
break if type == AMF0_OBJECT_END_MARKER
obj[key] = amf0_deserialize(type)
end
obj
@@ -158,11 +164,11 @@
end
def amf0_read_typed_object
# Create object to add to ref cache
class_name = amf0_read_string
- obj = @class_mapper.get_ruby_obj class_name
+ obj = @class_mapper.get_ruby_obj class_name
@ref_cache << obj
# Populate object
props = amf0_read_props
@class_mapper.populate_ruby_obj obj, props
@@ -170,65 +176,65 @@
end
def amf3_deserialize
type = read_int8 @source
case type
- when AMF3_UNDEFINED_MARKER
- nil
- when AMF3_NULL_MARKER
- nil
- when AMF3_FALSE_MARKER
- false
- when AMF3_TRUE_MARKER
- true
- when AMF3_INTEGER_MARKER
- amf3_read_integer
- when AMF3_DOUBLE_MARKER
- amf3_read_number
- when AMF3_STRING_MARKER
- amf3_read_string
- when AMF3_XML_DOC_MARKER, AMF3_XML_MARKER
- amf3_read_xml
- when AMF3_DATE_MARKER
- amf3_read_date
- when AMF3_ARRAY_MARKER
- amf3_read_array
- when AMF3_OBJECT_MARKER
- amf3_read_object
- when AMF3_BYTE_ARRAY_MARKER
- amf3_read_byte_array
- when AMF3_VECTOR_INT_MARKER, AMF3_VECTOR_UINT_MARKER, AMF3_VECTOR_DOUBLE_MARKER, AMF3_VECTOR_OBJECT_MARKER
- amf3_read_vector type
- when AMF3_DICT_MARKER
- amf3_read_dict
- else
- raise AMFError, "Invalid type: #{type}"
+ when AMF3_UNDEFINED_MARKER
+ nil
+ when AMF3_NULL_MARKER
+ nil
+ when AMF3_FALSE_MARKER
+ false
+ when AMF3_TRUE_MARKER
+ true
+ when AMF3_INTEGER_MARKER
+ amf3_read_integer
+ when AMF3_DOUBLE_MARKER
+ amf3_read_number
+ when AMF3_STRING_MARKER
+ amf3_read_string
+ when AMF3_XML_DOC_MARKER, AMF3_XML_MARKER
+ amf3_read_xml
+ when AMF3_DATE_MARKER
+ amf3_read_date
+ when AMF3_ARRAY_MARKER
+ amf3_read_array
+ when AMF3_OBJECT_MARKER
+ amf3_read_object
+ when AMF3_BYTE_ARRAY_MARKER
+ amf3_read_byte_array
+ when AMF3_VECTOR_INT_MARKER, AMF3_VECTOR_UINT_MARKER, AMF3_VECTOR_DOUBLE_MARKER, AMF3_VECTOR_OBJECT_MARKER
+ amf3_read_vector type
+ when AMF3_DICT_MARKER
+ amf3_read_dict
+ else
+ raise AMFError, "Invalid type: #{type}"
end
end
def amf3_read_integer
- n = 0
- b = read_word8(@source) || 0
+ n = 0
+ b = read_word8(@source) || 0
result = 0
while ((b & 0x80) != 0 && n < 3)
result = result << 7
result = result | (b & 0x7f)
- b = read_word8(@source) || 0
- n = n + 1
+ b = read_word8(@source) || 0
+ n = n + 1
end
- if (n < 3)
+ if n < 3
result = result << 7
result = result | b
else
#Use all 8 bits from the 4th byte
result = result << 8
result = result | b
#Check if the integer should be negative
- if (result > MAX_INTEGER)
+ if result > MAX_INTEGER
result -= (1 << 29)
end
end
result
end
@@ -237,115 +243,120 @@
res = read_double @source
(res.is_a?(Float) && res.nan?) ? nil : res # check for NaN and convert them to nil
end
def amf3_read_string
- type = amf3_read_integer
+ type = amf3_read_integer
is_reference = (type & 0x01) == 0
if is_reference
reference = type >> 1
return @string_cache[reference]
else
length = type >> 1
- str = ""
+ str = ''
if length > 0
str = @source.read(length)
- str.force_encoding("UTF-8") if str.respond_to?(:force_encoding)
+ str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
@string_cache << str
end
return str
end
end
def amf3_read_xml
- type = amf3_read_integer
+ result = nil
+
+ type = amf3_read_integer
is_reference = (type & 0x01) == 0
if is_reference
reference = type >> 1
- return @object_cache[reference]
+ result = @object_cache[reference]
else
length = type >> 1
- str = ""
+ str = ""
if length > 0
str = @source.read(length)
str.force_encoding("UTF-8") if str.respond_to?(:force_encoding)
@object_cache << str
end
- return str
+ result = str
end
+
+ result
end
def amf3_read_byte_array
- type = amf3_read_integer
+ type = amf3_read_integer
is_reference = (type & 0x01) == 0
if is_reference
reference = type >> 1
return @object_cache[reference]
else
length = type >> 1
- obj = StringIO.new @source.read(length)
+ obj = StringIO.new @source.read(length)
@object_cache << obj
obj
end
end
def amf3_read_array
- type = amf3_read_integer
+ type = amf3_read_integer
is_reference = (type & 0x01) == 0
if is_reference
reference = type >> 1
return @object_cache[reference]
else
- length = type >> 1
+ length = type >> 1
property_name = amf3_read_string
- array = property_name.length > 0 ? {} : []
+ array = property_name.length > 0 ? {} : []
@object_cache << array
while property_name.length > 0
- value = amf3_deserialize
+ value = amf3_deserialize
array[property_name] = value
- property_name = amf3_read_string
+ property_name = amf3_read_string
end
- 0.upto(length - 1) {|i| array[i] = amf3_deserialize }
+ 0.upto(length - 1) { |i| array[i] = amf3_deserialize }
array
end
end
def amf3_read_object
- type = amf3_read_integer
+ type = amf3_read_integer
is_reference = (type & 0x01) == 0
if is_reference
reference = type >> 1
return @object_cache[reference]
else
- class_type = type >> 1
+ class_type = type >> 1
class_is_reference = (class_type & 0x01) == 0
if class_is_reference
reference = class_type >> 1
- traits = @trait_cache[reference]
+ traits = @trait_cache[reference]
else
- externalizable = (class_type & 0x02) != 0
- dynamic = (class_type & 0x04) != 0
+ externalizable = (class_type & 0x02) != 0
+ dynamic = (class_type & 0x04) != 0
attribute_count = class_type >> 3
- class_name = amf3_read_string
+ class_name = amf3_read_string
class_attributes = []
- attribute_count.times{class_attributes << amf3_read_string} # Read class members
+ attribute_count.times { class_attributes << amf3_read_string } # Read class members
- traits = {
- :class_name => class_name,
- :members => class_attributes,
- :externalizable => externalizable,
- :dynamic => dynamic
- }
+ traits =
+ {
+ class_name: class_name,
+ members: class_attributes,
+ externalizable: externalizable,
+ dynamic: dynamic
+ }
@trait_cache << traits
end
# Optimization for deserializing ArrayCollection
if traits[:class_name] == "flex.messaging.io.ArrayCollection"
@@ -360,19 +371,19 @@
if traits[:externalizable]
obj.read_external self
else
props = {}
traits[:members].each do |key|
- value = amf3_deserialize
+ value = amf3_deserialize
props[key] = value
end
dynamic_props = nil
if traits[:dynamic]
dynamic_props = {}
- while (key = amf3_read_string) && key.length != 0 do # read next key
- value = amf3_deserialize
+ while (key = amf3_read_string) && key.length != 0 do # read next key
+ value = amf3_deserialize
dynamic_props[key] = value
end
end
@class_mapper.populate_ruby_obj obj, props, dynamic_props
@@ -380,73 +391,73 @@
obj
end
end
def amf3_read_date
- type = amf3_read_integer
+ type = amf3_read_integer
is_reference = (type & 0x01) == 0
if is_reference
reference = type >> 1
return @object_cache[reference]
else
seconds = read_double(@source).to_f/1000
- time = Time.at(seconds)
+ time = Time.at(seconds)
@object_cache << time
time
end
end
def amf3_read_dict
- type = amf3_read_integer
+ type = amf3_read_integer
is_reference = (type & 0x01) == 0
if is_reference
reference = type >> 1
return @object_cache[reference]
else
dict = {}
@object_cache << dict
- length = type >> 1
+ length = type >> 1
weak_keys = read_int8 @source # Ignore: Not supported in ruby
0.upto(length - 1) do |i|
dict[amf3_deserialize] = amf3_deserialize
end
dict
end
end
def amf3_read_vector vector_type
- type = amf3_read_integer
+ type = amf3_read_integer
is_reference = (type & 0x01) == 0
if is_reference
reference = type >> 1
return @object_cache[reference]
else
vec = []
@object_cache << vec
- length = type >> 1
+ length = type >> 1
fixed_vector = read_int8 @source # Ignore
case vector_type
- when AMF3_VECTOR_INT_MARKER
- 0.upto(length - 1) do |i|
- int = read_word32_network(@source)
- int = int - 2**32 if int > MAX_INTEGER
- vec << int
- end
- when AMF3_VECTOR_UINT_MARKER
- 0.upto(length - 1) do |i|
- vec << read_word32_network(@source)
- puts vec[i].to_s(2)
- end
- when AMF3_VECTOR_DOUBLE_MARKER
- 0.upto(length - 1) do |i|
- vec << amf3_read_number
- end
- when AMF3_VECTOR_OBJECT_MARKER
- vector_class = amf3_read_string # Ignore
- puts vector_class
- 0.upto(length - 1) do |i|
- vec << amf3_deserialize
- end
+ when AMF3_VECTOR_INT_MARKER
+ 0.upto(length - 1) do |i|
+ int = read_word32_network(@source)
+ int = int - 2**32 if int > MAX_INTEGER
+ vec << int
+ end
+ when AMF3_VECTOR_UINT_MARKER
+ 0.upto(length - 1) do |i|
+ vec << read_word32_network(@source)
+ puts vec[i].to_s(2)
+ end
+ when AMF3_VECTOR_DOUBLE_MARKER
+ 0.upto(length - 1) do |i|
+ vec << amf3_read_number
+ end
+ when AMF3_VECTOR_OBJECT_MARKER
+ vector_class = amf3_read_string # Ignore
+ puts vector_class
+ 0.upto(length - 1) do |i|
+ vec << amf3_deserialize
+ end
end
vec
end
end
end
\ No newline at end of file