9 static ID id_start_stream;
10 static ID id_end_stream;
11 static ID id_start_document;
12 static ID id_end_document;
15 static ID id_start_sequence;
16 static ID id_end_sequence;
17 static ID id_start_mapping;
18 static ID id_end_mapping;
20 #define PSYCH_TRANSCODE(_str, _yaml_enc, _internal_enc) \ 22 rb_enc_associate_index((_str), (_yaml_enc)); \ 24 (_str) = rb_str_export_to_enc((_str), (_internal_enc)); \ 27 static int io_reader(
void * data,
unsigned char *
buf,
size_t size,
size_t *read)
37 memcpy(buf, str, *read);
43 static void dealloc(
void * ptr)
45 yaml_parser_t * parser;
47 parser = (yaml_parser_t *)ptr;
48 yaml_parser_delete(parser);
53 static size_t memsize(
const void *ptr)
55 const yaml_parser_t *parser = ptr;
65 #ifdef RUBY_TYPED_FREE_IMMEDIATELY 72 yaml_parser_t * parser;
75 yaml_parser_initialize(parser);
80 static VALUE make_exception(yaml_parser_t * parser,
VALUE path)
84 line = parser->context_mark.line + 1;
85 column = parser->context_mark.column + 1;
91 INT2NUM(parser->problem_offset),
96 static VALUE transcode_string(
VALUE src,
int * parser_encoding)
103 if (source_encoding == utf8) {
104 *parser_encoding = YAML_UTF8_ENCODING;
108 if (source_encoding == utf16le) {
109 *parser_encoding = YAML_UTF16LE_ENCODING;
113 if (source_encoding == utf16be) {
114 *parser_encoding = YAML_UTF16BE_ENCODING;
121 *parser_encoding = YAML_UTF8_ENCODING;
125 static VALUE transcode_io(
VALUE src,
int * parser_encoding)
127 VALUE io_external_encoding;
128 int io_external_enc_index;
133 if (
NIL_P(io_external_encoding)) {
141 *parser_encoding = YAML_UTF8_ENCODING;
146 *parser_encoding = YAML_UTF8_ENCODING;
151 *parser_encoding = YAML_UTF16LE_ENCODING;
156 *parser_encoding = YAML_UTF16BE_ENCODING;
162 *parser_encoding = YAML_ANY_ENCODING;
168 *parser_encoding = YAML_ANY_ENCODING;
173 static VALUE protected_start_stream(
VALUE pointer)
176 return rb_funcall(args[0], id_start_stream, 1, args[1]);
179 static VALUE protected_start_document(
VALUE pointer)
182 return rb_funcall3(args[0], id_start_document, 3, args + 1);
185 static VALUE protected_end_document(
VALUE pointer)
188 return rb_funcall(args[0], id_end_document, 1, args[1]);
200 return rb_funcall3(args[0], id_scalar, 6, args + 1);
203 static VALUE protected_start_sequence(
VALUE pointer)
206 return rb_funcall3(args[0], id_start_sequence, 4, args + 1);
209 static VALUE protected_end_sequence(
VALUE handler)
211 return rb_funcall(handler, id_end_sequence, 0);
214 static VALUE protected_start_mapping(
VALUE pointer)
217 return rb_funcall3(args[0], id_start_mapping, 4, args + 1);
220 static VALUE protected_end_mapping(
VALUE handler)
222 return rb_funcall(handler, id_end_mapping, 0);
230 static VALUE protected_end_stream(
VALUE handler)
247 yaml_parser_t * parser;
252 int parser_encoding = YAML_ANY_ENCODING;
266 yaml_parser_delete(parser);
267 yaml_parser_initialize(parser);
272 yaml = transcode_io(yaml, &parser_encoding);
273 yaml_parser_set_encoding(parser, parser_encoding);
274 yaml_parser_set_input(parser, io_reader, (
void *)yaml);
278 yaml = transcode_string(yaml, &parser_encoding);
279 yaml_parser_set_encoding(parser, parser_encoding);
280 yaml_parser_set_input_string(
288 if(!yaml_parser_parse(parser, &event)) {
291 exception = make_exception(parser, path);
292 yaml_parser_delete(parser);
293 yaml_parser_initialize(parser);
299 case YAML_STREAM_START_EVENT:
304 args[1] =
INT2NUM((
long)event.data.stream_start.encoding);
308 case YAML_DOCUMENT_START_EVENT:
314 VALUE version =
event.data.document_start.version_directive ?
317 INT2NUM((
long)event.data.document_start.version_directive->major),
318 INT2NUM((
long)event.data.document_start.version_directive->minor)
321 if(event.data.document_start.tag_directives.start) {
322 yaml_tag_directive_t *start =
323 event.data.document_start.tag_directives.start;
324 yaml_tag_directive_t *end =
325 event.data.document_start.tag_directives.end;
326 for(; start != end; start++) {
346 args[2] = tag_directives;
347 args[3] =
event.data.document_start.implicit == 1 ?
Qtrue :
Qfalse;
351 case YAML_DOCUMENT_END_EVENT:
356 args[1] =
event.data.document_end.implicit == 1 ?
Qtrue :
Qfalse;
360 case YAML_ALIAS_EVENT:
364 if(event.data.alias.anchor) {
365 alias =
rb_str_new2((
const char *)event.data.alias.anchor);
375 case YAML_SCALAR_EVENT:
380 VALUE plain_implicit, quoted_implicit, style;
382 (
const char *)event.data.scalar.value,
383 (
long)event.data.scalar.length
389 if(event.data.scalar.anchor) {
390 anchor =
rb_str_new2((
const char *)event.data.scalar.anchor);
395 if(event.data.scalar.tag) {
396 tag =
rb_str_new2((
const char *)event.data.scalar.tag);
402 event.data.scalar.plain_implicit == 0 ?
Qfalse :
Qtrue;
405 event.data.scalar.quoted_implicit == 0 ?
Qfalse :
Qtrue;
407 style =
INT2NUM((
long)event.data.scalar.style);
413 args[4] = plain_implicit;
414 args[5] = quoted_implicit;
419 case YAML_SEQUENCE_START_EVENT:
424 VALUE implicit, style;
425 if(event.data.sequence_start.anchor) {
426 anchor =
rb_str_new2((
const char *)event.data.sequence_start.anchor);
432 if(event.data.sequence_start.tag) {
433 tag =
rb_str_new2((
const char *)event.data.sequence_start.tag);
439 event.data.sequence_start.implicit == 0 ?
Qfalse :
Qtrue;
441 style =
INT2NUM((
long)event.data.sequence_start.style);
452 case YAML_SEQUENCE_END_EVENT:
453 rb_protect(protected_end_sequence, handler, &state);
455 case YAML_MAPPING_START_EVENT:
460 VALUE implicit, style;
461 if(event.data.mapping_start.anchor) {
462 anchor =
rb_str_new2((
const char *)event.data.mapping_start.anchor);
467 if(event.data.mapping_start.tag) {
468 tag =
rb_str_new2((
const char *)event.data.mapping_start.tag);
474 event.data.mapping_start.implicit == 0 ?
Qfalse :
Qtrue;
476 style =
INT2NUM((
long)event.data.mapping_start.style);
487 case YAML_MAPPING_END_EVENT:
488 rb_protect(protected_end_mapping, handler, &state);
493 case YAML_STREAM_END_EVENT:
494 rb_protect(protected_end_stream, handler, &state);
498 yaml_event_delete(&event);
516 yaml_parser_t * parser;
520 args[0] =
INT2NUM(parser->mark.index);
521 args[1] =
INT2NUM(parser->mark.line);
522 args[2] =
INT2NUM(parser->mark.column);
557 id_start_stream =
rb_intern(
"start_stream");
559 id_start_document =
rb_intern(
"start_document");
560 id_end_document =
rb_intern(
"end_document");
563 id_start_sequence =
rb_intern(
"start_sequence");
564 id_end_sequence =
rb_intern(
"end_sequence");
565 id_start_mapping =
rb_intern(
"start_mapping");
566 id_end_mapping =
rb_intern(
"end_mapping");
int rb_enc_get_index(VALUE obj)
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
#define RUBY_TYPED_FREE_IMMEDIATELY
#define rb_usascii_str_new2
void rb_jump_tag(int tag)
Continues the exception caught by rb_protect() and rb_eval_string_protect().
#define TypedData_Get_Struct(obj, type, data_type, sval)
rb_encoding * rb_default_internal_encoding(void)
VALUE rb_ary_push(VALUE ary, VALUE item)
int rb_usascii_encindex(void)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
VALUE rb_iv_get(VALUE, const char *)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
rb_encoding * rb_utf8_encoding(void)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false
VALUE rb_require(const char *)
int rb_to_encoding_index(VALUE enc)
void Init_psych_parser(void)
RUBY_EXTERN VALUE rb_cObject
int rb_ascii8bit_encindex(void)
void rb_define_const(VALUE, const char *, VALUE)
#define PSYCH_TRANSCODE(_str, _yaml_enc, _internal_enc)
VALUE rb_const_get(VALUE, ID)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
unsigned char buf[MIME_BUF_SIZE]
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
int rb_utf8_encindex(void)
int rb_respond_to(VALUE, ID)
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
VALUE rb_str_export_to_enc(VALUE, rb_encoding *)
#define TypedData_Make_Struct(klass, type, data_type, sval)
VALUE rb_const_get_at(VALUE, ID)
#define StringValuePtr(v)
int rb_enc_find_index(const char *name)
VALUE rb_define_module(const char *name)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
VALUE rb_str_new(const char *, long)