Add helper parsing functions to cJSON
authorCharles Giessen <charles@lunarg.com>
Fri, 28 Apr 2023 18:59:41 +0000 (12:59 -0600)
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>
Mon, 29 May 2023 23:45:08 +0000 (17:45 -0600)
Since parsing an array of strings and strings from json files is very common,
this commit adds helper functions to do exactly that.

loader/cJSON.c
loader/cJSON.h

index 4353e85..8b12250 100644 (file)
@@ -1220,10 +1220,6 @@ void cJSON_Minify(char *json) {
     *into = 0; /* and null-terminate. */
 }
 
-// Read a JSON file into a buffer.
-//
-// @return -  A pointer to a cJSON object representing the JSON parse tree.
-//            This returned buffer should be freed by caller.
 VkResult loader_get_json(const struct loader_instance *inst, const char *filename, cJSON **json) {
     FILE *file = NULL;
     char *json_buf = NULL;
@@ -1297,3 +1293,41 @@ out:
 
     return res;
 }
+
+VkResult loader_parse_json_string(const struct loader_instance *inst, cJSON *object, const char *key, char **out_string) {
+    cJSON *item = cJSON_GetObjectItem(object, key);
+    if (NULL == item) return VK_ERROR_INITIALIZATION_FAILED;
+
+    char *str = cJSON_Print(item);
+    if (str == NULL) return VK_ERROR_OUT_OF_HOST_MEMORY;
+    *out_string = str;
+    return VK_SUCCESS;
+}
+VkResult loader_parse_json_array_of_strings(const struct loader_instance *inst, cJSON *object, const char *key, uint32_t *out_count,
+                                            char ***out_array_of_strings) {
+    cJSON *item = cJSON_GetObjectItem(object, key);
+    if (NULL == item) return VK_ERROR_INITIALIZATION_FAILED;
+
+    uint32_t count = cJSON_GetArraySize(item);
+    if (count == 0) {
+        *out_count = 0;
+        *out_array_of_strings = NULL;
+        return VK_SUCCESS;
+    }
+    *out_count = count;
+
+    char **out_data = loader_instance_heap_alloc(inst, sizeof(char *) * (count), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    if (out_data == NULL) return VK_ERROR_OUT_OF_HOST_MEMORY;
+    for (uint32_t i = 0; i < count; i++) {
+        cJSON *element = cJSON_GetArrayItem(item, i);
+        if (element == NULL) {
+            return VK_ERROR_INITIALIZATION_FAILED;
+        }
+        out_data[i] = cJSON_Print(element);
+        if (out_data[i] == NULL) {
+            return VK_ERROR_OUT_OF_HOST_MEMORY;
+        }
+    }
+    *out_array_of_strings = out_data;
+    return VK_SUCCESS;
+}
index f08a5bc..410ec27 100644 (file)
@@ -25,6 +25,8 @@
 
 #pragma once
 
+#include <stdint.h>
+
 typedef struct VkAllocationCallbacks VkAllocationCallbacks;
 
 #if defined(__cplusplus)
@@ -163,4 +165,17 @@ void cJSON_Minify(char *json);
 struct loader_instance;
 typedef enum VkResult VkResult;
 
+// Read a JSON file into a buffer.
+//
+// @return -  A pointer to a cJSON object representing the JSON parse tree.
+//            This returned buffer should be freed by caller.
 VkResult loader_get_json(const struct loader_instance *inst, const char *filename, cJSON **json);
+
+// Given a cJSON object, find the string associated with the key and puts an allocated string into out_string.
+// It is the callers responsibility to free out_string.
+VkResult loader_parse_json_string(const struct loader_instance *inst, cJSON *object, const char *key, char **out_string);
+
+// Given a cJSON object, find the array of strings assocated with they key and writes the count into out_count and data into
+// out_array_of_strings. It is the callers responsibility to free out_array_of_strings.
+VkResult loader_parse_json_array_of_strings(const struct loader_instance *inst, cJSON *object, const char *key, uint32_t *out_count,
+                                            char ***out_array_of_strings);