Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Simplify things by storing integer values only as int64_t's internall…

…y, and

 omit the range check during parsing since we already have the checks when
 accessing the value. There is no longer a json_type_int64, only json_type_int.
Fix some problems with parsing 0 and -0 values, and add a couple of tests.
Fix some minor compile issues on HPUX environments.


git-svn-id: http://svn.metaparadigm.com/svn/json-c/trunk@60 327403b1-1117-474d-bef2-5cb71233fd97
  • Loading branch information...
commit 252669cee672b101cc43b2baae86db4a8bcb80eb 1 parent f1ae67d
ehaszla authored
View
21 json_object.c
@@ -43,7 +43,6 @@ static const char* json_type_name[] = {
"object",
"array",
"string",
- "int64",
};
#endif /* REFCOUNT_DEBUG */
@@ -306,8 +305,6 @@ boolean json_object_get_boolean(struct json_object *jso)
case json_type_boolean:
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);
@@ -324,10 +321,6 @@ boolean json_object_get_boolean(struct json_object *jso)
static int json_object_int_to_json_string(struct json_object* jso,
struct printbuf *pb)
{
- return sprintbuf(pb, "%d", jso->o.c_int);
-}
-
-static int json_object_int64_to_json_string(struct json_object* jso, struct printbuf *pb) {
return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
}
@@ -336,7 +329,7 @@ struct json_object* json_object_new_int(int32_t i)
struct json_object *jso = json_object_new(json_type_int);
if(!jso) return NULL;
jso->_to_json_string = &json_object_int_to_json_string;
- jso->o.c_int = i;
+ jso->o.c_int64 = i;
return jso;
}
@@ -355,13 +348,11 @@ int32_t json_object_get_int(struct json_object *jso)
*/
if (json_parse_int64(jso->o.c_string, &cint64) != 0)
return 0; /* whoops, it didn't work. */
- o_type = json_type_int64;
+ o_type = json_type_int;
}
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;
@@ -380,9 +371,9 @@ int32_t json_object_get_int(struct json_object *jso)
struct json_object* json_object_new_int64(int64_t i)
{
- struct json_object *jso = json_object_new(json_type_int64);
+ struct json_object *jso = json_object_new(json_type_int);
if(!jso) return NULL;
- jso->_to_json_string = &json_object_int64_to_json_string;
+ jso->_to_json_string = &json_object_int_to_json_string;
jso->o.c_int64 = i;
return jso;
}
@@ -394,8 +385,6 @@ int64_t json_object_get_int64(struct json_object *jso)
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 (int64_t)jso->o.c_double;
@@ -435,8 +424,6 @@ double json_object_get_double(struct json_object *jso)
case json_type_double:
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;
View
13 json_object.h
@@ -47,7 +47,6 @@ typedef enum json_type {
json_type_object,
json_type_array,
json_type_string,
- json_type_int64
} json_type;
/* reference counting functions */
@@ -75,7 +74,6 @@ 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);
@@ -89,7 +87,6 @@ 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,15 +249,17 @@ extern boolean json_object_get_boolean(struct json_object *obj);
/* int type methods */
/** Create a new empty json_object of type json_type_int
+ * Note that values are stored as 64-bit values internally.
+ * To ensure the full range is maintained, use json_object_new_int64 instead.
* @param i the integer
* @returns a json_object of type json_type_int
*/
extern struct json_object* json_object_new_int(int32_t i);
-/** Create a new empty json_object of type json_type_int64
+/** Create a new empty json_object of type json_type_int
* @param i the integer
- * @returns a json_object of type json_type_int64
+ * @returns a json_object of type json_type_int
*/
extern struct json_object* json_object_new_int64(int64_t i);
@@ -271,6 +270,10 @@ extern struct json_object* json_object_new_int64(int64_t i);
* double objects will return their integer conversion. Strings will be
* parsed as an integer. If no conversion exists then 0 is returned.
*
+ * Note that integers are stored internally as 64-bit values.
+ * If the value of too big or too small to fit into 32-bit, INT32_MAX or
+ * INT32_MIN are returned, respectively.
+ *
* @param obj the json_object instance
* @returns an int
*/
View
1  json_object_private.h
@@ -30,7 +30,6 @@ struct json_object
union data {
boolean c_boolean;
double c_double;
- int32_t c_int;
int64_t c_int64;
struct lh_table *c_object;
struct array_list *c_array;
View
14 json_tokener.c
@@ -204,7 +204,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
case json_tokener_state_eatws:
/* Advance until we change state */
- while (isspace(c)) {
+ while (isspace((int)c)) {
if ((!ADVANCE_CHAR(str, tok)) || (!POP_CHAR(c, tok)))
goto out;
}
@@ -547,17 +547,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
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);
+ 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 {
View
22 json_util.c
@@ -10,6 +10,7 @@
*/
#include "config.h"
+#undef realloc
#include <stdio.h>
#include <stdlib.h>
@@ -131,7 +132,7 @@ int json_parse_int64(const char *buf, int64_t *retval)
int64_t num64;
if (sscanf(buf, "%" SCNd64, &num64) != 1)
{
- printf("Failed to parse, sscanf != 1\n");
+ MC_DEBUG("Failed to parse, sscanf != 1\n");
return 1;
}
const char *buf_skip_space = buf;
@@ -144,9 +145,11 @@ int json_parse_int64(const char *buf, int64_t *retval)
buf_skip_space++;
orig_has_neg = 1;
}
- // Skip leading zeros
- while (*buf_skip_space == '0' && *buf_skip_space)
+ // Skip leading zeros, but keep at least one digit
+ while (buf_skip_space[0] == '0' && buf_skip_space[1] != '\0')
buf_skip_space++;
+ if (buf_skip_space[0] == '0' && buf_skip_space[1] == '\0')
+ orig_has_neg = 0; // "-0" is the same as just plain "0"
if (errno != ERANGE)
{
@@ -171,7 +174,7 @@ int json_parse_int64(const char *buf, int64_t *retval)
if (orig_has_neg != recheck_has_neg ||
strncmp(buf_skip_space, buf_cmp_start, strlen(buf_cmp_start)) != 0 ||
(strlen(buf_skip_space) != buf_cmp_len &&
- isdigit(buf_skip_space[buf_cmp_len])
+ isdigit((int)buf_skip_space[buf_cmp_len])
)
)
{
@@ -188,3 +191,14 @@ int json_parse_int64(const char *buf, int64_t *retval)
*retval = num64;
return 0;
}
+
+#if HAVE_REALLOC == 0
+void* rpl_realloc(void* p, size_t n)
+{
+ if (n == 0)
+ n = 1;
+ if (p == 0)
+ return malloc(n);
+ return realloc(p, n);
+}
+#endif
View
2  printbuf.c
@@ -123,7 +123,7 @@ int sprintbuf(struct printbuf *p, const char *msg, ...)
would have been written - this code handles both cases. */
if(size == -1 || size > 127) {
va_start(ap, msg);
- if((size = vasprintf(&t, msg, ap)) == -1) { va_end(ap); return -1; }
+ if((size = vasprintf(&t, msg, ap)) < 0) { va_end(ap); return -1; }
va_end(ap);
printbuf_memappend(p, t, size);
free(t);
View
6 test_parse_int64.c
@@ -29,6 +29,12 @@ int main()
checkit("x");
+ checkit("0");
+ checkit("-0");
+
+ checkit("00000000");
+ checkit("-00000000");
+
checkit("1");
strcpy(buf, "2147483647"); // aka INT32_MAX
View
5 test_parse_int64.expected
@@ -1,5 +1,8 @@
-Failed to parse, sscanf != 1
buf=x parseit=1, value=-666
+buf=0 parseit=0, value=0
+buf=-0 parseit=0, value=0
+buf=00000000 parseit=0, value=0
+buf=-00000000 parseit=0, value=0
buf=1 parseit=0, value=1
buf=2147483647 parseit=0, value=2147483647
buf=-1 parseit=0, value=-1
Please sign in to comment.
Something went wrong with that request. Please try again.