View Issue Details

IDProjectCategoryView StatusLast Update
0000724LDMud 3.5Compilation, Installationpublic2011-11-21 23:40
Reporterfippo Assigned Tozesstra  
PrioritynormalSeverityfeatureReproducibilityN/A
Status resolvedResolutionfixed 
Target Version3.5.0Fixed in Version3.5.0 
Summary0000724: JSON
DescriptionSomeone recently asked me about that old patch (dec 2006) which contains efuns for integration of the JSON-C library (version 0.6 iirc) and why it is not included in the ldmud dist. I think I never even submitted it.
TagsNo tags attached.

Relationships

has duplicate 0000744 closedzesstra LDMud ship JSON parser 

Activities

2010-02-12 09:35

 

json.patch (7,879 bytes)   
Index: strfuns.c
===================================================================
--- strfuns.c	(revision 2314)
+++ strfuns.c	(working copy)
@@ -1157,5 +1157,147 @@
     return arg;
 } /* x_map_string () */
 
+#ifdef HAS_JSON
+/* support for javascript object notation
+ * depends on the json-c library
+ * see http://www.json.org for more information
+ */
+#include <json/json.h>
+#include "array.h"
+
+svalue_t *
+ldmud_json_inner_parse (svalue_t *sp, struct json_object *val) 
+{
+    if (is_error(val)) {
+	errorf("json_inner_parse: error");
+        /* NOTREACHED */
+        return sp;
+
+    }
+    if (val == NULL) {
+	/* TODO: I (fippo) am not sure, if this is a really good idea... */
+	put_number(sp, 0);
+	return sp;
+    }
+    switch(json_object_get_type(val)) {
+    case json_type_null: 
+	put_number(sp, 0);
+	break;
+    case json_type_boolean:
+	put_number(sp, json_object_get_boolean(val));
+	break;
+    case json_type_double:
+        put_float(sp, json_object_get_double(val));
+	break;
+    case json_type_int:
+	put_number(sp, json_object_get_int(val));
+	break;
+    case json_type_string:
+        put_c_string(sp, json_object_get_string(val));
+	break;
+    case json_type_object:
+      {
+	mapping_t *m;
+	struct lh_entry *e;
+	char *key;
+	struct json_object *newval;
+
+	m = allocate_mapping(json_object_get_object(val)->count, 1); 
+	for (e = json_object_get_object(val)->head; e ? (key = (char*)e->k, newval = (struct json_object *)e->v, e) : 0; e = e->next) {
+	    svalue_t mkey, *mval;
+	    put_c_string(&mkey, key);
+	    mval = get_map_lvalue(m, &mkey);
+	    free_svalue(&mkey);
+	    ldmud_json_inner_parse(mval, newval);
+	}
+	put_mapping(sp, m);
+	break;
+      }
+    case json_type_array:
+      {
+	vector_t *v;
+	struct array_list *a;
+	int size, i;
+	size = json_object_array_length(val);
+	v = allocate_array(size);
+	a = json_object_get_array(val);
+	for (i = 0; i < size; i++) {
+	    ldmud_json_inner_parse(&(v->item[i]), array_list_get_idx(a, i));
+	}
+	put_array(sp, v);
+	break;
+      }
+    }
+    return sp;
+}
+
+svalue_t *
+f_json_parse (svalue_t *sp) {
+    struct json_object *parsed;
+
+    parsed = json_tokener_parse(get_txt(sp->u.str));
+    free_svalue(sp);
+    ldmud_json_inner_parse (sp, parsed);
+    /* TODO: free the object */
+    return sp;
+}
+
+struct json_object *
+ldmud_json_inner_serialize (svalue_t *sp) {
+    struct json_object *val;
+    switch(sp->type) {
+    case T_NUMBER:
+	val = json_object_new_int(sp->u.number);
+	break;
+    case T_STRING:
+	val = json_object_new_string(get_txt(sp->u.str));
+	break;
+    case T_POINTER:
+      {
+	int i;
+	val = json_object_new_array();
+	for (i = VEC_SIZE(sp->u.vec) - 1; i >= 0; i--) 
+	    json_object_array_put_idx(val, i, 
+			ldmud_json_inner_serialize(&sp->u.vec->item[i]));
+	break;
+      }
+    case T_MAPPING:
+      {
+	int i;
+	val = json_object_new_object();
+	for (i = 0; i < MAP_SIZE(sp->u.map); i++) 
+	    walk_mapping(sp->u.map, &ldmud_json_walker, val);
+	break;
+      }
+    case T_FLOAT:
+	val = json_object_new_double(READ_DOUBLE(sp));
+	break;
+    default: /* those are unimplemented */
+	val = json_object_new_object();
+	break; 
+    }
+    return val;
+}
+
+void ldmud_json_walker(svalue_t *key, svalue_t *val, void *parent) 
+{
+    struct json_object *obj = (struct json_object *)parent;
+    if (key->type != T_STRING) 
+	errorf("json only serializes string keys\n");
+	/* NOTREACHED */
+    json_object_object_add(obj, get_txt(key->u.str), 
+			   ldmud_json_inner_serialize(val));
+}
+
+
+svalue_t *
+f_json_serialize (svalue_t *sp) {
+    struct json_object *val;
+    val = ldmud_json_inner_serialize(sp);
+    free_svalue(sp);
+    put_c_string(sp, json_object_to_json_string(val));
+    return sp;
+}
+#endif /* HAS_JSON */
 /*====================================================================*/
 
Index: strfuns.h
===================================================================
--- strfuns.h	(revision 2314)
+++ strfuns.h	(working copy)
@@ -40,4 +40,8 @@
 extern svalue_t * x_map_string (svalue_t *sp, int num_arg);
 extern svalue_t * x_filter_string (svalue_t *sp, int num_arg);
 
+#ifdef USE_JSON
+extern void ldmud_json_walker(svalue_t *key, svalue_t *val, void *parent);
+#endif
+
 #endif /* STRFUNS_H_ */
Index: func_spec
===================================================================
--- func_spec	(revision 2314)
+++ func_spec	(working copy)
@@ -752,6 +752,11 @@
 
 #endif /* USE_TLS */
 
+#ifdef HAS_JSON
+string	json_serialize(mixed);
+mixed	json_parse(string);
+#endif /* HAS_JSON */
+
 /* The following functions are optional and can be configured out.
  */
 
Index: autoconf/acconfig.h
===================================================================
--- autoconf/acconfig.h	(revision 2314)
+++ autoconf/acconfig.h	(working copy)
@@ -108,6 +108,9 @@
 /* Does SQLite3 use pthreads? */
 #undef SQLITE3_USES_PTHREADS
 
+/* Does the machine offer JSON (json-c)? */
+#undef HAS_JSON
+
 /* Does the machine offer GnuTLS? */
 #undef HAS_GNUTLS
 #undef HAS_GNUTLS_VERSION
Index: autoconf/configure.in
===================================================================
--- autoconf/configure.in	(revision 2314)
+++ autoconf/configure.in	(working copy)
@@ -121,6 +121,7 @@
 AC_MY_ARG_ENABLE(use-mysql,no,,[Enables mySQL support])
 AC_MY_ARG_ENABLE(use-pgsql,no,,[Enables PostgreSQL support])
 AC_MY_ARG_ENABLE(use-sqlite,no,,[Enables SQLite support])
+AC_MY_ARG_ENABLE(use-json,no,,[Enables JSON-C Support])
 AC_MY_ARG_ENABLE(use-pthreads,no,,[enable using of threads for socket writes])
 AC_MY_ARG_ENABLE(use-pcre,yes,,[Enables PCRE: no/yes/builtin/no-builtin])
 AC_MY_ARG_ENABLE(use-deprecated,yes,,[Enables obsolete and deprecated efuns])
@@ -320,6 +321,20 @@
   enable_use_sqlite="yes"
 fi
 
+AC_UPDATE_VAR(enable_use_json)
+if test "x$enable_use_json" = "x" || test "x$enable_use_json" = "xyes"; then
+  cdef_use_json="#define"
+  json_path=
+  enable_use_json="yes"
+elif test "x$enable_use_json" = "xno"; then
+  cdef_use_json="#undef"
+  json_path=
+else
+  cdef_use_json="#define"
+  json_path="$enable_use_json"
+  enable_use_json="yes"
+fi
+
 AC_UPDATE_VAR(enable_use_tls)
 if test "x$enable_use_tls" = "x" || test "x$enable_use_tls" = "xyes"; then
   cdef_use_tls="#define"
@@ -1632,6 +1647,23 @@
   fi
 fi
 
+# --- JSON ---
+cdef_enable_use_json="#undef"
+AC_CHECK_HEADER(json/json.h,,[
+		enable_use_json=no
+		lp_cv_has_json=no
+		])
+
+# The system has the json include files - now search for the libraries.
+if test "x$enable_use_json" = "x" || test "x$enable_use_json" = "xyes"; then
+    AC_CHECK_LIB(json, main, [
+		 AC_DEFINE(HAS_JSON)
+		 PKGLIBS="$PKGLIBS -ljson"
+		 lp_cv_has_json=yes
+		 cdef_use_json="#define"
+		 ])
+fi
+
 # --- Check if we need zlib libraries for mccp ---
 
 if test "x$enable_use_mccp" = "x" || test "x$enable_use_mccp" = "xyes"; then
@@ -2634,6 +2666,7 @@
 AC_SUBST(cdef_use_mysql)
 AC_SUBST(cdef_use_pgsql)
 AC_SUBST(cdef_use_sqlite)
+AC_SUBST(cdef_use_json)
 AC_SUBST(cdef_use_pthreads)
 AC_SUBST(cdef_use_alists)
 AC_SUBST(cdef_use_mccp)
Index: machine.h.in
===================================================================
--- machine.h.in	(revision 2314)
+++ machine.h.in	(working copy)
@@ -108,6 +108,9 @@
 /* Does SQLite3 use pthreads? */
 #undef SQLITE3_USES_PTHREADS
 
+/* Does the machine offer json-c support? */
+#undef HAS_JSON
+
 /* Does the machine offer GnuTLS? */
 #undef HAS_GNUTLS
 #undef HAS_GNUTLS_VERSION
Index: config.h.in
===================================================================
--- config.h.in	(revision 2314)
+++ config.h.in	(working copy)
@@ -353,6 +353,11 @@
  */
 @cdef_use_sqlite@ USE_SQLITE
 
+/*Define this if you want JSON support (assuming that your host
+ * actually offers this.
+ */
+@cdef_use_json@ USE_JSON
+
 /* Define this if you want alist support.
  */
 @cdef_use_alists@ USE_ALISTS
json.patch (7,879 bytes)   

zesstra

2010-02-12 10:25

administrator   ~0001715

Thanks Fippo. The patch applies mostly, with some changes in configure.in, but I did no further tests until now.
I think about adding the patch to ldmud-extensions first (repo for unofficial extensions/packages/user contributions for LDMud) and wait for comments from the user community.

Wildcat

2010-02-12 11:07

reporter   ~0001716

I was probably the one who mailed about it, I've been running it on Tsunami talking to a php webscript for about 6 weeks and no issues yet.

zesstra

2010-02-12 15:39

administrator   ~0001717

Ah. Ok. So, we are starting ldmud-extensions for contributions we are not yet sure about popularity or impact on the rest of the driver source. This can also be patches from/for specific muds or some ideas users want to play with, so that not everybody has to re-invent the wheel.
The idea is that we use a git repo with patches/packages at github, which everybody can clone and work on it (add patches, improve or test them etc).

As I said, I would start putting the patch there. Maybe somebody volounteers to write some documentation there... ;-)

FTR: Fippo, are you OK with the drivers 2-clause BSD license?

fippo

2010-02-13 13:23

reporter   ~0001722

zesstra: works for me - apart from the funny "no monetary gain" clause ,-)

zesstra

2010-02-13 13:31

administrator   ~0001723

Ok, great.
BTW: The monetary gain stuff is NOT part of the 2-clause BSD license. It concerns older parts of the drivers sources, but new contributions must not have that restriction.
The license we use since 2007 for new contributions to the driver (and preferably for ldmud-extensions) is this one here: http://github.com/zesstra/ldmud-extensions/blob/master/COPYING.template

zesstra

2010-07-14 15:12

administrator   ~0001879

Hate to ask, but is there already any documentation besides the .c? (Manpages)

zesstra

2010-11-19 23:01

administrator   ~0001923

I updated the patch to apply cleanly to the current trunk and added it to https://github.com/ldmud/ldmud-extensions.
If somebody adds some documentation and there are some more users to try/test it, I will add it to the main distribution.

zesstra

2011-11-21 23:40

administrator   ~0002081

Unfortunately, nobody seemed to interested to work on it.

However, I now spent some evenings on it and did some extensive changes concerning error handling, documentation, 64 bit support, struct support, mapping support and some other things. Especially the error handling was insufficient, because there were some places where objects could be leaked if there was an error in the recursion - especially bad because JSON objects are not garbage-collected. I also added a bunch of test cases.

The whole collection is in r3048 in the 3.5 branch (https://github.com/ldmud/ldmud/commit/a3121d77ea23777a31776b58ae7730b07e791ad3)

Issue History

Date Modified Username Field Change
2010-02-12 09:35 fippo New Issue
2010-02-12 09:35 fippo File Added: json.patch
2010-02-12 10:25 zesstra Note Added: 0001715
2010-02-12 11:07 Wildcat Note Added: 0001716
2010-02-12 15:39 zesstra Note Added: 0001717
2010-02-13 13:23 fippo Note Added: 0001722
2010-02-13 13:31 zesstra Note Added: 0001723
2010-07-14 15:03 zesstra Relationship added has duplicate 0000744
2010-07-14 15:12 zesstra Note Added: 0001879
2010-11-19 22:58 zesstra Assigned To => zesstra
2010-11-19 22:58 zesstra Status new => assigned
2010-11-19 23:01 zesstra Note Added: 0001923
2010-11-19 23:01 zesstra Status assigned => resolved
2010-11-19 23:01 zesstra Resolution open => fixed
2011-11-21 23:28 zesstra Status resolved => assigned
2011-11-21 23:28 zesstra Resolution fixed => open
2011-11-21 23:29 zesstra Project LDMud => LDMud 3.5
2011-11-21 23:29 zesstra Category Efuns => Compilation, Installation
2011-11-21 23:29 zesstra Product Version 3.3.718 =>
2011-11-21 23:29 zesstra Target Version => 3.5.0
2011-11-21 23:40 zesstra Note Added: 0002081
2011-11-21 23:40 zesstra Status assigned => resolved
2011-11-21 23:40 zesstra Fixed in Version => 3.5.0
2011-11-21 23:40 zesstra Resolution open => fixed