summaryrefslogtreecommitdiff
path: root/ext/ffi_yajl/ext
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2015-04-20 13:37:52 -0700
committerLamont Granquist <lamont@scriptkiddie.org>2015-04-20 13:37:52 -0700
commita1d4ff3ab371aecc92182f3fc9ff5a966a2df8bc (patch)
treeeaf61da3581bcbb0102a39d62b2d312f7040cb41 /ext/ffi_yajl/ext
parent5f9b3bd8e896cdba674d16dff83d4c9463d752d7 (diff)
parent329352cda438729a240ff450338f514938d74ba6 (diff)
downloadffi-yajl-a1d4ff3ab371aecc92182f3fc9ff5a966a2df8bc.tar.gz
Merge pull request #55 from chef/lcg/unique_key_checking
add :unique_key_checking flag to parser
Diffstat (limited to 'ext/ffi_yajl/ext')
-rw-r--r--ext/ffi_yajl/ext/parser/parser.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/ext/ffi_yajl/ext/parser/parser.c b/ext/ffi_yajl/ext/parser/parser.c
index a2813af..a5d2e9a 100644
--- a/ext/ffi_yajl/ext/parser/parser.c
+++ b/ext/ffi_yajl/ext/parser/parser.c
@@ -11,6 +11,7 @@ static VALUE mFFI_Yajl, mExt, mParser, cParseError;
typedef struct {
VALUE self;
int symbolizeKeys;
+ int uniqueKeyChecking;
} CTX;
void set_value(CTX *ctx, VALUE val) {
@@ -23,6 +24,12 @@ void set_value(CTX *ctx, VALUE val) {
rb_ary_push(last, val);
break;
case T_HASH:
+ if ( ctx->uniqueKeyChecking ) {
+ ID sym_has_key = rb_intern("has_key?");
+ if ( rb_funcall(last, sym_has_key, 1, key) == Qtrue ) {
+ rb_raise(cParseError, "repeated key: %s", RSTRING_PTR(key));
+ }
+ }
rb_hash_aset(last, key, val);
break;
default:
@@ -163,7 +170,7 @@ static yajl_callbacks callbacks = {
end_array_callback,
};
-int get_opts_key(VALUE self, char *key) {
+int get_opts_key(VALUE self, const char *key) {
VALUE opts = rb_iv_get(self, "@opts");
if (TYPE(opts) != T_HASH) {
rb_raise(rb_eTypeError, "opts is not a valid hash");
@@ -182,6 +189,7 @@ static VALUE mParser_do_yajl_parse(VALUE self, VALUE str, VALUE yajl_opts) {
ctx.self = self;
ctx.symbolizeKeys = get_opts_key(self, "symbolize_keys");
+ ctx.uniqueKeyChecking = get_opts_key(self, "unique_key_checking");
hand = yajl_alloc(&callbacks, NULL, (void *)&ctx);