ffi-yajl 0.0.1-universal-java → 3.0.1

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 (211) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +21 -201
  3. data/README.md +105 -10
  4. data/bin/ffi-yajl-bench +11 -11
  5. data/ext/ffi_yajl/ext/dlopen/dlopen.c +40 -0
  6. data/ext/ffi_yajl/ext/dlopen/extconf.rb +16 -0
  7. data/ext/ffi_yajl/ext/dlopen/yajl.sym +18 -0
  8. data/ext/ffi_yajl/ext/encoder/encoder.c +270 -115
  9. data/ext/ffi_yajl/ext/encoder/extconf.rb +71 -14
  10. data/ext/ffi_yajl/ext/parser/extconf.rb +71 -14
  11. data/ext/ffi_yajl/ext/parser/parser.c +85 -44
  12. data/lib/ffi_yajl/benchmark/encode.rb +39 -92
  13. data/lib/ffi_yajl/benchmark/encode_json_and_marshal.rb +23 -23
  14. data/lib/ffi_yajl/benchmark/encode_json_and_yaml.rb +24 -30
  15. data/lib/ffi_yajl/benchmark/encode_profile.rb +15 -19
  16. data/lib/ffi_yajl/benchmark/http.rb +21 -25
  17. data/lib/ffi_yajl/benchmark/parse.rb +77 -117
  18. data/lib/ffi_yajl/benchmark/parse_json_and_marshal.rb +27 -27
  19. data/lib/ffi_yajl/benchmark/parse_json_and_yaml.rb +30 -30
  20. data/lib/ffi_yajl/benchmark/parse_profile.rb +14 -18
  21. data/lib/ffi_yajl/benchmark/parse_profile_ruby_prof.rb +14 -19
  22. data/lib/ffi_yajl/benchmark/parse_stream.rb +28 -28
  23. data/lib/ffi_yajl/benchmark.rb +26 -6
  24. data/lib/ffi_yajl/encoder.rb +47 -6
  25. data/lib/ffi_yajl/ext.rb +37 -10
  26. data/lib/ffi_yajl/ffi/encoder.rb +150 -63
  27. data/lib/ffi_yajl/ffi/parser.rb +82 -64
  28. data/lib/ffi_yajl/ffi.rb +70 -46
  29. data/lib/ffi_yajl/map_library_name.rb +109 -0
  30. data/lib/ffi_yajl/parser.rb +69 -1
  31. data/lib/ffi_yajl/platform.rb +29 -0
  32. data/lib/ffi_yajl/version.rb +23 -1
  33. data/lib/ffi_yajl.rb +44 -8
  34. metadata +25 -238
  35. data/Rakefile +0 -62
  36. data/ext/libyajl2/extconf.rb +0 -65
  37. data/ext/libyajl2/vendored/.git +0 -1
  38. data/ext/libyajl2/vendored/.gitignore +0 -3
  39. data/ext/libyajl2/vendored/BUILDING +0 -23
  40. data/ext/libyajl2/vendored/BUILDING.win32 +0 -27
  41. data/ext/libyajl2/vendored/CMakeLists.txt +0 -79
  42. data/ext/libyajl2/vendored/COPYING +0 -13
  43. data/ext/libyajl2/vendored/ChangeLog +0 -175
  44. data/ext/libyajl2/vendored/README +0 -74
  45. data/ext/libyajl2/vendored/TODO +0 -9
  46. data/ext/libyajl2/vendored/YAJLDoc.cmake +0 -26
  47. data/ext/libyajl2/vendored/configure +0 -79
  48. data/ext/libyajl2/vendored/example/CMakeLists.txt +0 -23
  49. data/ext/libyajl2/vendored/example/README.md +0 -7
  50. data/ext/libyajl2/vendored/example/parse_config.c +0 -69
  51. data/ext/libyajl2/vendored/example/sample.config +0 -101
  52. data/ext/libyajl2/vendored/perf/CMakeLists.txt +0 -23
  53. data/ext/libyajl2/vendored/perf/documents.c +0 -1418
  54. data/ext/libyajl2/vendored/perf/documents.h +0 -28
  55. data/ext/libyajl2/vendored/perf/perftest.c +0 -134
  56. data/ext/libyajl2/vendored/reformatter/CMakeLists.txt +0 -39
  57. data/ext/libyajl2/vendored/reformatter/json_reformat.c +0 -194
  58. data/ext/libyajl2/vendored/src/CMakeLists.txt +0 -86
  59. data/ext/libyajl2/vendored/src/YAJL.dxy +0 -1258
  60. data/ext/libyajl2/vendored/src/api/yajl_common.h +0 -75
  61. data/ext/libyajl2/vendored/src/api/yajl_gen.h +0 -157
  62. data/ext/libyajl2/vendored/src/api/yajl_parse.h +0 -226
  63. data/ext/libyajl2/vendored/src/api/yajl_tree.h +0 -185
  64. data/ext/libyajl2/vendored/src/api/yajl_version.h.cmake +0 -23
  65. data/ext/libyajl2/vendored/src/yajl +0 -33
  66. data/ext/libyajl2/vendored/src/yajl.c +0 -175
  67. data/ext/libyajl2/vendored/src/yajl.pc.cmake +0 -9
  68. data/ext/libyajl2/vendored/src/yajl_alloc.c +0 -52
  69. data/ext/libyajl2/vendored/src/yajl_alloc.h +0 -34
  70. data/ext/libyajl2/vendored/src/yajl_buf.c +0 -103
  71. data/ext/libyajl2/vendored/src/yajl_buf.h +0 -57
  72. data/ext/libyajl2/vendored/src/yajl_bytestack.h +0 -69
  73. data/ext/libyajl2/vendored/src/yajl_encode.c +0 -220
  74. data/ext/libyajl2/vendored/src/yajl_encode.h +0 -34
  75. data/ext/libyajl2/vendored/src/yajl_gen.c +0 -354
  76. data/ext/libyajl2/vendored/src/yajl_lex.c +0 -763
  77. data/ext/libyajl2/vendored/src/yajl_lex.h +0 -117
  78. data/ext/libyajl2/vendored/src/yajl_parser.c +0 -498
  79. data/ext/libyajl2/vendored/src/yajl_parser.h +0 -78
  80. data/ext/libyajl2/vendored/src/yajl_tree.c +0 -503
  81. data/ext/libyajl2/vendored/src/yajl_version.c +0 -7
  82. data/ext/libyajl2/vendored/test/CMakeLists.txt +0 -23
  83. data/ext/libyajl2/vendored/test/cases/ac_difficult_json_c_test_case_with_comments.json +0 -1
  84. data/ext/libyajl2/vendored/test/cases/ac_difficult_json_c_test_case_with_comments.json.gold +0 -36
  85. data/ext/libyajl2/vendored/test/cases/ac_simple_with_comments.json +0 -11
  86. data/ext/libyajl2/vendored/test/cases/ac_simple_with_comments.json.gold +0 -9
  87. data/ext/libyajl2/vendored/test/cases/ag_false_then_garbage.json +0 -1
  88. data/ext/libyajl2/vendored/test/cases/ag_false_then_garbage.json.gold +0 -2
  89. data/ext/libyajl2/vendored/test/cases/ag_null_then_garbage.json +0 -1
  90. data/ext/libyajl2/vendored/test/cases/ag_null_then_garbage.json.gold +0 -2
  91. data/ext/libyajl2/vendored/test/cases/ag_true_then_garbage.json +0 -1
  92. data/ext/libyajl2/vendored/test/cases/ag_true_then_garbage.json.gold +0 -2
  93. data/ext/libyajl2/vendored/test/cases/am_eof.json +0 -1
  94. data/ext/libyajl2/vendored/test/cases/am_eof.json.gold +0 -4
  95. data/ext/libyajl2/vendored/test/cases/am_integers.json +0 -1
  96. data/ext/libyajl2/vendored/test/cases/am_integers.json.gold +0 -3
  97. data/ext/libyajl2/vendored/test/cases/am_multiple.json +0 -3
  98. data/ext/libyajl2/vendored/test/cases/am_multiple.json.gold +0 -5
  99. data/ext/libyajl2/vendored/test/cases/am_stuff.json +0 -7
  100. data/ext/libyajl2/vendored/test/cases/am_stuff.json.gold +0 -14
  101. data/ext/libyajl2/vendored/test/cases/ap_array_open.json +0 -1
  102. data/ext/libyajl2/vendored/test/cases/ap_array_open.json.gold +0 -2
  103. data/ext/libyajl2/vendored/test/cases/ap_eof_str.json +0 -1
  104. data/ext/libyajl2/vendored/test/cases/ap_eof_str.json.gold +0 -1
  105. data/ext/libyajl2/vendored/test/cases/ap_map_open.json +0 -1
  106. data/ext/libyajl2/vendored/test/cases/ap_map_open.json.gold +0 -2
  107. data/ext/libyajl2/vendored/test/cases/ap_partial_ok.json +0 -1
  108. data/ext/libyajl2/vendored/test/cases/ap_partial_ok.json.gold +0 -4
  109. data/ext/libyajl2/vendored/test/cases/array.json +0 -6
  110. data/ext/libyajl2/vendored/test/cases/array.json.gold +0 -22
  111. data/ext/libyajl2/vendored/test/cases/array_close.json +0 -1
  112. data/ext/libyajl2/vendored/test/cases/array_close.json.gold +0 -2
  113. data/ext/libyajl2/vendored/test/cases/bignums.json +0 -1
  114. data/ext/libyajl2/vendored/test/cases/bignums.json.gold +0 -5
  115. data/ext/libyajl2/vendored/test/cases/bogus_char.json +0 -4
  116. data/ext/libyajl2/vendored/test/cases/bogus_char.json.gold +0 -10
  117. data/ext/libyajl2/vendored/test/cases/codepoints_from_unicode_org.json +0 -1
  118. data/ext/libyajl2/vendored/test/cases/codepoints_from_unicode_org.json.gold +0 -2
  119. data/ext/libyajl2/vendored/test/cases/deep_arrays.json +0 -1
  120. data/ext/libyajl2/vendored/test/cases/deep_arrays.json.gold +0 -2049
  121. data/ext/libyajl2/vendored/test/cases/difficult_json_c_test_case.json +0 -1
  122. data/ext/libyajl2/vendored/test/cases/difficult_json_c_test_case.json.gold +0 -36
  123. data/ext/libyajl2/vendored/test/cases/doubles.json +0 -1
  124. data/ext/libyajl2/vendored/test/cases/doubles.json.gold +0 -7
  125. data/ext/libyajl2/vendored/test/cases/doubles_in_array.json +0 -1
  126. data/ext/libyajl2/vendored/test/cases/doubles_in_array.json.gold +0 -8
  127. data/ext/libyajl2/vendored/test/cases/empty_array.json +0 -1
  128. data/ext/libyajl2/vendored/test/cases/empty_array.json.gold +0 -3
  129. data/ext/libyajl2/vendored/test/cases/empty_string.json +0 -1
  130. data/ext/libyajl2/vendored/test/cases/empty_string.json.gold +0 -2
  131. data/ext/libyajl2/vendored/test/cases/escaped_bulgarian.json +0 -4
  132. data/ext/libyajl2/vendored/test/cases/escaped_bulgarian.json.gold +0 -7
  133. data/ext/libyajl2/vendored/test/cases/escaped_foobar.json +0 -1
  134. data/ext/libyajl2/vendored/test/cases/escaped_foobar.json.gold +0 -2
  135. data/ext/libyajl2/vendored/test/cases/false.json +0 -1
  136. data/ext/libyajl2/vendored/test/cases/false.json.gold +0 -2
  137. data/ext/libyajl2/vendored/test/cases/fg_false_then_garbage.json +0 -1
  138. data/ext/libyajl2/vendored/test/cases/fg_false_then_garbage.json.gold +0 -3
  139. data/ext/libyajl2/vendored/test/cases/fg_issue_7.json +0 -1
  140. data/ext/libyajl2/vendored/test/cases/fg_issue_7.json.gold +0 -3
  141. data/ext/libyajl2/vendored/test/cases/fg_null_then_garbage.json +0 -1
  142. data/ext/libyajl2/vendored/test/cases/fg_null_then_garbage.json.gold +0 -3
  143. data/ext/libyajl2/vendored/test/cases/fg_true_then_garbage.json +0 -1
  144. data/ext/libyajl2/vendored/test/cases/fg_true_then_garbage.json.gold +0 -3
  145. data/ext/libyajl2/vendored/test/cases/four_byte_utf8.json +0 -2
  146. data/ext/libyajl2/vendored/test/cases/four_byte_utf8.json.gold +0 -5
  147. data/ext/libyajl2/vendored/test/cases/high_overflow.json +0 -1
  148. data/ext/libyajl2/vendored/test/cases/high_overflow.json.gold +0 -2
  149. data/ext/libyajl2/vendored/test/cases/integers.json +0 -3
  150. data/ext/libyajl2/vendored/test/cases/integers.json.gold +0 -14
  151. data/ext/libyajl2/vendored/test/cases/invalid_utf8.json +0 -1
  152. data/ext/libyajl2/vendored/test/cases/invalid_utf8.json.gold +0 -3
  153. data/ext/libyajl2/vendored/test/cases/isolated_surrogate_marker.json +0 -1
  154. data/ext/libyajl2/vendored/test/cases/isolated_surrogate_marker.json.gold +0 -2
  155. data/ext/libyajl2/vendored/test/cases/leading_zero_in_number.json +0 -1
  156. data/ext/libyajl2/vendored/test/cases/leading_zero_in_number.json.gold +0 -5
  157. data/ext/libyajl2/vendored/test/cases/lonely_minus_sign.json +0 -7
  158. data/ext/libyajl2/vendored/test/cases/lonely_minus_sign.json.gold +0 -9
  159. data/ext/libyajl2/vendored/test/cases/lonely_number.json +0 -1
  160. data/ext/libyajl2/vendored/test/cases/lonely_number.json.gold +0 -2
  161. data/ext/libyajl2/vendored/test/cases/low_overflow.json +0 -1
  162. data/ext/libyajl2/vendored/test/cases/low_overflow.json.gold +0 -2
  163. data/ext/libyajl2/vendored/test/cases/map_close.json +0 -1
  164. data/ext/libyajl2/vendored/test/cases/map_close.json.gold +0 -2
  165. data/ext/libyajl2/vendored/test/cases/missing_integer_after_decimal_point.json +0 -1
  166. data/ext/libyajl2/vendored/test/cases/missing_integer_after_decimal_point.json.gold +0 -2
  167. data/ext/libyajl2/vendored/test/cases/missing_integer_after_exponent.json +0 -1
  168. data/ext/libyajl2/vendored/test/cases/missing_integer_after_exponent.json.gold +0 -2
  169. data/ext/libyajl2/vendored/test/cases/multiple.json +0 -3
  170. data/ext/libyajl2/vendored/test/cases/multiple.json.gold +0 -4
  171. data/ext/libyajl2/vendored/test/cases/non_utf8_char_in_string.json +0 -1
  172. data/ext/libyajl2/vendored/test/cases/non_utf8_char_in_string.json.gold +0 -8
  173. data/ext/libyajl2/vendored/test/cases/np_partial_bad.json +0 -1
  174. data/ext/libyajl2/vendored/test/cases/np_partial_bad.json.gold +0 -5
  175. data/ext/libyajl2/vendored/test/cases/null.json +0 -1
  176. data/ext/libyajl2/vendored/test/cases/null.json.gold +0 -2
  177. data/ext/libyajl2/vendored/test/cases/nulls_and_bools.json +0 -5
  178. data/ext/libyajl2/vendored/test/cases/nulls_and_bools.json.gold +0 -9
  179. data/ext/libyajl2/vendored/test/cases/simple.json +0 -5
  180. data/ext/libyajl2/vendored/test/cases/simple.json.gold +0 -9
  181. data/ext/libyajl2/vendored/test/cases/simple_with_comments.json +0 -11
  182. data/ext/libyajl2/vendored/test/cases/simple_with_comments.json.gold +0 -5
  183. data/ext/libyajl2/vendored/test/cases/string_invalid_escape.json +0 -1
  184. data/ext/libyajl2/vendored/test/cases/string_invalid_escape.json.gold +0 -3
  185. data/ext/libyajl2/vendored/test/cases/string_invalid_hex_char.json +0 -1
  186. data/ext/libyajl2/vendored/test/cases/string_invalid_hex_char.json.gold +0 -2
  187. data/ext/libyajl2/vendored/test/cases/string_with_escapes.json +0 -3
  188. data/ext/libyajl2/vendored/test/cases/string_with_escapes.json.gold +0 -7
  189. data/ext/libyajl2/vendored/test/cases/string_with_invalid_newline.json +0 -2
  190. data/ext/libyajl2/vendored/test/cases/string_with_invalid_newline.json.gold +0 -2
  191. data/ext/libyajl2/vendored/test/cases/three_byte_utf8.json +0 -1
  192. data/ext/libyajl2/vendored/test/cases/three_byte_utf8.json.gold +0 -7
  193. data/ext/libyajl2/vendored/test/cases/true.json +0 -1
  194. data/ext/libyajl2/vendored/test/cases/true.json.gold +0 -2
  195. data/ext/libyajl2/vendored/test/cases/unescaped_bulgarian.json +0 -1
  196. data/ext/libyajl2/vendored/test/cases/unescaped_bulgarian.json.gold +0 -4
  197. data/ext/libyajl2/vendored/test/cases/zerobyte.json +0 -1
  198. data/ext/libyajl2/vendored/test/cases/zerobyte.json.gold +0 -0
  199. data/ext/libyajl2/vendored/test/run_tests.sh +0 -94
  200. data/ext/libyajl2/vendored/test/yajl_test.c +0 -281
  201. data/ext/libyajl2/vendored/verify/CMakeLists.txt +0 -39
  202. data/ext/libyajl2/vendored/verify/json_verify.c +0 -116
  203. data/lib/ffi_yajl/json_gem.rb +0 -121
  204. data/lib/libyajl.so +0 -0
  205. data/lib/libyajl.so.2 +0 -0
  206. data/lib/libyajl.so.2.0.5 +0 -0
  207. data/lib/libyajl_s.a +0 -0
  208. data/spec/ffi_yajl/encoder_spec.rb +0 -39
  209. data/spec/ffi_yajl/json_gem_spec.rb +0 -355
  210. data/spec/ffi_yajl/parser_spec.rb +0 -78
  211. data/spec/spec_helper.rb +0 -14
@@ -2,18 +2,12 @@
2
2
  #include <yajl/yajl_gen.h>
3
3
 
4
4
  static VALUE mFFI_Yajl, mExt, mEncoder, mEncoder2, cEncodeError;
5
+ static VALUE cDate, cTime, cDateTime, cStringIO;
6
+ static VALUE cYajl_Gen;
5
7
 
6
8
  /* FIXME: the json gem does a whole bunch of indirection around monkeypatching... not sure if we need to as well... */
7
9
 
8
- #define CHECK_STATUS(call) \
9
- if ((status = (call)) != yajl_gen_status_ok) { rb_funcall(mEncoder2, rb_intern("raise_error_for_status"), 1, status); }
10
-
11
- typedef struct {
12
- VALUE json_opts;
13
- int processing_key;
14
- } ffi_state_t;
15
-
16
- static VALUE mEncoder_do_yajl_encode(VALUE self, VALUE obj, VALUE yajl_gen_opts) {
10
+ static VALUE mEncoder_do_yajl_encode(VALUE self, VALUE obj, VALUE yajl_gen_opts, VALUE json_opts) {
17
11
  ID sym_ffi_yajl = rb_intern("ffi_yajl");
18
12
  VALUE sym_yajl_gen_beautify = ID2SYM(rb_intern("yajl_gen_beautify"));
19
13
  VALUE sym_yajl_gen_validate_utf8 = ID2SYM(rb_intern("yajl_gen_validate_utf8"));
@@ -21,9 +15,10 @@ static VALUE mEncoder_do_yajl_encode(VALUE self, VALUE obj, VALUE yajl_gen_opts)
21
15
  yajl_gen yajl_gen;
22
16
  const unsigned char *buf;
23
17
  size_t len;
24
- ffi_state_t state;
18
+ VALUE state;
25
19
  VALUE ret;
26
20
  VALUE indent_string;
21
+ VALUE rb_yajl_gen;
27
22
 
28
23
  yajl_gen = yajl_gen_alloc(NULL);
29
24
 
@@ -41,9 +36,15 @@ static VALUE mEncoder_do_yajl_encode(VALUE self, VALUE obj, VALUE yajl_gen_opts)
41
36
  yajl_gen_config(yajl_gen, yajl_gen_indent_string, " ");
42
37
  }
43
38
 
44
- state.processing_key = 0;
39
+ state = rb_hash_new();
40
+
41
+ rb_hash_aset(state, rb_str_new2("processing_key"), Qfalse);
42
+
43
+ rb_hash_aset(state, rb_str_new2("json_opts"), json_opts);
45
44
 
46
- rb_funcall(obj, sym_ffi_yajl, 2, yajl_gen, (VALUE) &state);
45
+ rb_yajl_gen = Data_Wrap_Struct(cYajl_Gen, NULL, NULL, yajl_gen);
46
+
47
+ rb_funcall(obj, sym_ffi_yajl, 2, rb_yajl_gen, state);
47
48
 
48
49
  yajl_gen_get_buf(yajl_gen, &buf, &len);
49
50
 
@@ -54,167 +55,301 @@ static VALUE mEncoder_do_yajl_encode(VALUE self, VALUE obj, VALUE yajl_gen_opts)
54
55
  return ret;
55
56
  }
56
57
 
57
- typedef struct {
58
- VALUE yajl_gen;
59
- ffi_state_t *state;
60
- } ffs_extra_t;
61
-
62
58
  int rb_cHash_ffi_yajl_callback(VALUE key, VALUE val, VALUE extra) {
63
- ffs_extra_t *extra_p = (ffs_extra_t *)extra;
64
59
  ID sym_ffi_yajl = rb_intern("ffi_yajl");
60
+ VALUE state = rb_hash_aref(extra, rb_str_new2("state"));
61
+ VALUE rb_yajl_gen = rb_hash_aref(extra, rb_str_new2("yajl_gen"));
65
62
 
66
- extra_p->state->processing_key = 1;
67
- rb_funcall(key, sym_ffi_yajl, 2, extra_p->yajl_gen, extra_p->state);
68
- extra_p->state->processing_key = 0;
69
- rb_funcall(val, sym_ffi_yajl, 2, extra_p->yajl_gen, extra_p->state);
63
+ rb_hash_aset(state, rb_str_new2("processing_key"), Qtrue);
64
+ rb_funcall(key, sym_ffi_yajl, 2, rb_yajl_gen, state);
65
+ rb_hash_aset(state, rb_str_new2("processing_key"), Qfalse);
66
+
67
+ rb_funcall(val, sym_ffi_yajl, 2, rb_yajl_gen, state);
70
68
 
71
69
  return 0;
72
70
  }
73
71
 
74
- static VALUE rb_cHash_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) {
72
+ #define RB_FUNC0(call) rb_funcall(self, rb_intern(call), 0)
73
+
74
+ /*
75
+ * wrappers around yajl_gen_* functions
76
+ */
77
+
78
+ /* encode a c-string as a yajl string */
79
+ VALUE gen_cstring(VALUE rb_yajl_gen, char *cptr, int len) {
75
80
  yajl_gen_status status;
76
- ffs_extra_t extra;
81
+ struct yajl_gen_t *yajl_gen;
82
+ Data_Get_Struct(rb_yajl_gen, struct yajl_gen_t, yajl_gen);
77
83
 
78
- extra.yajl_gen = yajl_gen;
79
- extra.state = (ffi_state_t *)state;
84
+ if ((status = yajl_gen_string(yajl_gen, (unsigned char *)cptr, len)) != yajl_gen_status_ok) {
85
+ rb_funcall(mEncoder2, rb_intern("raise_error_for_status"), 2, INT2FIX(status), rb_str_new(cptr, len));
86
+ }
80
87
 
81
- CHECK_STATUS(
82
- yajl_gen_map_open((struct yajl_gen_t *) yajl_gen)
83
- );
84
- rb_hash_foreach(self, rb_cHash_ffi_yajl_callback, (VALUE) &extra);
85
- CHECK_STATUS(
86
- yajl_gen_map_close((struct yajl_gen_t *) yajl_gen)
87
- );
88
+ return Qnil;
89
+ }
90
+
91
+ /* encode a ruby-sring as a yajl string */
92
+ VALUE gen_string(VALUE rb_yajl_gen, VALUE str) {
93
+ char *cptr = RSTRING_PTR(str);
94
+ int len = RSTRING_LEN(str);
95
+
96
+ return gen_cstring(rb_yajl_gen, cptr, len);
97
+ }
98
+
99
+ /* calls #to_s on an object to encode it as a yajl string */
100
+ static VALUE gen_string_to_s(VALUE rb_yajl_gen, VALUE self) {
101
+ return gen_string(rb_yajl_gen, RB_FUNC0("to_s"));
102
+ }
103
+
104
+ /* encode a ruby string as a yajl number (also used to embed already-rendered json from #to_json) */
105
+ VALUE gen_number(VALUE rb_yajl_gen, VALUE str) {
106
+ yajl_gen_status status;
107
+ struct yajl_gen_t *yajl_gen;
108
+ Data_Get_Struct(rb_yajl_gen, struct yajl_gen_t, yajl_gen);
109
+ char *cptr = RSTRING_PTR(str);
110
+ int len = RSTRING_LEN(str);
111
+
112
+ if ((status = yajl_gen_number(yajl_gen, cptr, len)) != yajl_gen_status_ok) {
113
+ rb_funcall(mEncoder2, rb_intern("raise_error_for_status"), 2, INT2FIX(status), str);
114
+ }
88
115
 
89
116
  return Qnil;
90
117
  }
91
118
 
92
- static VALUE rb_cArray_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) {
119
+ /* encode hash open */
120
+ VALUE gen_map_open(VALUE rb_yajl_gen) {
93
121
  yajl_gen_status status;
94
- ID sym_ffi_yajl = rb_intern("ffi_yajl");
95
- long i;
96
- VALUE val;
122
+ struct yajl_gen_t *yajl_gen;
123
+ Data_Get_Struct(rb_yajl_gen, struct yajl_gen_t, yajl_gen);
97
124
 
98
- CHECK_STATUS(
99
- yajl_gen_array_open((struct yajl_gen_t *) yajl_gen)
100
- );
101
- for(i=0; i<RARRAY_LEN(self); i++) {
102
- val = rb_ary_entry(self, i);
103
- rb_funcall(val, sym_ffi_yajl, 2, yajl_gen, state);
125
+ if ((status = yajl_gen_map_open(yajl_gen)) != yajl_gen_status_ok) {
126
+ rb_funcall(mEncoder2, rb_intern("raise_error_for_status"), 2, INT2FIX(status), rb_str_new2("{"));
104
127
  }
105
- CHECK_STATUS(
106
- yajl_gen_array_close((struct yajl_gen_t *) yajl_gen)
107
- );
108
128
 
109
129
  return Qnil;
110
130
  }
111
131
 
112
- static VALUE rb_cNilClass_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) {
132
+ /* encode a hash close */
133
+ VALUE gen_map_close(VALUE rb_yajl_gen) {
113
134
  yajl_gen_status status;
114
- CHECK_STATUS(
115
- yajl_gen_null((struct yajl_gen_t *) yajl_gen)
116
- );
135
+ struct yajl_gen_t *yajl_gen;
136
+ Data_Get_Struct(rb_yajl_gen, struct yajl_gen_t, yajl_gen);
137
+
138
+ if ((status = yajl_gen_map_close(yajl_gen)) != yajl_gen_status_ok) {
139
+ rb_funcall(mEncoder2, rb_intern("raise_error_for_status"), 2, INT2FIX(status), rb_str_new2("}"));
140
+ }
141
+
117
142
  return Qnil;
118
143
  }
119
144
 
120
- static VALUE rb_cTrueClass_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) {
145
+ /* encode an array open */
146
+ VALUE gen_array_open(VALUE rb_yajl_gen) {
121
147
  yajl_gen_status status;
122
- CHECK_STATUS(
123
- yajl_gen_bool((struct yajl_gen_t *) yajl_gen, 1)
124
- );
148
+ struct yajl_gen_t *yajl_gen;
149
+ Data_Get_Struct(rb_yajl_gen, struct yajl_gen_t, yajl_gen);
150
+
151
+ if ((status = yajl_gen_array_open(yajl_gen)) != yajl_gen_status_ok) {
152
+ rb_funcall(mEncoder2, rb_intern("raise_error_for_status"), 2, INT2FIX(status), rb_str_new2("["));
153
+ }
154
+
125
155
  return Qnil;
126
156
  }
127
157
 
128
- static VALUE rb_cFalseClass_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) {
158
+ /* encode an array close */
159
+ VALUE gen_array_close(VALUE rb_yajl_gen) {
129
160
  yajl_gen_status status;
130
- CHECK_STATUS(
131
- yajl_gen_bool((struct yajl_gen_t *) yajl_gen, 0)
132
- );
161
+ struct yajl_gen_t *yajl_gen;
162
+ Data_Get_Struct(rb_yajl_gen, struct yajl_gen_t, yajl_gen);
163
+
164
+ if ((status = yajl_gen_array_close(yajl_gen)) != yajl_gen_status_ok) {
165
+ rb_funcall(mEncoder2, rb_intern("raise_error_for_status"), 2, INT2FIX(status), rb_str_new2("]"));
166
+ }
167
+
133
168
  return Qnil;
134
169
  }
135
170
 
136
- static VALUE rb_cFixnum_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) {
171
+ /* encode a json null */
172
+ VALUE gen_null(VALUE rb_yajl_gen) {
137
173
  yajl_gen_status status;
138
- ID sym_to_s = rb_intern("to_s");
139
- VALUE str = rb_funcall(self, sym_to_s, 0);
140
- char *cptr = RSTRING_PTR(str);
141
- int len = RSTRING_LEN(str);
174
+ struct yajl_gen_t *yajl_gen;
175
+ Data_Get_Struct(rb_yajl_gen, struct yajl_gen_t, yajl_gen);
142
176
 
143
- if (memcmp(cptr, "NaN", 3) == 0 || memcmp(cptr, "Infinity", 8) == 0 || memcmp(cptr, "-Infinity", 9) == 0) {
144
- rb_raise(cEncodeError, "'%s' is an invalid number", cptr);
177
+ if ((status = yajl_gen_null(yajl_gen)) != yajl_gen_status_ok) {
178
+ rb_funcall(mEncoder2, rb_intern("raise_error_for_status"), 2, INT2FIX(status), rb_str_new2("null"));
145
179
  }
146
- if ( ((ffi_state_t *)state)->processing_key ) {
147
- CHECK_STATUS(
148
- yajl_gen_string((struct yajl_gen_t *) yajl_gen, (unsigned char *)cptr, len)
149
- );
150
- } else {
151
- CHECK_STATUS(
152
- yajl_gen_integer((struct yajl_gen_t *) yajl_gen, NUM2INT(self))
153
- );
180
+
181
+ return Qnil;
182
+ }
183
+
184
+ /* encode a true value */
185
+ VALUE gen_true(VALUE rb_yajl_gen) {
186
+ yajl_gen_status status;
187
+ struct yajl_gen_t *yajl_gen;
188
+ Data_Get_Struct(rb_yajl_gen, struct yajl_gen_t, yajl_gen);
189
+
190
+ if ((status = yajl_gen_bool(yajl_gen, 1)) != yajl_gen_status_ok) {
191
+ rb_funcall(mEncoder2, rb_intern("raise_error_for_status"), 2, INT2FIX(status), rb_str_new2("true"));
154
192
  }
193
+
155
194
  return Qnil;
156
195
  }
157
196
 
158
- static VALUE rb_cBignum_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) {
197
+ /* encode a false value */
198
+ VALUE gen_false(VALUE rb_yajl_gen) {
159
199
  yajl_gen_status status;
160
- ID sym_to_s = rb_intern("to_s");
161
- VALUE str = rb_funcall(self, sym_to_s, 0);
162
- char *cptr = RSTRING_PTR(str);
163
- int len = RSTRING_LEN(str);
164
- if (memcmp(cptr, "NaN", 3) == 0 || memcmp(cptr, "Infinity", 8) == 0 || memcmp(cptr, "-Infinity", 9) == 0) {
165
- rb_raise(cEncodeError, "'%s' is an invalid number", cptr);
200
+ struct yajl_gen_t *yajl_gen;
201
+ Data_Get_Struct(rb_yajl_gen, struct yajl_gen_t, yajl_gen);
202
+
203
+ if ((status = yajl_gen_bool(yajl_gen, 0)) != yajl_gen_status_ok) {
204
+ rb_funcall(mEncoder2, rb_intern("raise_error_for_status"), 2, INT2FIX(status), rb_str_new2("false"));
205
+ }
206
+
207
+ return Qnil;
208
+ }
209
+
210
+ /*
211
+ * <Object>#to_ffi_yajl() method calls
212
+ */
213
+
214
+ static VALUE rb_cHash_ffi_yajl(VALUE self, VALUE rb_yajl_gen, VALUE state) {
215
+ if ( rb_hash_aref(state, rb_str_new2("processing_key")) == Qtrue ) {
216
+ gen_string(rb_yajl_gen, rb_funcall(self, rb_intern("to_s"), 0));
217
+ } else {
218
+
219
+ /* FIXME: i think this got refactored from something else and it is now pointless --
220
+ should just pass rb_yajl_gen directly instead of this 'extra' hash -- i don't
221
+ *think* this indirection is doing anything useful to mark memory against the GC */
222
+
223
+ VALUE extra = rb_hash_new();
224
+
225
+ rb_hash_aset(extra, rb_str_new2("yajl_gen"), rb_yajl_gen);
226
+
227
+ rb_hash_aset(extra, rb_str_new2("state"), state);
228
+
229
+ gen_map_open(rb_yajl_gen);
230
+
231
+ rb_hash_foreach(self, rb_cHash_ffi_yajl_callback, extra);
232
+
233
+ gen_map_close(rb_yajl_gen);
166
234
  }
167
- if ( ((ffi_state_t *)state)->processing_key ) {
168
- CHECK_STATUS(
169
- yajl_gen_string((struct yajl_gen_t *) yajl_gen, (unsigned char *)cptr, len)
170
- );
235
+
236
+ return Qnil;
237
+ }
238
+
239
+ static VALUE rb_cArray_ffi_yajl(VALUE self, VALUE rb_yajl_gen, VALUE state) {
240
+ if ( rb_hash_aref(state, rb_str_new2("processing_key")) == Qtrue ) {
241
+ gen_string(rb_yajl_gen, rb_funcall(self, rb_intern("to_s"), 0));
171
242
  } else {
172
- CHECK_STATUS(
173
- yajl_gen_number((struct yajl_gen_t *) yajl_gen, cptr, len)
174
- );
243
+ VALUE val;
244
+ long i;
245
+ ID sym_ffi_yajl = rb_intern("ffi_yajl");
246
+
247
+ gen_array_open(rb_yajl_gen);
248
+
249
+ for(i=0; i<RARRAY_LEN(self); i++) {
250
+ val = rb_ary_entry(self, i);
251
+ rb_funcall(val, sym_ffi_yajl, 2, rb_yajl_gen, state);
252
+ }
253
+
254
+ gen_array_close(rb_yajl_gen);
175
255
  }
256
+
176
257
  return Qnil;
177
258
  }
178
259
 
179
- static VALUE rb_cFloat_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) {
180
- yajl_gen_status status;
181
- ID sym_to_s = rb_intern("to_s");
182
- VALUE str = rb_funcall(self, sym_to_s, 0);
260
+ static VALUE rb_cNilClass_ffi_yajl(VALUE self, VALUE rb_yajl_gen, VALUE state) {
261
+ if ( rb_hash_aref(state, rb_str_new2("processing_key")) == Qtrue ) {
262
+ gen_cstring(rb_yajl_gen, "", sizeof("")-1);
263
+ } else {
264
+ gen_null(rb_yajl_gen);
265
+ }
266
+
267
+ return Qnil;
268
+ }
269
+
270
+ static VALUE rb_cTrueClass_ffi_yajl(VALUE self, VALUE rb_yajl_gen, VALUE state) {
271
+ if ( rb_hash_aref(state, rb_str_new2("processing_key")) == Qtrue ) {
272
+ gen_cstring(rb_yajl_gen, "true", sizeof("true")-1);
273
+ } else {
274
+ gen_true(rb_yajl_gen);
275
+ }
276
+
277
+ return Qnil;
278
+ }
279
+
280
+ static VALUE rb_cFalseClass_ffi_yajl(VALUE self, VALUE rb_yajl_gen, VALUE state) {
281
+ if ( rb_hash_aref(state, rb_str_new2("processing_key")) == Qtrue ) {
282
+ gen_cstring(rb_yajl_gen, "false", sizeof("false")-1);
283
+ } else {
284
+ gen_false(rb_yajl_gen);
285
+ }
286
+
287
+ return Qnil;
288
+ }
289
+
290
+ static VALUE rb_cFixnum_ffi_yajl(VALUE self, VALUE rb_yajl_gen, VALUE state) {
291
+ VALUE str = rb_funcall(self, rb_intern("to_s"), 0);
183
292
  char *cptr = RSTRING_PTR(str);
184
- int len = RSTRING_LEN(str);
185
- if (memcmp(cptr, "NaN", 3) == 0 || memcmp(cptr, "Infinity", 8) == 0 || memcmp(cptr, "-Infinity", 9) == 0) {
293
+
294
+ if (memcmp(cptr, "NaN", sizeof("NaN")) == 0 || memcmp(cptr, "Infinity", sizeof("Infinity")) == 0 || memcmp(cptr, "-Infinity", sizeof("-Infinity")) == 0) {
186
295
  rb_raise(cEncodeError, "'%s' is an invalid number", cptr);
187
296
  }
188
- if ( ((ffi_state_t *)state)->processing_key ) {
189
- CHECK_STATUS(
190
- yajl_gen_string((struct yajl_gen_t *) yajl_gen, (unsigned char *)cptr, len)
191
- );
297
+
298
+ if ( rb_hash_aref(state, rb_str_new2("processing_key")) == Qtrue ) {
299
+ gen_string(rb_yajl_gen, str);
192
300
  } else {
193
- CHECK_STATUS(
194
- yajl_gen_number((struct yajl_gen_t *) yajl_gen, cptr, len)
195
- );
301
+ gen_number(rb_yajl_gen, str);
196
302
  }
303
+
197
304
  return Qnil;
198
305
  }
199
306
 
307
+ static VALUE rb_cBignum_ffi_yajl(VALUE self, VALUE rb_yajl_gen, VALUE state) {
308
+ return rb_cFixnum_ffi_yajl(self, rb_yajl_gen, state);
309
+ }
200
310
 
201
- static VALUE rb_cString_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) {
202
- yajl_gen_status status;
203
- CHECK_STATUS(
204
- yajl_gen_string((struct yajl_gen_t *) yajl_gen, (unsigned char *)RSTRING_PTR(self), RSTRING_LEN(self))
205
- );
206
- return Qnil;
311
+ static VALUE rb_cFloat_ffi_yajl(VALUE self, VALUE rb_yajl_gen, VALUE state) {
312
+ return rb_cFixnum_ffi_yajl(self, rb_yajl_gen, state);
207
313
  }
208
314
 
209
- static VALUE rb_cObject_ffi_yajl(VALUE self, VALUE yajl_gen, VALUE state) {
210
- yajl_gen_status status;
315
+ static VALUE rb_cString_ffi_yajl(VALUE self, VALUE rb_yajl_gen, VALUE state) {
316
+ return gen_string(rb_yajl_gen, self);
317
+ }
318
+
319
+ static VALUE rb_cSymbol_ffi_yajl(VALUE self, VALUE rb_yajl_gen, VALUE state) {
320
+ return gen_string_to_s(rb_yajl_gen, self);
321
+ }
322
+
323
+ static VALUE rb_cDate_ffi_yajl(VALUE self, VALUE rb_yajl_gen, VALUE state) {
324
+ return gen_string_to_s(rb_yajl_gen, self);
325
+ }
326
+
327
+ static VALUE rb_cTime_ffi_yajl(VALUE self, VALUE rb_yajl_gen, VALUE state) {
328
+ ID sym_strftime = rb_intern("strftime");
329
+ VALUE str = rb_funcall(self, sym_strftime, 1, rb_str_new2("%Y-%m-%d %H:%M:%S %z"));
330
+
331
+ return gen_string(rb_yajl_gen, str);
332
+ }
333
+
334
+ static VALUE rb_cStringIO_ffi_yajl(VALUE self, VALUE rb_yajl_gen, VALUE state) {
335
+ return gen_string(rb_yajl_gen, RB_FUNC0("read"));
336
+ }
337
+
338
+ static VALUE rb_cDateTime_ffi_yajl(VALUE self, VALUE rb_yajl_gen, VALUE state) {
339
+ return gen_string_to_s(rb_yajl_gen, self);
340
+ }
341
+
342
+ static VALUE rb_cObject_ffi_yajl(VALUE self, VALUE rb_yajl_gen, VALUE state) {
211
343
  ID sym_to_json = rb_intern("to_json");
212
- VALUE str;
344
+ if ( rb_hash_aref(state, rb_str_new2("processing_key")) != Qtrue && rb_respond_to(self, sym_to_json) ) {
345
+ VALUE json_opts = rb_hash_aref(state, rb_str_new2("json_opts"));
346
+ VALUE str = rb_funcall(self, sym_to_json, 1, json_opts);
347
+
348
+ gen_number(rb_yajl_gen, str);
349
+ } else {
350
+ gen_string_to_s(rb_yajl_gen, self);
351
+ }
213
352
 
214
- str = rb_funcall(self, sym_to_json, 1, ((ffi_state_t *)state)->json_opts);
215
- CHECK_STATUS(
216
- yajl_gen_number((struct yajl_gen_t *) yajl_gen, (char *)RSTRING_PTR(str), RSTRING_LEN(str))
217
- );
218
353
  return Qnil;
219
354
  }
220
355
 
@@ -224,17 +359,37 @@ void Init_encoder() {
224
359
  cEncodeError = rb_define_class_under(mFFI_Yajl, "EncodeError", rb_eStandardError);
225
360
  mExt = rb_define_module_under(mFFI_Yajl, "Ext");
226
361
  mEncoder = rb_define_module_under(mExt, "Encoder");
227
- rb_define_method(mEncoder, "do_yajl_encode", mEncoder_do_yajl_encode, 2);
362
+ cYajl_Gen = rb_define_class_under(mEncoder, "YajlGen", rb_cObject);
363
+ rb_undef_alloc_func(cYajl_Gen);
364
+ rb_define_method(mEncoder, "do_yajl_encode", mEncoder_do_yajl_encode, 3);
365
+
366
+ /* use rb_const_get instead of rb_define_class so that we don't get superclass mismatches */
367
+ ID sym_Date = rb_intern("Date");
368
+ cDate = rb_const_get(rb_cObject, sym_Date);
369
+ ID sym_Time = rb_intern("Time");
370
+ cTime = rb_const_get(rb_cObject, sym_Time);
371
+ ID sym_DateTime = rb_intern("DateTime");
372
+ cDateTime = rb_const_get(rb_cObject, sym_DateTime);
373
+ ID sym_StringIO = rb_intern("StringIO");
374
+ cStringIO = rb_const_get(rb_cObject, sym_StringIO);
228
375
 
229
376
  rb_define_method(rb_cHash, "ffi_yajl", rb_cHash_ffi_yajl, 2);
230
377
  rb_define_method(rb_cArray, "ffi_yajl", rb_cArray_ffi_yajl, 2);
231
378
  rb_define_method(rb_cNilClass, "ffi_yajl", rb_cNilClass_ffi_yajl, 2);
232
379
  rb_define_method(rb_cTrueClass, "ffi_yajl", rb_cTrueClass_ffi_yajl, 2);
233
380
  rb_define_method(rb_cFalseClass, "ffi_yajl", rb_cFalseClass_ffi_yajl, 2);
381
+ #ifdef rb_cFixnum /* ruby < 2.4 */
234
382
  rb_define_method(rb_cFixnum, "ffi_yajl", rb_cFixnum_ffi_yajl, 2);
235
383
  rb_define_method(rb_cBignum, "ffi_yajl", rb_cBignum_ffi_yajl, 2);
384
+ #else
385
+ rb_define_method(rb_cInteger, "ffi_yajl", rb_cFixnum_ffi_yajl, 2);
386
+ #endif
236
387
  rb_define_method(rb_cFloat, "ffi_yajl", rb_cFloat_ffi_yajl, 2);
237
388
  rb_define_method(rb_cString, "ffi_yajl", rb_cString_ffi_yajl, 2);
389
+ rb_define_method(rb_cSymbol, "ffi_yajl", rb_cSymbol_ffi_yajl, 2);
390
+ rb_define_method(cDate, "ffi_yajl", rb_cDate_ffi_yajl, 2);
391
+ rb_define_method(cTime, "ffi_yajl", rb_cTime_ffi_yajl, 2);
392
+ rb_define_method(cDateTime, "ffi_yajl", rb_cDateTime_ffi_yajl, 2);
393
+ rb_define_method(cStringIO, "ffi_yajl", rb_cStringIO_ffi_yajl, 2);
238
394
  rb_define_method(rb_cObject, "ffi_yajl", rb_cObject_ffi_yajl, 2);
239
395
  }
240
-
@@ -1,29 +1,86 @@
1
- require 'mkmf'
1
+ # rubocop:disable Style/GlobalVars
2
+ require "mkmf"
3
+ require "rubygems"
4
+ require "libyajl2"
2
5
 
3
- # the customer is always right, ruby is always compiled to be stupid
4
- $CFLAGS = ENV['CFLAGS'] if ENV['CFLAGS']
5
- $LDFLAGS = ENV['LDFLAGS'] if ENV['LDFLAGS']
6
- RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
6
+ RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"] if ENV["CC"]
7
7
 
8
- # search our gem root first to pick up libyajl2 that we vendored
9
- gem_root = File.expand_path(File.join(File.dirname(__FILE__), "../../../.."))
10
- $CFLAGS = "-I#{gem_root}/include -L#{gem_root}/lib #{$CFLAGS}"
11
- $LDFLAGS = "-L#{gem_root}/lib #{$CFLAGS}"
8
+ # pick up the vendored libyajl2 out of the libyajl2 gem
9
+ $CFLAGS = " -I#{Libyajl2.include_path} #{$CFLAGS}"
10
+ $LDFLAGS = " -L#{Libyajl2.opt_path} #{$LDFLAGS}"
11
+
12
+ # remove "-Wl,--no-undefined" flag if existent to allow for loading with dlopen
13
+ $LDFLAGS.slice!("-Wl,--no-undefined")
12
14
 
13
- puts gem_root
14
15
  puts $CFLAGS
15
16
  puts $LDFLAGS
16
17
 
17
18
  # except if you're doing an unoptimized gcc install we're going to help you out a bit
18
- if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc|clang/
19
+ if RbConfig::MAKEFILE_CONFIG["CC"] =~ /gcc|clang/
19
20
  $CFLAGS << " -O3" unless $CFLAGS[/-O\d/]
20
21
  # how many people realize that -Wall is a compiler-specific flag???
21
22
  # apparently not many based on reading lots of shitty extconf.rb's out there
22
23
  $CFLAGS << " -Wall"
23
24
  end
24
25
 
25
- $LDFLAGS << " -lyajl"
26
+ def windows?
27
+ !!(RUBY_PLATFORM =~ /mswin|mingw|cygwin|windows/)
28
+ end
29
+
30
+ def macos?
31
+ !!(RUBY_PLATFORM =~ /darwin/)
32
+ end
33
+
34
+ def clang?
35
+ cc_version = `#{RbConfig.expand("$(CC) --version")}`
36
+ cc_version.match?(/clang/i)
37
+ end
38
+
39
+ # XCode 14 warns if `-Wl,-undefined dynamic_lookup` is specified, and as
40
+ # a result Ruby interpreters compiled under XCode 14 no longer specify
41
+ # this flag by default in DLDFLAGS. Let's specify the list of dynamic symbols
42
+ # here to avoid compilation failures.
43
+ if clang? && macos?
44
+ symfile = File.join(__dir__, "../dlopen/yajl.sym")
45
+ dynamic_symbols = File.readlines(symfile)
46
+ dynamic_symbols.each do |sym|
47
+ $DLDFLAGS << " -Wl,-U,#{sym.strip}"
48
+ end
49
+ end
50
+
51
+ if windows?
52
+ # include our libyajldll.a definitions on windows in the libyajl2 gem
53
+ $libs = "#{$libs} -lyajldll"
54
+ end
55
+
56
+ # NOTE: find_library has the side effect of adding -lyajl to the flags which we are deliberately
57
+ # avoiding doing with the libyajl2-gem (allowing it to be lazily loaded with dlopen)
58
+ if !windows? && !find_header("yajl/yajl_tree.h")
59
+ puts "libyajl2 headers not found in libyajl2-gem, searching for system libraries..."
60
+
61
+ HEADER_DIRS = [
62
+ "/opt/local/include", # MacPorts
63
+ "/usr/local/include", # /usr/local
64
+ RbConfig::CONFIG["includedir"], # Ruby
65
+ "/usr/include", # (default)
66
+ ].freeze
67
+
68
+ LIB_DIRS = [
69
+ "/opt/local/lib", # MacPorts
70
+ "/usr/local/lib", # /usr/local + Homebrew
71
+ RbConfig::CONFIG["libdir"], # Ruby
72
+ "/usr/lib", # (default)
73
+ ].freeze
74
+
75
+ # add --with-yajl-dir, --with-yajl-include, --with-yajl-lib
76
+ dir_config("yajl", HEADER_DIRS, LIB_DIRS)
77
+
78
+ # here we use find_library in order to deliberately link with -lyajl as a useful side-effect
79
+ unless find_header("yajl/yajl_tree.h") && find_library("yajl", "yajl_complete_parse")
80
+ abort "libyajl2 is missing. please install libyajl2"
81
+ end
82
+ end
26
83
 
27
- dir_config 'encoder'
84
+ dir_config "encoder"
28
85
 
29
- create_makefile 'ffi_yajl/ext/encoder'
86
+ create_makefile "ffi_yajl/ext/encoder"