From ef49fb417f582ec837cde6b551a0bf0cfafe3d4d Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 3 Mar 2021 12:52:21 +0100 Subject: Use cJSON instead of the existing json library --- src/transmission.c | 118 +++++++++++++++++++---------------------------------- 1 file changed, 41 insertions(+), 77 deletions(-) (limited to 'src/transmission.c') diff --git a/src/transmission.c b/src/transmission.c index d08c74c..916ccc7 100644 --- a/src/transmission.c +++ b/src/transmission.c @@ -1,7 +1,7 @@ #include "transmission.h" #include "program.h" #include "buffer.h" -#include "json.h" +#include "../depends/cJSON.h" #include "rss_html_common.h" #include #include @@ -74,61 +74,40 @@ int transmission_start_daemon(const char *download_dir) { return 0; } -static struct json_object_s* json_object_get_child_object_by_name(struct json_object_s *json_obj, const char *field_name) { - struct json_value_s *json_child_obj = json_object_get_field_by_name(json_obj, field_name); - if(!json_child_obj || json_child_obj->type != json_type_object) - return NULL; - return (struct json_object_s*)json_child_obj->payload; -} - -static struct json_string_s* json_object_get_child_string_by_name(struct json_object_s *json_obj, const char *field_name) { - struct json_value_s *json_child_str = json_object_get_field_by_name(json_obj, field_name); - if(!json_child_str || json_child_str->type != json_type_string) - return NULL; - return (struct json_string_s*)json_child_str->payload; -} - -static struct json_number_s* json_object_get_child_number_by_name(struct json_object_s *json_obj, const char *field_name) { - struct json_value_s *json_number_str = json_object_get_field_by_name(json_obj, field_name); - if(!json_number_str || json_number_str->type != json_type_number) - return NULL; - return (struct json_number_s*)json_number_str->payload; -} - -static int transmission_response_is_success(struct json_object_s *json_root) { - struct json_string_s *result_field = json_object_get_child_string_by_name(json_root, "result"); - if(!result_field) { +static int transmission_response_is_success(cJSON *json_root) { + cJSON *result_field = cJSON_GetObjectItemCaseSensitive(json_root, "result"); + if(!result_field || !cJSON_IsString(result_field)) { fprintf(stderr, "Error: Transmission response is missing result field\n"); return -1; } - return strcmp(result_field->string, "success"); + return strcmp(result_field->valuestring, "success"); } -static int transmission_add_torrent_response_get_torrent_name(struct json_object_s *json_root, int *torrent_id, const char **torrent_name) { - struct json_object_s *arguments_obj = json_object_get_child_object_by_name(json_root, "arguments"); - if(!arguments_obj) { +static int transmission_add_torrent_response_get_torrent_name(cJSON *json_root, int *torrent_id, const char **torrent_name) { + cJSON *arguments_obj = cJSON_GetObjectItemCaseSensitive(json_root, "arguments"); + if(!cJSON_IsObject(arguments_obj)) { fprintf(stderr, "Error: transmission add torrent response is missing arguments field or its not an object\n"); return -1; } - struct json_object_s *torrent_added_obj = json_object_get_child_object_by_name(arguments_obj, "torrent-added"); - if(!torrent_added_obj) - torrent_added_obj = json_object_get_child_object_by_name(arguments_obj, "torrent-duplicate"); + cJSON *torrent_added_obj = cJSON_GetObjectItemCaseSensitive(arguments_obj, "torrent-added"); + if(!cJSON_IsObject(torrent_added_obj)) + torrent_added_obj = cJSON_GetObjectItemCaseSensitive(arguments_obj, "torrent-duplicate"); - if(!torrent_added_obj) { + if(!cJSON_IsObject(torrent_added_obj)) { fprintf(stderr, "Error: transmission add torrent response is missing both torrent-added and torrent-duplicate argument\n"); return -1; } if(torrent_id) { - struct json_number_s *torrent_id_field = json_object_get_child_number_by_name(torrent_added_obj, "id"); - if(!torrent_id_field) { + cJSON *torrent_id_field = cJSON_GetObjectItemCaseSensitive(torrent_added_obj, "id"); + if(!cJSON_IsNumber(torrent_id_field)) { fprintf(stderr, "Error: transmission add torrent response is missing torrent id\n"); return -1; } - *torrent_id = atoi(torrent_id_field->number); + *torrent_id = torrent_id_field->valuedouble; if(*torrent_id == 0) { fprintf(stderr, "Error: transmission add torrent response has invalid torrent id\n"); return -1; @@ -136,12 +115,12 @@ static int transmission_add_torrent_response_get_torrent_name(struct json_object } if(torrent_name) { - struct json_string_s *torrent_name_field = json_object_get_child_string_by_name(torrent_added_obj, "name"); - if(!torrent_name_field) { + cJSON *torrent_name_field = cJSON_GetObjectItemCaseSensitive(torrent_added_obj, "name"); + if(!cJSON_IsString(torrent_name_field)) { fprintf(stderr, "Error: transmission add torrent response is missing torrent name\n"); return -1; } - *torrent_name = torrent_name_field->string; + *torrent_name = torrent_name_field->valuestring; } return 0; @@ -151,7 +130,7 @@ int transmission_add_torrent(TransmissionSession *session, const char *url, int int result = 0; Buffer buffer; buffer_init(&buffer); - struct json_value_s *json_response_val = NULL; + cJSON *json_response = NULL; /* TODO: json escape url */ char request[4096]; @@ -180,16 +159,14 @@ int transmission_add_torrent(TransmissionSession *session, const char *url, int } } - json_response_val = json_parse(buffer.data, buffer.size); - if(!json_response_val || json_response_val->type != json_type_object) { + json_response = cJSON_ParseWithLength(buffer.data, buffer.size); + if(!json_response || !cJSON_IsObject(json_response)) { fprintf(stderr, "Failed to parse torrent add response: %.*s as json\n", (int)buffer.size, (char*)buffer.data); result = -1; goto cleanup; } - - struct json_object_s *json_response_obj = json_value_as_object(json_response_val); - if(transmission_response_is_success(json_response_obj) != 0) { + if(transmission_response_is_success(json_response) != 0) { fprintf(stderr, "Error: transmission torrent add request failed, response: %.*s\n", (int)buffer.size, (char*)buffer.data); result = -1; goto cleanup; @@ -197,7 +174,7 @@ int transmission_add_torrent(TransmissionSession *session, const char *url, int int response_torrent_id; const char *response_torrent_name; - result = transmission_add_torrent_response_get_torrent_name(json_response_obj, + result = transmission_add_torrent_response_get_torrent_name(json_response, torrent_id ? &response_torrent_id : NULL, torrent_name ? &response_torrent_name : NULL); @@ -211,7 +188,7 @@ int transmission_add_torrent(TransmissionSession *session, const char *url, int *torrent_name = strdup(response_torrent_name); cleanup: - free(json_response_val); + cJSON_Delete(json_response); buffer_deinit(&buffer); return result; } @@ -220,7 +197,7 @@ int transmission_list_torrents(TransmissionSession *session, TorrentListCallback int result = 0; Buffer buffer; buffer_init(&buffer); - struct json_value_s *json_response_val = NULL; + cJSON *json_response = NULL; char request[100]; int written_bytes = snprintf(request, sizeof(request), "{ \"arguments\": { \"fields\": [ \"id\", \"name\", \"percentDone\" ] }, \"method\": \"torrent-get\" }"); @@ -248,62 +225,49 @@ int transmission_list_torrents(TransmissionSession *session, TorrentListCallback } } - json_response_val = json_parse(buffer.data, buffer.size); - if(!json_response_val || json_response_val->type != json_type_object) { + json_response = cJSON_ParseWithLength(buffer.data, buffer.size); + if(!json_response || !cJSON_IsObject(json_response)) { fprintf(stderr, "Failed to parse torrent list response: %.*s as json\n", (int)buffer.size, (char*)buffer.data); result = -1; goto cleanup; } - - struct json_object_s *json_response_obj = json_value_as_object(json_response_val); - if(transmission_response_is_success(json_response_obj) != 0) { + if(transmission_response_is_success(json_response) != 0) { fprintf(stderr, "Error: transmission torrent list request failed, response: %.*s\n", (int)buffer.size, (char*)buffer.data); result = -1; goto cleanup; } - struct json_value_s *arguments_field = json_object_get_field_by_name(json_response_obj, "arguments"); - if(!arguments_field || arguments_field->type != json_type_object) { + cJSON *arguments_field = cJSON_GetObjectItemCaseSensitive(json_response, "arguments"); + if(!cJSON_IsObject(arguments_field)) { fprintf(stderr, "Error: transmission torrent list response is missing arguments or its not an object\n"); result = -1; goto cleanup; } - struct json_object_s *arguments_field_obj = json_value_as_object(arguments_field); - struct json_value_s *torrents_field = json_object_get_field_by_name(arguments_field_obj, "torrents"); - if(!torrents_field || torrents_field->type != json_type_array) { + cJSON *torrents_field = cJSON_GetObjectItemCaseSensitive(arguments_field, "torrents"); + if(!cJSON_IsArray(torrents_field)) { fprintf(stderr, "Error: transmission torrent list response is missing torrents or its not an array\n"); result = -1; goto cleanup; } - struct json_array_element_s *torrent_item = json_value_as_array(torrents_field)->start; - while(torrent_item) { - struct json_object_s *torrent_item_obj = json_value_as_object(torrent_item->value); - if(!torrent_item_obj) + cJSON *torrent_item = NULL; + cJSON_ArrayForEach(torrent_item, torrents_field) { + if(!cJSON_IsObject(torrent_item)) continue; - struct json_value_s *id_field = json_object_get_field_by_name(torrent_item_obj, "id"); - struct json_value_s *name_field = json_object_get_field_by_name(torrent_item_obj, "name"); - struct json_value_s *percent_done_field = json_object_get_field_by_name(torrent_item_obj, "percentDone"); - if(!id_field || id_field->type != json_type_number - || !name_field || name_field->type != json_type_string - || !percent_done_field || percent_done_field->type != json_type_number) - { + cJSON *id_field = cJSON_GetObjectItemCaseSensitive(torrent_item, "id"); + cJSON *name_field = cJSON_GetObjectItemCaseSensitive(torrent_item, "name"); + cJSON *percent_done_field = cJSON_GetObjectItemCaseSensitive(torrent_item, "percentDone"); + if(!cJSON_IsNumber(id_field) || !cJSON_IsString(name_field) || !cJSON_IsNumber(percent_done_field)) continue; - } - - callback(atoi(json_value_as_number(id_field)->number), - json_value_as_string(name_field)->string, - atof(json_value_as_number(percent_done_field)->number), - userdata); - torrent_item = torrent_item->next; + callback(id_field->valuedouble, name_field->valuestring, percent_done_field->valuedouble, userdata); } cleanup: - free(json_response_val); + cJSON_Delete(json_response); buffer_deinit(&buffer); return result; } -- cgit v1.2.3