brianmario-yajl-ruby 0.3.1 → 0.3.2

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.
Files changed (5) hide show
  1. data/CHANGELOG.rdoc +3 -0
  2. data/Rakefile +11 -0
  3. data/VERSION.yml +1 -1
  4. data/ext/yajl.c +148 -0
  5. metadata +2 -1
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,8 @@
1
1
  = Changelog
2
2
 
3
+ 0.3.2 (April 24th, 2009)
4
+ * version bump: forgot to include yajl.c in the gem
5
+
3
6
  0.3.1 (April 23rd, 2009)
4
7
  * fixed borked gemspec
5
8
 
data/Rakefile CHANGED
@@ -7,6 +7,17 @@ begin
7
7
  gem.homepage = "http://github.com/brianmario/yajl-ruby"
8
8
  gem.authors = ["Brian Lopez"]
9
9
  gem.require_paths = ["ext"]
10
+ gem.extra_rdoc_files = [
11
+ "README.rdoc",
12
+ "CHANGELOG.rdoc"
13
+ ]
14
+ gem.files = [
15
+ "CHANGELOG.rdoc",
16
+ "README.rdoc",
17
+ "Rakefile",
18
+ "VERSION.yml",
19
+ "ext/yajl.c"
20
+ ]
10
21
  gem.extensions = ["ext/extconf.rb"]
11
22
  gem.files.include %w(lib/jeweler/templates/.document lib/jeweler/templates/.gitignore)
12
23
  # gem.rubyforge_project = "yajl-ruby"
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 1
2
+ :patch: 2
3
3
  :major: 0
4
4
  :minor: 3
data/ext/yajl.c ADDED
@@ -0,0 +1,148 @@
1
+ #include <yajl/yajl_parse.h>
2
+ #include <yajl/yajl_gen.h>
3
+ #include <ruby.h>
4
+
5
+ static VALUE cParseError;
6
+
7
+ void set_static_value(void * ctx, VALUE val) {
8
+ VALUE len = RARRAY((VALUE)ctx)->len;
9
+
10
+ if (len > 0) {
11
+ VALUE lastEntry = rb_ary_entry((VALUE)ctx, len-1);
12
+ VALUE hash;
13
+ switch (TYPE(lastEntry)) {
14
+ case T_ARRAY:
15
+ rb_ary_push(lastEntry, val);
16
+ if (TYPE(val) == T_HASH || TYPE(val) == T_ARRAY) {
17
+ rb_ary_push((VALUE)ctx, val);
18
+ }
19
+ break;
20
+ case T_HASH:
21
+ rb_hash_aset(lastEntry, val, Qnil);
22
+ rb_ary_push((VALUE)ctx, val);
23
+ break;
24
+ case T_STRING:
25
+ hash = rb_ary_entry((VALUE)ctx, len-2);
26
+ if (TYPE(hash) == T_HASH) {
27
+ rb_hash_aset(hash, lastEntry, val);
28
+ rb_ary_pop((VALUE)ctx);
29
+ if (TYPE(val) == T_HASH || TYPE(val) == T_ARRAY) {
30
+ rb_ary_push((VALUE)ctx, val);
31
+ }
32
+ }
33
+ break;
34
+ }
35
+ } else {
36
+ rb_ary_push((VALUE)ctx, val);
37
+ }
38
+ }
39
+
40
+ static int found_null(void * ctx) {
41
+ set_static_value(ctx, Qnil);
42
+ return 1;
43
+ }
44
+
45
+ static int found_boolean(void * ctx, int boolean) {
46
+ set_static_value(ctx, boolean ? Qtrue : Qfalse);
47
+ return 1;
48
+ }
49
+
50
+ static int found_number(void * ctx, const char * numberVal, unsigned int numberLen) {
51
+ set_static_value(ctx, rb_str2inum(rb_str_new(numberVal, numberLen), 10));
52
+ return 1;
53
+ }
54
+
55
+ static int found_string(void * ctx, const unsigned char * stringVal, unsigned int stringLen) {
56
+ set_static_value(ctx, rb_str_new((char *)stringVal, stringLen));
57
+ return 1;
58
+ }
59
+
60
+ static int found_hash_key(void * ctx, const unsigned char * stringVal, unsigned int stringLen) {
61
+ set_static_value(ctx, rb_str_new((char *)stringVal, stringLen));
62
+ return 1;
63
+ }
64
+
65
+ static int found_start_hash(void * ctx) {
66
+ set_static_value(ctx, rb_hash_new());
67
+ return 1;
68
+ }
69
+
70
+ static int found_end_hash(void * ctx) {
71
+ if (RARRAY((VALUE)ctx)->len > 1) {
72
+ rb_ary_pop((VALUE)ctx);
73
+ }
74
+ return 1;
75
+ }
76
+
77
+ static int found_start_array(void * ctx) {
78
+ set_static_value(ctx, rb_ary_new());
79
+ return 1;
80
+ }
81
+
82
+ static int found_end_array(void * ctx) {
83
+ if (RARRAY((VALUE)ctx)->len > 1) {
84
+ rb_ary_pop((VALUE)ctx);
85
+ }
86
+ return 1;
87
+ }
88
+
89
+ static yajl_callbacks callbacks = {
90
+ found_null,
91
+ found_boolean,
92
+ NULL,
93
+ NULL,
94
+ found_number,
95
+ found_string,
96
+ found_start_hash,
97
+ found_hash_key,
98
+ found_end_hash,
99
+ found_start_array,
100
+ found_end_array
101
+ };
102
+
103
+ static ID intern_io_read, intern_eof;
104
+ yajl_parser_config cfg = {1, 0};
105
+
106
+ static VALUE t_parse(VALUE self, VALUE io) {
107
+ yajl_handle hand;
108
+ yajl_status stat;
109
+ int bufferSize = 8192;
110
+ intern_io_read = rb_intern("read");
111
+ intern_eof = rb_intern("eof?");
112
+ VALUE ctx = rb_ary_new();
113
+
114
+ // allocate our parser
115
+ hand = yajl_alloc(&callbacks, &cfg, NULL, (void *)ctx);
116
+ VALUE parsed = rb_str_new("", 0);
117
+ VALUE rbufsize = INT2FIX(bufferSize);
118
+
119
+ // now parse from the IO
120
+ while (rb_funcall(io, intern_eof, 0) == Qfalse) {
121
+ rb_funcall(io, intern_io_read, 2, rbufsize, parsed);
122
+
123
+ stat = yajl_parse(hand, (const unsigned char *)RSTRING(parsed)->ptr, RSTRING(parsed)->len);
124
+
125
+ if (stat != yajl_status_ok && stat != yajl_status_insufficient_data) {
126
+ unsigned char * str = yajl_get_error(hand, 1, (const unsigned char *)RSTRING_PTR(parsed), RSTRING_LEN(parsed));
127
+ rb_raise(cParseError, "%s", (const char *) str);
128
+ yajl_free_error(hand, str);
129
+ break;
130
+ }
131
+ }
132
+
133
+ // parse any remaining buffered data
134
+ stat = yajl_parse_complete(hand);
135
+ yajl_free(hand);
136
+
137
+ return rb_ary_pop(ctx);
138
+ }
139
+
140
+ static VALUE mYajl, mNative;
141
+
142
+ void Init_yajl() {
143
+ mYajl = rb_define_module("Yajl");
144
+ mNative = rb_define_module_under(mYajl, "Native");
145
+ rb_define_module_function(mNative, "parse", t_parse, 1);
146
+ VALUE rb_cStandardError = rb_const_get(rb_cObject, rb_intern("StandardError"));
147
+ cParseError = rb_define_class_under(mYajl, "ParseError", rb_cStandardError);
148
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brianmario-yajl-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Lopez
@@ -26,6 +26,7 @@ files:
26
26
  - README.rdoc
27
27
  - Rakefile
28
28
  - VERSION.yml
29
+ - ext/yajl.c
29
30
  has_rdoc: true
30
31
  homepage: http://github.com/brianmario/yajl-ruby
31
32
  post_install_message: