Преглед на файлове

README: new doc: Example

Max Bruckner преди 7 години
родител
ревизия
cdcd553769
променени са 1 файла, в които са добавени 211 реда и са изтрити 0 реда
  1. 211 0
      README.md

+ 211 - 0
README.md

@@ -12,6 +12,7 @@ Ultralightweight JSON parser in ANSI C.
   * [Working with the data structure](#working-with-the-data-structure)
   * [Parsing JSON](#parsing-json)
   * [Printing JSON](#printing-json)
+  * [Example](#example)
   * [Some JSON](#some-json)
   * [Here's the structure](#heres-the-structure)
   * [Caveats](#caveats)
@@ -252,6 +253,216 @@ If you have a rough idea of how big your resulting string will be, you can use `
 
 These dynamic buffer allocations can be completely avoided by using `cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format)`. It takes a buffer to a pointer to print to and it's length. If the length is reached, printing will fail and it returns `0`. In case of success, `1` is returned. Note that you should provide 5 bytes more than is actually needed, because cJSON is not 100% accurate in estimating if the provided memory is enough.
 
+### Example
+In this example we want to build and parse the following JSON:
+
+```json
+{
+    "name": "Awesome 4K",
+    "resolutions": [
+        {
+            "width": 1280,
+            "height": 720
+        },
+        {
+            "width": 1920,
+            "height": 1080
+        },
+        {
+            "width": 3840,
+            "height": 2160
+        }
+    ]
+}
+```
+
+#### Printing
+Let's build the above JSON and print it to a string:
+```c
+//create a monitor with a list of supported resolutions
+char* create_monitor(void)
+{
+    const unsigned int resolution_numbers[3][2] = {
+        {1280, 720},
+        {1920, 1080},
+        {3840, 2160}
+    };
+    char *string = NULL;
+    cJSON *name = NULL;
+    cJSON *resolutions = NULL;
+    cJSON *resolution = NULL;
+    cJSON *width = NULL;
+    cJSON *height = NULL;
+    size_t index = 0;
+
+    cJSON *monitor = cJSON_CreateObject();
+    if (monitor == NULL)
+    {
+        goto end;
+    }
+
+    name = cJSON_CreateString("Awesome 4K");
+    if (name == NULL)
+    {
+        goto end;
+    }
+    /* after creation was successful, immediately add it to the monitor,
+     * thereby transfering ownership of the pointer to it */
+    cJSON_AddItemToObject(monitor, "name", name);
+
+    resolutions = cJSON_CreateArray();
+    if (resolutions == NULL)
+    {
+        goto end;
+    }
+    cJSON_AddItemToObject(monitor, "resolutions", resolutions);
+
+    for (index = 0; index < (sizeof(resolution_numbers) / (2 * sizeof(int))); ++index)
+    {
+        resolution = cJSON_CreateObject();
+        if (resolution == NULL)
+        {
+            goto end;
+        }
+        cJSON_AddItemToArray(resolutions, resolution);
+
+        width = cJSON_CreateNumber(resolution_numbers[index][0]);
+        if (width == NULL)
+        {
+            goto end;
+        }
+        cJSON_AddItemToObject(resolution, "width", width);
+
+        height = cJSON_CreateNumber(resolution_numbers[index][1]);
+        if (height == NULL)
+        {
+            goto end;
+        }
+        cJSON_AddItemToObject(resolution, "height", height);
+    }
+
+    string = cJSON_Print(monitor);
+    if (string == NULL)
+    {
+        fprintf(stderr, "Failed to print monitor.\n");
+    }
+
+end:
+    cJSON_Delete(monitor);
+    return string;
+}
+```
+
+Alternatively we can use the `cJSON_Add...ToObject` helper functions to make our lifes a little easier:
+```c
+char *create_monitor_with_helpers(void)
+{
+    const unsigned int resolution_numbers[3][2] = {
+        {1280, 720},
+        {1920, 1080},
+        {3840, 2160}
+    };
+    char *string = NULL;
+    cJSON *resolutions = NULL;
+    size_t index = 0;
+
+    cJSON *monitor = cJSON_CreateObject();
+
+    if (cJSON_AddStringToObject(monitor, "name", "Awesome 4K") == NULL)
+    {
+        goto end;
+    }
+
+    resolutions = cJSON_AddArrayToObject(monitor, "resolutions");
+    if (resolutions == NULL)
+    {
+        goto end;
+    }
+
+    for (index = 0; index < (sizeof(resolution_numbers) / (2 * sizeof(int))); ++index)
+    {
+        cJSON *resolution = cJSON_CreateObject();
+
+        if (cJSON_AddNumberToObject(resolution, "width", resolution_numbers[index][0]) == NULL)
+        {
+            goto end;
+        }
+
+        if(cJSON_AddNumberToObject(resolution, "height", resolution_numbers[index][1]) == NULL)
+        {
+            goto end;
+        }
+
+        cJSON_AddItemToArray(resolutions, resolution);
+    }
+
+    string = cJSON_Print(monitor);
+    if (string == NULL) {
+        fprintf(stderr, "Failed to print monitor.\n");
+    }
+
+end:
+    cJSON_Delete(monitor);
+    return string;
+}
+```
+
+#### Parsing
+In this example we will parse a JSON in the above format and check if the monitor supports a Full HD resolution while printing some diagnostic output:
+
+```c
+/* return 1 if the monitor supports full hd, 0 otherwise */
+int supports_full_hd(const char * const monitor)
+{
+    const cJSON *resolution = NULL;
+    const cJSON *resolutions = NULL;
+    const cJSON *name = NULL;
+    int status = 0;
+    cJSON *monitor_json = cJSON_Parse(monitor);
+    if (monitor_json == NULL)
+    {
+        const char *error_ptr = cJSON_GetErrorPtr();
+        if (error_ptr != NULL)
+        {
+            fprintf(stderr, "Error before: %s\n", error_ptr);
+        }
+        status = 0;
+        goto end;
+    }
+
+    name = cJSON_GetObjectItemCaseSensitive(monitor_json, "name");
+    if (cJSON_IsString(name) && (name->valuestring != NULL))
+    {
+        printf("Checking monitor \"%s\"\n", name->valuestring);
+    }
+
+    resolutions = cJSON_GetObjectItemCaseSensitive(monitor_json, "resolutions");
+    cJSON_ArrayForEach(resolution, resolutions)
+    {
+        cJSON *width = cJSON_GetObjectItemCaseSensitive(resolution, "width");
+        cJSON *height = cJSON_GetObjectItemCaseSensitive(resolution, "height");
+
+        if (!cJSON_IsNumber(width) || !cJSON_IsNumber(height))
+        {
+            status = 0;
+            goto end;
+        }
+
+        if ((width->valuedouble == 1920) && (height->valuedouble == 1080))
+        {
+            status = 1;
+            goto end;
+        }
+    }
+
+end:
+    cJSON_Delete(monitor_json);
+    return status;
+}
+```
+
+Note that there are no NULL checks except for the result of `cJSON_Parse` because `cJSON_GetObjectItemCaseSensitive` checks for `NULL` inputs already, so a `NULL` value is just propagated and `cJSON_IsNumber` and `cJSON_IsString` return `0` if the input is `NULL`.
+
 ### Some JSON:
 
 ```json