19
20
#define PSYCH_TRANSCODE(_str, _yaml_enc, _internal_enc) \
21
rb_enc_associate_index(_str, _yaml_enc); \
22
rb_enc_associate_index((_str), (_yaml_enc)); \
22
23
if(_internal_enc) \
23
_str = rb_str_export_to_enc(_str, _internal_enc); \
24
(_str) = rb_str_export_to_enc((_str), (_internal_enc)); \
26
27
static int io_reader(void * data, unsigned char *buf, size_t size, size_t *read)
43
static void dealloc(void * ptr)
45
yaml_parser_t * parser;
47
parser = (yaml_parser_t *)ptr;
48
yaml_parser_delete(parser);
52
static VALUE allocate(VALUE klass)
54
yaml_parser_t * parser;
56
parser = xmalloc(sizeof(yaml_parser_t));
57
yaml_parser_initialize(parser);
59
return Data_Wrap_Struct(klass, 0, dealloc, parser);
44
64
* parser.parse(yaml)
51
71
static VALUE parse(VALUE self, VALUE yaml)
73
yaml_parser_t * parser;
54
74
yaml_event_t event;
57
77
#ifdef HAVE_RUBY_ENCODING_H
58
int encoding = rb_enc_find_index("ASCII-8BIT");
59
rb_encoding * internal_enc;
78
int encoding = rb_utf8_encindex();
79
rb_encoding * internal_enc = rb_default_internal_encoding();
61
81
VALUE handler = rb_iv_get(self, "@handler");
64
yaml_parser_initialize(&parser);
83
Data_Get_Struct(self, yaml_parser_t, parser);
66
85
if (OBJ_TAINTED(yaml)) tainted = 1;
68
87
if(rb_respond_to(yaml, id_read)) {
69
yaml_parser_set_input(&parser, io_reader, (void *)yaml);
88
yaml_parser_set_input(parser, io_reader, (void *)yaml);
70
89
if (RTEST(rb_obj_is_kind_of(yaml, rb_cIO))) tainted = 1;
73
92
yaml_parser_set_input_string(
75
94
(const unsigned char *)RSTRING_PTR(yaml),
76
95
(size_t)RSTRING_LEN(yaml)
81
if(!yaml_parser_parse(&parser, &event)) {
82
size_t line = parser.mark.line + 1;
83
size_t column = parser.mark.column;
85
yaml_parser_delete(&parser);
86
rb_raise(ePsychSyntaxError, "couldn't parse YAML at line %d column %d",
100
if(!yaml_parser_parse(parser, &event)) {
102
size_t line = parser->mark.line;
103
size_t column = parser->mark.column;
105
if(rb_respond_to(yaml, id_path))
106
path = rb_funcall(yaml, id_path, 0);
108
path = rb_str_new2("<unknown>");
110
yaml_parser_delete(parser);
111
yaml_parser_initialize(parser);
113
rb_raise(ePsychSyntaxError, "(%s): couldn't parse YAML at line %d column %d",
114
StringValuePtr(path),
87
115
(int)line, (int)column);
90
118
switch(event.type) {
91
119
case YAML_STREAM_START_EVENT:
93
#ifdef HAVE_RUBY_ENCODING_H
94
switch(event.data.stream_start.encoding) {
95
case YAML_ANY_ENCODING:
97
case YAML_UTF8_ENCODING:
98
encoding = rb_enc_find_index("UTF-8");
100
case YAML_UTF16LE_ENCODING:
101
encoding = rb_enc_find_index("UTF-16LE");
103
case YAML_UTF16BE_ENCODING:
104
encoding = rb_enc_find_index("UTF-16BE");
109
internal_enc = rb_default_internal_encoding();
112
121
rb_funcall(handler, id_start_stream, 1,
113
122
INT2NUM((long)event.data.stream_start.encoding)
315
* parser.external_encoding=(encoding)
317
* Set the encoding for this parser to +encoding+
319
static VALUE set_external_encoding(VALUE self, VALUE encoding)
321
yaml_parser_t * parser;
324
Data_Get_Struct(self, yaml_parser_t, parser);
326
if(parser->encoding) {
327
exception = rb_const_get_at(mPsych, rb_intern("Exception"));
328
rb_raise(exception, "don't set the encoding twice!");
331
yaml_parser_set_encoding(parser, NUM2INT(encoding));
338
* parser.mark # => #<Psych::Parser::Mark>
340
* Returns a Psych::Parser::Mark object that contains line, column, and index
343
static VALUE mark(VALUE self)
347
yaml_parser_t * parser;
349
Data_Get_Struct(self, yaml_parser_t, parser);
350
mark_klass = rb_const_get_at(cPsychParser, rb_intern("Mark"));
351
args[0] = INT2NUM(parser->mark.index);
352
args[1] = INT2NUM(parser->mark.line);
353
args[2] = INT2NUM(parser->mark.column);
355
return rb_class_new_instance(3, args, mark_klass);
304
358
void Init_psych_parser()
324
379
ePsychSyntaxError = rb_define_class_under(mPsych, "SyntaxError", rb_eSyntaxError);
326
381
rb_define_method(cPsychParser, "parse", parse, 1);
382
rb_define_method(cPsychParser, "mark", mark, 0);
383
rb_define_method(cPsychParser, "external_encoding=", set_external_encoding, 1);
328
385
id_read = rb_intern("read");
386
id_path = rb_intern("path");
329
387
id_empty = rb_intern("empty");
330
388
id_start_stream = rb_intern("start_stream");
331
389
id_end_stream = rb_intern("end_stream");