Class: Wankel::StreamEncoder

Inherits:
Object
  • Object
show all
Defined in:
lib/wankel/stream_encoder.rb,
ext/wankel/wankel_stream_encoder.c

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Object

call-seq: new()

:beautify generate indented (beautiful) output. Default ‘false`.

:indent_string Set an indent string which is used when yajl_gen_beautify

is enabled. Maybe something like \\t or some number of
spaces. The default is four spaces ' '.

:validate_utf8 Normally the generator does not validate that strings you

pass to it are valid UTF8. Enabling this option will cause
it to do so.

:escape_solidus the forward solidus (slash or ‘/’ in human) is not required

to be escaped in json text. By default, YAJL will not escape
it in the iterest of saving bytes. Setting this flag will
cause YAJL to always escape '/' in generated JSON strings.


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'ext/wankel/wankel_stream_encoder.c', line 50

static VALUE wankelStreamEncoder_initialize(int argc, VALUE * argv, VALUE self) {
    VALUE defaults = rb_const_get(c_wankel, intern_DEFAULTS);
    VALUE io, options;
	wankel_encoder * p;
    yajl_alloc_funcs alloc_funcs;
	
    rb_scan_args(argc, argv, "11", &io, &options);

    if(options == Qnil) {
        rb_iv_set(self, "@options", rb_funcall(defaults, intern_clone, 0) );
    } else {
        Check_Type(options, T_HASH);
        rb_iv_set(self, "@options", rb_funcall(defaults, intern_merge, 1, options) );
    }
	options = rb_iv_get(self, "@options");
	
	if (!rb_respond_to(io, intern_io_write)) {
		rb_raise(e_encodeError, "output must be a an IO");
	}
    Data_Get_Struct(self, wankel_encoder, p);
	p->output = io;

	alloc_funcs.malloc = yajl_helper_malloc;
	alloc_funcs.realloc = yajl_helper_realloc;
	alloc_funcs.free = yajl_helper_free;
	p->g = yajl_gen_alloc(&alloc_funcs);
	yajl_gen_configure(p->g, options);

	p->write_buffer_size = FIX2INT(rb_hash_aref(options, ID2SYM(rb_intern("write_buffer_size"))));
		
    return self;
}

Instance Method Details

#array_closeObject



213
214
215
216
217
218
219
220
221
222
223
224
# File 'ext/wankel/wankel_stream_encoder.c', line 213

static VALUE wankelStreamEncoder_array_close(VALUE self) {
	wankel_encoder * p;
	yajl_gen_status status;
    Data_Get_Struct(self, wankel_encoder, p);
	
    status = yajl_gen_array_close(p->g);
	yajl_helper_check_gen_status(status);
	
	wankelStreamEncoder_write_buffer(p);
	
	return Qnil;
}

#array_openObject



200
201
202
203
204
205
206
207
208
209
210
211
# File 'ext/wankel/wankel_stream_encoder.c', line 200

static VALUE wankelStreamEncoder_array_open(VALUE self) {
	wankel_encoder * p;
	yajl_gen_status status;
    Data_Get_Struct(self, wankel_encoder, p);
	
    status = yajl_gen_array_open(p->g);
	yajl_helper_check_gen_status(status);
	
	wankelStreamEncoder_write_buffer(p);
	
	return Qnil;
}

#boolean(b) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
# File 'ext/wankel/wankel_stream_encoder.c', line 161

static VALUE wankelStreamEncoder_boolean(VALUE self, VALUE b) {
	wankel_encoder * p;
	yajl_gen_status status;
    Data_Get_Struct(self, wankel_encoder, p);

	status = yajl_gen_bool(p->g, RTEST(b));
	yajl_helper_check_gen_status(status);
	
	wankelStreamEncoder_write_buffer(p);
	
	return Qnil;
}

#flushObject



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'ext/wankel/wankel_stream_encoder.c', line 226

static VALUE wankelStreamEncoder_flush(VALUE self) {
    size_t len;
	VALUE rbBuffer;
	wankel_encoder * p;
	yajl_gen_status status;
    const unsigned char * buffer;
    Data_Get_Struct(self, wankel_encoder, p);
	
	status = yajl_gen_get_buf(p->g, &buffer, &len);
	yajl_helper_check_gen_status(status);
	
	rbBuffer = rb_str_new((const char *)buffer, len);
	rb_enc_associate(rbBuffer, rb_utf8_encoding());
	rb_io_write(p->output, rbBuffer);
	yajl_gen_clear(p->g);

	return Qnil;
}

#map_closeObject



187
188
189
190
191
192
193
194
195
196
197
198
# File 'ext/wankel/wankel_stream_encoder.c', line 187

static VALUE wankelStreamEncoder_map_close(VALUE self) {
	wankel_encoder * p;
	yajl_gen_status status;
    Data_Get_Struct(self, wankel_encoder, p);
	
    status = yajl_gen_map_close(p->g);
	yajl_helper_check_gen_status(status);
	
	wankelStreamEncoder_write_buffer(p);
	
	return Qnil;
}

#map_openObject



174
175
176
177
178
179
180
181
182
183
184
185
# File 'ext/wankel/wankel_stream_encoder.c', line 174

static VALUE wankelStreamEncoder_map_open(VALUE self) {
	wankel_encoder * p;
	yajl_gen_status status;
    Data_Get_Struct(self, wankel_encoder, p);
	
    status = yajl_gen_map_open(p->g);
	yajl_helper_check_gen_status(status);
	
	wankelStreamEncoder_write_buffer(p);
	
	return Qnil;
}

#nullObject



148
149
150
151
152
153
154
155
156
157
158
159
# File 'ext/wankel/wankel_stream_encoder.c', line 148

static VALUE wankelStreamEncoder_null(VALUE self) {
	wankel_encoder * p;
	yajl_gen_status status;
    Data_Get_Struct(self, wankel_encoder, p);
	
    status = yajl_gen_null(p->g);
	yajl_helper_check_gen_status(status);
	
	wankelStreamEncoder_write_buffer(p);
	
	return Qnil;
}

#number(number) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'ext/wankel/wankel_stream_encoder.c', line 105

static VALUE wankelStreamEncoder_number(VALUE self, VALUE number) {
    size_t len;
    const char * cptr;
	wankel_encoder * p;
	yajl_gen_status status;
	VALUE str = rb_funcall(number, intern_to_s, 0);

    Data_Get_Struct(self, wankel_encoder, p);
    cptr = RSTRING_PTR(str);
    len = RSTRING_LEN(str);
	
    if (memcmp(cptr, "NaN", 3) == 0 || memcmp(cptr, "Infinity", 8) == 0 || memcmp(cptr, "-Infinity", 9) == 0) {
        rb_raise(e_encodeError, "'%s' is an invalid number", cptr);
    }
	
    status = yajl_gen_number(p->g, cptr, len);
	yajl_helper_check_gen_status(status);

	wankelStreamEncoder_write_buffer(p);
	
	return Qnil;
}

#outputObject



98
99
100
101
102
103
# File 'ext/wankel/wankel_stream_encoder.c', line 98

static VALUE wankelStreamEncoder_output(VALUE self) {
    wankel_encoder * p;
    Data_Get_Struct(self, wankel_encoder, p);
    
    return p->output;
}

#output=(io) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'ext/wankel/wankel_stream_encoder.c', line 83

static VALUE wankelStreamEncoder_change_io(VALUE self, VALUE io) {
    wankel_encoder * p;
    
    if (!rb_respond_to(io, intern_io_write)) {
        rb_raise(e_encodeError, "output must be a an IO");
    }

    Data_Get_Struct(self, wankel_encoder, p);
        
    wankelStreamEncoder_flush(self);
    p->output = io;
    
    return Qnil;
}

#string(string) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'ext/wankel/wankel_stream_encoder.c', line 128

static VALUE wankelStreamEncoder_string(VALUE self, VALUE string) {
    size_t len;
    const char * cptr;
	wankel_encoder * p;
	yajl_gen_status status;
	
	Check_Type(string, T_STRING);
	
    Data_Get_Struct(self, wankel_encoder, p);
    cptr = RSTRING_PTR(string);
    len = RSTRING_LEN(string);
	
    status = yajl_gen_string(p->g, (const unsigned char *)cptr, len);
	yajl_helper_check_gen_status(status);

	wankelStreamEncoder_write_buffer(p);
	
	return Qnil;
}

#value(val) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/wankel/stream_encoder.rb', line 4

def value(val)
  case val
  when NilClass
    null
  when TrueClass, FalseClass
    boolean(val)
  when Numeric
    number(val)
  when String
    string(val)
  when Array
    array_open
    val.each {|v| value(v) }
    array_close
  when Hash
    map_open
    val.each {|k, v| string(k.to_s); value(v) }
    map_close
  else
    case @options[:mode]
    when :strict
      raise Wankel::EncodeError, "Unkown JSON type #{val.class}"
    when :nil
      null
    else
      value(val.send(@options[:mode]))
    end
  end
end