ext/oj/fast.c in oj-3.11.5 vs ext/oj/fast.c in oj-3.11.6
- old
+ new
@@ -78,26 +78,10 @@
static int move_step(Doc doc, const char *path, int loc);
static Leaf get_doc_leaf(Doc doc, const char *path);
static Leaf get_leaf(Leaf *stack, Leaf *lp, const char *path);
static void each_value(Doc doc, Leaf leaf);
-static void doc_init(Doc doc);
-static void doc_free(Doc doc);
-static VALUE doc_open(VALUE clas, VALUE str);
-static VALUE doc_open_file(VALUE clas, VALUE filename);
-static VALUE doc_where(VALUE self);
-static VALUE doc_local_key(VALUE self);
-static VALUE doc_home(VALUE self);
-static VALUE doc_type(int argc, VALUE *argv, VALUE self);
-static VALUE doc_fetch(int argc, VALUE *argv, VALUE self);
-static VALUE doc_each_leaf(int argc, VALUE *argv, VALUE self);
-static VALUE doc_move(VALUE self, VALUE str);
-static VALUE doc_each_child(int argc, VALUE *argv, VALUE self);
-static VALUE doc_each_value(int argc, VALUE *argv, VALUE self);
-static VALUE doc_dump(int argc, VALUE *argv, VALUE self);
-static VALUE doc_size(VALUE self);
-
VALUE oj_doc_class = Qundef;
// This is only for CentOS 5.4 with Ruby 1.9.3-p0.
#ifndef HAVE_STPCPY
char *stpcpy(char *dest, const char *src) {
@@ -897,16 +881,18 @@
if (stack < lp) {
leaf = get_leaf(stack, lp - 1, path);
} else {
return 0;
}
- } else if (COL_VAL == leaf->value_type && 0 != leaf->elements) {
+ } else if (NULL == leaf->elements) {
+ leaf = NULL;
+ } else if (COL_VAL == leaf->value_type) {
Leaf first = leaf->elements->next;
Leaf e = first;
int type = leaf->rtype;
- leaf = 0;
+ leaf = NULL;
if (T_ARRAY == type) {
int cnt = 0;
for (; '0' <= *path && *path <= '9'; path++) {
cnt = cnt * 10 + (*path - '0');
@@ -927,10 +913,11 @@
} else if (T_HASH == type) {
const char *key = path;
const char *slash = next_slash(path);
int klen;
+ leaf = NULL;
if (0 == slash) {
klen = (int)strlen(key);
path += klen;
} else {
klen = (int)(slash - key);
@@ -1215,11 +1202,11 @@
/* Document-method: parse
* @see Oj::Doc.open
*/
-/* @overload where?() => String
+/* @overload where() => String
*
* Returns a String that describes the absolute path to the current location
* in the JSON document.
*/
static VALUE doc_where(VALUE self) {
@@ -1257,10 +1244,29 @@
return rb_str_new(path, p - path);
}
}
+/* @overload where?() => String
+ * @deprecated
+ * Returns a String that describes the absolute path to the current location
+ * in the JSON document.
+ */
+static VALUE doc_where_q(VALUE self) {
+ return doc_where(self);
+}
+
+/* @overload path() => String
+ *
+ * Returns a String that describes the absolute path to the current location
+ * in the JSON document.
+ */
+static VALUE doc_path(VALUE self) {
+ return doc_where(self);
+}
+
+
/* @overload local_key() => String, Fixnum, nil
*
* Returns the final key to the current location.
* @example
* Oj::Doc.open('[1,2,3]') { |doc| doc.move('/2'); doc.local_key() } #=> 2
@@ -1338,18 +1344,18 @@
}
}
return type;
}
-/* @overload fetch(path=nil) => nil, true, false, Fixnum, Float, String, Array,
+/* @overload fetch(path=nil,default=nil) => nil, true, false, Fixnum, Float, String, Array,
* Hash
*
* Returns the value at the location identified by the path or the current
* location if the path is nil or not provided. This method will create and
* return an Array or Hash if that is the type of Object at the location
* specified. This is more expensive than navigating to the leaves of the JSON
- * document.
+ * document. If a default is provided that is used if no value if found.
* @param [String] path path to the location to get the type of if provided
* @example
* Oj::Doc.open('[1,2]') { |doc| doc.fetch() } #=> [1, 2]
* Oj::Doc.open('[1,2]') { |doc| doc.fetch('/1') } #=> 1
*/
@@ -1371,10 +1377,32 @@
val = leaf_value(doc, leaf);
}
return val;
}
+/* @overload exists?(path) => true, false
+ *
+ * Returns true if the value at the location identified by the path exists.
+ * @param [String] path path to the location
+ * @example
+ * Oj::Doc.open('[1,2]') { |doc| doc.exists('/1') } #=> true
+ * Oj::Doc.open('[1,2]') { |doc| doc.exists('/3') } #=> false
+ */
+static VALUE doc_exists(VALUE self, VALUE str) {
+ Doc doc;
+ Leaf leaf;
+
+ doc = self_doc(self);
+ Check_Type(str, T_STRING);
+ if (0 != (leaf = get_doc_leaf(doc, StringValuePtr(str)))) {
+ if (NULL != leaf) {
+ return Qtrue;
+ }
+ }
+ return Qfalse;
+}
+
/* @overload each_leaf(path=nil) => nil
*
* Yields to the provided block for each leaf node with the identified
* location of the JSON document as the root. The parameter passed to the
* block on yield is the Doc instance after moving to the child location.
@@ -1693,14 +1721,17 @@
void oj_init_doc() {
oj_doc_class = rb_define_class_under(Oj, "Doc", rb_cObject);
rb_define_singleton_method(oj_doc_class, "open", doc_open, 1);
rb_define_singleton_method(oj_doc_class, "open_file", doc_open_file, 1);
rb_define_singleton_method(oj_doc_class, "parse", doc_open, 1);
- rb_define_method(oj_doc_class, "where?", doc_where, 0);
+ rb_define_method(oj_doc_class, "where?", doc_where_q, 0);
+ rb_define_method(oj_doc_class, "where", doc_where, 0);
+ rb_define_method(oj_doc_class, "path", doc_path, 0);
rb_define_method(oj_doc_class, "local_key", doc_local_key, 0);
rb_define_method(oj_doc_class, "home", doc_home, 0);
rb_define_method(oj_doc_class, "type", doc_type, -1);
rb_define_method(oj_doc_class, "fetch", doc_fetch, -1);
+ rb_define_method(oj_doc_class, "exists?", doc_exists, 1);
rb_define_method(oj_doc_class, "each_leaf", doc_each_leaf, -1);
rb_define_method(oj_doc_class, "move", doc_move, 1);
rb_define_method(oj_doc_class, "each_child", doc_each_child, -1);
rb_define_method(oj_doc_class, "each_value", doc_each_value, -1);
rb_define_method(oj_doc_class, "dump", doc_dump, -1);