Beispiel #1
0
static const char *json_strend(ACL_JSON *json, const char *data)
{
	ACL_JSON_NODE *parent;

	SKIP_SPACE(data);
	if (*data == 0)
		return NULL;

	if (*data == ',' || *data == ';') {
		json->status = ACL_JSON_S_NEXT;
		return data;
	}

	parent = acl_json_node_parent(json->curr_node);
	if (*data != parent->right_ch) {  /* xxx */
		data++;
		return data;
	}

	if (parent == json->root) {
		json->finish = 1;
		return NULL;
	}

	data++;
	json->curr_node = parent;
	json->status = ACL_JSON_S_NEXT;
	return data;
}
Beispiel #2
0
static const char *json_brother(ACL_JSON *json, const char *data)
{
	ACL_JSON_NODE *parent;

	if (json->curr_node == json->root) {
		json->finish = 1;
		return NULL;
	}

	SKIP_SPACE(data);
	if (*data == 0)
		return NULL;

	/* 如果到达根结点的结束符,则 json 解析过程完毕 */
	parent = acl_json_node_parent(json->curr_node);
	acl_assert(parent);

	if (*data == ',' || *data == ';') {
		data++;

		if (parent->left_ch == '{')
			json->status = ACL_JSON_S_MEMBER;
		else if (parent->left_ch == '[')
			json->status = ACL_JSON_S_ELEMENT;
		else
			json->status = ACL_JSON_S_NEXT;

		json->curr_node = parent;
		return data;
	}

	if (*data == parent->right_ch) {
		data++;

		if (parent == json->root) {
			json->finish = 1;
			return NULL;
		}

		json->curr_node = parent;
		/* 查询父结点的下一个兄弟结点 */
		json->status = ACL_JSON_S_NEXT;
		return data;
	}

	if (parent->left_ch == '{')
		json->status = ACL_JSON_S_MEMBER;
	else if (parent->left_ch == '[')
		json->status = ACL_JSON_S_ELEMENT;
	else
		json->status = ACL_JSON_S_NEXT;

	json->curr_node = parent;
	return data;
}
Beispiel #3
0
static const char *json_pair(ACL_JSON *json, const char *data)
{
	ACL_JSON_NODE *parent = acl_json_node_parent(json->curr_node);

	SKIP_SPACE(data);
	if (*data == 0)
		return NULL;

	acl_assert(parent);

	/* 如果当前字符为父结点的右分隔符,则表示父结点结束 */
	if (*data == parent->right_ch) {
		data++;  /* 去掉父结点的右分隔符 */

		if (parent == json->root) {
			/* 如果根结点分析结束则整个 json 分析完毕 */
			json->finish = 1;
			return NULL;
		}
		/* 弹出父结点 */
		json->curr_node = parent;
		/* 查询父结点的下一个兄弟结点 */
		json->status = ACL_JSON_S_NEXT;
		return data;
	}

	/* 为 '{' 或 '[' 时说明遇到了当前结点的子结点 */
	if (*data == '{') {
		data++;
		json->status = ACL_JSON_S_OBJ;
		return data;
	}
	else if (*data == '[') {
		data++;
		json->status = ACL_JSON_S_ARRAY;
		return data;
	}

	/* 如果标签名前有引号,记录下该引号 */
	if (IS_QUOTE(*data) && json->curr_node->quote == 0)
		json->curr_node->quote = *data++;

	json->curr_node->type = ACL_JSON_T_PAIR;
	json->status = ACL_JSON_S_TAG;

	return data;
}
Beispiel #4
0
static const char *json_tag(ACL_JSON *json, const char *data)
{
	ACL_JSON_NODE *node = json->curr_node;
	int   ch;

	while ((ch = *data) != 0) {
		/* 如果前面有引号,则需要找到结尾引号 */
		if (node->quote) {
			if (node->backslash) {
				if (ch == 'b')
					ADDCH(node->ltag, '\b');
				else if (ch == 'f')
					ADDCH(node->ltag, '\f');
				else if (ch == 'n')
					ADDCH(node->ltag, '\n');
				else if (ch == 'r')
					ADDCH(node->ltag, '\r');
				else if (ch == 't')
					ADDCH(node->ltag, '\t');
				else
					ADDCH(node->ltag, ch);
				node->backslash = 0;
			}

			/* 当为双字节汉字时,第一个字节为的高位为 1,
			 * 第二个字节为 92,正好与转义字符相同
			 */
			else if (ch == '\\') {
				/* 处理半个汉字的情形 */
				if (node->part_word) {
					ADDCH(node->ltag, ch);
					node->part_word = 0;
				} else
					node->backslash = 1;
			} else if (ch == node->quote) {
				ACL_JSON_NODE *parent;

				parent = acl_json_node_parent(node);

				acl_assert(parent);

				/* 数组对象的子结点允许为单独的字符串或对象 */
				if (parent->left_ch == '[')
					json->status = ACL_JSON_S_NEXT;

				/* 标签值分析结束,下一步需要找到冒号 */
				else
					json->status = ACL_JSON_S_COLON;

				node->quote = 0;
				node->part_word = 0;
				data++;
				break;
			}

			/* 是否兼容后半个汉字为转义符 '\' 的情况 */
			else if ((json->flag & ACL_JSON_FLAG_PART_WORD)) {
				ADDCH(node->ltag, ch);

				/* 处理半个汉字的情形 */
				if (node->part_word)
					node->part_word = 0;
				else if (ch < 0)
					node->part_word = 1;
			} else {
				ADDCH(node->ltag, ch);
			}
		}

		/* 分析标签名前没有引号的情况 */

		else if (node->backslash) {
			ADDCH(node->ltag, ch);
			node->backslash = 0;
		}

		/* 当为双字节汉字时,第一个字节为的高位为 1,
		 * 第二个字节为 92,正好与转义字符相同
		 */
		else if (ch == '\\') {
			/* 处理半个汉字的情形 */
			if (node->part_word) {
				ADDCH(node->ltag, ch);
				node->part_word = 0;
			} else
				node->backslash = 1;
		} else if (IS_SPACE(ch) || ch == ':') {
			/* 标签名分析结束,下一步需要找到冒号 */
			json->status = ACL_JSON_S_COLON;
			node->part_word = 0;
			break;
		}

		/* 是否兼容后半个汉字为转义符 '\' 的情况 */
		else if ((json->flag & ACL_JSON_FLAG_PART_WORD)) {
			ADDCH(node->ltag, ch);

			/* 处理半个汉字的情形 */
			if (node->part_word)
				node->part_word = 0;
			else if (ch < 0)
				node->part_word = 1;
		} else {
			ADDCH(node->ltag, ch);
		}
		data++;
	}

	/* 如果标签名非空,则需要保证以 0 结尾 */
	if (LEN(node->ltag) > 0)
		ACL_VSTRING_TERMINATE(node->ltag);

	return data;
}
Beispiel #5
0
static const char *json_strend(ACL_JSON *json, const char *data)
{
	ACL_JSON_NODE *node = json->curr_node;
	ACL_JSON_NODE *parent;

	SKIP_SPACE(data);
	if (*data == 0)
		return data;

#define	EQ(x, y) !strcasecmp((x), ((y)))
#define	IS_NUMBER(x) (acl_alldig((x)) \
		|| ((*(x) == '-' || *(x) == '+') \
			&& *((x) + 1) != 0 && acl_alldig((x) + 1)))

	if (node->parent && node->parent->type == ACL_JSON_T_ARRAY) {
		if (node->quote == 0) {
			const char* txt = STR(node->text);

			if (EQ(txt, "null"))
				node->type = ACL_JSON_T_A_NULL
					| ACL_JSON_T_LEAF;
			else if (EQ(txt, "true") || EQ(txt, "false"))
				node->type = ACL_JSON_T_A_BOOL
					| ACL_JSON_T_LEAF;
			else if (IS_NUMBER(txt))
				node->type = ACL_JSON_T_A_NUMBER
					| ACL_JSON_T_LEAF;
			else if (acl_is_double(txt))
				node->type = ACL_JSON_T_A_DOUBLE
					| ACL_JSON_T_LEAF;
			else
				node->type = ACL_JSON_T_A_STRING
					| ACL_JSON_T_LEAF;
		} else
			node->type = ACL_JSON_T_A_STRING | ACL_JSON_T_LEAF;
	} else if (node->quote == 0) {
		const char* txt = STR(node->text);

		if (EQ(txt, "null"))
			node->type = ACL_JSON_T_NULL | ACL_JSON_T_LEAF;
		else if (EQ(txt, "true") || EQ(txt, "false"))
			node->type = ACL_JSON_T_BOOL | ACL_JSON_T_LEAF;
		else if (IS_NUMBER(txt))
			node->type = ACL_JSON_T_NUMBER | ACL_JSON_T_LEAF;
		else if (acl_is_double(txt))
			node->type = ACL_JSON_T_DOUBLE | ACL_JSON_T_LEAF;
		else
			node->type = ACL_JSON_T_STRING | ACL_JSON_T_LEAF;
	} else
		node->type = ACL_JSON_T_STRING | ACL_JSON_T_LEAF;


	if (*data == ',' || *data == ';') {
		json->status = ACL_JSON_S_NEXT;
		return data;
	}

	parent = acl_json_node_parent(json->curr_node);
	if (*data != parent->right_ch) {  /* xxx */
		data++;
		return data;
	}

	data++;
	if (parent == json->root) {
		json->finish = 1;
		return data;
	}

	json->curr_node = parent;
	json->status = ACL_JSON_S_NEXT;
	return data;
}