neerfri-ramf 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. data/LICENSE +166 -0
  2. data/README +3 -0
  3. data/Rakefile +17 -0
  4. data/lib/ramf/amf_header.rb +9 -0
  5. data/lib/ramf/amf_message.rb +26 -0
  6. data/lib/ramf/amf_object.rb +54 -0
  7. data/lib/ramf/configuration.rb +8 -0
  8. data/lib/ramf/default_operation_processor.rb +20 -0
  9. data/lib/ramf/deserializer/amf0_reader.rb +61 -0
  10. data/lib/ramf/deserializer/amf3_reader.rb +242 -0
  11. data/lib/ramf/deserializer/base.rb +76 -0
  12. data/lib/ramf/deserializer.rb +9 -0
  13. data/lib/ramf/extensions/class.rb +139 -0
  14. data/lib/ramf/extensions/exception.rb +3 -0
  15. data/lib/ramf/extensions/hash.rb +8 -0
  16. data/lib/ramf/extensions/object.rb +44 -0
  17. data/lib/ramf/flex_class_traits.rb +98 -0
  18. data/lib/ramf/flex_objects/acknowledge_message.rb +31 -0
  19. data/lib/ramf/flex_objects/byte_array.rb +9 -0
  20. data/lib/ramf/flex_objects/command_message.rb +86 -0
  21. data/lib/ramf/flex_objects/error_message.rb +14 -0
  22. data/lib/ramf/flex_objects/flex_anonymous_object.rb +37 -0
  23. data/lib/ramf/flex_objects/flex_object.rb +13 -0
  24. data/lib/ramf/flex_objects/remoting_message.rb +26 -0
  25. data/lib/ramf/io/common_read_write.rb +73 -0
  26. data/lib/ramf/io/constants.rb +79 -0
  27. data/lib/ramf/io/flex_class_signature.rb +16 -0
  28. data/lib/ramf/io/place_holder.rb +8 -0
  29. data/lib/ramf/io/reference_table.rb +74 -0
  30. data/lib/ramf/operation_processors_manager.rb +30 -0
  31. data/lib/ramf/operation_request.rb +51 -0
  32. data/lib/ramf/serializer/amf0_writer.rb +89 -0
  33. data/lib/ramf/serializer/amf3_writer.rb +193 -0
  34. data/lib/ramf/serializer/base.rb +57 -0
  35. data/lib/ramf/serializer.rb +9 -0
  36. data/lib/ramf/util.rb +34 -0
  37. data/lib/ramf.rb +62 -0
  38. data/spec/amf_object_spec.rb +85 -0
  39. data/spec/deserializer_spec.rb +22 -0
  40. data/spec/examples/examples_helper.rb +75 -0
  41. data/spec/examples/remoting_login_spec.rb +53 -0
  42. data/spec/examples/simple_amf_spec.rb +55 -0
  43. data/spec/examples/simple_remoting_spec.rb +60 -0
  44. data/spec/extensions/class_extensions_spec.rb +62 -0
  45. data/spec/fixtures/catalog.yml +5 -0
  46. data/spec/fixtures/deserializer1.bin +0 -0
  47. data/spec/fixtures/deserializer1.rb +31 -0
  48. data/spec/fixtures/deserializer2.bin +0 -0
  49. data/spec/fixtures/deserializer2.rb +40 -0
  50. data/spec/fixtures/deserializer3.bin +0 -0
  51. data/spec/fixtures/ping_command_message.amf +0 -0
  52. data/spec/fixtures/remoting_login_operation.amf +0 -0
  53. data/spec/fixtures/simple_remoting_message.amf +0 -0
  54. data/spec/flex_class_traits_spec.rb +52 -0
  55. data/spec/inherited_class_traits_spec.rb +58 -0
  56. data/spec/io/reference_table_spec.rb +38 -0
  57. data/spec/operation_processors_manager_spec.rb +61 -0
  58. data/spec/serializer/amf3_writer_spec.rb +565 -0
  59. data/spec/serializer/base_spec.rb +92 -0
  60. data/spec/serializer/full_spec.rb +172 -0
  61. data/spec/spec_helper.rb +28 -0
  62. metadata +153 -0
@@ -0,0 +1,9 @@
1
+
2
+ require 'ramf/deserializer/base'
3
+ require 'ramf/deserializer/amf0_reader'
4
+ require 'ramf/deserializer/amf3_reader'
5
+
6
+ module RAMF
7
+ module Deserializer
8
+ end
9
+ end
@@ -0,0 +1,139 @@
1
+ class Class
2
+
3
+ #returns the FlexClassTraits object of the class,
4
+ #if it doesn't exist, it will create one.
5
+ #
6
+ # class Car
7
+ # @@my_flex_remoting = flex_remoting
8
+ # #Why would you be doing that ???
9
+ # end
10
+ def flex_remoting
11
+ @flex_remoting ||= RAMF::FlexClassTraits.new(self, true, :transient=>[:flex_remoting])
12
+ end
13
+
14
+ #This method defines members that are transient, which means
15
+ #they will not be sent by amf, and will be ignored if received from amf.
16
+ #For Exmple:
17
+ # class User
18
+ # flex_remoting_transient :encrypted_password, :encription_salt
19
+ # end
20
+ #this will define <tt>:encrypted_password, :encription_salt</tt> not
21
+ #to be sent over amf.
22
+ #Make sure they are not important to represent the object when it comes from amf.
23
+ def flex_remoting_transient(*args)
24
+ flex_remoting.transient_members += args.map {|v| v.to_sym}
25
+ end
26
+
27
+ #defines members for a specific scope.
28
+ #For exmple:
29
+ # class User
30
+ # flex_remoting_scope :limited, :except=>[:phone,:email]
31
+ # flex_remoting_scope :private, :only=>[:fullname, :nickname]
32
+ # end
33
+ #this will set :phone and :email attributes not to be sent
34
+ #when using <tt> render :amf=>@user, :scope=>:limited </tt>.
35
+ #
36
+ #it will also set only :fullname and :nickname to be sent when
37
+ #using <tt> render :amf=>@user_list, :scope=>:private </tt>
38
+ #
39
+ #Each scope can only be set with either :except or :only, not both.
40
+ def flex_remoting_scope(scope, options)
41
+ raise "only & except" if options[:only] && options[:except]
42
+ flex_remoting.amf_scope_options[scope] = options
43
+ end
44
+
45
+ #define the action script name of the class (or what they set
46
+ #in RemoteAlias('') )
47
+ # class SomeRubyClass
48
+ # flex_alias_name :SomeActionScriptClass
49
+ # end
50
+ #this will make the client side(flex) receive a class
51
+ #named SomeActionScriptClass
52
+ def flex_alias(class_name)
53
+ flex_remoting.name = class_name.to_s
54
+ end
55
+
56
+ #This method defines members that are fixed with the object, which means
57
+ #they will use to define the class's signature during serialization.
58
+ #For Exmple:
59
+ # class User
60
+ # flex_remoting_members :great_attribute, :important_attribute
61
+ # end
62
+ #this will define <tt>:great_attribute, :important_attribute</tt> to
63
+ #always be sent over amf.
64
+ #
65
+ #Note that some classes can use other mechanisms to find sealed members,
66
+ #this is the most simple way to do so.
67
+
68
+ def flex_remoting_members(*members)
69
+ flex_remoting.defined_members = members
70
+ end
71
+
72
+ #Defines dynamic members finder block.
73
+ #The block should return an array of symbols or nil(for empty array)
74
+ #each symbol in the array will represent a dynamic member to be serialized
75
+ #For example:
76
+ # class User
77
+ # flex_dynamic_members_finder do |instance, scope|
78
+ # instance.instance_variable_get("@dynamic") ? [:dynamic] : []
79
+ # end
80
+ # end
81
+ #this will add :dynamic to the list of dynamic members if an instance variable named @dynamic exists.
82
+ def flex_dynamic_members_finder(&block)
83
+ flex_remoting.dynamic_members_finders.push(block)
84
+ end
85
+
86
+ #defines a callback to set the value of the object's members.
87
+ #For example:
88
+ # class User
89
+ # attr_accessor :my_other_data #this is a hash...
90
+ # flex_members_reader do |obj, member, value|
91
+ # obj.my_other_data.has_key?(member) ? obj.my_other_data[member]=value : obj.send(member.to_s+"=",value)
92
+ # end
93
+ # end
94
+ #if the hash <tt>my_other_data</tt> has key <tt>member</tt> insert the value to the hash,
95
+ #otherwise use a setter method
96
+ def flex_members_writer(&block)
97
+ flex_remoting.members_writer = block
98
+ end
99
+
100
+ #defines a callback to set the value of the object's dynamic members.
101
+ #For example:
102
+ # class User
103
+ # attr_accessor :my_dynamic_members #this is a hash...
104
+ # flex_dynamic_members_reader do |obj, member, value|
105
+ # obj.my_dynamic_members[member] = value
106
+ # end
107
+ # end
108
+ #this will set all dynamic members to the hash <tt>my_dynamic_members</tt>
109
+ def flex_dynamic_members_writer(&block)
110
+ flex_remoting.dynamic_members_writer = block
111
+ end
112
+
113
+ #defines a callback to get the value of the object's members.
114
+ #For example:
115
+ # class User
116
+ # attr_accessor :my_other_data #this is a hash...
117
+ # flex_members_reader do |obj, member|
118
+ # obj.my_other_data.has_key?(member) ? obj.my_other_data[member] : obj.send(member)
119
+ # end
120
+ # end
121
+ #if the hash <tt>my_other_data</tt> has key <tt>member</tt> get it from the hash,
122
+ #otherwise get it from calling the appropriate method
123
+ def flex_members_reader(&block)
124
+ flex_remoting.members_reader = block
125
+ end
126
+
127
+ #defines a callback to get the value of the object's dynamic members.
128
+ #For example:
129
+ # class User
130
+ # attr_accessor :my_dynamic_members #this is a hash...
131
+ # flex_dynamic_members_reader do |obj, member|
132
+ # obj.my_dynamic_members[member]
133
+ # end
134
+ # end
135
+ #this will get all dynamic members from the hash <tt>my_dynamic_members</tt>
136
+ def flex_dynamic_members_reader(&block)
137
+ flex_remoting.dynamic_members_reader = block
138
+ end
139
+ end
@@ -0,0 +1,3 @@
1
+ class Exception
2
+ flex_remoting_members :message, :backtrace
3
+ end
@@ -0,0 +1,8 @@
1
+ class Hash
2
+
3
+ flex_remoting.instance_variable_set("@name","")
4
+
5
+ flex_dynamic_members_finder do |instance, scope|
6
+ instance.keys
7
+ end
8
+ end
@@ -0,0 +1,44 @@
1
+ class Object
2
+
3
+ flex_dynamic_members_finder do |instance, scope|
4
+ instance.instance_variables.map{|v| v[1..-1].to_sym}
5
+ end
6
+
7
+ flex_members_reader do |instance, member|
8
+ instance.send(member)
9
+ end
10
+
11
+ flex_members_writer do |obj, key, value|
12
+ obj.respond_to?("#{key}=") ? obj.send("#{key}=",value) : obj.instance_variable_set("@#{key}",value)
13
+ end
14
+
15
+ flex_dynamic_members_reader do |instance, member|
16
+ case
17
+ when instance.respond_to?(member)
18
+ instance.send(member)
19
+ when instance.instance_variable_defined?("@#{member}")
20
+ instance.instance_variable_get("@#{member}")
21
+ when instance.respond_to?(:[])
22
+ instance[member]
23
+ else
24
+ begin
25
+ instance.send(member)
26
+ rescue NoMethodError=>e
27
+ warn("***Warning: Couldn't find value from dynamic member #{member} in object #{instance.class.name}!")
28
+ nil
29
+ end
30
+ end
31
+ end
32
+
33
+ flex_dynamic_members_writer do |instance, member, value|
34
+ instance.send("#{member}=", value)
35
+ end
36
+
37
+ unless defined?(returning)
38
+ def returning(value)
39
+ yield(value)
40
+ value
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,98 @@
1
+ require 'rubygems'
2
+ module RAMF
3
+ #The term 'traits' is used to describe the defining characteristics of a class. (amf3 spec document section 3.12)
4
+ class FlexClassTraits
5
+
6
+ KNOWN_CLASSES = {}
7
+
8
+ def self.find_ruby_class(name)
9
+ # RAILS_DEFAULT_LOGGER.info "name: #{name.to_s.inspect}"
10
+ # RAILS_DEFAULT_LOGGER.info "KNOWN_CLASSES[name]:#{KNOWN_CLASSES[name.to_s].inspect}"
11
+ # RAILS_DEFAULT_LOGGER.info "KNOWN_CLASSES:\n#{KNOWN_CLASSES.inspect}"
12
+ Object.module_eval(KNOWN_CLASSES[name.to_s]) rescue nil
13
+ end
14
+
15
+ attr_reader :klass, :members, :name
16
+ attr_accessor :transient_members, :amf_scope_options, :is_dynamic
17
+ attr_accessor :dynamic_members_writer, :members_writer
18
+ attr_accessor :dynamic_members_reader, :members_reader
19
+
20
+ def initialize(klass,is_dynamic, options = {})
21
+ @klass = klass
22
+ @amf_scope_options = get_duplicate_from_super({}, :amf_scope_options)
23
+ @members = {}
24
+ self.name= klass.name
25
+ @is_dynamic = is_dynamic
26
+ @defined_members = []
27
+ @transient_members = options[:transient] || []
28
+ [:dynamic_members_writer, :members_writer, :dynamic_members_reader, :members_reader].each do |a|
29
+ default = Proc.new{raise "No #{a} defined for #{klass}"}
30
+ instance_variable_set("@#{a}", get_attribute_from_super(default, a))
31
+ end
32
+ end
33
+
34
+ def name=(new_name)
35
+ new_name = new_name.to_s
36
+ if KNOWN_CLASSES[new_name] && KNOWN_CLASSES[new_name]!=klass.name
37
+ raise("An ActionScript class named '#{new_name}' already exists.")
38
+ end
39
+ KNOWN_CLASSES.delete(@name)
40
+ @name = new_name
41
+ KNOWN_CLASSES[new_name] = klass.name
42
+ end
43
+
44
+ def transient_members
45
+ (@transient_members + get_attribute_from_super([], :transient_members)).uniq
46
+ end
47
+
48
+ def members(scope = RAMF::Configuration::DEFAULT_SCOPE)
49
+ @members[scope] ||= find_members(scope)
50
+ end
51
+
52
+ def defined_members=(members)
53
+ @defined_members = members.flatten.map {|v| v.to_sym}
54
+ end
55
+
56
+ def dynamic_members_finders
57
+ @dynamic_members_finders ||= get_duplicate_from_super([], :dynamic_members_finders)
58
+ end
59
+
60
+ def dynamic_members(instance, scope = RAMF::Configuration::DEFAULT_SCOPE)
61
+ members = dynamic_members_finders.map{|b| b.call(instance, scope)}.flatten.uniq
62
+ members -= members(scope)
63
+ members -= transient_members
64
+ scope_opt = amf_scope_options[scope]
65
+ except = scope_opt && scope_opt[:except] ? scope_opt[:except] : []
66
+ members -= except
67
+ members.inject({}) do |hash,member|
68
+ hash[member] = dynamic_members_reader.call(instance,member)
69
+ hash
70
+ end
71
+ end
72
+
73
+ ##############################################################
74
+ private
75
+
76
+ def find_members(scope)
77
+ if (amf_scope_options[scope] && amf_scope_options[scope][:only])
78
+ members = amf_scope_options[scope][:only]
79
+ else
80
+ members = get_duplicate_from_super([], :members, scope) + @defined_members
81
+ members += klass.flex_members if klass.respond_to?(:flex_members)
82
+ members -= transient_members
83
+ members -= amf_scope_options[scope][:except] if amf_scope_options[scope]
84
+ end
85
+ members
86
+ end
87
+
88
+ def get_duplicate_from_super(default, attribute, *args)
89
+ get_attribute_from_super(default, attribute, *args).dup
90
+ end
91
+
92
+
93
+ def get_attribute_from_super(default, attribute, *args)
94
+ klass.superclass ? klass.superclass.flex_remoting.send(attribute,*args) : default
95
+ end
96
+
97
+ end
98
+ end
@@ -0,0 +1,31 @@
1
+ module RAMF
2
+ module FlexObjects
3
+ class AcknowledgeMessage
4
+ flex_alias 'flex.messaging.messages.AcknowledgeMessage'
5
+ MEMBERS = [:messageId, :clientId, :destination, :body, :timeToLive, :timestamp, :headers, :correlationId]
6
+
7
+ flex_remoting_members MEMBERS
8
+ attr_accessor *MEMBERS
9
+
10
+ def initialize(options={})
11
+ @messageId = rand_uuid
12
+ @clientId = options[:clientId] ||rand_uuid
13
+ @destination = nil
14
+ @body = options[:body] || nil
15
+ @timeToLive = 0
16
+ @timestamp = Time.now.to_i * 100
17
+ @headers = {}
18
+ @correlationId = options[:correlationId]
19
+ end
20
+
21
+ def rand_uuid
22
+ [8,4,4,4,12].map {|n| rand_hex_3(n)}.join('-').to_s
23
+ end
24
+
25
+ def rand_hex_3(l)
26
+ "%0#{l}x" % rand(1 << l*4)
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,9 @@
1
+ require 'tempfile'
2
+
3
+ class RAMF::FlexObjects::ByteArray < Tempfile
4
+ def initialize(content)
5
+ super("RAMFTemp")
6
+ self.write content
7
+ self.rewind
8
+ end
9
+ end
@@ -0,0 +1,86 @@
1
+ class RAMF::FlexObjects::CommandMessage
2
+ flex_alias "flex.messaging.messages.CommandMessage"
3
+ flex_remoting_members :operation, :correlationId, :clientId,
4
+ :messageId, :body, :timestamp, :timeToLive,
5
+ :destination, :headers
6
+
7
+ attr_accessor :operation, :correlationId, :clientId,
8
+ :messageId, :body, :timestamp, :timeToLive,
9
+ :destination, :headers
10
+
11
+ ######################################OPERATION TYPES###############################3
12
+ #holdes the operations names for easier debugging and exception reporting
13
+ OPERATION_NAMES = {}
14
+
15
+ #This operation is used to subscribe to a remote destination.
16
+ SUBSCRIBE_OPERATION = 0; OPERATION_NAMES[0] = "SUBSCRIBE_OPERATION"
17
+
18
+ #This operation is used to unsubscribe from a remote destination.
19
+ UNSUBSCRIBE_OPERATION = 1; OPERATION_NAMES[1] = "UNSUBSCRIBE_OPERATION"
20
+
21
+ #This operation is used to poll a remote destination for pending, undelivered messages.
22
+ POLL_OPERATION = 2; OPERATION_NAMES[2] = "POLL_OPERATION"
23
+
24
+ #This operation is used by a remote destination to sync missed or cached messages
25
+ #back to a client as a result of a client issued poll command.
26
+ CLIENT_SYNC_OPERATION = 4; OPERATION_NAMES[4] = "CLIENT_SYNC_OPERATION"
27
+
28
+ #This operation is used to test connectivity over the current channel to
29
+ #the remote endpoint.
30
+ CLIENT_PING_OPERATION = 5; OPERATION_NAMES[5] = "CLIENT_PING_OPERATION"
31
+
32
+ #This operation is used to request a list of failover endpoint URIs
33
+ #for the remote destination based on cluster membership.
34
+ CLUSTER_REQUEST_OPERATION = 7; OPERATION_NAMES[7] = "CLUSTER_REQUEST_OPERATION"
35
+
36
+ #This operation is used to send credentials to the endpoint so that
37
+ #the user can be logged in over the current channel.
38
+ #The credentials need to be Base64 encoded and stored in the <code>body</code>
39
+ #of the message.
40
+ LOGIN_OPERATION = 8; OPERATION_NAMES[8] = "LOGIN_OPERATION"
41
+
42
+ #This operation is used to log the user out of the current channel, and
43
+ #will invalidate the server session if the channel is HTTP based.
44
+ LOGOUT_OPERATION = 9; OPERATION_NAMES[9] = "LOGOUT_OPERATION"
45
+
46
+ #This operation is used to indicate that the client's subscription with a
47
+ #remote destination has timed out.
48
+ SUBSCRIPTION_INVALIDATE_OPERATION = 10; OPERATION_NAMES[10] = "SUBSCRIPTION_INVALIDATE_OPERATION"
49
+
50
+ #Used by the MultiTopicConsumer to subscribe/unsubscribe for more
51
+ #than one topic in the same message.
52
+ MULTI_SUBSCRIBE_OPERATION = 11; OPERATION_NAMES[11] = "MULTI_SUBSCRIBE_OPERATION"
53
+
54
+ #This operation is used to indicate that a channel has disconnected.
55
+ DISCONNECT_OPERATION = 12; OPERATION_NAMES[12] = "DISCONNECT_OPERATION"
56
+
57
+ #This is the default operation for new CommandMessage instances.
58
+ UNKNOWN_OPERATION = 10000; OPERATION_NAMES[10000] = "UNKNOWN_OPERATION"
59
+
60
+ ######################################HEADER VALUES###############################
61
+
62
+ #Endpoints can imply what features they support by reporting the
63
+ #latest version of messaging they are capable of during the handshake of
64
+ #the initial ping CommandMessage.
65
+ MESSAGING_VERSION = "DSMessagingVersion"
66
+
67
+ def credentials_for_login_operation
68
+ RAMF::Util.extract_credentials(body.to_s) || {:userid => nil, :password => nil}
69
+ end
70
+
71
+ #construct an Operation object from the command message <tt>message</tt>
72
+ def to_operation
73
+ case operation
74
+ when CLIENT_PING_OPERATION
75
+ RAMF::OperationRequest.new :operation => operation,
76
+ :messageId=>messageId
77
+ when LOGIN_OPERATION
78
+ RAMF::OperationRequest.new :operation => operation,
79
+ :credentials => credentials_for_login_operation,
80
+ :messageId=>messageId
81
+ else
82
+ raise "Unimplemented Operation: #{operation} - #{OPERATION_NAMES[operation]}"
83
+ end
84
+ end
85
+
86
+ end
@@ -0,0 +1,14 @@
1
+ class RAMF::FlexObjects::ErrorMessage < RAMF::FlexObjects::AcknowledgeMessage
2
+ flex_alias "flex.messaging.messages.ErrorMessage"
3
+ flex_remoting_members :extendedData, :faultCode, :faultDetail, :faultString, :rootCause
4
+
5
+ attr_accessor :extendedData, :faultCode, :faultDetail, :faultString, :rootCause
6
+
7
+ def initialize(options = {})
8
+ super(options)
9
+ self.extendedData = options[:exception]
10
+ self.faultDetail = options[:exception].message if options[:exception]
11
+ self.faultString = options[:exception].message if options[:exception]
12
+ end
13
+
14
+ end
@@ -0,0 +1,37 @@
1
+ module RAMF
2
+ module FlexObjects
3
+
4
+ #This class is used to create objects that are anonymous flex objects.
5
+ #these objects are very much like a ruby hash but their attributes can be accessed
6
+ #via methods as well.
7
+ #
8
+ # some_object = RAMF::FlexObjects::FlexAnonymousObject.new
9
+ # => {}
10
+ # some_object.my_attribute = "Wow !"
11
+ # => "Wow !"
12
+ # some_object
13
+ # => {:my_attribute=>"Wow !"}
14
+ # some_object.my_attribute == some_object[:my_attribute]
15
+ # => true
16
+ #
17
+ class FlexAnonymousObject < Hash
18
+
19
+ flex_alias ""
20
+
21
+ def method_missing(method_name,*args,&block)
22
+ method_name = method_name.to_s
23
+ if method_name[method_name.length-1,1] == "="
24
+ self["#{method_name[0,method_name.length-1]}".to_sym] = args.first
25
+ else
26
+ self["#{method_name}".to_sym]
27
+ end
28
+ end
29
+
30
+
31
+ # def flex_dynamic_members(scope = :default)
32
+ # self.keys.inject({}) {|mem, key| mem[key.to_s] = self[key]; mem}
33
+ # end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,13 @@
1
+ module RAMF
2
+ module FlexObjects
3
+ class FlexObject < FlexAnonymousObject
4
+
5
+ attr_reader :_explicitType
6
+
7
+ def initialize(_explicitType)
8
+ super
9
+ @_explicitType = _explicitType
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ require 'base64'
2
+
3
+ class RAMF::FlexObjects::RemotingMessage
4
+ flex_alias 'flex.messaging.messages.RemotingMessage'
5
+ flex_remoting_members :operation, :source, :correlationId, :clientId,
6
+ :messageId, :body, :timestamp, :timeToLive,
7
+ :destination, :headers
8
+
9
+ attr_accessor :operation, :source, :correlationId, :clientId,
10
+ :messageId, :body, :timestamp, :timeToLive,
11
+ :destination, :headers
12
+
13
+ def credentials_header
14
+ RAMF::Util.extract_credentials(headers[:DSRemoteCredentials].to_s) || {:userid => nil, :password => nil}
15
+ end
16
+
17
+ #construct an Operation object from the remoting message <tt>message</tt>
18
+ def to_operation
19
+ RAMF::OperationRequest.new :service => RAMF::Util.service_name(destination.to_s),
20
+ :method => RAMF::Util.method_name(operation.to_s),
21
+ :args => body,
22
+ :credentials => credentials_header,
23
+ :messageId=>messageId
24
+ end
25
+
26
+ end
@@ -0,0 +1,73 @@
1
+ module RAMF
2
+ module IO
3
+ module CommonReadWrite
4
+ BigEndian = :BigEndian
5
+ LittleEndian = :LittleEndian
6
+ @@BYTE_ORDER = nil
7
+
8
+ #examines the locale byte order on the running machine
9
+ def byte_order
10
+ if @@BYTE_ORDER.nil?
11
+ @@BYTE_ORDER = ([0x12345678].pack("L") == "\x12\x34\x56\x78") ? :BigEndian : :LittleEndian
12
+ end
13
+ end
14
+
15
+ def byte_order_little?
16
+ (byte_order == :LittleEndian)
17
+ end
18
+
19
+ def byte_order_big?
20
+ (byte_order == :BigEndian)
21
+ end
22
+
23
+ def readU8(stream)
24
+ stream.read(1).unpack('C').first
25
+ end
26
+
27
+ def readU16(stream)
28
+ stream.read(2).unpack('n').first
29
+ end
30
+
31
+ def readU32(stream)
32
+ stream.read(4).unpack('N').first
33
+ end
34
+
35
+ def read_double(stream)
36
+ stream.read(8).unpack('G').first
37
+ end
38
+
39
+ def readUTF8(stream)
40
+ length = readU16(stream)
41
+ stream.read(length)
42
+ end
43
+
44
+ def writeU8(val, stream)
45
+ stream.write [val].pack('C')
46
+ end
47
+
48
+ def writeU16(val,stream)
49
+ stream.write [val].pack('n')
50
+ end
51
+
52
+ #write an unsigned 32-bit integer in network (big-endian) byte order
53
+ def writeU32(val,stream)
54
+ stream.write [val].pack('N')
55
+ end
56
+
57
+ def writeUTF8(string,stream)
58
+ writeU16(string.length,stream)
59
+ stream.write string
60
+ end
61
+
62
+ def writeUTF8Long(string,stream)
63
+ writeU32(string.length, stream)
64
+ stream.write string
65
+ end
66
+
67
+ def write_double(val,stream)
68
+ stream.write( @double_mappings[val] ||= [val].pack('G'))
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,79 @@
1
+ module RAMF
2
+ module IO
3
+ module Constants
4
+ #AMF0
5
+ AMF0_NUMBER = 0x00
6
+ AMF0_BOOLEAN = 0x01
7
+ AMF0_STRING = 0x02
8
+ AMF0_OBJECT = 0x03
9
+ AMF0_MOVIE_CLIP = 0x04
10
+ AMF0_NULL = 0x05
11
+ AMF0_UNDEFINED = 0x06
12
+ AMF0_REFERENCE = 0x07
13
+ AMF0_MIXED_ARRAY = 0x08
14
+ AMF0_EOO = 0x09
15
+ AMF0_ARRAY = 0x0A
16
+ AMF0_DATE = 0x0B
17
+ AMF0_LONG_STRING = 0x0C
18
+ AMF0_UNSUPPORTED = 0x0D
19
+ AMF0_RECORDSET = 0x0E
20
+ AMF0_XML = 0x0F
21
+ AMF0_TYPED_OBJECT = 0x10
22
+
23
+ #AMF0 MARKERS
24
+ AMF0_NUMBER_MARKER = "\000"
25
+ AMF0_BOOLEAN_MARKER = "\001"
26
+ AMF0_STRING_MARKER = "\002"
27
+ AMF0_OBJECT_MARKER = "\003"
28
+ AMF0_MOVIE_CLIP_MARKER = "\004"
29
+ AMF0_NULL_MARKER = "\005"
30
+ AMF0_UNDEFINED_MARKER = "\006"
31
+ AMF0_REFERENCE_MARKER = "\007"
32
+ AMF0_ECMA_ARRAY_MARKER = "\010"
33
+ AMF0_OBJECT_END_MARKER = "\011"
34
+ AMF0_ARRAY_MARKER = "\012"
35
+ AMF0_DATE_MARKER = "\013"
36
+ AMF0_LONG_STRING_MARKER = "\014"
37
+ AMF0_UNSUPPORTED_MARKER = "\015"
38
+ AMF0_RECORDSET_MARKER = "\016"
39
+ AMF0_XML_MARKER = "\017"
40
+ AMF0_TYPED_OBJECT_MARKER = "\020"
41
+
42
+ #AMF3
43
+ AMF3_TYPE = 0x11
44
+ AMF3_UNDEFINED = 0x00
45
+ AMF3_NULL = 0x01
46
+ AMF3_FALSE = 0x02
47
+ AMF3_TRUE = 0x03
48
+ AMF3_INTEGER = 0x04
49
+ AMF3_DOUBLE = 0x05
50
+ AMF3_STRING = 0x06
51
+ AMF3_XML_DOC = 0x07
52
+ AMF3_DATE = 0x08
53
+ AMF3_ARRAY = 0x09
54
+ AMF3_OBJECT = 0x0A
55
+ AMF3_XML = 0x0B
56
+ AMF3_BYTE_ARRAY = 0x0C
57
+ AMF3_INTEGER_MAX = 268435455
58
+ AMF3_INTEGER_MIN = -268435456
59
+
60
+ #AMF3 Markers
61
+ AMF3_TYPE_MARKER = "\021"
62
+ AMF3_UNDEFINED_MARKER = "\000"
63
+ AMF3_NULL_MARKER = "\001"
64
+ AMF3_FALSE_MARKER = "\002"
65
+ AMF3_TRUE_MARKER = "\003"
66
+ AMF3_INTEGER_MARKER = "\004"
67
+ AMF3_DOUBLE_MARKER = "\005"
68
+ AMF3_STRING_MARKER = "\006"
69
+ AMF3_XML_DOC_MARKER = "\007"
70
+ AMF3_DATE_MARKER = "\010"
71
+ AMF3_ARRAY_MARKER = "\011"
72
+ AMF3_OBJECT_MARKER = "\012"
73
+ AMF3_XML_STRING_MARKER = "\013"
74
+ AMF3_BYTE_ARRAY_MARKER = "\014"
75
+
76
+ AMF3_EMPTY_STRING = "\001"
77
+ end
78
+ end
79
+ end