Permalink
Browse files

* Add int64 support. Two new functions json_object_net_int64 and

    json_object_get_int64. Binary compatibility preserved.
    Eric Haszlakiewicz, EHASZLA at transunion com
    Rui Miguel Silva Seabra, rms at 1407 dot org



git-svn-id: http://svn.metaparadigm.com/svn/json-c/trunk@56 327403b1-1117-474d-bef2-5cb71233fd97
  • Loading branch information...
1 parent 88ded9c commit c4dceae1c53bc37cacc46a806f8a02524d12a382 @michaeljclark michaeljclark committed Oct 6, 2010
Showing with 569 additions and 40 deletions.
  1. +4 −0 ChangeLog
  2. +1 −1 Doxyfile
  3. +21 −11 Makefile.am
  4. +1 −5 config.h.in
  5. +21 −0 json_inttypes.h
  6. +66 −6 json_object.c
  7. +25 −3 json_object.h
  8. +2 −1 json_object_private.h
  9. +18 −6 json_tokener.c
  10. +65 −0 json_util.c
  11. +1 −0 json_util.h
  12. +12 −0 parse_int64.test
  13. +114 −0 test-defs.sh
  14. +1 −1 test1.c
  15. +44 −0 test1.expected
  16. +12 −0 test1.test
  17. +1 −0 test2.expected
  18. +12 −0 test2.test
  19. +11 −6 test4.c
  20. +3 −0 test4.expected
  21. +12 −0 test4.test
  22. +99 −0 test_parse_int64.c
  23. +23 −0 test_parse_int64.expected
View
@@ -1,4 +1,8 @@
0.10
+ * Add int64 support. Two new functions json_object_net_int64 and
+ json_object_get_int64. Binary compatibility preserved.
+ Eric Haszlakiewicz, EHASZLA at transunion com
+ Rui Miguel Silva Seabra, rms at 1407 dot org
* Fix subtle bug in linkhash where lookup could hang after all slots
were filled then successively freed.
Spotted by Jean-Marc Naud, j dash m at newtraxtech dot com
View
@@ -23,7 +23,7 @@ PROJECT_NAME = json-c
# This could be handy for archiving the generated documentation or
# if some version control system is used.
-PROJECT_NUMBER = 0.2
+PROJECT_NUMBER = 0.10
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
View
@@ -9,16 +9,17 @@ pkgconfig_DATA = json.pc
libjsonincludedir = $(includedir)/json
libjsoninclude_HEADERS = \
- json.h \
+ arraylist.h \
bits.h \
debug.h \
- linkhash.h \
- arraylist.h \
- printbuf.h \
- json_util.h \
+ json.h \
+ json_inttypes.h \
json_object.h \
- json_object_private.h \
- json_tokener.h
+ json_object_private.h \
+ json_tokener.h \
+ json_util.h \
+ linkhash.h \
+ printbuf.h
libjson_la_LDFLAGS = -version-info 0:1:0
@@ -31,16 +32,25 @@ libjson_la_SOURCES = \
linkhash.c \
printbuf.c
-check_PROGRAMS = test1 test2 test3 test4
+check_PROGRAMS = test1 test2 test4 test_parse_int64
test1_SOURCES = test1.c
test1_LDADD = $(lib_LTLIBRARIES)
test2_SOURCES = test2.c
test2_LDADD = $(lib_LTLIBRARIES)
-test3_SOURCES = test3.c
-test3_LDADD = $(lib_LTLIBRARIES)
-
test4_SOURCES = test4.c
test4_LDADD = $(lib_LTLIBRARIES)
+
+test_parse_int64_SOURCES = test_parse_int64.c
+test_parse_int64_LDADD = $(lib_LTLIBRARIES)
+
+TESTS = test1.test test2.test test4.test parse_int64.test
+EXTRA_DIST += $(TESTS)
+testsubdir=testSubDir
+TESTS_ENVIRONMENT = top_builddir=$(top_builddir)
+
+distclean-local:
+ -rm -rf $(testsubdir)
+
View
@@ -80,10 +80,6 @@
/* Define to 1 if you have the `vsyslog' function. */
#undef HAVE_VSYSLOG
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#undef LT_OBJDIR
-
/* Name of package */
#undef PACKAGE
@@ -117,5 +113,5 @@
/* Define to rpl_realloc if the replacement function should be used. */
#undef realloc
-/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t
View
@@ -0,0 +1,21 @@
+
+#ifndef _json_inttypes_h_
+#define _json_inttypes_h_
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+
+/* Anything less than Visual Studio C++ 10 is missing stdint.h and inttypes.h */
+typedef __int64 int64_t;
+#define PRId64 "I64d"
+#define SCNd64 "I64d"
+
+#else
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+/* inttypes.h includes stdint.h */
+
+#endif
+
+#endif
View
@@ -20,8 +20,10 @@
#include "printbuf.h"
#include "linkhash.h"
#include "arraylist.h"
+#include "json_inttypes.h"
#include "json_object.h"
#include "json_object_private.h"
+#include "json_util.h"
#if !HAVE_STRNDUP
char* strndup(const char* str, size_t n);
@@ -41,6 +43,7 @@ static const char* json_type_name[] = {
"object",
"array",
"string",
+ "int64",
};
#endif /* REFCOUNT_DEBUG */
@@ -304,6 +307,8 @@ boolean json_object_get_boolean(struct json_object *jso)
return jso->o.c_boolean;
case json_type_int:
return (jso->o.c_int != 0);
+ case json_type_int64:
+ return (jso->o.c_int64 != 0);
case json_type_double:
return (jso->o.c_double != 0);
case json_type_string:
@@ -322,7 +327,11 @@ static int json_object_int_to_json_string(struct json_object* jso,
return sprintbuf(pb, "%d", jso->o.c_int);
}
-struct json_object* json_object_new_int(int i)
+static int json_object_int64_to_json_string(struct json_object* jso, struct printbuf *pb) {
+ return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
+}
+
+struct json_object* json_object_new_int(int32_t i)
{
struct json_object *jso = json_object_new(json_type_int);
if(!jso) return NULL;
@@ -331,20 +340,69 @@ struct json_object* json_object_new_int(int i)
return jso;
}
-int json_object_get_int(struct json_object *jso)
+int32_t json_object_get_int(struct json_object *jso)
{
- int cint;
-
if(!jso) return 0;
+
+ enum json_type o_type = jso->o_type;
+ int64_t cint64 = jso->o.c_int64;
+
+ if (o_type == json_type_string)
+ {
+ /*
+ * 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)
+ return 0; /* whoops, it didn't work. */
+ o_type = json_type_int64;
+ }
+
switch(jso->o_type) {
case json_type_int:
return jso->o.c_int;
+ case json_type_int64:
+ /* Make sure we return the correct values for out of range numbers. */
+ if (cint64 <= INT32_MIN)
+ return INT32_MIN;
+ else if (cint64 >= INT32_MAX)
+ return INT32_MAX;
+ else
+ return (int32_t)cint64;
+ case json_type_double:
+ return (int32_t)jso->o.c_double;
+ case json_type_boolean:
+ return jso->o.c_boolean;
+ default:
+ return 0;
+ }
+}
+
+struct json_object* json_object_new_int64(int64_t i)
+{
+ struct json_object *jso = json_object_new(json_type_int64);
+ if(!jso) return NULL;
+ jso->_to_json_string = &json_object_int64_to_json_string;
+ jso->o.c_int64 = i;
+ return jso;
+}
+
+int64_t json_object_get_int64(struct json_object *jso)
+{
+ int64_t cint;
+
+ if(!jso) return 0;
+ switch(jso->o_type) {
+ case json_type_int:
+ return (int64_t)jso->o.c_int;
+ case json_type_int64:
+ return jso->o.c_int64;
case json_type_double:
- return (int)jso->o.c_double;
+ return (int64_t)jso->o.c_double;
case json_type_boolean:
return jso->o.c_boolean;
case json_type_string:
- if(sscanf(jso->o.c_string, "%d", &cint) == 1) return cint;
+ if (json_parse_int64(jso->o.c_string, &cint) == 0) return cint;
default:
return 0;
}
@@ -378,6 +436,8 @@ double json_object_get_double(struct json_object *jso)
return jso->o.c_double;
case json_type_int:
return jso->o.c_int;
+ case json_type_int64:
+ return jso->o.c_int64;
case json_type_boolean:
return jso->o.c_boolean;
case json_type_string:
View
@@ -46,7 +46,8 @@ typedef enum json_type {
json_type_int,
json_type_object,
json_type_array,
- json_type_string
+ json_type_string,
+ json_type_int64
} json_type;
/* reference counting functions */
@@ -74,6 +75,7 @@ extern void json_object_put(struct json_object *obj);
json_type_object,
json_type_array,
json_type_string,
+ json_type_int64,
*/
extern int json_object_is_type(struct json_object *obj, enum json_type type);
@@ -87,6 +89,7 @@ extern int json_object_is_type(struct json_object *obj, enum json_type type);
json_type_object,
json_type_array,
json_type_string,
+ json_type_int64,
*/
extern enum json_type json_object_get_type(struct json_object *obj);
@@ -252,7 +255,15 @@ extern boolean json_object_get_boolean(struct json_object *obj);
* @param i the integer
* @returns a json_object of type json_type_int
*/
-extern struct json_object* json_object_new_int(int i);
+extern struct json_object* json_object_new_int(int32_t i);
+
+
+/** Create a new empty json_object of type json_type_int64
+ * @param i the integer
+ * @returns a json_object of type json_type_int64
+ */
+extern struct json_object* json_object_new_int64(int64_t i);
+
/** Get the int value of a json_object
*
@@ -263,7 +274,18 @@ extern struct json_object* json_object_new_int(int i);
* @param obj the json_object instance
* @returns an int
*/
-extern int json_object_get_int(struct json_object *obj);
+extern int32_t json_object_get_int(struct json_object *obj);
+
+/** Get the int value of a json_object
+ *
+ * The type is coerced to a int64 if the passed object is not a int64.
+ * double objects will return their int64 conversion. Strings will be
+ * parsed as an int64. If no conversion exists then 0 is returned.
+ *
+ * @param obj the json_object instance
+ * @returns an int64
+ */
+extern int64_t json_object_get_int64(struct json_object *obj);
/* double type methods */
@@ -30,7 +30,8 @@ struct json_object
union data {
boolean c_boolean;
double c_double;
- int c_int;
+ int32_t c_int;
+ int64_t c_int64;
struct lh_table *c_object;
struct array_list *c_array;
char *c_string;
View
@@ -20,14 +20,16 @@
#include <stddef.h>
#include <ctype.h>
#include <string.h>
+#include <limits.h>
#include "bits.h"
#include "debug.h"
#include "printbuf.h"
#include "arraylist.h"
+#include "json_inttypes.h"
#include "json_object.h"
#include "json_tokener.h"
-
+#include "json_util.h"
#if !HAVE_STRNCASECMP && defined(_MSC_VER)
/* MSC has the version as _strnicmp */
@@ -542,11 +544,21 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
printbuf_memappend_fast(tok->pb, case_start, case_len);
}
{
- int numi;
- double numd;
- if(!tok->is_double && sscanf(tok->pb->buf, "%d", &numi) == 1) {
- current = json_object_new_int(numi);
- } else if(tok->is_double && sscanf(tok->pb->buf, "%lf", &numd) == 1) {
+ int64_t num64;
+ double numd;
+ if (!tok->is_double && json_parse_int64(tok->pb->buf, &num64) == 0) {
+ // Decode the type based on the value range to keep compatibilty
+ // with code that checks the type of objects. i.e. this:
+ // json_object_get_type(o) == json_type_int
+ // will continue to work.
+ // The other option would be to eliminate any distinction between
+ // int and int64 types, but that would change the ABI of
+ // json_object_get_int().
+ if (num64 < INT32_MAX && num64 > INT32_MIN)
+ current = json_object_new_int(num64);
+ else
+ current = json_object_new_int64(num64);
+ } else if(tok->is_double && sscanf(tok->pb->buf, "%lf", &numd) == 1) {
current = json_object_new_double(numd);
} else {
tok->err = json_tokener_error_parse_number;
Oops, something went wrong.

0 comments on commit c4dceae

Please sign in to comment.