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,28 @@
1
+ #include <ruby.h>
2
+ #ifdef HAVE_RB_STR_ENCODE
3
+ #include <ruby/encoding.h>
4
+ #endif
5
+
6
+ typedef struct {
7
+ int version;
8
+ VALUE class_mapper;
9
+ VALUE src;
10
+ char* stream;
11
+ unsigned long pos;
12
+ unsigned long size;
13
+ VALUE obj_cache;
14
+ VALUE str_cache;
15
+ VALUE trait_cache;
16
+ } AMF_DESERIALIZER;
17
+
18
+ char des_read_byte(AMF_DESERIALIZER *des);
19
+ char des_read_ahead_byte(AMF_DESERIALIZER *des);
20
+ int des_read_uint16(AMF_DESERIALIZER *des);
21
+ unsigned int des_read_uint32(AMF_DESERIALIZER *des);
22
+ double des_read_double(AMF_DESERIALIZER *des);
23
+ int des_read_int(AMF_DESERIALIZER *des);
24
+ VALUE des_read_string(AMF_DESERIALIZER *des, unsigned int len);
25
+ VALUE des_read_sym(AMF_DESERIALIZER *des, unsigned int len);
26
+ void des_set_src(AMF_DESERIALIZER *des, VALUE src);
27
+
28
+ VALUE des_deserialize(VALUE self, VALUE ver, VALUE src);
@@ -0,0 +1,18 @@
1
+ require 'mkmf'
2
+
3
+ # Disable the native extension by creating an empty Makefile on JRuby
4
+ if defined? JRUBY_VERSION
5
+ message "Generating phony Makefile for JRuby so the gem installs"
6
+ mfile = File.join(File.dirname(__FILE__), 'Makefile')
7
+ File.open(mfile, 'w') {|f| f.write dummy_makefile(File.dirname(__FILE__)) }
8
+ exit 0
9
+ end
10
+
11
+ if enable_config("sort-props", false)
12
+ $defs.push("-DSORT_PROPS") unless $defs.include? "-DSORT_PROPS"
13
+ end
14
+ have_func('rb_str_encode')
15
+
16
+ $CFLAGS += " -Wall"
17
+
18
+ create_makefile('rocketamf_ext')
@@ -0,0 +1,184 @@
1
+ #include "deserializer.h"
2
+ #include "serializer.h"
3
+ #include "constants.h"
4
+
5
+ extern VALUE mRocketAMF;
6
+ extern VALUE mRocketAMFExt;
7
+ extern VALUE cDeserializer;
8
+ extern VALUE cSerializer;
9
+ VALUE cRocketAMFHeader;
10
+ VALUE cRocketAMFMessage;
11
+ VALUE cRocketAMFAbstractMessage;
12
+ ID id_amf_version;
13
+ ID id_headers;
14
+ ID id_messages;
15
+ ID id_data;
16
+
17
+ /*
18
+ * call-seq:
19
+ * env.populate_from_stream(stream, class_mapper=nil)
20
+ *
21
+ * Included into RocketAMF::Envelope, this method handles deserializing an AMF
22
+ * request/response into the envelope
23
+ */
24
+ static VALUE env_populate_from_stream(int argc, VALUE *argv, VALUE self) {
25
+ static VALUE cClassMapper = 0;
26
+ if(cClassMapper == 0) cClassMapper = rb_const_get(mRocketAMF, rb_intern("ClassMapper"));
27
+
28
+ // Parse args
29
+ VALUE src;
30
+ VALUE class_mapper;
31
+ rb_scan_args(argc, argv, "11", &src, &class_mapper);
32
+ if(class_mapper == Qnil) class_mapper = rb_class_new_instance(0, NULL, cClassMapper);
33
+
34
+ // Create AMF0 deserializer
35
+ VALUE args[3];
36
+ args[0] = class_mapper;
37
+ VALUE des_rb = rb_class_new_instance(1, args, cDeserializer);
38
+ AMF_DESERIALIZER *des;
39
+ Data_Get_Struct(des_rb, AMF_DESERIALIZER, des);
40
+ des_set_src(des, src);
41
+
42
+ // Read amf version
43
+ int amf_ver = des_read_uint16(des);
44
+
45
+ // Read headers
46
+ VALUE headers = rb_hash_new();
47
+ int header_cnt = des_read_uint16(des);
48
+ int i;
49
+ for(i = 0; i < header_cnt; i++) {
50
+ VALUE name = des_read_string(des, des_read_uint16(des));
51
+ VALUE must_understand = des_read_byte(des) != 0 ? Qtrue : Qfalse;
52
+ des_read_uint32(des); // Length is ignored
53
+ VALUE data = des_deserialize(des_rb, INT2FIX(0), Qnil);
54
+
55
+ args[0] = name;
56
+ args[1] = must_understand;
57
+ args[2] = data;
58
+ rb_hash_aset(headers, name, rb_class_new_instance(3, args, cRocketAMFHeader));
59
+ }
60
+
61
+ // Read messages
62
+ VALUE messages = rb_ary_new();
63
+ int message_cnt = des_read_uint16(des);
64
+ for(i = 0; i < message_cnt; i++) {
65
+ VALUE target_uri = des_read_string(des, des_read_uint16(des));
66
+ VALUE response_uri = des_read_string(des, des_read_uint16(des));
67
+ des_read_uint32(des); // Length is ignored
68
+ VALUE data = des_deserialize(des_rb, INT2FIX(0), Qnil);
69
+
70
+ // If they're using the flex remoting APIs, remove array wrapper
71
+ if(TYPE(data) == T_ARRAY && RARRAY_LEN(data) == 1 && rb_obj_is_kind_of(RARRAY_PTR(data)[0], cRocketAMFAbstractMessage) == Qtrue) {
72
+ data = RARRAY_PTR(data)[0];
73
+ }
74
+
75
+ args[0] = target_uri;
76
+ args[1] = response_uri;
77
+ args[2] = data;
78
+ rb_ary_push(messages, rb_class_new_instance(3, args, cRocketAMFMessage));
79
+ }
80
+
81
+ // Populate remoting object
82
+ rb_ivar_set(self, id_amf_version, INT2FIX(amf_ver));
83
+ rb_ivar_set(self, id_headers, headers);
84
+ rb_ivar_set(self, id_messages, messages);
85
+
86
+ return self;
87
+ }
88
+
89
+ /*
90
+ * call-seq:
91
+ * env.serialize(class_mapper=nil)
92
+ *
93
+ * Included into RocketAMF::Envelope, this method handles serializing an AMF
94
+ * request/response into a string
95
+ */
96
+ static VALUE env_serialize(int argc, VALUE *argv, VALUE self) {
97
+ static VALUE cClassMapper = 0;
98
+ if(cClassMapper == 0) cClassMapper = rb_const_get(mRocketAMF, rb_intern("ClassMapper"));
99
+
100
+ // Parse args
101
+ VALUE class_mapper;
102
+ rb_scan_args(argc, argv, "01", &class_mapper);
103
+ if(class_mapper == Qnil) class_mapper = rb_class_new_instance(0, NULL, cClassMapper);
104
+
105
+ // Get instance variables
106
+ long amf_ver = FIX2LONG(rb_ivar_get(self, id_amf_version));
107
+ VALUE headers = rb_funcall(rb_ivar_get(self, id_headers), rb_intern("values"), 0); // Get array of header values
108
+ VALUE messages = rb_ivar_get(self, id_messages);
109
+
110
+ // Create AMF0 serializer
111
+ VALUE args[1] = {class_mapper};
112
+ VALUE ser_rb = rb_class_new_instance(1, args, cSerializer);
113
+ AMF_SERIALIZER *ser;
114
+ Data_Get_Struct(ser_rb, AMF_SERIALIZER, ser);
115
+
116
+ // Write version
117
+ ser_write_uint16(ser, amf_ver);
118
+
119
+ // Write headers
120
+ long header_cnt = RARRAY_LEN(headers);
121
+ ser_write_uint16(ser, header_cnt);
122
+ int i;
123
+ char *str;
124
+ long str_len;
125
+ for(i = 0; i < header_cnt; i++) {
126
+ VALUE header = RARRAY_PTR(headers)[i];
127
+
128
+ // Write header name
129
+ ser_get_string(rb_funcall(header, rb_intern("name"), 0), Qtrue, &str, &str_len);
130
+ ser_write_uint16(ser, str_len);
131
+ rb_str_buf_cat(ser->stream, str, str_len);
132
+
133
+ // Write understand flag
134
+ ser_write_byte(ser, rb_funcall(header, rb_intern("must_understand"), 0) == Qtrue ? 1 : 0);
135
+
136
+ // Serialize data
137
+ ser_write_uint32(ser, -1); // length of data - -1 if you don't know
138
+ ser_serialize(ser_rb, INT2FIX(0), rb_funcall(header, id_data, 0));
139
+ }
140
+
141
+ // Write messages
142
+ long message_cnt = RARRAY_LEN(messages);
143
+ ser_write_uint16(ser, message_cnt);
144
+ for(i = 0; i < message_cnt; i++) {
145
+ VALUE message = RARRAY_PTR(messages)[i];
146
+
147
+ // Write target_uri
148
+ ser_get_string(rb_funcall(message, rb_intern("target_uri"), 0), Qtrue, &str, &str_len);
149
+ ser_write_uint16(ser, str_len);
150
+ rb_str_buf_cat(ser->stream, str, str_len);
151
+
152
+ // Write response_uri
153
+ ser_get_string(rb_funcall(message, rb_intern("response_uri"), 0), Qtrue, &str, &str_len);
154
+ ser_write_uint16(ser, str_len);
155
+ rb_str_buf_cat(ser->stream, str, str_len);
156
+
157
+ // Serialize data
158
+ ser_write_uint32(ser, -1); // length of data - -1 if you don't know
159
+ if(amf_ver == 3) {
160
+ ser_write_byte(ser, AMF0_AMF3_MARKER);
161
+ ser_serialize(ser_rb, INT2FIX(3), rb_funcall(message, id_data, 0));
162
+ } else {
163
+ ser_serialize(ser_rb, INT2FIX(0), rb_funcall(message, id_data, 0));
164
+ }
165
+ }
166
+
167
+ return ser->stream;
168
+ }
169
+
170
+
171
+ void Init_rocket_amf_remoting() {
172
+ VALUE mEnvelope = rb_define_module_under(mRocketAMFExt, "Envelope");
173
+ rb_define_method(mEnvelope, "populate_from_stream", env_populate_from_stream, -1);
174
+ rb_define_method(mEnvelope, "serialize", env_serialize, -1);
175
+
176
+ // Get refs to commonly used symbols and ids
177
+ id_amf_version = rb_intern("@amf_version");
178
+ id_headers = rb_intern("@headers");
179
+ id_messages = rb_intern("@messages");
180
+ id_data = rb_intern("data");
181
+ cRocketAMFHeader = rb_const_get(mRocketAMF, rb_intern("Header"));
182
+ cRocketAMFMessage = rb_const_get(mRocketAMF, rb_intern("Message"));
183
+ cRocketAMFAbstractMessage = rb_const_get(rb_const_get(mRocketAMF, rb_intern("Types")), rb_intern("AbstractMessage"));
184
+ }
@@ -0,0 +1,38 @@
1
+ #include <ruby.h>
2
+
3
+ VALUE mRocketAMF;
4
+ VALUE mRocketAMFExt;
5
+ VALUE cDeserializer;
6
+ VALUE cSerializer;
7
+ VALUE cStringIO;
8
+ VALUE cDate;
9
+ VALUE cDateTime;
10
+ VALUE sym_class_name;
11
+ VALUE sym_members;
12
+ VALUE sym_externalizable;
13
+ VALUE sym_dynamic;
14
+
15
+ void Init_rocket_amf_deserializer();
16
+ void Init_rocket_amf_serializer();
17
+ void Init_rocket_amf_fast_class_mapping();
18
+ void Init_rocket_amf_remoting();
19
+
20
+ void Init_rocketamf_ext() {
21
+ mRocketAMF = rb_define_module("RocketAMF");
22
+ mRocketAMFExt = rb_define_module_under(mRocketAMF, "Ext");
23
+
24
+ // Set up classes
25
+ Init_rocket_amf_deserializer();
26
+ Init_rocket_amf_serializer();
27
+ Init_rocket_amf_fast_class_mapping();
28
+ Init_rocket_amf_remoting();
29
+
30
+ // Get refs to commonly used symbols and ids
31
+ cStringIO = rb_const_get(rb_cObject, rb_intern("StringIO"));
32
+ cDate = rb_const_get(rb_cObject, rb_intern("Date"));
33
+ cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime"));
34
+ sym_class_name = ID2SYM(rb_intern("class_name"));
35
+ sym_members = ID2SYM(rb_intern("members"));
36
+ sym_externalizable = ID2SYM(rb_intern("externalizable"));
37
+ sym_dynamic = ID2SYM(rb_intern("dynamic"));
38
+ }