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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/README.rdoc +52 -0
- data/Rakefile +59 -0
- data/benchmark.rb +86 -0
- data/doc/amf3-speification.pdf +0 -0
- data/ext/rocketamf_ext/class_mapping.c +483 -0
- data/ext/rocketamf_ext/constants.h +52 -0
- data/ext/rocketamf_ext/deserializer.c +776 -0
- data/ext/rocketamf_ext/deserializer.h +28 -0
- data/ext/rocketamf_ext/extconf.rb +18 -0
- data/ext/rocketamf_ext/remoting.c +184 -0
- data/ext/rocketamf_ext/rocketamf_ext.c +38 -0
- data/ext/rocketamf_ext/serializer.c +834 -0
- data/ext/rocketamf_ext/serializer.h +29 -0
- data/ext/rocketamf_ext/utility.h +4 -0
- data/lib/amf/common/hash_with_type.rb +20 -0
- data/lib/amf/ext.rb +22 -0
- data/lib/amf/pure/amf_constants.rb +42 -0
- data/lib/amf/pure/deserializer.rb +354 -0
- data/lib/amf/pure/errors/all_files.rb +2 -0
- data/lib/amf/pure/errors/amf_error.rb +5 -0
- data/lib/amf/pure/errors/amf_error_incomplete.rb +5 -0
- data/lib/amf/pure/helpers/all_files.rb +8 -0
- data/lib/amf/pure/helpers/cache_objects.rb +18 -0
- data/lib/amf/pure/helpers/cache_strings.rb +14 -0
- data/lib/amf/pure/helpers/io_helper_base.rb +19 -0
- data/lib/amf/pure/helpers/io_helper_read.rb +67 -0
- data/lib/amf/pure/helpers/io_helper_write.rb +49 -0
- data/lib/amf/pure/mapping/class_mapper.rb +159 -0
- data/lib/amf/pure/mapping/mapping_set.rb +49 -0
- data/lib/amf/pure/serializer.rb +318 -0
- data/lib/amf/pure.rb +16 -0
- data/lib/amf.rb +140 -0
- data/mrpin-amf.gemspec +24 -0
- data/spec/fixtures/objects/complex/amf3-associative-array.bin +1 -0
- data/spec/fixtures/objects/complex/amf3-byte-array.bin +0 -0
- data/spec/fixtures/objects/complex/amf3-date.bin +0 -0
- data/spec/fixtures/objects/complex/amf3-dictionary.bin +0 -0
- data/spec/fixtures/objects/complex/amf3-dynamic-object.bin +2 -0
- data/spec/fixtures/objects/complex/amf3-empty-array.bin +1 -0
- data/spec/fixtures/objects/complex/amf3-empty-dictionary.bin +0 -0
- data/spec/fixtures/objects/complex/amf3-hash.bin +2 -0
- data/spec/fixtures/objects/complex/amf3-mixed-array.bin +10 -0
- data/spec/fixtures/objects/complex/amf3-primitive-array.bin +1 -0
- data/spec/fixtures/objects/complex/amf3-typed-object.bin +2 -0
- data/spec/fixtures/objects/encoding/amf3-complex-encoded-string-array.bin +1 -0
- data/spec/fixtures/objects/encoding/amf3-encoded-string-ref.bin +0 -0
- data/spec/fixtures/objects/references/amf3-array-ref.bin +1 -0
- data/spec/fixtures/objects/references/amf3-byte-array-ref.bin +1 -0
- data/spec/fixtures/objects/references/amf3-date-ref.bin +0 -0
- data/spec/fixtures/objects/references/amf3-empty-array-ref.bin +1 -0
- data/spec/fixtures/objects/references/amf3-empty-string-ref.bin +1 -0
- data/spec/fixtures/objects/references/amf3-graph-member.bin +0 -0
- data/spec/fixtures/objects/references/amf3-object-ref.bin +0 -0
- data/spec/fixtures/objects/references/amf3-string-ref.bin +0 -0
- data/spec/fixtures/objects/references/amf3-trait-ref.bin +3 -0
- data/spec/fixtures/objects/simple/amf3-0.bin +0 -0
- data/spec/fixtures/objects/simple/amf3-bigNum.bin +0 -0
- data/spec/fixtures/objects/simple/amf3-false.bin +1 -0
- data/spec/fixtures/objects/simple/amf3-float.bin +0 -0
- data/spec/fixtures/objects/simple/amf3-large-max.bin +0 -0
- data/spec/fixtures/objects/simple/amf3-large-min.bin +0 -0
- data/spec/fixtures/objects/simple/amf3-max.bin +1 -0
- data/spec/fixtures/objects/simple/amf3-min.bin +0 -0
- data/spec/fixtures/objects/simple/amf3-null.bin +1 -0
- data/spec/fixtures/objects/simple/amf3-string.bin +1 -0
- data/spec/fixtures/objects/simple/amf3-symbol.bin +1 -0
- data/spec/fixtures/objects/simple/amf3-true.bin +1 -0
- data/spec/helpers/class_mapping_test.rb +4 -0
- data/spec/helpers/class_mapping_test2.rb +3 -0
- data/spec/helpers/fixtures.rb +34 -0
- data/spec/helpers/other_class.rb +4 -0
- data/spec/helpers/ruby_class.rb +4 -0
- data/spec/helpers/test_ruby_class.rb +4 -0
- data/spec/spec-class_mapping.rb +98 -0
- data/spec/spec_deserializer.rb +239 -0
- data/spec/spec_fast_class_mapping.rb +147 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/spec_serializer.rb +267 -0
- 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
|
+
}
|