@@ -14,7 +14,6 @@ class RubyObjectEncoder {
14
14
Writer<StringBuffer> writer;
15
15
16
16
void test () {
17
- writer.StartObject ();
18
17
writer.Key (" hello" );
19
18
writer.String (" world" );
20
19
writer.Key (" t" );
@@ -35,22 +34,105 @@ class RubyObjectEncoder {
35
34
writer.EndObject ();
36
35
}
37
36
37
+ void encode_array (VALUE ary) {
38
+ writer.StartArray ();
39
+ int length = RARRAY_LEN (ary);
40
+ RARRAY_PTR_USE (ary, ptr, {
41
+ for (int i = 0 ; i < length; i++) {
42
+ encode_any (ptr[i]);
43
+ }
44
+ });
45
+ writer.EndArray ();
46
+ }
47
+
48
+ void encode_key (VALUE key) {
49
+ switch (rb_type (key)) {
50
+ case T_STRING:
51
+ writer.Key (RSTRING_PTR (key), RSTRING_LEN (key));
52
+ return ;
53
+ default :
54
+ raise_unknown (key);
55
+ }
56
+ }
57
+
58
+ static int encode_hash_i_cb (VALUE key, VALUE val, VALUE ctx) {
59
+ RubyObjectEncoder *encoder = (RubyObjectEncoder *)ctx;
60
+ encoder->encode_hash_i (key, val);
61
+ return ST_CONTINUE;
62
+ }
63
+
64
+ void encode_hash_i (VALUE key, VALUE val) {
65
+ encode_key (key);
66
+ encode_any (val);
67
+ }
68
+
69
+ void encode_hash (VALUE hash) {
70
+ writer.StartObject ();
71
+ rb_hash_foreach (hash, encode_hash_i_cb, (VALUE)this );
72
+ writer.EndObject ();
73
+ }
74
+
75
+ void encode_fixnum (VALUE v) {
76
+ writer.Int (RB_FIX2INT (v));
77
+ }
78
+
79
+ void encode_float (VALUE v) {
80
+ double f = rb_float_value (v);
81
+ writer.Double (f);
82
+ }
83
+
84
+ void encode_string (VALUE v) {
85
+ // fixme: copy boolean?
86
+ writer.String (RSTRING_PTR (v), RSTRING_LEN (v));
87
+ }
88
+
89
+ void encode_any (VALUE v) {
90
+ switch (rb_type (v)) {
91
+ case T_NIL:
92
+ writer.Null ();
93
+ return ;
94
+ case T_FALSE:
95
+ writer.Bool (false );
96
+ return ;
97
+ case T_TRUE:
98
+ writer.Bool (true );
99
+ return ;
100
+ case T_FIXNUM:
101
+ return encode_fixnum (v);
102
+ case T_FLOAT:
103
+ return encode_float (v);
104
+ case T_HASH:
105
+ return encode_hash (v);
106
+ case T_ARRAY:
107
+ return encode_array (v);
108
+ case T_STRING:
109
+ return encode_string (v);
110
+ default :
111
+ raise_unknown (v);
112
+ }
113
+ }
114
+
115
+ void raise_unknown (VALUE obj) {
116
+ VALUE inspect = rb_inspect (obj);
117
+ rb_raise (rb_eRuntimeError, " can't encode type: %s" , StringValueCStr (inspect));
118
+ }
119
+
38
120
public:
39
121
RubyObjectEncoder (): depth(0 ), buf(), writer(buf) {
40
122
};
41
123
42
124
int depth;
43
125
44
- VALUE encode () {
45
- test ( );
126
+ VALUE encode (VALUE obj ) {
127
+ encode_any (obj );
46
128
VALUE ruby_string = rb_str_new (buf.GetString (), buf.GetSize ());
47
129
return ruby_string;
48
130
}
49
131
};
50
132
51
133
VALUE encode (VALUE _self, VALUE obj) {
52
134
RubyObjectEncoder encoder;
53
- return encoder.encode ();
135
+ return encoder.encode (obj );
54
136
}
55
137
56
138
extern " C" void
0 commit comments