aboutsummaryrefslogtreecommitdiffstats
path: root/vnfs/VESreporting_vFW5.0_DANOS/evel/evel-library/code/evel_library/evel_json_buffer.c
diff options
context:
space:
mode:
authorroot <root@danos-build.zbl31w4ywk4ulg0far32rd2huc.cx.internal.cloudapp.net>2020-04-27 21:53:00 +0000
committerMarco Platania <platania@research.att.com>2020-04-28 14:52:48 +0000
commit08eddb8df44beacbb7b4047e313a771292030ccc (patch)
treeede637e3c6725bfd999d115b6ad330f1caa2602f /vnfs/VESreporting_vFW5.0_DANOS/evel/evel-library/code/evel_library/evel_json_buffer.c
parent6610dc1180d0dfbe30a737306d0f059b463aeb26 (diff)
Initial VES for DANOS vRouter
1. Create vpp_measurement_reporter that use DANOS configd query to retrieve statistics and libevel to transmit 2. Copy VES evel library to build a debian package under vpp_measurement_report 3. Add debian files to create a vpp_measurement_reporter + libevel debian package 4. Add debian install and systemctl start files 5. Add instruction to build VES reporter debian package (that will include libevel.so) 6. Add instructions to build DANOS ISO with VES reporter debian package and creating glance image Issue-ID: INT-1566 Change-Id: If18f16525f07f1b6bae0fc105e0452263b4bf661 Signed-off-by: Brian Freeman <bf1936@att.com>
Diffstat (limited to 'vnfs/VESreporting_vFW5.0_DANOS/evel/evel-library/code/evel_library/evel_json_buffer.c')
-rw-r--r--vnfs/VESreporting_vFW5.0_DANOS/evel/evel-library/code/evel_library/evel_json_buffer.c872
1 files changed, 872 insertions, 0 deletions
diff --git a/vnfs/VESreporting_vFW5.0_DANOS/evel/evel-library/code/evel_library/evel_json_buffer.c b/vnfs/VESreporting_vFW5.0_DANOS/evel/evel-library/code/evel_library/evel_json_buffer.c
new file mode 100644
index 00000000..cf1323d7
--- /dev/null
+++ b/vnfs/VESreporting_vFW5.0_DANOS/evel/evel-library/code/evel_library/evel_json_buffer.c
@@ -0,0 +1,872 @@
+/*************************************************************************//**
+ *
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Unless otherwise specified, all software contained herein is
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ ****************************************************************************/
+
+/**************************************************************************//**
+ * @file
+ * Source module relating to internal EVEL_JSON_BUFFER manipulation functions.
+ *
+ ****************************************************************************/
+
+#include <assert.h>
+#include <string.h>
+
+#include "evel_throttle.h"
+
+/*****************************************************************************/
+/* Local prototypes. */
+/*****************************************************************************/
+static char * evel_json_kv_comma(EVEL_JSON_BUFFER * jbuf);
+
+/**************************************************************************//**
+ * Initialize a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to initialise.
+ * @param json Pointer to the underlying working buffer to use.
+ * @param max_size Size of storage available in the JSON buffer.
+ * @param throttle_spec Pointer to throttle specification. Can be NULL.
+ *****************************************************************************/
+void evel_json_buffer_init(EVEL_JSON_BUFFER * jbuf,
+ char * const json,
+ const int max_size,
+ EVEL_THROTTLE_SPEC * throttle_spec)
+{
+ EVEL_ENTER();
+
+ assert(jbuf != NULL);
+ assert(json != NULL);
+ jbuf->json = json;
+ jbuf->max_size = max_size;
+ jbuf->offset = 0;
+ jbuf->throttle_spec = throttle_spec;
+ jbuf->depth = 0;
+ jbuf->checkpoint = -1;
+
+ EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode an integer value to a JSON buffer.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param value The integer to add to it.
+ *****************************************************************************/
+void evel_enc_int(EVEL_JSON_BUFFER * jbuf,
+ const int value)
+{
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ "%d", value);
+
+ EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode a string key and string value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ * @param option Pointer to holder of the corresponding value to encode.
+ * @return true if the key, value was added, false if it was suppressed.
+ *****************************************************************************/
+bool evel_enc_kv_opt_string(EVEL_JSON_BUFFER * jbuf,
+ const char * const key,
+ const EVEL_OPTION_STRING * const option)
+{
+ bool added = false;
+
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(option != NULL);
+
+ if (option->is_set)
+ {
+ if ((jbuf->depth == EVEL_THROTTLE_FIELD_DEPTH) &&
+ (jbuf->throttle_spec != NULL) &&
+ evel_throttle_suppress_field(jbuf->throttle_spec, key))
+ {
+ EVEL_INFO("Suppressed: %s, %s", key, option->value);
+ }
+ else
+ {
+ EVEL_DEBUG("Encoded: %s, %s", key, option->value);
+ evel_enc_kv_string(jbuf, key, option->value);
+ added = true;
+ }
+ }
+
+ EVEL_EXIT();
+
+ return added;
+}
+
+/**************************************************************************//**
+ * Encode a string key and string value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ * @param value Pointer to the corresponding value to encode.
+ *****************************************************************************/
+void evel_enc_kv_string(EVEL_JSON_BUFFER * jbuf,
+ const char * const key,
+ const char * const value)
+{
+ int index;
+ int length;
+
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+ assert(key != NULL);
+
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ "%s\"%s\": \"",
+ evel_json_kv_comma(jbuf),
+ key);
+
+ /***************************************************************************/
+ /* We need to escape quotation marks and backslashes in the value. */
+ /***************************************************************************/
+ length = strlen(value);
+
+ for (index = 0; index < length; index++)
+ {
+ /*************************************************************************/
+ /* Drop out if no more space. */
+ /*************************************************************************/
+ if (jbuf->max_size - jbuf->offset < 2)
+ {
+ break;
+ }
+
+ /*************************************************************************/
+ /* Add an escape character if necessary, then write the character */
+ /* itself. */
+ /*************************************************************************/
+ if ((value[index] == '\"') || (value[index] == '\\'))
+ {
+ jbuf->json[jbuf->offset] = '\\';
+ jbuf->offset++;
+ }
+
+ jbuf->json[jbuf->offset] = value[index];
+ jbuf->offset++;
+ }
+
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ "\"");
+
+ EVEL_EXIT();
+}
+
+
+/**************************************************************************//**
+ * Encode a string key and integer value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ * @param option Pointer to holder of the corresponding value to encode.
+ * @return true if the key, value was added, false if it was suppressed.
+ *****************************************************************************/
+bool evel_enc_kv_opt_int(EVEL_JSON_BUFFER * jbuf,
+ const char * const key,
+ const EVEL_OPTION_INT * const option)
+{
+ bool added = false;
+
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(option != NULL);
+
+ if (option->is_set)
+ {
+ if ((jbuf->depth == EVEL_THROTTLE_FIELD_DEPTH) &&
+ (jbuf->throttle_spec != NULL) &&
+ evel_throttle_suppress_field(jbuf->throttle_spec, key))
+ {
+ EVEL_INFO("Suppressed: %s, %d", key, option->value);
+ }
+ else
+ {
+ EVEL_DEBUG("Encoded: %s, %d", key, option->value);
+ evel_enc_kv_int(jbuf, key, option->value);
+ added = true;
+ }
+ }
+
+ EVEL_EXIT();
+
+ return added;
+}
+
+/**************************************************************************//**
+ * Encode a string key and integer value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ * @param value The corresponding value to encode.
+ *****************************************************************************/
+void evel_enc_kv_int(EVEL_JSON_BUFFER * jbuf,
+ const char * const key,
+ const int value)
+{
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+ assert(key != NULL);
+
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ "%s\"%s\": %d",
+ evel_json_kv_comma(jbuf),
+ key,
+ value);
+
+ EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode a string key and json object value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ * @param value The corresponding json string to encode.
+ *****************************************************************************/
+void evel_enc_kv_object(EVEL_JSON_BUFFER * jbuf,
+ const char * const key,
+ const char * value)
+{
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+ assert(key != NULL);
+
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ "%s\"%s\": %s",
+ evel_json_kv_comma(jbuf),
+ key,
+ value);
+
+ EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode a string key and double value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ * @param option Pointer to holder of the corresponding value to encode.
+ * @return true if the key, value was added, false if it was suppressed.
+ *****************************************************************************/
+bool evel_enc_kv_opt_double(EVEL_JSON_BUFFER * jbuf,
+ const char * const key,
+ const EVEL_OPTION_DOUBLE * const option)
+{
+ bool added = false;
+
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(option != NULL);
+
+ if (option->is_set)
+ {
+ if ((jbuf->depth == EVEL_THROTTLE_FIELD_DEPTH) &&
+ (jbuf->throttle_spec != NULL) &&
+ evel_throttle_suppress_field(jbuf->throttle_spec, key))
+ {
+ EVEL_INFO("Suppressed: %s, %1f", key, option->value);
+ }
+ else
+ {
+ EVEL_DEBUG("Encoded: %s, %1f", key, option->value);
+ evel_enc_kv_double(jbuf, key, option->value);
+ added = true;
+ }
+ }
+
+ EVEL_EXIT();
+
+ return added;
+}
+
+/**************************************************************************//**
+ * Encode a string key and double value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ * @param value The corresponding value to encode.
+ *****************************************************************************/
+void evel_enc_kv_double(EVEL_JSON_BUFFER * jbuf,
+ const char * const key,
+ const double value)
+{
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+ assert(key != NULL);
+
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ "%s\"%s\": %1f",
+ evel_json_kv_comma(jbuf),
+ key,
+ value);
+
+ EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode a string key and unsigned long long value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ * @param option Pointer to holder of the corresponding value to encode.
+ * @return true if the key, value was added, false if it was suppressed.
+ *****************************************************************************/
+bool evel_enc_kv_opt_ull(EVEL_JSON_BUFFER * jbuf,
+ const char * const key,
+ const EVEL_OPTION_ULL * const option)
+{
+ bool added = false;
+
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(option != NULL);
+
+ if (option->is_set)
+ {
+ if ((jbuf->depth == EVEL_THROTTLE_FIELD_DEPTH) &&
+ (jbuf->throttle_spec != NULL) &&
+ evel_throttle_suppress_field(jbuf->throttle_spec, key))
+ {
+ EVEL_INFO("Suppressed: %s, %1lu", key, option->value);
+ }
+ else
+ {
+ EVEL_DEBUG("Encoded: %s, %1lu", key, option->value);
+ evel_enc_kv_ull(jbuf, key, option->value);
+ added = true;
+ }
+ }
+
+ EVEL_EXIT();
+
+ return added;
+}
+
+/**************************************************************************//**
+ * Encode a string key and unsigned long long value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ * @param value The corresponding value to encode.
+ *****************************************************************************/
+void evel_enc_kv_ull(EVEL_JSON_BUFFER * jbuf,
+ const char * const key,
+ const unsigned long long value)
+{
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+ assert(key != NULL);
+
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ "%s\"%s\": %llu",
+ evel_json_kv_comma(jbuf),
+ key,
+ value);
+
+ EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode a string key and time value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ * @param option Pointer to holder of the corresponding value to encode.
+ * @return true if the key, value was added, false if it was suppressed.
+ *****************************************************************************/
+bool evel_enc_kv_opt_time(EVEL_JSON_BUFFER * jbuf,
+ const char * const key,
+ const EVEL_OPTION_TIME * const option)
+{
+ bool added = false;
+
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(option != NULL);
+
+ if (option->is_set)
+ {
+ if ((jbuf->depth == EVEL_THROTTLE_FIELD_DEPTH) &&
+ (jbuf->throttle_spec != NULL) &&
+ evel_throttle_suppress_field(jbuf->throttle_spec, key))
+ {
+ EVEL_INFO("Suppressed time: %s", key);
+ }
+ else
+ {
+ EVEL_DEBUG("Encoded time: %s", key);
+ evel_enc_kv_time(jbuf, key, &option->value);
+ added = true;
+ }
+ }
+
+ EVEL_EXIT();
+
+ return added;
+}
+
+/**************************************************************************//**
+ * Encode a string key and time value to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ * @param time Pointer to the time to encode.
+ *****************************************************************************/
+void evel_enc_kv_time(EVEL_JSON_BUFFER * jbuf,
+ const char * const key,
+ const time_t * time)
+{
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+ assert(key != NULL);
+ assert(time != NULL);
+
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ "%s\"%s\": \"",
+ evel_json_kv_comma(jbuf),
+ key);
+ jbuf->offset += strftime(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ EVEL_RFC2822_STRFTIME_FORMAT,
+ localtime(time));
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ "\"");
+ EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode a key and version.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ * @param major_version The major version to encode.
+ * @param minor_version The minor version to encode.
+ *****************************************************************************/
+void evel_enc_version(EVEL_JSON_BUFFER * jbuf,
+ const char * const key,
+ const int major_version,
+ const int minor_version)
+{
+ float ver;
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+ assert(key != NULL);
+
+ ver = (float)major_version + (float)minor_version/10.0;
+
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ "%s\"%s\": %.1f",
+ evel_json_kv_comma(jbuf),
+ key,
+ ver);
+
+ EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add the key and opening bracket of an optional named list to a JSON buffer.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ * @return true if the list was opened, false if it was suppressed.
+ *****************************************************************************/
+bool evel_json_open_opt_named_list(EVEL_JSON_BUFFER * jbuf,
+ const char * const key)
+{
+ bool opened = false;
+
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+ assert(key != NULL);
+
+ if ((jbuf->depth == EVEL_THROTTLE_FIELD_DEPTH) &&
+ (jbuf->throttle_spec != NULL) &&
+ evel_throttle_suppress_field(jbuf->throttle_spec, key))
+ {
+ EVEL_INFO("Suppressed: %s", key);
+ opened = false;
+ }
+ else
+ {
+ evel_json_open_named_list(jbuf, key);
+ opened = true;
+ }
+
+ EVEL_EXIT();
+
+ return opened;
+}
+
+/**************************************************************************//**
+ * Add the key and opening bracket of a named list to a JSON buffer.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ *****************************************************************************/
+void evel_json_open_named_list(EVEL_JSON_BUFFER * jbuf,
+ const char * const key)
+{
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+ assert(key != NULL);
+
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ "%s\"%s\": [",
+ evel_json_kv_comma(jbuf),
+ key);
+ jbuf->depth++;
+
+ EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add the closing bracket of a list to a JSON buffer.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ *****************************************************************************/
+void evel_json_close_list(EVEL_JSON_BUFFER * jbuf)
+{
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ "]");
+ jbuf->depth--;
+
+ EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Encode a list item with format and param list to a ::EVEL_JSON_BUFFER.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param format Format string in standard printf format.
+ * @param ... Variable parameters for format string.
+ *****************************************************************************/
+void evel_enc_list_item(EVEL_JSON_BUFFER * jbuf,
+ const char * const format,
+ ...)
+{
+ va_list largs;
+
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+ assert(format != NULL);
+
+ /***************************************************************************/
+ /* Add a comma unless we're at the start of the list. */
+ /***************************************************************************/
+ if (jbuf->json[jbuf->offset - 1] != '[')
+ {
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ ", ");
+ }
+
+ va_start(largs, format);
+ jbuf->offset += vsnprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ format,
+ largs);
+ va_end(largs);
+
+ EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add the opening bracket of an optional named object to a JSON buffer.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ *****************************************************************************/
+bool evel_json_open_opt_named_object(EVEL_JSON_BUFFER * jbuf,
+ const char * const key)
+{
+ bool opened = false;
+
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+ assert(key != NULL);
+
+ if ((jbuf->depth == EVEL_THROTTLE_FIELD_DEPTH) &&
+ (jbuf->throttle_spec != NULL) &&
+ evel_throttle_suppress_field(jbuf->throttle_spec, key))
+ {
+ EVEL_INFO("Suppressed: %s", key);
+ opened = false;
+ }
+ else
+ {
+ evel_json_open_named_object(jbuf, key);
+ opened = true;
+ }
+
+ EVEL_EXIT();
+
+ return opened;
+}
+
+/**************************************************************************//**
+ * Add the opening bracket of an object to a JSON buffer.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @param key Pointer to the key to encode.
+ * @return true if the object was opened, false if it was suppressed.
+ *****************************************************************************/
+void evel_json_open_named_object(EVEL_JSON_BUFFER * jbuf,
+ const char * const key)
+{
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+ assert(key != NULL);
+
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ "%s\"%s\": {",
+ evel_json_kv_comma(jbuf),
+ key);
+ jbuf->depth++;
+
+ EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add the opening bracket of an object to a JSON buffer.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ *****************************************************************************/
+void evel_json_open_object(EVEL_JSON_BUFFER * jbuf)
+{
+ char * comma;
+
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+
+ if ((jbuf->offset != 0) && (jbuf->json[jbuf->offset-1] == '}'))
+ {
+ comma = ", ";
+ }
+ else
+ {
+ comma = "";
+ }
+
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ "%s{",
+ comma);
+ jbuf->depth++;
+
+ EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Add the closing bracket of an object to a JSON buffer.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ *****************************************************************************/
+void evel_json_close_object(EVEL_JSON_BUFFER * jbuf)
+{
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+
+ jbuf->offset += snprintf(jbuf->json + jbuf->offset,
+ jbuf->max_size - jbuf->offset,
+ "}");
+ jbuf->depth--;
+
+ EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Determine whether to add a comma when adding a key-value pair.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ * @returns A string containing the comma if it is required.
+ *****************************************************************************/
+char * evel_json_kv_comma(EVEL_JSON_BUFFER * jbuf)
+{
+ char * result;
+
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+
+ if ((jbuf->offset == 0) ||
+ (jbuf->json[jbuf->offset-1] == '{') ||
+ (jbuf->json[jbuf->offset-1] == '['))
+ {
+ result = "";
+ }
+ else
+ {
+ result = ", ";
+ }
+
+ EVEL_EXIT();
+
+ return result;
+}
+
+/**************************************************************************//**
+ * Add a checkpoint - a stake in the ground to which we can rewind.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ *****************************************************************************/
+void evel_json_checkpoint(EVEL_JSON_BUFFER * jbuf)
+{
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+
+ /***************************************************************************/
+ /* Store the current offset. */
+ /***************************************************************************/
+ jbuf->checkpoint = jbuf->offset;
+
+ EVEL_EXIT();
+}
+
+/**************************************************************************//**
+ * Rewind to the latest checkoint.
+ *
+ * @param jbuf Pointer to working ::EVEL_JSON_BUFFER.
+ *****************************************************************************/
+void evel_json_rewind(EVEL_JSON_BUFFER * jbuf)
+{
+ EVEL_ENTER();
+
+ /***************************************************************************/
+ /* Check preconditions. */
+ /***************************************************************************/
+ assert(jbuf != NULL);
+ assert(jbuf->checkpoint >= 0);
+ assert(jbuf->checkpoint <= jbuf->offset);
+
+ /***************************************************************************/
+ /* Reinstate the offset from the last checkpoint. */
+ /***************************************************************************/
+ jbuf->offset = jbuf->checkpoint;
+ jbuf->checkpoint = -1;
+
+ EVEL_EXIT();
+}