update json_object_new_string_len, json_escape_str (internal). Writer handles \x00 correctly

Added parse_null test. This does not change anything with how the parser handles \u0000 or null characters

This commit is addapted from one by Adomas Paltanavičius <adomas@leanholding.com>



git-svn-id: http://svn.metaparadigm.com/svn/json-c/trunk@63 327403b1-1117-474d-bef2-5cb71233fd97
diff --git a/json_object.c b/json_object.c
index 2b6dad4..8f1a67e 100644
--- a/json_object.c
+++ b/json_object.c
@@ -83,15 +83,13 @@
 
 /* string escaping */
 
-static int json_escape_str(struct printbuf *pb, char *str)
+static int json_escape_str(struct printbuf *pb, char *str, int len)
 {
   int pos = 0, start_offset = 0;
   unsigned char c;
-  do {
+  while (len--) {
     c = str[pos];
     switch(c) {
-    case '\0':
-      break;
     case '\b':
     case '\n':
     case '\r':
@@ -120,7 +118,7 @@
 	start_offset = ++pos;
       } else pos++;
     }
-  } while(c);
+  }
   if(pos - start_offset > 0)
     printbuf_memappend(pb, str + start_offset, pos - start_offset);
   return 0;
@@ -218,7 +216,7 @@
 	json_object_object_foreachC(jso, iter) {
 			if(i) sprintbuf(pb, ",");
 			sprintbuf(pb, " \"");
-			json_escape_str(pb, iter.key);
+			json_escape_str(pb, iter.key, strlen(iter.key));
 			sprintbuf(pb, "\": ");
 			if(iter.val == NULL) sprintbuf(pb, "null");
 			else iter.val->_to_json_string(iter.val, pb);
@@ -309,7 +307,7 @@
   case json_type_double:
     return (jso->o.c_double != 0);
   case json_type_string:
-    return (strlen(jso->o.c_string) != 0);
+    return (jso->o.c_string.len != 0);
   default:
     return FALSE;
   }
@@ -346,7 +344,7 @@
 	 * Parse strings into 64-bit numbers, then use the
 	 * 64-to-32-bit number handling below.
 	 */
-	if (json_parse_int64(jso->o.c_string, &cint64) != 0)
+	if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
 		return 0; /* whoops, it didn't work. */
 	o_type = json_type_int;
   }
@@ -391,7 +389,7 @@
   case json_type_boolean:
     return jso->o.c_boolean;
   case json_type_string:
-	if (json_parse_int64(jso->o.c_string, &cint) == 0) return cint;
+	if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
   default:
     return 0;
   }
@@ -428,7 +426,7 @@
   case json_type_boolean:
     return jso->o.c_boolean;
   case json_type_string:
-    if(sscanf(jso->o.c_string, "%lf", &cdouble) == 1) return cdouble;
+    if(sscanf(jso->o.c_string.str, "%lf", &cdouble) == 1) return cdouble;
   default:
     return 0.0;
   }
@@ -441,14 +439,14 @@
 					     struct printbuf *pb)
 {
   sprintbuf(pb, "\"");
-  json_escape_str(pb, jso->o.c_string);
+  json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
   sprintbuf(pb, "\"");
   return 0;
 }
 
 static void json_object_string_delete(struct json_object* jso)
 {
-  free(jso->o.c_string);
+  free(jso->o.c_string.str);
   json_object_generic_delete(jso);
 }
 
@@ -458,7 +456,8 @@
   if(!jso) return NULL;
   jso->_delete = &json_object_string_delete;
   jso->_to_json_string = &json_object_string_to_json_string;
-  jso->o.c_string = strdup(s);
+  jso->o.c_string.str = strdup(s);
+  jso->o.c_string.len = strlen(s);
   return jso;
 }
 
@@ -468,7 +467,9 @@
   if(!jso) return NULL;
   jso->_delete = &json_object_string_delete;
   jso->_to_json_string = &json_object_string_to_json_string;
-  jso->o.c_string = strndup(s, len);
+  jso->o.c_string.str = malloc(len);
+  memcpy(jso->o.c_string.str, (void *)s, len);
+  jso->o.c_string.len = len;
   return jso;
 }
 
@@ -477,12 +478,22 @@
   if(!jso) return NULL;
   switch(jso->o_type) {
   case json_type_string:
-    return jso->o.c_string;
+    return jso->o.c_string.str;
   default:
     return json_object_to_json_string(jso);
   }
 }
 
+int json_object_get_string_len(struct json_object *jso)  {
+  if(!jso) return 0;
+  switch(jso->o_type) {
+  case json_type_string:
+    return jso->o.c_string.len;
+  default:
+    return 0;
+  }
+}
+
 
 /* json_object_array */