rack-amf 0.0.4 → 1.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.
- data/README.rdoc +18 -9
- data/Rakefile +23 -38
- data/lib/rack/amf/environment.rb +5 -8
- data/lib/rack/amf/middleware/pass_through.rb +5 -4
- data/lib/rack/amf/middleware/service_manager.rb +11 -3
- data/lib/rack/amf/middleware.rb +2 -1
- data/lib/rack/amf/request.rb +3 -16
- data/lib/rack/amf/response.rb +8 -67
- data/lib/rack/amf.rb +41 -1
- data/spec/{rack/service_manager_spec.rb → service_manager_spec.rb} +1 -2
- data/spec/spec.opts +2 -1
- data/spec/spec_helper.rb +1 -24
- metadata +19 -84
- data/lib/amf/class_mapping.rb +0 -211
- data/lib/amf/common.rb +0 -28
- data/lib/amf/constants.rb +0 -47
- data/lib/amf/pure/deserializer.rb +0 -361
- data/lib/amf/pure/io_helpers.rb +0 -94
- data/lib/amf/pure/remoting.rb +0 -120
- data/lib/amf/pure/serializer.rb +0 -327
- data/lib/amf/pure.rb +0 -14
- data/lib/amf/values/array_collection.rb +0 -9
- data/lib/amf/values/messages.rb +0 -133
- data/lib/amf/values/typed_hash.rb +0 -13
- data/lib/amf/version.rb +0 -9
- data/lib/amf.rb +0 -17
- data/spec/amf/class_mapping_set_spec.rb +0 -34
- data/spec/amf/class_mapping_spec.rb +0 -120
- data/spec/amf/deserializer_spec.rb +0 -311
- data/spec/amf/remoting_spec.rb +0 -51
- data/spec/amf/serializer_spec.rb +0 -328
- data/spec/amf/values/array_collection_spec.rb +0 -6
- data/spec/amf/values/messages_spec.rb +0 -31
- data/spec/fixtures/objects/amf0-boolean.bin +0 -1
- data/spec/fixtures/objects/amf0-date.bin +0 -0
- data/spec/fixtures/objects/amf0-ecma-ordinal-array.bin +0 -0
- data/spec/fixtures/objects/amf0-hash.bin +0 -0
- data/spec/fixtures/objects/amf0-null.bin +0 -1
- data/spec/fixtures/objects/amf0-number.bin +0 -0
- data/spec/fixtures/objects/amf0-object.bin +0 -0
- data/spec/fixtures/objects/amf0-ref-test.bin +0 -0
- data/spec/fixtures/objects/amf0-strict-array.bin +0 -0
- data/spec/fixtures/objects/amf0-string.bin +0 -0
- data/spec/fixtures/objects/amf0-typed-object.bin +0 -0
- data/spec/fixtures/objects/amf0-undefined.bin +0 -1
- data/spec/fixtures/objects/amf0-untyped-object.bin +0 -0
- data/spec/fixtures/objects/amf3-0.bin +0 -0
- data/spec/fixtures/objects/amf3-arrayRef.bin +0 -1
- data/spec/fixtures/objects/amf3-bigNum.bin +0 -0
- data/spec/fixtures/objects/amf3-date.bin +0 -0
- data/spec/fixtures/objects/amf3-datesRef.bin +0 -0
- data/spec/fixtures/objects/amf3-dynObject.bin +0 -2
- data/spec/fixtures/objects/amf3-emptyArray.bin +0 -1
- data/spec/fixtures/objects/amf3-emptyArrayRef.bin +0 -1
- data/spec/fixtures/objects/amf3-emptyStringRef.bin +0 -1
- data/spec/fixtures/objects/amf3-false.bin +0 -1
- data/spec/fixtures/objects/amf3-graphMember.bin +0 -0
- data/spec/fixtures/objects/amf3-hash.bin +0 -2
- data/spec/fixtures/objects/amf3-largeMax.bin +0 -0
- data/spec/fixtures/objects/amf3-largeMin.bin +0 -0
- data/spec/fixtures/objects/amf3-max.bin +0 -1
- data/spec/fixtures/objects/amf3-min.bin +0 -0
- data/spec/fixtures/objects/amf3-mixedArray.bin +0 -11
- data/spec/fixtures/objects/amf3-null.bin +0 -1
- data/spec/fixtures/objects/amf3-objRef.bin +0 -0
- data/spec/fixtures/objects/amf3-primArray.bin +0 -1
- data/spec/fixtures/objects/amf3-string.bin +0 -1
- data/spec/fixtures/objects/amf3-stringRef.bin +0 -0
- data/spec/fixtures/objects/amf3-symbol.bin +0 -1
- data/spec/fixtures/objects/amf3-true.bin +0 -1
- data/spec/fixtures/objects/amf3-typedObject.bin +0 -2
- data/spec/fixtures/request/acknowledge-response.bin +0 -0
- data/spec/fixtures/request/amf0-error-response.bin +0 -0
- data/spec/fixtures/request/commandMessage.bin +0 -0
- data/spec/fixtures/request/remotingMessage.bin +0 -0
- data/spec/fixtures/request/simple-response.bin +0 -0
- data/spec/rack/request_spec.rb +0 -6
- data/spec/rack/response_spec.rb +0 -47
data/lib/amf/pure/io_helpers.rb
DELETED
@@ -1,94 +0,0 @@
|
|
1
|
-
module AMF
|
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
|
data/lib/amf/pure/remoting.rb
DELETED
@@ -1,120 +0,0 @@
|
|
1
|
-
require 'amf/pure/io_helpers'
|
2
|
-
|
3
|
-
module AMF
|
4
|
-
module Pure
|
5
|
-
# AMF request object wrapper, it is responsible for deserializing AMF requests
|
6
|
-
class Request
|
7
|
-
attr_reader :amf_version, :headers, :messages
|
8
|
-
|
9
|
-
def initialize
|
10
|
-
@amf_version = 0
|
11
|
-
@headers = []
|
12
|
-
@messages = []
|
13
|
-
end
|
14
|
-
|
15
|
-
def populate_from_stream stream
|
16
|
-
stream = StringIO.new(stream) unless StringIO === stream
|
17
|
-
|
18
|
-
# Read AMF version
|
19
|
-
@amf_version = read_word16_network stream
|
20
|
-
|
21
|
-
# Read in headers
|
22
|
-
header_count = read_word16_network stream
|
23
|
-
0.upto(header_count-1) do
|
24
|
-
name = stream.read(read_word16_network(stream))
|
25
|
-
must_understand = read_int8(stream) != 0
|
26
|
-
length = read_word32_network stream
|
27
|
-
data = AMF.deserialize stream
|
28
|
-
@headers << Header.new(name, must_understand, data)
|
29
|
-
end
|
30
|
-
|
31
|
-
# Read in messages
|
32
|
-
message_count = read_word16_network stream
|
33
|
-
0.upto(message_count-1) do
|
34
|
-
target_uri = stream.read(read_word16_network(stream))
|
35
|
-
response_uri = stream.read(read_word16_network(stream))
|
36
|
-
length = read_word32_network stream
|
37
|
-
data = AMF.deserialize stream
|
38
|
-
if data.is_a?(Array) && data.length == 1 && data[0].is_a?(::AMF::Values::AbstractMessage)
|
39
|
-
data = data[0]
|
40
|
-
end
|
41
|
-
@messages << Message.new(target_uri, response_uri, data)
|
42
|
-
end
|
43
|
-
|
44
|
-
self
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
include AMF::Pure::ReadIOHelpers
|
49
|
-
end
|
50
|
-
|
51
|
-
# AMF response object wrapper, it is responsible for serializing the AMF response
|
52
|
-
class Response
|
53
|
-
attr_accessor :amf_version, :headers, :messages
|
54
|
-
|
55
|
-
def initialize
|
56
|
-
@amf_version = 0
|
57
|
-
@headers = []
|
58
|
-
@messages = []
|
59
|
-
end
|
60
|
-
|
61
|
-
def serialize
|
62
|
-
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 do |h|
|
70
|
-
stream << pack_int16_network(h.name.length)
|
71
|
-
stream << h.name
|
72
|
-
stream << pack_int8(h.must_understand ? 1 : 0)
|
73
|
-
stream << pack_word32_network(-1)
|
74
|
-
stream << AMF.serialize(h.data, 0)
|
75
|
-
end
|
76
|
-
|
77
|
-
# Write messages
|
78
|
-
stream << pack_int16_network(@messages.length) # Message count
|
79
|
-
@messages.each do |m|
|
80
|
-
stream << pack_int16_network(m.target_uri.length)
|
81
|
-
stream << m.target_uri
|
82
|
-
|
83
|
-
stream << pack_int16_network(m.response_uri.length)
|
84
|
-
stream << m.response_uri
|
85
|
-
|
86
|
-
stream << pack_word32_network(-1)
|
87
|
-
stream << AMF0_AMF3_MARKER if @amf_version == 3
|
88
|
-
stream << AMF.serialize(m.data, @amf_version)
|
89
|
-
end
|
90
|
-
|
91
|
-
stream
|
92
|
-
end
|
93
|
-
|
94
|
-
private
|
95
|
-
include AMF::Pure::WriteIOHelpers
|
96
|
-
end
|
97
|
-
|
98
|
-
# AMF::Pure::Request or AMF::Pure::Response header
|
99
|
-
class Header
|
100
|
-
attr_accessor :name, :must_understand, :data
|
101
|
-
|
102
|
-
def initialize name, must_understand, data
|
103
|
-
@name = name
|
104
|
-
@must_understand = must_understand
|
105
|
-
@data = data
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
# AMF::Pure::Request or AMF::Pure::Response message
|
110
|
-
class Message
|
111
|
-
attr_accessor :target_uri, :response_uri, :data
|
112
|
-
|
113
|
-
def initialize target_uri, response_uri, data
|
114
|
-
@target_uri = target_uri
|
115
|
-
@response_uri = response_uri
|
116
|
-
@data = data
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
data/lib/amf/pure/serializer.rb
DELETED
@@ -1,327 +0,0 @@
|
|
1
|
-
require 'amf/pure/io_helpers'
|
2
|
-
|
3
|
-
module AMF
|
4
|
-
module Pure
|
5
|
-
# AMF0 implementation of serializer
|
6
|
-
class Serializer
|
7
|
-
def initialize
|
8
|
-
@ref_cache = SerializerCache.new :object
|
9
|
-
end
|
10
|
-
|
11
|
-
def version
|
12
|
-
0
|
13
|
-
end
|
14
|
-
|
15
|
-
def serialize obj, stream = ""
|
16
|
-
if obj.respond_to?(:to_amf)
|
17
|
-
stream << obj.to_amf(self)
|
18
|
-
elsif @ref_cache[obj] != nil
|
19
|
-
write_reference @ref_cache[obj], stream
|
20
|
-
elsif obj.is_a?(NilClass)
|
21
|
-
write_null stream
|
22
|
-
elsif obj.is_a?(TrueClass) || obj.is_a?(FalseClass)
|
23
|
-
write_boolean obj, stream
|
24
|
-
elsif obj.is_a?(Float) || obj.is_a?(Integer)
|
25
|
-
write_number obj, stream
|
26
|
-
elsif obj.is_a?(Symbol) || obj.is_a?(String)
|
27
|
-
write_string obj.to_s, stream
|
28
|
-
elsif obj.is_a?(Time)
|
29
|
-
write_date obj, stream
|
30
|
-
elsif obj.is_a?(Array)
|
31
|
-
write_array obj, stream
|
32
|
-
elsif obj.is_a?(Hash)
|
33
|
-
write_hash obj, stream
|
34
|
-
elsif obj.is_a?(Object)
|
35
|
-
write_object obj, stream
|
36
|
-
end
|
37
|
-
stream
|
38
|
-
end
|
39
|
-
|
40
|
-
def write_null stream
|
41
|
-
stream << AMF0_NULL_MARKER
|
42
|
-
end
|
43
|
-
|
44
|
-
def write_boolean bool, stream
|
45
|
-
stream << AMF0_BOOLEAN_MARKER
|
46
|
-
stream << pack_int8(bool ? 1 : 0)
|
47
|
-
end
|
48
|
-
|
49
|
-
def write_number num, stream
|
50
|
-
stream << AMF0_NUMBER_MARKER
|
51
|
-
stream << pack_double(num)
|
52
|
-
end
|
53
|
-
|
54
|
-
def write_string str, stream
|
55
|
-
len = str.length
|
56
|
-
if len > 2**16-1
|
57
|
-
stream << AMF0_LONG_STRING_MARKER
|
58
|
-
stream << pack_word32_network(len)
|
59
|
-
else
|
60
|
-
stream << AMF0_STRING_MARKER
|
61
|
-
stream << pack_int16_network(len)
|
62
|
-
end
|
63
|
-
stream << str
|
64
|
-
end
|
65
|
-
|
66
|
-
def write_date date, stream
|
67
|
-
stream << AMF0_DATE_MARKER
|
68
|
-
|
69
|
-
date.utc unless date.utc?
|
70
|
-
seconds = (date.to_f * 1000).to_i
|
71
|
-
stream << pack_double(seconds)
|
72
|
-
|
73
|
-
stream << pack_int16_network(0)
|
74
|
-
end
|
75
|
-
|
76
|
-
def write_reference index, stream
|
77
|
-
stream << AMF0_REFERENCE_MARKER
|
78
|
-
stream << pack_int16_network(index)
|
79
|
-
end
|
80
|
-
|
81
|
-
def write_array array, stream
|
82
|
-
@ref_cache.add_obj array
|
83
|
-
stream << AMF0_STRICT_ARRAY_MARKER
|
84
|
-
stream << pack_word32_network(array.length)
|
85
|
-
array.each do |elem|
|
86
|
-
serialize elem, stream
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def write_hash hash, stream
|
91
|
-
@ref_cache.add_obj hash
|
92
|
-
stream << AMF0_HASH_MARKER
|
93
|
-
stream << pack_word32_network(hash.length)
|
94
|
-
write_prop_list hash, stream
|
95
|
-
end
|
96
|
-
|
97
|
-
def write_object obj, stream
|
98
|
-
@ref_cache.add_obj obj
|
99
|
-
|
100
|
-
# Is it a typed object?
|
101
|
-
class_name = ClassMapper.get_as_class_name obj
|
102
|
-
if class_name
|
103
|
-
stream << AMF0_TYPED_OBJECT_MARKER
|
104
|
-
stream << pack_int16_network(class_name.length)
|
105
|
-
stream << class_name
|
106
|
-
else
|
107
|
-
stream << AMF0_OBJECT_MARKER
|
108
|
-
end
|
109
|
-
|
110
|
-
write_prop_list obj, stream
|
111
|
-
end
|
112
|
-
|
113
|
-
private
|
114
|
-
include AMF::Pure::WriteIOHelpers
|
115
|
-
def write_prop_list obj, stream
|
116
|
-
# Write prop list
|
117
|
-
props = ClassMapper.props_for_serialization obj
|
118
|
-
props.sort.each do |key, value| # Sort keys before writing
|
119
|
-
stream << pack_int16_network(key.length)
|
120
|
-
stream << key
|
121
|
-
serialize value, stream
|
122
|
-
end
|
123
|
-
|
124
|
-
# Write end
|
125
|
-
stream << pack_int16_network(0)
|
126
|
-
stream << AMF0_OBJECT_END_MARKER
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
# AMF3 implementation of serializer
|
131
|
-
class AMF3Serializer
|
132
|
-
attr_reader :string_cache
|
133
|
-
|
134
|
-
def initialize
|
135
|
-
@string_cache = SerializerCache.new :string
|
136
|
-
@object_cache = SerializerCache.new :object
|
137
|
-
end
|
138
|
-
|
139
|
-
def version
|
140
|
-
3
|
141
|
-
end
|
142
|
-
|
143
|
-
def serialize obj, stream = ""
|
144
|
-
if obj.respond_to?(:to_amf)
|
145
|
-
stream << obj.to_amf(self)
|
146
|
-
elsif obj.is_a?(NilClass)
|
147
|
-
write_null stream
|
148
|
-
elsif obj.is_a?(TrueClass)
|
149
|
-
write_true stream
|
150
|
-
elsif obj.is_a?(FalseClass)
|
151
|
-
write_false stream
|
152
|
-
elsif obj.is_a?(Float)
|
153
|
-
write_float obj, stream
|
154
|
-
elsif obj.is_a?(Integer)
|
155
|
-
write_integer obj, stream
|
156
|
-
elsif obj.is_a?(Symbol) || obj.is_a?(String)
|
157
|
-
write_string obj.to_s, stream
|
158
|
-
elsif obj.is_a?(Time)
|
159
|
-
write_date obj, stream
|
160
|
-
elsif obj.is_a?(Array)
|
161
|
-
write_array obj, stream
|
162
|
-
elsif obj.is_a?(Hash) || obj.is_a?(Object)
|
163
|
-
write_object obj, stream
|
164
|
-
end
|
165
|
-
stream
|
166
|
-
end
|
167
|
-
|
168
|
-
def write_reference index, stream
|
169
|
-
header = index << 1 # shift value left to leave a low bit of 0
|
170
|
-
stream << pack_integer(header)
|
171
|
-
end
|
172
|
-
|
173
|
-
def write_null stream
|
174
|
-
stream << AMF3_NULL_MARKER
|
175
|
-
end
|
176
|
-
|
177
|
-
def write_true stream
|
178
|
-
stream << AMF3_TRUE_MARKER
|
179
|
-
end
|
180
|
-
|
181
|
-
def write_false stream
|
182
|
-
stream << AMF3_FALSE_MARKER
|
183
|
-
end
|
184
|
-
|
185
|
-
def write_integer int, stream
|
186
|
-
if int < MIN_INTEGER || int > MAX_INTEGER # Check valid range for 29 bits
|
187
|
-
write_float int.to_f, stream
|
188
|
-
else
|
189
|
-
stream << AMF3_INTEGER_MARKER
|
190
|
-
stream << pack_integer(int)
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
def write_float float, stream
|
195
|
-
stream << AMF3_DOUBLE_MARKER
|
196
|
-
stream << pack_double(float)
|
197
|
-
end
|
198
|
-
|
199
|
-
def write_string str, stream
|
200
|
-
stream << AMF3_STRING_MARKER
|
201
|
-
write_utf8_vr str, stream
|
202
|
-
end
|
203
|
-
|
204
|
-
def write_date date, stream
|
205
|
-
stream << AMF3_DATE_MARKER
|
206
|
-
if @object_cache[date] != nil
|
207
|
-
write_reference @object_cache[date], stream
|
208
|
-
else
|
209
|
-
# Cache date
|
210
|
-
@object_cache.add_obj date
|
211
|
-
|
212
|
-
# Build AMF string
|
213
|
-
date.utc unless date.utc?
|
214
|
-
seconds = (date.to_f * 1000).to_i
|
215
|
-
stream << pack_integer(AMF3_NULL_MARKER)
|
216
|
-
stream << pack_double(seconds)
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
def write_array array, stream
|
221
|
-
stream << AMF3_ARRAY_MARKER
|
222
|
-
if @object_cache[array] != nil
|
223
|
-
write_reference @object_cache[array], stream
|
224
|
-
else
|
225
|
-
# Cache array
|
226
|
-
@object_cache.add_obj array
|
227
|
-
|
228
|
-
# Build AMF string
|
229
|
-
header = array.length << 1 # make room for a low bit of 1
|
230
|
-
header = header | 1 # set the low bit to 1
|
231
|
-
stream << pack_integer(header)
|
232
|
-
stream << AMF3_CLOSE_DYNAMIC_ARRAY
|
233
|
-
array.each do |elem|
|
234
|
-
serialize elem, stream
|
235
|
-
end
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
def write_object obj, stream
|
240
|
-
stream << AMF3_OBJECT_MARKER
|
241
|
-
if @object_cache[obj] != nil
|
242
|
-
write_reference @object_cache[obj], stream
|
243
|
-
else
|
244
|
-
# Cache object
|
245
|
-
@object_cache.add_obj obj
|
246
|
-
|
247
|
-
# Always serialize things as dynamic objects
|
248
|
-
stream << AMF3_DYNAMIC_OBJECT
|
249
|
-
|
250
|
-
# Write class name/anonymous
|
251
|
-
class_name = ClassMapper.get_as_class_name obj
|
252
|
-
if class_name
|
253
|
-
write_utf8_vr class_name, stream
|
254
|
-
else
|
255
|
-
stream << AMF3_ANONYMOUS_OBJECT
|
256
|
-
end
|
257
|
-
|
258
|
-
# Write out properties
|
259
|
-
props = ClassMapper.props_for_serialization obj
|
260
|
-
props.sort.each do |key, val| # Sort props until Ruby 1.9 becomes common
|
261
|
-
write_utf8_vr key.to_s, stream
|
262
|
-
serialize val, stream
|
263
|
-
end
|
264
|
-
|
265
|
-
# Write close
|
266
|
-
stream << AMF3_CLOSE_DYNAMIC_OBJECT
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
private
|
271
|
-
include AMF::Pure::WriteIOHelpers
|
272
|
-
|
273
|
-
def write_utf8_vr str, stream
|
274
|
-
if str == ''
|
275
|
-
stream << AMF3_EMPTY_STRING
|
276
|
-
elsif @string_cache[str] != nil
|
277
|
-
write_reference @string_cache[str], stream
|
278
|
-
else
|
279
|
-
# Cache string
|
280
|
-
@string_cache.add_obj str
|
281
|
-
|
282
|
-
# Build AMF string
|
283
|
-
header = str.length << 1 # make room for a low bit of 1
|
284
|
-
header = header | 1 # set the low bit to 1
|
285
|
-
stream << pack_integer(header)
|
286
|
-
stream << str
|
287
|
-
end
|
288
|
-
end
|
289
|
-
end
|
290
|
-
|
291
|
-
class SerializerCache #:nodoc:
|
292
|
-
def self.new type
|
293
|
-
if type == :string
|
294
|
-
StringCache.new
|
295
|
-
elsif type == :object
|
296
|
-
ObjectCache.new
|
297
|
-
end
|
298
|
-
end
|
299
|
-
|
300
|
-
class StringCache < Hash #:nodoc:
|
301
|
-
def initialize
|
302
|
-
@cache_index = 0
|
303
|
-
end
|
304
|
-
|
305
|
-
def add_obj str
|
306
|
-
self[str] = @cache_index
|
307
|
-
@cache_index += 1
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
class ObjectCache < Hash #:nodoc:
|
312
|
-
def initialize
|
313
|
-
@cache_index = 0
|
314
|
-
end
|
315
|
-
|
316
|
-
def [] obj
|
317
|
-
super(obj.object_id)
|
318
|
-
end
|
319
|
-
|
320
|
-
def add_obj obj
|
321
|
-
self[obj.object_id] = @cache_index
|
322
|
-
@cache_index += 1
|
323
|
-
end
|
324
|
-
end
|
325
|
-
end
|
326
|
-
end
|
327
|
-
end
|
data/lib/amf/pure.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'amf/constants'
|
2
|
-
require 'amf/pure/deserializer'
|
3
|
-
require 'amf/pure/serializer'
|
4
|
-
require 'amf/pure/remoting'
|
5
|
-
|
6
|
-
module AMF
|
7
|
-
# This module holds all the modules/classes that implement AMF's
|
8
|
-
# functionality in pure ruby.
|
9
|
-
module Pure
|
10
|
-
$DEBUG and warn "Using pure library for AMF."
|
11
|
-
end
|
12
|
-
|
13
|
-
include AMF::Pure
|
14
|
-
end
|
data/lib/amf/values/messages.rb
DELETED
@@ -1,133 +0,0 @@
|
|
1
|
-
module AMF
|
2
|
-
module Values #:nodoc:
|
3
|
-
# Base class for all special AS3 response messages. Maps to
|
4
|
-
# <tt>flex.messaging.messages.AbstractMessage</tt>
|
5
|
-
class AbstractMessage
|
6
|
-
attr_accessor :clientId
|
7
|
-
attr_accessor :destination
|
8
|
-
attr_accessor :messageId
|
9
|
-
attr_accessor :timestamp
|
10
|
-
attr_accessor :timeToLive
|
11
|
-
attr_accessor :headers
|
12
|
-
attr_accessor :body
|
13
|
-
|
14
|
-
protected
|
15
|
-
def rand_uuid
|
16
|
-
[8,4,4,4,12].map {|n| rand_hex_3(n)}.join('-').to_s
|
17
|
-
end
|
18
|
-
|
19
|
-
def rand_hex_3(l)
|
20
|
-
"%0#{l}x" % rand(1 << l*4)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# Maps to <tt>flex.messaging.messages.RemotingMessage</tt>
|
25
|
-
class RemotingMessage < AbstractMessage
|
26
|
-
# The name of the service to be called including package name
|
27
|
-
attr_accessor :source
|
28
|
-
|
29
|
-
# The name of the method to be called
|
30
|
-
attr_accessor :operation
|
31
|
-
|
32
|
-
# The arguments to call the method with
|
33
|
-
attr_accessor :parameters
|
34
|
-
|
35
|
-
def initialize
|
36
|
-
@clientId = rand_uuid
|
37
|
-
@destination = nil
|
38
|
-
@messageId = rand_uuid
|
39
|
-
@timestamp = Time.new.to_i*100
|
40
|
-
@timeToLive = 0
|
41
|
-
@headers = {}
|
42
|
-
@body = nil
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Maps to <tt>flex.messaging.messages.AsyncMessage</tt>
|
47
|
-
class AsyncMessage < AbstractMessage
|
48
|
-
attr_accessor :correlationId
|
49
|
-
end
|
50
|
-
|
51
|
-
# Maps to <tt>flex.messaging.messages.CommandMessage</tt>
|
52
|
-
class CommandMessage < AsyncMessage
|
53
|
-
SUBSCRIBE_OPERATION = 0
|
54
|
-
UNSUSBSCRIBE_OPERATION = 1
|
55
|
-
POLL_OPERATION = 2
|
56
|
-
CLIENT_SYNC_OPERATION = 4
|
57
|
-
CLIENT_PING_OPERATION = 5
|
58
|
-
CLUSTER_REQUEST_OPERATION = 7
|
59
|
-
LOGIN_OPERATION = 8
|
60
|
-
LOGOUT_OPERATION = 9
|
61
|
-
SESSION_INVALIDATE_OPERATION = 10
|
62
|
-
MULTI_SUBSCRIBE_OPERATION = 11
|
63
|
-
DISCONNECT_OPERATION = 12
|
64
|
-
UNKNOWN_OPERATION = 10000
|
65
|
-
|
66
|
-
attr_accessor :operation
|
67
|
-
|
68
|
-
def initialize
|
69
|
-
@operation = UNKNOWN_OPERATION
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
# Maps to <tt>flex.messaging.messages.AcknowledgeMessage</tt>
|
74
|
-
class AcknowledgeMessage < AsyncMessage
|
75
|
-
def initialize message=nil
|
76
|
-
@clientId = rand_uuid
|
77
|
-
@destination = nil
|
78
|
-
@messageId = rand_uuid
|
79
|
-
@timestamp = Time.new.to_i*100
|
80
|
-
@timeToLive = 0
|
81
|
-
@headers = {}
|
82
|
-
@body = nil
|
83
|
-
|
84
|
-
if message.is_a?(AbstractMessage)
|
85
|
-
@correlationId = message.messageId
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
# Maps to <tt>flex.messaging.messages.ErrorMessage</tt> in AMF3 mode
|
91
|
-
class ErrorMessage < AcknowledgeMessage
|
92
|
-
# Extended data that will facilitate custom error processing on the client
|
93
|
-
attr_accessor :extendedData
|
94
|
-
|
95
|
-
# The fault code for the error, which defaults to the class name of the
|
96
|
-
# causing exception
|
97
|
-
attr_accessor :faultCode
|
98
|
-
|
99
|
-
# Detailed description of what caused the error
|
100
|
-
attr_accessor :faultDetail
|
101
|
-
|
102
|
-
# A simple description of the error
|
103
|
-
attr_accessor :faultString
|
104
|
-
|
105
|
-
# Optional "root cause" of the error
|
106
|
-
attr_accessor :rootCause
|
107
|
-
|
108
|
-
def initialize message, exception
|
109
|
-
super message
|
110
|
-
|
111
|
-
@e = exception
|
112
|
-
@faultCode = @e.class.name
|
113
|
-
@faultDetail = @e.backtrace.join("\n")
|
114
|
-
@faultString = @e.message
|
115
|
-
end
|
116
|
-
|
117
|
-
def to_amf serializer
|
118
|
-
stream = ""
|
119
|
-
if serializer.version == 0
|
120
|
-
data = {
|
121
|
-
:faultCode => @faultCode,
|
122
|
-
:faultDetail => @faultDetail,
|
123
|
-
:faultString => @faultString
|
124
|
-
}
|
125
|
-
serializer.write_hash(data, stream)
|
126
|
-
else
|
127
|
-
serializer.write_object(self, stream)
|
128
|
-
end
|
129
|
-
stream
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module AMF
|
2
|
-
module Values #:nodoc:
|
3
|
-
# Hash-like object that can store a type string. Used to preserve type information
|
4
|
-
# for unmapped objects after deserialization.
|
5
|
-
class TypedHash < Hash
|
6
|
-
attr_reader :type
|
7
|
-
|
8
|
-
def initialize type
|
9
|
-
@type = type
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|