+/*
+ * Copyright (c) 2009 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.
+ */
+
#define _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include <jansson.h>
#include "hashtable.h"
-
-#define max(a, b) ((a) > (b) ? (a) : (b))
+#include "jansson_private.h"
+#include "utf.h"
+#include "util.h"
#define container_of(ptr_, type_, member_) \
((type_ *)((char *)ptr_ - (size_t)&((type_ *)0)->member_))
typedef struct {
json_t json;
- hashtable_t *hashtable;
+ hashtable_t hashtable;
} json_object_t;
typedef struct {
typedef struct {
json_t json;
double value;
-} json_number_t;
+} json_real_t;
+
+typedef struct {
+ json_t json;
+ int value;
+} json_integer_t;
#define json_to_object(json_) container_of(json_, json_object_t, json)
#define json_to_array(json_) container_of(json_, json_array_t, json)
#define json_to_string(json_) container_of(json_, json_string_t, json)
-#define json_to_number(json_) container_of(json_, json_number_t, json)
+#define json_to_real(json_) container_of(json_, json_real_t, json)
+#define json_to_integer(json_) container_of(json_, json_integer_t, json)
static inline void json_init(json_t *json, json_type type)
{
return NULL;
json_init(&object->json, JSON_OBJECT);
- object->hashtable =
- hashtable_new(hash_string, string_equal, free, value_decref);
- if(!object->hashtable)
+ if(hashtable_init(&object->hashtable, hash_string, string_equal,
+ free, value_decref))
{
free(object);
return NULL;
static void json_delete_object(json_object_t *object)
{
- hashtable_free(object->hashtable);
+ hashtable_close(&object->hashtable);
free(object);
}
if(!json_is_object(json))
return NULL;
- return hashtable_get(object->hashtable, key);
+ object = json_to_object(json);
+ return hashtable_get(&object->hashtable, key);
}
-int json_object_set(json_t *json, const char *key, json_t *value)
+int json_object_set_nocheck(json_t *json, const char *key, json_t *value)
{
json_object_t *object;
return -1;
object = json_to_object(json);
- return hashtable_set(object->hashtable, strdup(key), json_incref(value));
+ return hashtable_set(&object->hashtable, strdup(key), json_incref(value));
+}
+
+int json_object_set(json_t *json, const char *key, json_t *value)
+{
+ if(!utf8_check_string(key, -1))
+ return -1;
+
+ return json_object_set_nocheck(json, key, value);
}
int json_object_del(json_t *json, const char *key)
return -1;
object = json_to_object(json);
- return hashtable_del(object->hashtable, key);
+ return hashtable_del(&object->hashtable, key);
}
void *json_object_iter(json_t *json)
return NULL;
object = json_to_object(json);
- return hashtable_iter(object->hashtable);
+ return hashtable_iter(&object->hashtable);
}
void *json_object_iter_next(json_t *json, void *iter)
return NULL;
object = json_to_object(json);
- return hashtable_iter_next(object->hashtable, iter);
+ return hashtable_iter_next(&object->hashtable, iter);
}
const char *json_object_iter_key(void *iter)
/*** string ***/
-json_t *json_string(const char *value)
+json_t *json_string_nocheck(const char *value)
{
json_string_t *string = malloc(sizeof(json_string_t));
if(!string)
return &string->json;
}
+json_t *json_string(const char *value)
+{
+ if(!utf8_check_string(value, -1))
+ return NULL;
+
+ return json_string_nocheck(value);
+}
+
const char *json_string_value(const json_t *json)
{
if(!json_is_string(json))
free(string);
}
-json_t *json_number(double value)
+
+/*** integer ***/
+
+json_t *json_integer(int value)
{
- json_number_t *number = malloc(sizeof(json_number_t));
- if(!number)
+ json_integer_t *integer = malloc(sizeof(json_integer_t));
+ if(!integer)
return NULL;
- json_init(&number->json, JSON_NUMBER);
+ json_init(&integer->json, JSON_INTEGER);
+
+ integer->value = value;
+ return &integer->json;
+}
- number->value = value;
- return &number->json;
+int json_integer_value(const json_t *json)
+{
+ if(!json_is_integer(json))
+ return 0;
+
+ return json_to_integer(json)->value;
}
+static void json_delete_integer(json_integer_t *integer)
+{
+ free(integer);
+}
-/*** number ***/
-double json_number_value(const json_t *json)
+/*** real ***/
+
+json_t *json_real(double value)
{
- if(!json_is_number(json))
- return 0.0;
+ json_real_t *real = malloc(sizeof(json_real_t));
+ if(!real)
+ return NULL;
+ json_init(&real->json, JSON_REAL);
+
+ real->value = value;
+ return &real->json;
+}
- return json_to_number(json)->value;
+double json_real_value(const json_t *json)
+{
+ if(!json_is_real(json))
+ return 0;
+
+ return json_to_real(json)->value;
+}
+
+static void json_delete_real (json_real_t *real)
+{
+ free(real);
}
-static void json_delete_number(json_number_t *number)
+
+/*** number ***/
+
+double json_number_value(const json_t *json)
{
- free(number);
+ if(json_is_integer(json))
+ return json_integer_value(json);
+ else if(json_is_real(json))
+ return json_real_value(json);
+ else
+ return 0.0;
}
else if(json_is_string(json))
json_delete_string(json_to_string(json));
- else if(json_is_number(json))
- json_delete_number(json_to_number(json));
+ else if(json_is_integer(json))
+ json_delete_integer(json_to_integer(json));
+
+ else if(json_is_real(json))
+ json_delete_real(json_to_real(json));
/* json_delete is not called for true, false or null */
}