X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=src%2Fvalue.c;h=1aaec90ccf7221f175174c1849047cf62d0a9b45;hb=2f4d6f8ae768886f8ee831bae169763856b5a827;hp=d3302037b9c26219dd445f03cb04596dbdcafa2b;hpb=a2adf6ec98bb45a3152e5006606a3d511e7b77a0;p=jansson.git diff --git a/src/value.c b/src/value.c index d330203..1aaec90 100644 --- a/src/value.c +++ b/src/value.c @@ -1,18 +1,26 @@ +/* + * Copyright (c) 2009 Petri Lehtinen + * + * 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 #include #include #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 { @@ -30,12 +38,18 @@ 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) { @@ -78,9 +92,8 @@ json_t *json_object(void) 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; @@ -90,7 +103,7 @@ json_t *json_object(void) static void json_delete_object(json_object_t *object) { - hashtable_free(object->hashtable); + hashtable_close(&object->hashtable); free(object); } @@ -101,10 +114,11 @@ json_t *json_object_get(const json_t *json, const char *key) 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; @@ -112,7 +126,15 @@ int json_object_set(json_t *json, const char *key, json_t *value) 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) @@ -123,7 +145,7 @@ 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) @@ -134,7 +156,7 @@ 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) @@ -145,7 +167,7 @@ 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) @@ -250,7 +272,7 @@ int json_array_append(json_t *json, json_t *value) /*** 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) @@ -261,6 +283,14 @@ json_t *json_string(const char *value) 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)) @@ -275,31 +305,71 @@ static void json_delete_string(json_string_t *string) 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; } @@ -348,8 +418,11 @@ void json_delete(json_t *json) 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 */ }