mrpin-amf 2.1.8

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 (81) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/README.rdoc +52 -0
  4. data/Rakefile +59 -0
  5. data/benchmark.rb +86 -0
  6. data/doc/amf3-speification.pdf +0 -0
  7. data/ext/rocketamf_ext/class_mapping.c +483 -0
  8. data/ext/rocketamf_ext/constants.h +52 -0
  9. data/ext/rocketamf_ext/deserializer.c +776 -0
  10. data/ext/rocketamf_ext/deserializer.h +28 -0
  11. data/ext/rocketamf_ext/extconf.rb +18 -0
  12. data/ext/rocketamf_ext/remoting.c +184 -0
  13. data/ext/rocketamf_ext/rocketamf_ext.c +38 -0
  14. data/ext/rocketamf_ext/serializer.c +834 -0
  15. data/ext/rocketamf_ext/serializer.h +29 -0
  16. data/ext/rocketamf_ext/utility.h +4 -0
  17. data/lib/amf/common/hash_with_type.rb +20 -0
  18. data/lib/amf/ext.rb +22 -0
  19. data/lib/amf/pure/amf_constants.rb +42 -0
  20. data/lib/amf/pure/deserializer.rb +354 -0
  21. data/lib/amf/pure/errors/all_files.rb +2 -0
  22. data/lib/amf/pure/errors/amf_error.rb +5 -0
  23. data/lib/amf/pure/errors/amf_error_incomplete.rb +5 -0
  24. data/lib/amf/pure/helpers/all_files.rb +8 -0
  25. data/lib/amf/pure/helpers/cache_objects.rb +18 -0
  26. data/lib/amf/pure/helpers/cache_strings.rb +14 -0
  27. data/lib/amf/pure/helpers/io_helper_base.rb +19 -0
  28. data/lib/amf/pure/helpers/io_helper_read.rb +67 -0
  29. data/lib/amf/pure/helpers/io_helper_write.rb +49 -0
  30. data/lib/amf/pure/mapping/class_mapper.rb +159 -0
  31. data/lib/amf/pure/mapping/mapping_set.rb +49 -0
  32. data/lib/amf/pure/serializer.rb +318 -0
  33. data/lib/amf/pure.rb +16 -0
  34. data/lib/amf.rb +140 -0
  35. data/mrpin-amf.gemspec +24 -0
  36. data/spec/fixtures/objects/complex/amf3-associative-array.bin +1 -0
  37. data/spec/fixtures/objects/complex/amf3-byte-array.bin +0 -0
  38. data/spec/fixtures/objects/complex/amf3-date.bin +0 -0
  39. data/spec/fixtures/objects/complex/amf3-dictionary.bin +0 -0
  40. data/spec/fixtures/objects/complex/amf3-dynamic-object.bin +2 -0
  41. data/spec/fixtures/objects/complex/amf3-empty-array.bin +1 -0
  42. data/spec/fixtures/objects/complex/amf3-empty-dictionary.bin +0 -0
  43. data/spec/fixtures/objects/complex/amf3-hash.bin +2 -0
  44. data/spec/fixtures/objects/complex/amf3-mixed-array.bin +10 -0
  45. data/spec/fixtures/objects/complex/amf3-primitive-array.bin +1 -0
  46. data/spec/fixtures/objects/complex/amf3-typed-object.bin +2 -0
  47. data/spec/fixtures/objects/encoding/amf3-complex-encoded-string-array.bin +1 -0
  48. data/spec/fixtures/objects/encoding/amf3-encoded-string-ref.bin +0 -0
  49. data/spec/fixtures/objects/references/amf3-array-ref.bin +1 -0
  50. data/spec/fixtures/objects/references/amf3-byte-array-ref.bin +1 -0
  51. data/spec/fixtures/objects/references/amf3-date-ref.bin +0 -0
  52. data/spec/fixtures/objects/references/amf3-empty-array-ref.bin +1 -0
  53. data/spec/fixtures/objects/references/amf3-empty-string-ref.bin +1 -0
  54. data/spec/fixtures/objects/references/amf3-graph-member.bin +0 -0
  55. data/spec/fixtures/objects/references/amf3-object-ref.bin +0 -0
  56. data/spec/fixtures/objects/references/amf3-string-ref.bin +0 -0
  57. data/spec/fixtures/objects/references/amf3-trait-ref.bin +3 -0
  58. data/spec/fixtures/objects/simple/amf3-0.bin +0 -0
  59. data/spec/fixtures/objects/simple/amf3-bigNum.bin +0 -0
  60. data/spec/fixtures/objects/simple/amf3-false.bin +1 -0
  61. data/spec/fixtures/objects/simple/amf3-float.bin +0 -0
  62. data/spec/fixtures/objects/simple/amf3-large-max.bin +0 -0
  63. data/spec/fixtures/objects/simple/amf3-large-min.bin +0 -0
  64. data/spec/fixtures/objects/simple/amf3-max.bin +1 -0
  65. data/spec/fixtures/objects/simple/amf3-min.bin +0 -0
  66. data/spec/fixtures/objects/simple/amf3-null.bin +1 -0
  67. data/spec/fixtures/objects/simple/amf3-string.bin +1 -0
  68. data/spec/fixtures/objects/simple/amf3-symbol.bin +1 -0
  69. data/spec/fixtures/objects/simple/amf3-true.bin +1 -0
  70. data/spec/helpers/class_mapping_test.rb +4 -0
  71. data/spec/helpers/class_mapping_test2.rb +3 -0
  72. data/spec/helpers/fixtures.rb +34 -0
  73. data/spec/helpers/other_class.rb +4 -0
  74. data/spec/helpers/ruby_class.rb +4 -0
  75. data/spec/helpers/test_ruby_class.rb +4 -0
  76. data/spec/spec-class_mapping.rb +98 -0
  77. data/spec/spec_deserializer.rb +239 -0
  78. data/spec/spec_fast_class_mapping.rb +147 -0
  79. data/spec/spec_helper.rb +8 -0
  80. data/spec/spec_serializer.rb +267 -0
  81. metadata +146 -0
@@ -0,0 +1,29 @@
1
+ #include <ruby.h>
2
+ #ifdef HAVE_RB_STR_ENCODE
3
+ #include <ruby/st.h>
4
+ #include <ruby/encoding.h>
5
+ #else
6
+ #include <st.h>
7
+ #endif
8
+
9
+ typedef struct {
10
+ int version;
11
+ VALUE class_mapper;
12
+ VALUE stream;
13
+ long depth;
14
+ st_table* str_cache;
15
+ long str_index;
16
+ st_table* trait_cache;
17
+ long trait_index;
18
+ st_table* obj_cache;
19
+ long obj_index;
20
+ } AMF_SERIALIZER;
21
+
22
+ void ser_write_byte(AMF_SERIALIZER *ser, char byte);
23
+ void ser_write_int(AMF_SERIALIZER *ser, int num);
24
+ void ser_write_uint16(AMF_SERIALIZER *ser, long num);
25
+ void ser_write_uint32(AMF_SERIALIZER *ser, long num);
26
+ void ser_write_double(AMF_SERIALIZER *ser, double num);
27
+ void ser_get_string(VALUE obj, VALUE encode, char** str, long* len);
28
+
29
+ VALUE ser_serialize(VALUE self, VALUE ver, VALUE obj);
@@ -0,0 +1,4 @@
1
+ // Before RFLOAT_VALUE, value was in a different place in the struct
2
+ #ifndef RFLOAT_VALUE
3
+ #define RFLOAT_VALUE(v) (RFLOAT(v)->value)
4
+ #endif
@@ -0,0 +1,20 @@
1
+ module AMF
2
+ # Hash-like object that can store a type string. Used to preserve type information
3
+ # for unmapped objects after deserialization.
4
+ class HashWithType < Hash
5
+
6
+ #
7
+ # Properties
8
+ #
9
+
10
+ attr_reader :class_type
11
+
12
+ #
13
+ # Methods
14
+ #
15
+
16
+ def initialize(type)
17
+ @class_type = type
18
+ end
19
+ end
20
+ end
data/lib/amf/ext.rb ADDED
@@ -0,0 +1,22 @@
1
+ begin
2
+ # Fat binaries for Windows
3
+ RUBY_VERSION =~ /(\d+.\d+)/
4
+ require "#{$1}/rocketamf_ext"
5
+ rescue LoadError
6
+ require 'rocketamf_ext'
7
+ end
8
+
9
+ module AMF
10
+ # This module holds all the modules/classes that implement AMF's functionality
11
+ # in C
12
+ module Ext
13
+ $DEBUG and warn 'Using C library for AMF.'
14
+ end
15
+
16
+ #:stopdoc:
17
+ # Import serializer/deserializer
18
+ Deserializer = AMF::Ext::Deserializer
19
+ Serializer = AMF::Ext::Serializer
20
+
21
+ #:startdoc:
22
+ end
@@ -0,0 +1,42 @@
1
+ module AMF
2
+ module AMFConstants
3
+ # AMF3 Type Markers
4
+ AMF3_MARKER_UNDEFINED = 0x00 #"\000"
5
+ AMF3_MARKER_NULL = 0x01 #"\001"
6
+
7
+ AMF3_MARKER_FALSE = 0x02 #"\002"
8
+ AMF3_MARKER_TRUE = 0x03 #"\003"
9
+
10
+ AMF3_MARKER_INTEGER = 0x04 #"\004"
11
+ AMF3_MARKER_DOUBLE = 0x05 #"\005"
12
+ AMF3_MARKER_STRING = 0x06 #"\006"
13
+ AMF3_MARKER_XML_DOC = 0x07 #"\a" not supported
14
+ AMF3_MARKER_DATE = 0x08 #"\b"
15
+ AMF3_MARKER_ARRAY = 0x09 #"\t"
16
+ AMF3_MARKER_OBJECT = 0x0A #"\n"
17
+ AMF3_MARKER_XML = 0x0B #"\v" not supported
18
+ AMF3_MARKER_BYTE_ARRAY = 0x0C #"\f"
19
+
20
+ AMF3_MARKER_VECTOR_INT = 0x0D #"\r" not supported
21
+ AMF3_MARKER_VECTOR_UINT = 0x0E #"\016" not supported
22
+ AMF3_MARKER_VECTOR_DOUBLE = 0x0F #"\017" not supported
23
+ AMF3_MARKER_VECTOR_OBJECT = 0x10 #"\020" not supported
24
+
25
+ AMF3_MARKER_DICTIONARY = 0x11 #"\021"
26
+
27
+ # Other AMF3 Markers
28
+ AMF3_EMPTY_STRING = 0x01
29
+
30
+ AMF3_CLOSE_DYNAMIC_OBJECT = 0x01
31
+ AMF3_CLOSE_DYNAMIC_ARRAY = 0x01
32
+
33
+ # The minimum value for an integer that will avoid promotion to an ActionScript's Number type.
34
+ INTEGER_MIN = -268_435_456
35
+ # The maximum value for an integer that will avoid promotion to an ActionScript's Number type.
36
+ INTEGER_MAX = 268_435_455
37
+
38
+ MIN_INT_2_BYTE = 0x80
39
+ MIN_INT_3_BYTE = 0x4000
40
+ MIN_INT_4_BYTE = 0x200000
41
+ end
42
+ end
@@ -0,0 +1,354 @@
1
+ module AMF
2
+ module Pure
3
+ # Pure ruby deserializer for AMF3 requests
4
+ class Deserializer
5
+
6
+ #
7
+ # Modules
8
+ #
9
+ private
10
+ include AMF::Pure::IOHelperRead
11
+ include AMF::AMFConstants
12
+
13
+ #
14
+ # Properties
15
+ #
16
+
17
+ # Used for read_object
18
+ public
19
+ attr_reader :source
20
+
21
+ # Pass in the class mapper instance to use when deserializing. This
22
+ # enables better caching behavior in the class mapper and allows
23
+ # one to change mappings between deserialization attempts.
24
+ public
25
+ def initialize(class_mapper)
26
+ @class_mapper = class_mapper
27
+ end
28
+
29
+ # Deserialize the source using AMF3. Source should either
30
+ # be a string or StringIO object. If you pass a StringIO object,
31
+ # it will have its position updated to the end of the deserialized
32
+ # data.
33
+ # raise AMFError if error appeared in deserialize, source is nil
34
+ # raise AMFErrorIncomplete if source is incomplete
35
+ # return hash {objects: [], incomplete_objects: String}
36
+ public
37
+ def deserialize(source)
38
+ raise AMFError, 'no source to deserialize' if source.nil?
39
+
40
+ @source = source.is_a?(StringIO) ? source : StringIO.new(source)
41
+
42
+ objects = []
43
+
44
+ incomplete_objects = nil
45
+
46
+ until @source.eof?
47
+
48
+ @cache_strings = []
49
+ @cache_objects = []
50
+ @cache_traits = []
51
+
52
+ source_position = @source.pos
53
+
54
+ begin
55
+ objects << amf3_deserialize
56
+ rescue AMFErrorIncomplete, AMFError => e
57
+
58
+ @source.pos = source_position
59
+
60
+ incomplete_objects = @source.read
61
+
62
+ break
63
+ end
64
+ end
65
+
66
+ {
67
+ objects: objects,
68
+ incomplete_objects: incomplete_objects
69
+ }
70
+ end
71
+
72
+ # Reads an object from the deserializer stream and returns it.
73
+ public
74
+ def read_object
75
+ amf3_deserialize
76
+ end
77
+
78
+ private
79
+ def amf3_deserialize
80
+ type = read_int8(@source)
81
+
82
+ case type
83
+ when AMF3_MARKER_UNDEFINED
84
+ nil
85
+ when AMF3_MARKER_NULL
86
+ nil
87
+ when AMF3_MARKER_FALSE
88
+ false
89
+ when AMF3_MARKER_TRUE
90
+ true
91
+ when AMF3_MARKER_INTEGER
92
+ amf3_read_integer
93
+ when AMF3_MARKER_DOUBLE
94
+ amf3_read_number
95
+ when AMF3_MARKER_STRING
96
+ amf3_read_string
97
+ when AMF3_MARKER_DATE
98
+ amf3_read_date
99
+ when AMF3_MARKER_ARRAY
100
+ amf3_read_array
101
+ when AMF3_MARKER_OBJECT
102
+ amf3_read_object
103
+ when AMF3_MARKER_BYTE_ARRAY
104
+ amf3_read_byte_array
105
+ when AMF3_MARKER_VECTOR_INT, AMF3_MARKER_VECTOR_UINT, AMF3_MARKER_VECTOR_DOUBLE, AMF3_MARKER_VECTOR_OBJECT, AMF3_MARKER_XML_DOC, AMF3_MARKER_XML
106
+ raise AMFError, "Unsupported type: #{type}"
107
+ when AMF3_MARKER_DICTIONARY
108
+ amf3_read_dictionary
109
+ else
110
+ raise AMFError, "Invalid type: #{type}"
111
+ end
112
+ end
113
+
114
+ private
115
+ def get_as_reference_object(type)
116
+ result = nil
117
+
118
+ if (type & 0x01) == 0 #is reference?
119
+ reference = type >> 1
120
+ result = @cache_objects[reference]
121
+ end
122
+
123
+ result
124
+ end
125
+
126
+ private
127
+ def get_as_reference_string(type)
128
+ result = nil
129
+
130
+ if (type & 0x01) == 0 #is reference?
131
+ reference = type >> 1
132
+ result = @cache_strings[reference]
133
+ end
134
+
135
+ result
136
+ end
137
+
138
+ private
139
+ def amf3_read_integer
140
+ result = 0
141
+
142
+ n = 0
143
+ b = read_word8(@source) || 0
144
+
145
+ while (b & 0x80) != 0 && n < 3
146
+ result = result << 7
147
+ result = result | (b & 0x7f)
148
+ b = read_word8(@source) || 0
149
+ n = n + 1
150
+ end
151
+
152
+ if n < 3
153
+ result = result << 7
154
+ result = result | b
155
+ else
156
+ #Use all 8 bits from the 4th byte
157
+ result = result << 8
158
+ result = result | b
159
+
160
+ #Check if the integer should be negative
161
+ if result > INTEGER_MAX
162
+ result -= (1 << 29)
163
+ end
164
+ end
165
+
166
+ result
167
+ end
168
+
169
+ private
170
+ def amf3_read_number
171
+ result = read_double(@source)
172
+
173
+ #check for NaN and convert them to nil
174
+ if result.is_a?(Float) && result.nan?
175
+ result = nil
176
+ end
177
+
178
+ result
179
+ end
180
+
181
+ private
182
+ def amf3_read_string
183
+ result = nil
184
+
185
+ type = amf3_read_integer
186
+
187
+ result = get_as_reference_string(type)
188
+
189
+ if result.nil?
190
+ length = type >> 1
191
+ result = ''
192
+
193
+ if length > 0
194
+
195
+ if length > (@source.size - @source.pos)
196
+ raise AMFErrorIncomplete.new
197
+ end
198
+
199
+ result = @source.read(length)
200
+ result.force_encoding('UTF-8') if result.respond_to?(:force_encoding)
201
+ @cache_strings << result
202
+ end
203
+ end
204
+
205
+ result
206
+ end
207
+
208
+ private
209
+ def amf3_read_date
210
+ result = nil
211
+
212
+ type = amf3_read_integer
213
+
214
+ result = get_as_reference_object(type)
215
+
216
+ if result.nil?
217
+ seconds = read_double(@source).to_f / 1000
218
+ result = Time.at(seconds)
219
+ @cache_objects << result
220
+ end
221
+
222
+ result
223
+ end
224
+
225
+ private
226
+ def amf3_read_array
227
+ result = nil
228
+
229
+ type = amf3_read_integer
230
+
231
+ result = get_as_reference_object(type)
232
+
233
+ if result.nil?
234
+ length = type >> 1
235
+ property_name = amf3_read_string
236
+ result = property_name.length > 0 ? {} : []
237
+ @cache_objects << result
238
+
239
+ while property_name.length > 0
240
+ value = amf3_deserialize
241
+ result[property_name] = value
242
+ property_name = amf3_read_string
243
+ end
244
+
245
+ 0.upto(length - 1) { |i| result[i] = amf3_deserialize }
246
+ end
247
+
248
+ result
249
+ end
250
+
251
+ # dynamic - c an instance of a Class definition with the dynamic trait declared; public variable members can be added and removed from instances dynamically at runtime
252
+ private
253
+ def amf3_read_object
254
+ result = nil
255
+
256
+ type = amf3_read_integer
257
+
258
+ result = get_as_reference_object(type)
259
+
260
+ if result.nil?
261
+ class_type = type >> 1
262
+ class_is_reference = (class_type & 0x01) == 0
263
+
264
+ if class_is_reference
265
+ reference = class_type >> 1
266
+ traits = @cache_traits[reference]
267
+ else
268
+ dynamic = (class_type & 0x04) != 0
269
+ attribute_count = class_type >> 3
270
+ class_name = amf3_read_string
271
+
272
+ class_attributes = []
273
+ attribute_count.times { class_attributes << amf3_read_string } # Read class members
274
+
275
+ traits =
276
+ {
277
+ class_name: class_name,
278
+ members: class_attributes,
279
+ dynamic: dynamic
280
+ }
281
+ @cache_traits << traits
282
+ end
283
+
284
+ result = @class_mapper.create_object(traits[:class_name])
285
+ @cache_objects << result
286
+
287
+ properties = {}
288
+
289
+ traits[:members].each do |key|
290
+ value = amf3_deserialize
291
+ properties[key] = value
292
+ end
293
+
294
+ if traits[:dynamic]
295
+ while (key = amf3_read_string) && key.length != 0 do # read next key
296
+ value = amf3_deserialize
297
+ properties[key] = value
298
+ end
299
+ end
300
+
301
+ @class_mapper.object_deserialize(result, properties)
302
+ end
303
+
304
+ result
305
+ end
306
+
307
+ private
308
+ def amf3_read_byte_array
309
+ result = nil
310
+
311
+ type = amf3_read_integer
312
+
313
+ result = get_as_reference_object(type)
314
+
315
+ if result.nil?
316
+ length = type >> 1
317
+
318
+ if length > (@source.size - @source.pos)
319
+ raise AMFErrorIncomplete.new
320
+ end
321
+
322
+ result = StringIO.new(@source.read(length))
323
+ @cache_objects << result
324
+ end
325
+
326
+ result
327
+ end
328
+
329
+ private
330
+ def amf3_read_dictionary
331
+ result = nil
332
+
333
+ type = amf3_read_integer
334
+
335
+ result = get_as_reference_object(type)
336
+
337
+ if result.nil?
338
+ result = {}
339
+ @cache_objects << result
340
+ length = type >> 1
341
+ weak_keys = read_int8(@source) # Ignore: Not supported in ruby
342
+
343
+ 0.upto(length - 1) do |i|
344
+ result[amf3_deserialize] = amf3_deserialize
345
+ end
346
+
347
+ end
348
+
349
+ result
350
+ end
351
+
352
+ end #Deserializer
353
+ end #Pure
354
+ end
@@ -0,0 +1,2 @@
1
+ require 'amf/pure/errors/amf_error'
2
+ require 'amf/pure/errors/amf_error_incomplete'
@@ -0,0 +1,5 @@
1
+ module AMF
2
+ # The standard AMF error.
3
+ class AMFError < StandardError
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module AMF
2
+ # Error for incomplete messages
3
+ class AMFErrorIncomplete < AMFError
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ require 'amf/pure/amf_constants'
2
+
3
+ require 'amf/pure/helpers/io_helper_base'
4
+ require 'amf/pure/helpers/io_helper_write'
5
+ require 'amf/pure/helpers/io_helper_read'
6
+
7
+ require 'amf/pure/helpers/cache_objects'
8
+ require 'amf/pure/helpers/cache_strings'
@@ -0,0 +1,18 @@
1
+ module AMF
2
+ module Pure
3
+ class CacheObjects < Hash #:nodoc:
4
+ def initialize
5
+ @cache_index = 0
6
+ end
7
+
8
+ def [](obj)
9
+ super(obj.object_id)
10
+ end
11
+
12
+ def add_object(value)
13
+ self[value.object_id] = @cache_index
14
+ @cache_index += 1
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ module AMF
2
+ module Pure
3
+ class CacheStrings < Hash #:nodoc:
4
+ def initialize
5
+ @cache_index = 0
6
+ end
7
+
8
+ def add_string(value)
9
+ self[value] = @cache_index
10
+ @cache_index += 1
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ module AMF
2
+ module Pure
3
+ module IOHelperBase
4
+
5
+ def byte_order
6
+ if [0x12345678].pack('L') == "\x12\x34\x56\x78"
7
+ :BigEndian
8
+ else
9
+ :LittleEndian
10
+ end
11
+ end
12
+
13
+ def byte_order_little?
14
+ byte_order == :LittleEndian
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,67 @@
1
+ require 'amf/pure/helpers/io_helper_base'
2
+
3
+ module AMF
4
+ module Pure
5
+ module IOHelperRead #:nodoc:
6
+
7
+ include IOHelperBase
8
+
9
+ #
10
+ # Methods
11
+ #
12
+
13
+ public
14
+ def read_int8(source)
15
+ raise AMFErrorIncomplete.new if source.eof?
16
+
17
+ source.read(1).unpack('c').first
18
+ end
19
+
20
+ public
21
+ def read_word8(source)
22
+ raise AMFErrorIncomplete.new if source.eof?
23
+
24
+ source.read(1).unpack('C').first
25
+ end
26
+
27
+ public
28
+ def read_double(source)
29
+ bytes_to_read = 8
30
+
31
+ raise AMFErrorIncomplete.new if bytes_to_read > (source.size - source.pos)
32
+
33
+ source.read(bytes_to_read).unpack('G').first
34
+ end
35
+
36
+ public
37
+ def read_word16_network(source)
38
+ bytes_to_read = 2
39
+
40
+ raise AMFErrorIncomplete.new if bytes_to_read > (source.size - source.pos)
41
+
42
+ source.read(2).unpack('n').first
43
+ end
44
+
45
+ public
46
+ def read_int16_network(source)
47
+ bytes_to_read = 2
48
+
49
+ raise AMFErrorIncomplete.new if bytes_to_read > (source.size - source.pos)
50
+
51
+ result = source.read(bytes_to_read)
52
+ result.reverse! if byte_order_little? # swap bytes as native=little (and we want network)
53
+ result.unpack('s').first
54
+ end
55
+
56
+ public
57
+ def read_word32_network(source)
58
+ bytes_to_read = 4
59
+
60
+ raise AMFErrorIncomplete.new if bytes_to_read > (source.size - source.pos)
61
+
62
+ source.read(bytes_to_read).unpack('N').first
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,49 @@
1
+ require 'amf/pure/helpers/io_helper_base'
2
+
3
+ module AMF
4
+ module Pure
5
+ module IOHelperWrite #:nodoc:
6
+
7
+ include IOHelperBase
8
+
9
+ def pack_integer(integer)
10
+ integer = integer & 0x1fffffff
11
+
12
+ if integer < AMF::AMFConstants::MIN_INT_2_BYTE
13
+ [integer].pack('c')
14
+ elsif integer < AMF::AMFConstants::MIN_INT_3_BYTE
15
+ [integer >> 7 & 0x7f | 0x80].pack('c') +
16
+ [integer & 0x7f].pack('c')
17
+ elsif integer < AMF::AMFConstants::MIN_INT_4_BYTE
18
+ [integer >> 14 & 0x7f | 0x80].pack('c') +
19
+ [integer >> 7 & 0x7f | 0x80].pack('c') +
20
+ [integer & 0x7f].pack('c')
21
+ else
22
+ [integer >> 22 & 0x7f | 0x80].pack('c')+
23
+ [integer >> 15 & 0x7f | 0x80].pack('c')+
24
+ [integer >> 8 & 0x7f | 0x80].pack('c')+
25
+ [integer & 0xff].pack('c')
26
+ end
27
+ end
28
+
29
+ def pack_double(double)
30
+ [double].pack('G')
31
+ end
32
+
33
+ def pack_int8(val)
34
+ [val].pack('c')
35
+ end
36
+
37
+ def pack_int16_network(val)
38
+ [val].pack('n')
39
+ end
40
+
41
+ def pack_word32_network(val)
42
+ result = [val].pack('L')
43
+ result.reverse! if byte_order_little? # swap bytes as native=little (and we want network)
44
+ result
45
+ end
46
+
47
+ end
48
+ end
49
+ end