mrpin-rocketamf 1.0.4 → 2.0.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. checksums.yaml +4 -4
  2. data/README.rdoc +1 -1
  3. data/Rakefile +7 -7
  4. data/benchmark.rb +44 -37
  5. data/ext/rocketamf_ext/class_mapping.c +11 -11
  6. data/ext/rocketamf_ext/remoting.c +1 -1
  7. data/lib/rocketamf.rb +41 -98
  8. data/lib/rocketamf/constants.rb +20 -20
  9. data/lib/rocketamf/errors.rb +2 -0
  10. data/lib/rocketamf/errors/amf_error.rb +5 -0
  11. data/lib/rocketamf/errors/amf_error_incomplete.rb +5 -0
  12. data/lib/rocketamf/ext.rb +0 -6
  13. data/lib/rocketamf/extensions.rb +4 -4
  14. data/lib/rocketamf/{class_mapping.rb → mapping/class_mapping.rb} +70 -103
  15. data/lib/rocketamf/mapping/mapping_set.rb +63 -0
  16. data/lib/rocketamf/pure.rb +1 -9
  17. data/lib/rocketamf/pure/deserializer.rb +234 -262
  18. data/lib/rocketamf/pure/helpers/io_helper_base.rb +19 -0
  19. data/lib/rocketamf/pure/helpers/io_helper_read.rb +67 -0
  20. data/lib/rocketamf/pure/helpers/io_helper_write.rb +48 -0
  21. data/lib/rocketamf/pure/helpers/object_cache.rb +20 -0
  22. data/lib/rocketamf/pure/helpers/string_cache.rb +14 -0
  23. data/lib/rocketamf/pure/serializer.rb +138 -271
  24. data/lib/rocketamf/types.rb +1 -0
  25. data/lib/rocketamf/{values → types}/typed_hash.rb +12 -2
  26. data/mrpin-rocketamf.gemspec +27 -16
  27. data/spec/class_mapping_spec.rb +59 -52
  28. data/spec/deserializer_spec.rb +164 -328
  29. data/spec/fast_class_mapping_spec.rb +52 -46
  30. data/spec/helpers/class_mapping_test.rb +4 -0
  31. data/spec/helpers/class_mapping_test2.rb +3 -0
  32. data/spec/helpers/externalizable_test.rb +24 -0
  33. data/spec/helpers/fixtures.rb +28 -0
  34. data/spec/helpers/other_class.rb +4 -0
  35. data/spec/helpers/ruby_class.rb +4 -0
  36. data/spec/helpers/test_ruby_class.rb +4 -0
  37. data/spec/serializer_spec.rb +248 -339
  38. data/spec/spec_helper.rb +4 -49
  39. metadata +47 -53
  40. data/lib/rocketamf/pure/io_helpers.rb +0 -94
  41. data/lib/rocketamf/pure/remoting.rb +0 -117
  42. data/lib/rocketamf/remoting.rb +0 -196
  43. data/lib/rocketamf/values/messages.rb +0 -214
  44. data/spec/fixtures/objects/amf0-boolean.bin +0 -1
  45. data/spec/fixtures/objects/amf0-complex-encoded-string.bin +0 -0
  46. data/spec/fixtures/objects/amf0-date.bin +0 -0
  47. data/spec/fixtures/objects/amf0-ecma-ordinal-array.bin +0 -0
  48. data/spec/fixtures/objects/amf0-empty-string-key-hash.bin +0 -0
  49. data/spec/fixtures/objects/amf0-hash.bin +0 -0
  50. data/spec/fixtures/objects/amf0-null.bin +0 -1
  51. data/spec/fixtures/objects/amf0-number.bin +0 -0
  52. data/spec/fixtures/objects/amf0-object.bin +0 -0
  53. data/spec/fixtures/objects/amf0-ref-test.bin +0 -0
  54. data/spec/fixtures/objects/amf0-strict-array.bin +0 -0
  55. data/spec/fixtures/objects/amf0-string.bin +0 -0
  56. data/spec/fixtures/objects/amf0-time.bin +0 -0
  57. data/spec/fixtures/objects/amf0-typed-object.bin +0 -0
  58. data/spec/fixtures/objects/amf0-undefined.bin +0 -1
  59. data/spec/fixtures/objects/amf0-untyped-object.bin +0 -0
  60. data/spec/fixtures/objects/amf0-xml-doc.bin +0 -0
  61. data/spec/messages_spec.rb +0 -39
  62. data/spec/remoting_spec.rb +0 -196
data/spec/spec_helper.rb CHANGED
@@ -1,55 +1,10 @@
1
1
  require 'rubygems'
2
2
  require 'rspec'
3
- require 'rspec/autorun'
4
3
 
5
4
  $:.unshift(File.dirname(__FILE__) + '/../lib')
6
- require 'rocketamf'
7
- require 'rocketamf/pure/io_helpers' # Just to make sure they get loaded
8
-
9
- def request_fixture(binary_path)
10
- data = File.open(File.dirname(__FILE__) + '/fixtures/request/' + binary_path, "rb").read
11
- data.force_encoding("ASCII-8BIT") if data.respond_to?(:force_encoding)
12
- data
13
- end
14
-
15
- def object_fixture(binary_path)
16
- data = File.open(File.dirname(__FILE__) + '/fixtures/objects/' + binary_path, "rb").read
17
- data.force_encoding("ASCII-8BIT") if data.respond_to?(:force_encoding)
18
- data
19
- end
20
-
21
- def create_envelope(binary_path)
22
- RocketAMF::Envelope.new.populate_from_stream(StringIO.new(request_fixture(binary_path)))
23
- end
24
5
 
25
- # Helper classes
26
- class RubyClass; attr_accessor :baz, :foo; end;
27
- class OtherClass; attr_accessor :bar, :foo; end;
28
- class ClassMappingTest
29
- attr_accessor :prop_a
30
- attr_accessor :prop_b
31
- end
32
- class ClassMappingTest2 < ClassMappingTest
33
- attr_accessor :prop_c
34
- end
35
- module ANamespace; class TestRubyClass; end; end
36
- class ExternalizableTest
37
- include RocketAMF::Pure::ReadIOHelpers
38
- include RocketAMF::Pure::WriteIOHelpers
39
-
40
- attr_accessor :one, :two
41
-
42
- def encode_amf serializer
43
- serializer.write_object(self, nil, {:class_name => 'ExternalizableTest', :dynamic => false, :externalizable => true, :members => []})
44
- end
45
-
46
- def read_external des
47
- @one = read_double(des.source)
48
- @two = read_double(des.source)
49
- end
6
+ require 'rocketamf'
7
+ require 'rocketamf/pure/helpers/io_helper_write' # Just to make sure they get loaded
8
+ require 'rocketamf/pure/helpers/io_helper_read' # Just to make sure they get loaded
50
9
 
51
- def write_external ser
52
- ser.stream << pack_double(@one)
53
- ser.stream << pack_double(@two)
54
- end
55
- end
10
+ Dir[File.dirname(__FILE__) + '/helpers/*.rb'].each { |file| require file }
metadata CHANGED
@@ -1,34 +1,36 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mrpin-rocketamf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jacob Henry
8
8
  - Stephen Augenstein
9
9
  - Joc O'Connor
10
+ - Gregory Tkach
10
11
  autorequire:
11
12
  bindir: bin
12
13
  cert_chain: []
13
- date: 2014-08-26 00:00:00.000000000 Z
14
+ date: 2015-01-01 00:00:00.000000000 Z
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
17
  name: rake-compiler
17
18
  requirement: !ruby/object:Gem::Requirement
18
19
  requirements:
19
- - - '>='
20
+ - - ~>
20
21
  - !ruby/object:Gem::Version
21
22
  version: '0'
22
23
  type: :development
23
24
  prerelease: false
24
25
  version_requirements: !ruby/object:Gem::Requirement
25
26
  requirements:
26
- - - '>='
27
+ - - ~>
27
28
  - !ruby/object:Gem::Version
28
29
  version: '0'
29
- description:
30
+ description: Fast AMF3 serializer/deserializer with remoting request/response wrappers
31
+ to simplify integration
30
32
  email:
31
- - perl.programmer@gmail.com
33
+ - gregory.tkach@gmail.com
32
34
  executables: []
33
35
  extensions:
34
36
  - ext/rocketamf_ext/extconf.rb
@@ -36,46 +38,41 @@ extra_rdoc_files:
36
38
  - README.rdoc
37
39
  files:
38
40
  - README.rdoc
39
- - benchmark.rb
40
- - mrpin-rocketamf.gemspec
41
41
  - Rakefile
42
- - lib/rocketamf/class_mapping.rb
42
+ - benchmark.rb
43
+ - ext/rocketamf_ext/class_mapping.c
44
+ - ext/rocketamf_ext/constants.h
45
+ - ext/rocketamf_ext/deserializer.c
46
+ - ext/rocketamf_ext/deserializer.h
47
+ - ext/rocketamf_ext/extconf.rb
48
+ - ext/rocketamf_ext/remoting.c
49
+ - ext/rocketamf_ext/rocketamf_ext.c
50
+ - ext/rocketamf_ext/serializer.c
51
+ - ext/rocketamf_ext/serializer.h
52
+ - ext/rocketamf_ext/utility.h
53
+ - lib/rocketamf.rb
43
54
  - lib/rocketamf/constants.rb
55
+ - lib/rocketamf/errors.rb
56
+ - lib/rocketamf/errors/amf_error.rb
57
+ - lib/rocketamf/errors/amf_error_incomplete.rb
44
58
  - lib/rocketamf/ext.rb
45
59
  - lib/rocketamf/extensions.rb
60
+ - lib/rocketamf/mapping/class_mapping.rb
61
+ - lib/rocketamf/mapping/mapping_set.rb
62
+ - lib/rocketamf/pure.rb
46
63
  - lib/rocketamf/pure/deserializer.rb
47
- - lib/rocketamf/pure/io_helpers.rb
48
- - lib/rocketamf/pure/remoting.rb
64
+ - lib/rocketamf/pure/helpers/io_helper_base.rb
65
+ - lib/rocketamf/pure/helpers/io_helper_read.rb
66
+ - lib/rocketamf/pure/helpers/io_helper_write.rb
67
+ - lib/rocketamf/pure/helpers/object_cache.rb
68
+ - lib/rocketamf/pure/helpers/string_cache.rb
49
69
  - lib/rocketamf/pure/serializer.rb
50
- - lib/rocketamf/pure.rb
51
- - lib/rocketamf/remoting.rb
52
- - lib/rocketamf/values/messages.rb
53
- - lib/rocketamf/values/typed_hash.rb
54
- - lib/rocketamf.rb
70
+ - lib/rocketamf/types.rb
71
+ - lib/rocketamf/types/typed_hash.rb
72
+ - mrpin-rocketamf.gemspec
55
73
  - spec/class_mapping_spec.rb
56
74
  - spec/deserializer_spec.rb
57
75
  - spec/fast_class_mapping_spec.rb
58
- - spec/messages_spec.rb
59
- - spec/remoting_spec.rb
60
- - spec/serializer_spec.rb
61
- - spec/spec_helper.rb
62
- - spec/fixtures/objects/amf0-boolean.bin
63
- - spec/fixtures/objects/amf0-complex-encoded-string.bin
64
- - spec/fixtures/objects/amf0-date.bin
65
- - spec/fixtures/objects/amf0-ecma-ordinal-array.bin
66
- - spec/fixtures/objects/amf0-empty-string-key-hash.bin
67
- - spec/fixtures/objects/amf0-hash.bin
68
- - spec/fixtures/objects/amf0-null.bin
69
- - spec/fixtures/objects/amf0-number.bin
70
- - spec/fixtures/objects/amf0-object.bin
71
- - spec/fixtures/objects/amf0-ref-test.bin
72
- - spec/fixtures/objects/amf0-strict-array.bin
73
- - spec/fixtures/objects/amf0-string.bin
74
- - spec/fixtures/objects/amf0-time.bin
75
- - spec/fixtures/objects/amf0-typed-object.bin
76
- - spec/fixtures/objects/amf0-undefined.bin
77
- - spec/fixtures/objects/amf0-untyped-object.bin
78
- - spec/fixtures/objects/amf0-xml-doc.bin
79
76
  - spec/fixtures/objects/amf3-0.bin
80
77
  - spec/fixtures/objects/amf3-array-collection.bin
81
78
  - spec/fixtures/objects/amf3-array-ref.bin
@@ -130,18 +127,18 @@ files:
130
127
  - spec/fixtures/request/simple-request.bin
131
128
  - spec/fixtures/request/simple-response.bin
132
129
  - spec/fixtures/request/unsupportedCommandMessage.bin
133
- - ext/rocketamf_ext/class_mapping.c
134
- - ext/rocketamf_ext/deserializer.c
135
- - ext/rocketamf_ext/remoting.c
136
- - ext/rocketamf_ext/rocketamf_ext.c
137
- - ext/rocketamf_ext/serializer.c
138
- - ext/rocketamf_ext/constants.h
139
- - ext/rocketamf_ext/deserializer.h
140
- - ext/rocketamf_ext/serializer.h
141
- - ext/rocketamf_ext/utility.h
142
- - ext/rocketamf_ext/extconf.rb
130
+ - spec/helpers/class_mapping_test.rb
131
+ - spec/helpers/class_mapping_test2.rb
132
+ - spec/helpers/externalizable_test.rb
133
+ - spec/helpers/fixtures.rb
134
+ - spec/helpers/other_class.rb
135
+ - spec/helpers/ruby_class.rb
136
+ - spec/helpers/test_ruby_class.rb
137
+ - spec/serializer_spec.rb
138
+ - spec/spec_helper.rb
143
139
  homepage: https://github.com/mrpin/mrpin-rocketamf
144
- licenses: []
140
+ licenses:
141
+ - MIT
145
142
  metadata: {}
146
143
  post_install_message:
147
144
  rdoc_options:
@@ -162,15 +159,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
159
  version: '0'
163
160
  requirements: []
164
161
  rubyforge_project:
165
- rubygems_version: 2.1.11
162
+ rubygems_version: 2.2.2
166
163
  signing_key:
167
164
  specification_version: 4
168
- summary: Fast AMF serializer/deserializer with remoting request/response wrappers
169
- to simplify integration
165
+ summary: Fast AMF3 serializer/deserializer
170
166
  test_files:
171
167
  - spec/class_mapping_spec.rb
172
168
  - spec/deserializer_spec.rb
173
169
  - spec/fast_class_mapping_spec.rb
174
- - spec/messages_spec.rb
175
- - spec/remoting_spec.rb
176
170
  - spec/serializer_spec.rb
@@ -1,94 +0,0 @@
1
- module RocketAMF
2
- module Pure
3
- module ReadIOHelpers #:nodoc:
4
- def read_int8 source
5
- source.read(1).unpack('c').first
6
- end
7
-
8
- def read_word8 source
9
- source.read(1).unpack('C').first
10
- end
11
-
12
- def read_double source
13
- source.read(8).unpack('G').first
14
- end
15
-
16
- def read_word16_network source
17
- source.read(2).unpack('n').first
18
- end
19
-
20
- def read_int16_network source
21
- str = source.read(2)
22
- str.reverse! if byte_order_little? # swap bytes as native=little (and we want network)
23
- str.unpack('s').first
24
- end
25
-
26
- def read_word32_network source
27
- source.read(4).unpack('N').first
28
- end
29
-
30
- def byte_order
31
- if [0x12345678].pack("L") == "\x12\x34\x56\x78"
32
- :BigEndian
33
- else
34
- :LittleEndian
35
- end
36
- end
37
-
38
- def byte_order_little?
39
- (byte_order == :LittleEndian) ? true : false;
40
- end
41
- end
42
-
43
- module WriteIOHelpers #:nodoc:
44
- def pack_integer(integer)
45
- integer = integer & 0x1fffffff
46
- if(integer < 0x80)
47
- [integer].pack('c')
48
- elsif(integer < 0x4000)
49
- [integer >> 7 & 0x7f | 0x80].pack('c')+
50
- [integer & 0x7f].pack('c')
51
- elsif(integer < 0x200000)
52
- [integer >> 14 & 0x7f | 0x80].pack('c') +
53
- [integer >> 7 & 0x7f | 0x80].pack('c') +
54
- [integer & 0x7f].pack('c')
55
- else
56
- [integer >> 22 & 0x7f | 0x80].pack('c')+
57
- [integer >> 15 & 0x7f | 0x80].pack('c')+
58
- [integer >> 8 & 0x7f | 0x80].pack('c')+
59
- [integer & 0xff].pack('c')
60
- end
61
- end
62
-
63
- def pack_double(double)
64
- [double].pack('G')
65
- end
66
-
67
- def pack_int8(val)
68
- [val].pack('c')
69
- end
70
-
71
- def pack_int16_network(val)
72
- [val].pack('n')
73
- end
74
-
75
- def pack_word32_network(val)
76
- str = [val].pack('L')
77
- str.reverse! if byte_order_little? # swap bytes as native=little (and we want network)
78
- str
79
- end
80
-
81
- def byte_order
82
- if [0x12345678].pack("L") == "\x12\x34\x56\x78"
83
- :BigEndian
84
- else
85
- :LittleEndian
86
- end
87
- end
88
-
89
- def byte_order_little?
90
- (byte_order == :LittleEndian) ? true : false;
91
- end
92
- end
93
- end
94
- end
@@ -1,117 +0,0 @@
1
- require 'rocketamf/pure/io_helpers'
2
-
3
- module RocketAMF
4
- module Pure
5
- # Included into RocketAMF::Envelope, this module replaces the
6
- # populate_from_stream and serialize methods with actual working versions
7
- module Envelope
8
- # Included into RocketAMF::Envelope, this method handles deserializing an
9
- # AMF request/response into the envelope
10
- def populate_from_stream stream, class_mapper=nil
11
- stream = StringIO.new(stream) unless StringIO === stream
12
- des = Deserializer.new(class_mapper || RocketAMF::ClassMapper.new)
13
- des.source = stream
14
-
15
- # Initialize
16
- @amf_version = 0
17
- @headers = {}
18
- @messages = []
19
-
20
- # Read AMF version
21
- @amf_version = read_word16_network stream
22
-
23
- # Read in headers
24
- header_count = read_word16_network stream
25
- 0.upto(header_count-1) do
26
- name = stream.read(read_word16_network(stream))
27
- name.force_encoding("UTF-8") if name.respond_to?(:force_encoding)
28
-
29
- must_understand = read_int8(stream) != 0
30
-
31
- length = read_word32_network stream
32
- data = des.deserialize(0, nil)
33
-
34
- @headers[name] = RocketAMF::Header.new(name, must_understand, data)
35
- end
36
-
37
- # Read in messages
38
- message_count = read_word16_network stream
39
- 0.upto(message_count-1) do
40
- target_uri = stream.read(read_word16_network(stream))
41
- target_uri.force_encoding("UTF-8") if target_uri.respond_to?(:force_encoding)
42
-
43
- response_uri = stream.read(read_word16_network(stream))
44
- response_uri.force_encoding("UTF-8") if response_uri.respond_to?(:force_encoding)
45
-
46
- length = read_word32_network stream
47
- data = des.deserialize(0, nil)
48
- if data.is_a?(Array) && data.length == 1 && data[0].is_a?(::RocketAMF::Values::AbstractMessage)
49
- data = data[0]
50
- end
51
-
52
- @messages << RocketAMF::Message.new(target_uri, response_uri, data)
53
- end
54
-
55
- self
56
- end
57
-
58
- # Included into RocketAMF::Envelope, this method handles serializing an
59
- # AMF request/response into a string
60
- def serialize class_mapper=nil
61
- ser = Serializer.new(class_mapper || RocketAMF::ClassMapper.new)
62
- stream = ser.stream
63
-
64
- # Write version
65
- stream << pack_int16_network(@amf_version)
66
-
67
- # Write headers
68
- stream << pack_int16_network(@headers.length) # Header count
69
- @headers.each_value do |h|
70
- # Write header name
71
- name_str = h.name
72
- name_str.encode!("UTF-8").force_encoding("ASCII-8BIT") if name_str.respond_to?(:encode)
73
- stream << pack_int16_network(name_str.bytesize)
74
- stream << name_str
75
-
76
- # Write must understand flag
77
- stream << pack_int8(h.must_understand ? 1 : 0)
78
-
79
- # Serialize data
80
- stream << pack_word32_network(-1) # length of data - -1 if you don't know
81
- ser.serialize(0, h.data)
82
- end
83
-
84
- # Write messages
85
- stream << pack_int16_network(@messages.length) # Message count
86
- @messages.each do |m|
87
- # Write target_uri
88
- uri_str = m.target_uri
89
- uri_str.encode!("UTF-8").force_encoding("ASCII-8BIT") if uri_str.respond_to?(:encode)
90
- stream << pack_int16_network(uri_str.bytesize)
91
- stream << uri_str
92
-
93
- # Write response_uri
94
- uri_str = m.response_uri
95
- uri_str.encode!("UTF-8").force_encoding("ASCII-8BIT") if uri_str.respond_to?(:encode)
96
- stream << pack_int16_network(uri_str.bytesize)
97
- stream << uri_str
98
-
99
- # Serialize data
100
- stream << pack_word32_network(-1) # length of data - -1 if you don't know
101
- if @amf_version == 3
102
- stream << AMF0_AMF3_MARKER
103
- ser.serialize(3, m.data)
104
- else
105
- ser.serialize(0, m.data)
106
- end
107
- end
108
-
109
- stream
110
- end
111
-
112
- private
113
- include RocketAMF::Pure::ReadIOHelpers
114
- include RocketAMF::Pure::WriteIOHelpers
115
- end
116
- end
117
- end
@@ -1,196 +0,0 @@
1
- module RocketAMF
2
- # Container for the AMF request/response.
3
- class Envelope
4
- attr_reader :amf_version, :headers, :messages
5
-
6
- def initialize props={}
7
- @amf_version = props[:amf_version] || 0
8
- @headers = props[:headers] || {}
9
- @messages = props[:messages] || []
10
- end
11
-
12
- # Populates the envelope from the given stream or string using the given
13
- # class mapper, or creates a new one. Returns self for easy chaining.
14
- #
15
- # Example:
16
- #
17
- # req = RocketAMF::Envelope.new.populate_from_stream(env['rack.input'].read)
18
- #--
19
- # Implemented in pure/remoting.rb RocketAMF::Pure::Envelope
20
- def populate_from_stream stream, class_mapper=nil
21
- raise AMFError, 'Must load "rocketamf/pure"'
22
- end
23
-
24
- # Creates the appropriate message and adds it to <tt>messages</tt> to call
25
- # the given target using the standard (old) remoting APIs. You can call multiple
26
- # targets in the same request, unlike with the flex remotings APIs.
27
- #
28
- # Example:
29
- #
30
- # req = RocketAMF::Envelope.new
31
- # req.call 'test', "arg_1", ["args", "args"]
32
- # req.call 'Controller.action'
33
- def call target, *args
34
- raise "Cannot use different call types" unless @call_type.nil? || @call_type == :simple
35
- @call_type = :simple
36
-
37
- msg_num = messages.length+1
38
- @messages << RocketAMF::Message.new(target, "/#{msg_num}", args)
39
- end
40
-
41
- # Creates the appropriate message and adds it to <tt>messages</tt> using the
42
- # new flex (RemoteObject) remoting APIs. You can only make one flex remoting
43
- # call per envelope, and the AMF version must be set to 3.
44
- #
45
- # Example:
46
- #
47
- # req = RocketAMF::Envelope.new :amf_version => 3
48
- # req.call_flex 'Controller.action', "arg_1", ["args", "args"]
49
- def call_flex target, *args
50
- raise "Can only call one flex target per request" if @call_type == :flex
51
- raise "Cannot use different call types" if @call_type == :simple
52
- raise "Cannot use flex remoting calls with AMF0" if @amf_version != 3
53
- @call_type = :flex
54
-
55
- flex_msg = RocketAMF::Values::RemotingMessage.new
56
- target_parts = target.split(".")
57
- flex_msg.operation = target_parts.pop # Use pop so that a missing source is possible without issues
58
- flex_msg.source = target_parts.pop
59
- flex_msg.body = args
60
- @messages << RocketAMF::Message.new('null', '/2', flex_msg) # /2 because it always sends a command message before
61
- end
62
-
63
- # Serializes the envelope to a string using the given class mapper, or creates
64
- # a new one, and returns the result
65
- #--
66
- # Implemented in pure/remoting.rb RocketAMF::Pure::Envelope
67
- def serialize class_mapper=nil
68
- raise AMFError, 'Must load "rocketamf/pure"'
69
- end
70
-
71
- # Builds response from the request, iterating over each method call and using
72
- # the return value as the method call's return value. Marks as envelope as
73
- # constructed after running.
74
- #--
75
- # Iterate over all the sent messages. If they're somthing we can handle, like
76
- # a command message, then simply add the response message ourselves. If it's
77
- # a method call, then call the block with the method and args, catching errors
78
- # for handling. Then create the appropriate response message using the return
79
- # value of the block as the return value for the method call.
80
- def each_method_call request, &block
81
- raise 'Response already constructed' if @constructed
82
-
83
- # Set version from response
84
- # Can't just copy version because FMS sends version as 1
85
- @amf_version = request.amf_version == 3 ? 3 : 0
86
-
87
- request.messages.each do |m|
88
- # What's the request body?
89
- case m.data
90
- when Values::CommandMessage
91
- # Pings should be responded to with an AcknowledgeMessage built using the ping
92
- # Everything else is unsupported
93
- command_msg = m.data
94
- if command_msg.operation == Values::CommandMessage::CLIENT_PING_OPERATION
95
- response_value = Values::AcknowledgeMessage.new(command_msg)
96
- else
97
- e = Exception.new("CommandMessage #{command_msg.operation} not implemented")
98
- e.set_backtrace ["RocketAMF::Envelope each_method_call"]
99
- response_value = Values::ErrorMessage.new(command_msg, e)
100
- end
101
- when Values::RemotingMessage
102
- # Using RemoteObject style message calls
103
- remoting_msg = m.data
104
- acknowledge_msg = Values::AcknowledgeMessage.new(remoting_msg)
105
- method_base = remoting_msg.source.to_s.empty? ? '' : remoting_msg.source+'.'
106
- body = dispatch_call :method => method_base+remoting_msg.operation, :args => remoting_msg.body, :source => remoting_msg, :block => block
107
-
108
- # Response should be the bare ErrorMessage if there was an error
109
- if body.is_a?(Values::ErrorMessage)
110
- response_value = body
111
- else
112
- acknowledge_msg.body = body
113
- response_value = acknowledge_msg
114
- end
115
- else
116
- # Standard response message
117
- response_value = dispatch_call :method => m.target_uri, :args => m.data, :source => m, :block => block
118
- end
119
-
120
- target_uri = m.response_uri
121
- target_uri += response_value.is_a?(Values::ErrorMessage) ? '/onStatus' : '/onResult'
122
- @messages << ::RocketAMF::Message.new(target_uri, '', response_value)
123
- end
124
-
125
- @constructed = true
126
- end
127
-
128
- # Returns the result of a response envelope, or an array of results if there
129
- # are multiple action call messages. It automatically unwraps flex-style
130
- # RemoteObject response messages, where the response result is inside a
131
- # RocketAMF::Values::AcknowledgeMessage.
132
- #
133
- # Example:
134
- #
135
- # req = RocketAMF::Envelope.new
136
- # req.call('TestController.test', 'first_arg', 'second_arg')
137
- # res = RocketAMF::Envelope.new
138
- # res.each_method_call req do |method, args|
139
- # ['a', 'b']
140
- # end
141
- # res.result #=> ['a', 'b']
142
- def result
143
- results = []
144
- messages.each do |msg|
145
- if msg.data.is_a?(Values::AcknowledgeMessage)
146
- results << msg.data.body
147
- else
148
- results << msg.data
149
- end
150
- end
151
- results.length > 1 ? results : results[0]
152
- end
153
-
154
- # Whether or not the response has been constructed. Can be used to prevent
155
- # serialization when no processing has taken place.
156
- def constructed?
157
- @constructed
158
- end
159
-
160
- # Return the serialized envelope as a string
161
- def to_s
162
- serialize
163
- end
164
-
165
- def dispatch_call p #:nodoc:
166
- begin
167
- p[:block].call(p[:method], p[:args])
168
- rescue Exception => e
169
- # Create ErrorMessage object using the source message as the base
170
- Values::ErrorMessage.new(p[:source], e)
171
- end
172
- end
173
- end
174
-
175
- # RocketAMF::Envelope header
176
- class Header
177
- attr_accessor :name, :must_understand, :data
178
-
179
- def initialize name, must_understand, data
180
- @name = name
181
- @must_understand = must_understand
182
- @data = data
183
- end
184
- end
185
-
186
- # RocketAMF::Envelope message
187
- class Message
188
- attr_accessor :target_uri, :response_uri, :data
189
-
190
- def initialize target_uri, response_uri, data
191
- @target_uri = target_uri
192
- @response_uri = response_uri
193
- @data = data
194
- end
195
- end
196
- end