[Feature][S300][task-view-1900][arms] Docking with ARMS platform,basic documents

Change-Id: I89df7b9e3685d6f6205bd2a4ff00ac67c8f447cb
diff --git a/lynq/S300/ap/app/apparms/json-c/json_pointer.c b/lynq/S300/ap/app/apparms/json-c/json_pointer.c
new file mode 100755
index 0000000..5abccdb
--- /dev/null
+++ b/lynq/S300/ap/app/apparms/json-c/json_pointer.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2016 Alexandru Ardelean.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+
+#include "strerror_override.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "json_pointer.h"
+#include "strdup_compat.h"
+#include "vasprintf_compat.h"
+
+/* Avoid ctype.h and locale overhead */
+#define is_plain_digit(c) ((c) >= '0' && (c) <= '9')
+
+/**
+ * JavaScript Object Notation (JSON) Pointer
+ *   RFC 6901 - https://tools.ietf.org/html/rfc6901
+ */
+
+static void string_replace_all_occurrences_with_char(char *s, const char *occur, char repl_char)
+{
+	size_t slen = strlen(s);
+	size_t skip = strlen(occur) - 1; /* length of the occurrence, minus the char we're replacing */
+	char *p = s;
+	while ((p = strstr(p, occur)))
+	{
+		*p = repl_char;
+		p++;
+		slen -= skip;
+		memmove(p, (p + skip), slen - (p - s) + 1); /* includes null char too */
+	}
+}
+
+static int is_valid_index(struct json_object *jo, const char *path, size_t *idx)
+{
+	size_t i, len = strlen(path);
+	long int idx_val = -1;
+	/* this code-path optimizes a bit, for when we reference the 0-9 index range
+	 * in a JSON array and because leading zeros not allowed
+	 */
+	if (len == 1)
+	{
+		if (is_plain_digit(path[0]))
+		{
+			*idx = (path[0] - '0');
+			goto check_oob;
+		}
+		errno = EINVAL;
+		return 0;
+	}
+	/* leading zeros not allowed per RFC */
+	if (path[0] == '0')
+	{
+		errno = EINVAL;
+		return 0;
+	}
+	/* RFC states base-10 decimals */
+	for (i = 0; i < len; i++)
+	{
+		if (!is_plain_digit(path[i]))
+		{
+			errno = EINVAL;
+			return 0;
+		}
+	}
+
+	idx_val = strtol(path, NULL, 10);
+	if (idx_val < 0)
+	{
+		errno = EINVAL;
+		return 0;
+	}
+	*idx = idx_val;
+
+check_oob:
+	len = json_object_array_length(jo);
+	if (*idx >= len)
+	{
+		errno = ENOENT;
+		return 0;
+	}
+
+	return 1;
+}
+
+static int json_pointer_get_single_path(struct json_object *obj, char *path,
+                                        struct json_object **value)
+{
+	if (json_object_is_type(obj, json_type_array))
+	{
+		size_t idx;
+		if (!is_valid_index(obj, path, &idx))
+			return -1;
+		obj = json_object_array_get_idx(obj, idx);
+		if (obj)
+		{
+			if (value)
+				*value = obj;
+			return 0;
+		}
+		/* Entry not found */
+		errno = ENOENT;
+		return -1;
+	}
+
+	/* RFC states that we first must eval all ~1 then all ~0 */
+	string_replace_all_occurrences_with_char(path, "~1", '/');
+	string_replace_all_occurrences_with_char(path, "~0", '~');
+
+	if (!json_object_object_get_ex(obj, path, value))
+	{
+		errno = ENOENT;
+		return -1;
+	}
+
+	return 0;
+}
+
+static int json_pointer_set_single_path(struct json_object *parent, const char *path,
+                                        struct json_object *value)
+{
+	if (json_object_is_type(parent, json_type_array))
+	{
+		size_t idx;
+		/* RFC (Chapter 4) states that '-' may be used to add new elements to an array */
+		if (path[0] == '-' && path[1] == '\0')
+			return json_object_array_add(parent, value);
+		if (!is_valid_index(parent, path, &idx))
+			return -1;
+		return json_object_array_put_idx(parent, idx, value);
+	}
+
+	/* path replacements should have been done in json_pointer_get_single_path(),
+	 * and we should still be good here
+	 */
+	if (json_object_is_type(parent, json_type_object))
+		return json_object_object_add(parent, path, value);
+
+	/* Getting here means that we tried to "dereference" a primitive JSON type
+	 * (like string, int, bool).i.e. add a sub-object to it
+	 */
+	errno = ENOENT;
+	return -1;
+}
+
+static int json_pointer_get_recursive(struct json_object *obj, char *path,
+                                      struct json_object **value)
+{
+	char *endp;
+	int rc;
+
+	/* All paths (on each recursion level must have a leading '/' */
+	if (path[0] != '/')
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	path++;
+
+	endp = strchr(path, '/');
+	if (endp)
+		*endp = '\0';
+
+	/* If we err-ed here, return here */
+	if ((rc = json_pointer_get_single_path(obj, path, &obj)))
+		return rc;
+
+	if (endp)
+	{
+		/* Put the slash back, so that the sanity check passes on next recursion level */
+		*endp = '/';
+		return json_pointer_get_recursive(obj, endp, value);
+	}
+
+	/* We should be at the end of the recursion here */
+	if (value)
+		*value = obj;
+
+	return 0;
+}
+
+int json_pointer_get(struct json_object *obj, const char *path, struct json_object **res)
+{
+	char *path_copy = NULL;
+	int rc;
+
+	if (!obj || !path)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	if (path[0] == '\0')
+	{
+		if (res)
+			*res = obj;
+		return 0;
+	}
+
+	/* pass a working copy to the recursive call */
+	if (!(path_copy = strdup(path)))
+	{
+		errno = ENOMEM;
+		return -1;
+	}
+	rc = json_pointer_get_recursive(obj, path_copy, res);
+	free(path_copy);
+
+	return rc;
+}
+
+int json_pointer_getf(struct json_object *obj, struct json_object **res, const char *path_fmt, ...)
+{
+	char *path_copy = NULL;
+	int rc = 0;
+	va_list args;
+
+	if (!obj || !path_fmt)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	va_start(args, path_fmt);
+	rc = vasprintf(&path_copy, path_fmt, args);
+	va_end(args);
+
+	if (rc < 0)
+		return rc;
+
+	if (path_copy[0] == '\0')
+	{
+		if (res)
+			*res = obj;
+		goto out;
+	}
+
+	rc = json_pointer_get_recursive(obj, path_copy, res);
+out:
+	free(path_copy);
+
+	return rc;
+}
+
+int json_pointer_set(struct json_object **obj, const char *path, struct json_object *value)
+{
+	const char *endp;
+	char *path_copy = NULL;
+	struct json_object *set = NULL;
+	int rc;
+
+	if (!obj || !path)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	if (path[0] == '\0')
+	{
+		json_object_put(*obj);
+		*obj = value;
+		return 0;
+	}
+
+	if (path[0] != '/')
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	/* If there's only 1 level to set, stop here */
+	if ((endp = strrchr(path, '/')) == path)
+	{
+		path++;
+		return json_pointer_set_single_path(*obj, path, value);
+	}
+
+	/* pass a working copy to the recursive call */
+	if (!(path_copy = strdup(path)))
+	{
+		errno = ENOMEM;
+		return -1;
+	}
+	path_copy[endp - path] = '\0';
+	rc = json_pointer_get_recursive(*obj, path_copy, &set);
+	free(path_copy);
+
+	if (rc)
+		return rc;
+
+	endp++;
+	return json_pointer_set_single_path(set, endp, value);
+}
+
+int json_pointer_setf(struct json_object **obj, struct json_object *value, const char *path_fmt,
+                      ...)
+{
+	char *endp;
+	char *path_copy = NULL;
+	struct json_object *set = NULL;
+	va_list args;
+	int rc = 0;
+
+	if (!obj || !path_fmt)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	/* pass a working copy to the recursive call */
+	va_start(args, path_fmt);
+	rc = vasprintf(&path_copy, path_fmt, args);
+	va_end(args);
+
+	if (rc < 0)
+		return rc;
+
+	if (path_copy[0] == '\0')
+	{
+		json_object_put(*obj);
+		*obj = value;
+		goto out;
+	}
+
+	if (path_copy[0] != '/')
+	{
+		errno = EINVAL;
+		rc = -1;
+		goto out;
+	}
+
+	/* If there's only 1 level to set, stop here */
+	if ((endp = strrchr(path_copy, '/')) == path_copy)
+	{
+		set = *obj;
+		goto set_single_path;
+	}
+
+	*endp = '\0';
+	rc = json_pointer_get_recursive(*obj, path_copy, &set);
+
+	if (rc)
+		goto out;
+
+set_single_path:
+	endp++;
+	rc = json_pointer_set_single_path(set, endp, value);
+out:
+	free(path_copy);
+	return rc;
+}