/*
- * Copyright (c) 2009-2011 Petri Lehtinen <petri@digip.org>
+ * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
*
* Jansson is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
+#include <math.h>
-#include <jansson.h>
+#include "jansson.h"
#include "hashtable.h"
#include "jansson_private.h"
#include "utf.h"
+/* Work around nonstandard isnan() and isinf() implementations */
+#ifndef isnan
+static JSON_INLINE int isnan(double x) { return x != x; }
+#endif
+#ifndef isinf
+static JSON_INLINE int isinf(double x) { return !isnan(x) && isnan(x - x); }
+#endif
static JSON_INLINE void json_init(json_t *json, json_type type)
{
int json_object_update(json_t *object, json_t *other)
{
- void *iter;
+ const char *key;
+ json_t *value;
if(!json_is_object(object) || !json_is_object(other))
return -1;
- iter = json_object_iter(other);
- while(iter) {
- const char *key;
- json_t *value;
-
- key = json_object_iter_key(iter);
- value = json_object_iter_value(iter);
-
+ json_object_foreach(other, key, value) {
if(json_object_set_nocheck(object, key, value))
return -1;
+ }
+
+ return 0;
+}
- iter = json_object_iter_next(other, iter);
+int json_object_update_existing(json_t *object, json_t *other)
+{
+ const char *key;
+ json_t *value;
+
+ if(!json_is_object(object) || !json_is_object(other))
+ return -1;
+
+ json_object_foreach(other, key, value) {
+ if(json_object_get(object, key))
+ json_object_set_nocheck(object, key, value);
+ }
+
+ return 0;
+}
+
+int json_object_update_missing(json_t *object, json_t *other)
+{
+ const char *key;
+ json_t *value;
+
+ if(!json_is_object(object) || !json_is_object(other))
+ return -1;
+
+ json_object_foreach(other, key, value) {
+ if(!json_object_get(object, key))
+ json_object_set_nocheck(object, key, value);
}
return 0;
return 0;
}
+void *json_object_key_to_iter(const char *key)
+{
+ if(!key)
+ return NULL;
+
+ return hashtable_key_to_iter(key);
+}
+
static int json_object_equal(json_t *object1, json_t *object2)
{
- void *iter;
+ const char *key;
+ json_t *value1, *value2;
if(json_object_size(object1) != json_object_size(object2))
return 0;
- iter = json_object_iter(object1);
- while(iter)
- {
- const char *key;
- json_t *value1, *value2;
-
- key = json_object_iter_key(iter);
- value1 = json_object_iter_value(iter);
+ json_object_foreach(object1, key, value1) {
value2 = json_object_get(object2, key);
if(!json_equal(value1, value2))
return 0;
-
- iter = json_object_iter_next(object1, iter);
}
return 1;
static json_t *json_object_copy(json_t *object)
{
json_t *result;
- void *iter;
+
+ const char *key;
+ json_t *value;
result = json_object();
if(!result)
return NULL;
- iter = json_object_iter(object);
- while(iter)
- {
- const char *key;
- json_t *value;
-
- key = json_object_iter_key(iter);
- value = json_object_iter_value(iter);
+ json_object_foreach(object, key, value)
json_object_set_nocheck(result, key, value);
- iter = json_object_iter_next(object, iter);
- }
-
return result;
}
static json_t *json_object_deep_copy(json_t *object)
{
json_t *result;
- void *iter;
+
+ const char *key;
+ json_t *value;
result = json_object();
if(!result)
return NULL;
- iter = json_object_iter(object);
- while(iter)
- {
- const char *key;
- json_t *value;
-
- key = json_object_iter_key(iter);
- value = json_object_iter_value(iter);
+ json_object_foreach(object, key, value)
json_object_set_new_nocheck(result, key, json_deep_copy(value));
- iter = json_object_iter_next(object, iter);
- }
-
return result;
}
json_t *json_real(double value)
{
- json_real_t *real = jsonp_malloc(sizeof(json_real_t));
+ json_real_t *real;
+
+ if(isnan(value) || isinf(value))
+ return NULL;
+
+ real = jsonp_malloc(sizeof(json_real_t));
if(!real)
return NULL;
json_init(&real->json, JSON_REAL);
int json_real_set(json_t *json, double value)
{
- if(!json_is_real(json))
- return 0;
+ if(!json_is_real(json) || isnan(value) || isinf(value))
+ return -1;
json_to_real(json)->value = value;
double json_number_value(const json_t *json)
{
if(json_is_integer(json))
- return json_integer_value(json);
+ return (double)json_integer_value(json);
else if(json_is_real(json))
return json_real_value(json);
else