Json node can be disabled and won't appear in the json string.

This commit is contained in:
shuxin   zheng 2024-08-23 18:50:47 +08:00
parent afaa17db51
commit d0a75a3843
5 changed files with 173 additions and 77 deletions

View File

@ -28,6 +28,9 @@ struct ACL_JSON_NODE {
#define ACL_JSON_T_A_NULL (1 << 3)
#define ACL_JSON_T_A_DOUBLE (1 << 4)
#define ACL_JSON_T_A_TYPES (ACL_JSON_T_A_NULL | ACL_JSON_T_A_BOOL | \
ACL_JSON_T_A_NUMBER | ACL_JSON_T_A_DOUBLE | ACL_JSON_T_A_STRING)
#define ACL_JSON_T_STRING (1 << 5)
#define ACL_JSON_T_NUMBER (1 << 6)
#define ACL_JSON_T_BOOL (1 << 7)
@ -49,6 +52,7 @@ struct ACL_JSON_NODE {
unsigned char right_ch; /**< 本节点的最后一个字符: } or ] */
unsigned backslash:1; /**< 转义字符 \ */
unsigned part_word:1; /**< 半个汉字的情况处理标志位 */
unsigned disabled:1; /**< 该节点是否被禁止 */
ACL_JSON *json; /**< json 对象 */
ACL_RING node; /**< 当前节点 */
@ -126,6 +130,21 @@ ACL_API ACL_JSON_NODE *acl_json_node_alloc(ACL_JSON *json);
*/
ACL_API int acl_json_node_delete(ACL_JSON_NODE *node);
/**
* / json json json
* 便
* @param node {ACL_JSON_NODE*} json
* @param yes {int} json
*/
ACL_API void acl_json_node_disable(ACL_JSON_NODE *node, int yes);
/**
* json
* @param node {ACL_JSON_NODE*} json
* @return {int} 0
*/
ACL_API int acl_json_node_disabled(ACL_JSON_NODE *node);
/**
* json ( json )
* @param node1 {ACL_JSON_NODE*} json

View File

@ -1,5 +1,4 @@
#include "StdAfx.h"
#include <stdio.h>
#ifndef ACL_PREPARE_COMPILE
#include "stdlib/acl_define.h"
#include "stdlib/acl_mymalloc.h"
@ -105,6 +104,7 @@ ACL_JSON_NODE *acl_json_node_alloc(ACL_JSON *json)
node->right_ch = 0;
node->backslash = 0;
node->part_word = 0;
node->disabled = 0;
node->json = json;
node->iter_head = node_iter_head;
@ -133,6 +133,16 @@ int acl_json_node_delete(ACL_JSON_NODE *node)
return n;
}
void acl_json_node_disable(ACL_JSON_NODE *node, int yes)
{
node->disabled = yes ? 1 : (unsigned) 0;
}
int acl_json_node_disabled(ACL_JSON_NODE *node)
{
return node->disabled != (unsigned) 0;
}
void acl_json_node_append(ACL_JSON_NODE *node1, ACL_JSON_NODE *node2)
{
acl_ring_append(&node1->node, &node2->node);
@ -155,12 +165,14 @@ ACL_JSON_NODE *acl_json_node_next(ACL_JSON_NODE *node)
ACL_RING *ring_ptr = acl_ring_succ(&node->node);
ACL_JSON_NODE *parent;
if (ring_ptr == &node->node)
if (ring_ptr == &node->node) {
return NULL;
}
parent = node->parent;
acl_assert(parent != NULL);
if (ring_ptr == &parent->children)
if (ring_ptr == &parent->children) {
return NULL;
}
return acl_ring_to_appl(ring_ptr, ACL_JSON_NODE, node);
}
@ -173,8 +185,9 @@ ACL_JSON_NODE *acl_json_node_prev(ACL_JSON_NODE *node)
return NULL;
parent = node->parent;
acl_assert(parent != NULL);
if (ring_ptr == &parent->children)
if (ring_ptr == &parent->children) {
return NULL;
}
return acl_ring_to_appl(ring_ptr, ACL_JSON_NODE, node);
}
@ -236,8 +249,9 @@ static ACL_JSON_NODE *json_iter_next(ACL_ITER *it, ACL_JSON *json)
/* 当前节点的兄弟节点遍历完毕,最后遍历当前节点的父节点的兄弟节点 */
do {
if (parent == json->root)
if (parent == json->root) {
break;
}
ring_ptr = acl_ring_succ(&parent->node);
parent = acl_json_node_parent(parent);
@ -310,8 +324,9 @@ static ACL_JSON_NODE *json_iter_prev(ACL_ITER *it, ACL_JSON *json)
/* 当前节点的兄弟节点遍历完毕,最后遍历当前节点的父节点的兄弟节点 */
do {
if (parent == json->root)
if (parent == json->root) {
break;
}
ring_ptr = acl_ring_pred(&parent->node);
parent = acl_json_node_parent(parent);
if (parent == NULL)
@ -388,6 +403,7 @@ ACL_JSON_NODE *acl_json_node_duplicate(ACL_JSON *json, ACL_JSON_NODE *from)
to->right_ch = from->right_ch;
to->type = from->type;
to->depth = from->depth; /* XXX? */
to->disabled = from->disabled;
acl_vstring_strcpy(to->ltag, STR(from->ltag));
acl_vstring_strcpy(to->text, STR(from->text));
@ -395,8 +411,9 @@ ACL_JSON_NODE *acl_json_node_duplicate(ACL_JSON *json, ACL_JSON_NODE *from)
child_from = acl_ring_to_appl(iter.ptr, ACL_JSON_NODE, node);
child_to = acl_json_node_duplicate(json, child_from);
acl_json_node_add_child(to, child_to);
if (from->tag_node == child_from)
if (from->tag_node == child_from) {
to->tag_node = child_to;
}
}
return to;
@ -418,7 +435,7 @@ ACL_JSON *acl_json_dbuf_create(ACL_DBUF_POOL *dbuf, ACL_JSON_NODE *node)
json = (ACL_JSON*) acl_dbuf_pool_calloc(dbuf, sizeof(ACL_JSON));
json->dbuf = dbuf;
json->dbuf_inner = NULL;
json->dbuf_inner = NULL;
/* 如果传入的节点为 root 节点,则直接赋值创建 root 即可 */
if (node == root) {
@ -463,14 +480,16 @@ void acl_json_foreach_init(ACL_JSON *json, ACL_JSON_NODE *node)
void acl_json_free(ACL_JSON *json)
{
if (json->dbuf_inner)
if (json->dbuf_inner) {
acl_dbuf_pool_destroy(json->dbuf_inner);
}
}
void acl_json_reset(ACL_JSON *json)
{
if (json->dbuf_inner != NULL)
if (json->dbuf_inner != NULL) {
acl_dbuf_pool_reset(json->dbuf, json->dbuf_keep);
}
json->root = acl_json_node_alloc(json);
#if 0

View File

@ -20,8 +20,9 @@ ACL_JSON_NODE *acl_json_getFirstElementByTagName(
acl_foreach(iter, json) {
ACL_JSON_NODE *node = (ACL_JSON_NODE*) iter.data;
if (strcasecmp(tag, STR(node->ltag)) == 0)
if (strcasecmp(tag, STR(node->ltag)) == 0) {
return node;
}
}
return NULL;
@ -257,9 +258,8 @@ void acl_json_node_append_child(ACL_JSON_NODE *parent, ACL_JSON_NODE *child)
const char *myname = "acl_json_node_append_child";
if (parent->type != ACL_JSON_T_ARRAY
&& parent->type != ACL_JSON_T_OBJ
&& parent != parent->json->root)
{
&& parent->type != ACL_JSON_T_OBJ
&& parent != parent->json->root) {
acl_msg_fatal("%s(%d): parent's type not array or obj",
myname, __LINE__);
}
@ -299,6 +299,26 @@ static void json_escape_append(ACL_VSTRING *buf, const char *src)
ACL_VSTRING_TERMINATE(buf);
}
static void child_end(ACL_JSON *json, ACL_JSON_NODE *node, ACL_VSTRING *buf)
{
/* 当本节点为叶节点且后面没有兄弟节点时,需要一级一级回溯
*
*
*/
while (acl_json_node_next(node) == NULL) {
if (node->parent == json->root) {
break;
}
node = node->parent;
/* right_ch: '}' or ']' */
if (node->right_ch != 0) {
ACL_VSTRING_ADDCH(buf, node->right_ch);
}
}
}
void acl_json_building(ACL_JSON *json, size_t length,
int (*callback)(ACL_JSON *, ACL_VSTRING *, void *), void *ctx)
{
@ -325,8 +345,9 @@ void acl_json_building(ACL_JSON *json, size_t length,
json->root->right_ch = '}';
}
if (json->root->left_ch > 0)
if (json->root->left_ch > 0) {
ACL_VSTRING_ADDCH(buf, json->root->left_ch);
}
acl_foreach(iter, json) {
if (ACL_VSTRING_LEN(buf) >= length && callback != NULL) {
@ -341,10 +362,11 @@ void acl_json_building(ACL_JSON *json, size_t length,
node = (ACL_JSON_NODE*) iter.data;
prev = acl_json_node_prev(node);
if (prev != NULL) {
if ((json->flag & ACL_JSON_FLAG_ADD_SPACE))
if ((json->flag & ACL_JSON_FLAG_ADD_SPACE)) {
acl_vstring_strcat(buf, ", ");
else
} else {
acl_vstring_strcat(buf, ",");
}
}
/* 只有当标签的对应值为 JSON 对象或数组对象时 tag_node 非空 */
@ -352,21 +374,24 @@ void acl_json_building(ACL_JSON *json, size_t length,
if (LEN(node->ltag) > 0) {
json_escape_append(buf, STR(node->ltag));
ACL_VSTRING_ADDCH(buf, ':');
if ((json->flag & ACL_JSON_FLAG_ADD_SPACE))
if ((json->flag & ACL_JSON_FLAG_ADD_SPACE)) {
ACL_VSTRING_ADDCH(buf, ' ');
}
}
/* '{' or '[' */
if (node->left_ch != 0)
if (node->left_ch != 0) {
ACL_VSTRING_ADDCH(buf, node->left_ch);
}
}
/* 当节点有标签名时 */
else if (LEN(node->ltag) > 0) {
json_escape_append(buf, STR(node->ltag));
ACL_VSTRING_ADDCH(buf, ':');
if ((json->flag & ACL_JSON_FLAG_ADD_SPACE))
if ((json->flag & ACL_JSON_FLAG_ADD_SPACE)) {
ACL_VSTRING_ADDCH(buf, ' ');
}
switch (node->type & ~ACL_JSON_T_LEAF) {
case ACL_JSON_T_NULL:
@ -384,9 +409,8 @@ void acl_json_building(ACL_JSON *json, size_t length,
}
/* 当节点为数组的成员时 */
else if (LEN(node->text) > 0 && node->parent
&& node->parent->left_ch != 0)
{
else if (node->parent && node->parent->type == ACL_JSON_T_ARRAY
&& (node->type & ACL_JSON_T_A_TYPES)) {
switch (node->type & ~ACL_JSON_T_LEAF) {
case ACL_JSON_T_A_NULL:
acl_vstring_strcat(buf, "null");
@ -417,8 +441,9 @@ void acl_json_building(ACL_JSON *json, size_t length,
if (acl_ring_size(&node->children) > 0) {
continue;
} else if (acl_json_node_next(node) != NULL) {
if (node->right_ch > 0)
if (node->right_ch > 0) {
ACL_VSTRING_ADDCH(buf, node->right_ch);
}
continue;
}
@ -430,20 +455,12 @@ void acl_json_building(ACL_JSON *json, size_t length,
*
*
*/
while (acl_json_node_next(node) == NULL) {
if (node->parent == json->root)
break;
node = node->parent;
/* right_ch: '}' or ']' */
if (node->right_ch != 0)
ACL_VSTRING_ADDCH(buf, node->right_ch);
}
child_end(json, node, buf);
}
if (json->root->right_ch > 0)
if (json->root->right_ch > 0) {
ACL_VSTRING_ADDCH(buf, json->root->right_ch);
}
ACL_VSTRING_TERMINATE(buf);
if (ACL_VSTRING_LEN(buf) > 0 && callback != NULL) {
@ -456,8 +473,29 @@ void acl_json_building(ACL_JSON *json, size_t length,
acl_vstring_free(buf);
/* 将第二个参数置 NULL 表示处理完毕 */
if (callback != NULL)
if (callback != NULL) {
(void) callback(json, NULL, ctx);
}
}
static int is_parents_disabled(ACL_JSON_NODE *node)
{
while ((node = node->parent)) {
if (node->disabled) {
return 1;
}
}
return 0;
}
static int is_first_node(ACL_JSON_NODE *node)
{
while ((node = acl_json_node_prev(node))) {
if (!node->disabled) {
return 0;
}
}
return 1;
}
ACL_VSTRING *acl_json_build(ACL_JSON *json, ACL_VSTRING *buf)
@ -466,8 +504,9 @@ ACL_VSTRING *acl_json_build(ACL_JSON *json, ACL_VSTRING *buf)
ACL_ITER iter;
ACL_RING *ring_ptr = acl_ring_succ(&json->root->children);
if (buf == NULL)
if (buf == NULL) {
buf = acl_vstring_alloc(256);
}
/* 为了兼容历史的BUG所以此处只能如此处理了--zsx, 2021.3.27 */
@ -487,17 +526,28 @@ ACL_VSTRING *acl_json_build(ACL_JSON *json, ACL_VSTRING *buf)
json->root->right_ch = '}';
}
if (json->root->left_ch > 0)
if (json->root->left_ch > 0) {
ACL_VSTRING_ADDCH(buf, json->root->left_ch);
}
acl_foreach(iter, json) {
node = (ACL_JSON_NODE*) iter.data;
if (node->disabled) { // 跳过被禁止的 json 节点
child_end(json, node, buf);
continue;
}
if (is_parents_disabled(node)) {
continue;
}
prev = acl_json_node_prev(node);
if (prev != NULL) {
if ((json->flag & ACL_JSON_FLAG_ADD_SPACE))
if (prev != NULL && (!prev->disabled || !is_first_node(node))) {
if ((json->flag & ACL_JSON_FLAG_ADD_SPACE)) {
acl_vstring_strcat(buf, ", ");
else
} else {
acl_vstring_strcat(buf, ",");
}
}
/* 只有当标签的对应值为 JSON 对象或数组对象时 tag_node 非空 */
@ -505,21 +555,24 @@ ACL_VSTRING *acl_json_build(ACL_JSON *json, ACL_VSTRING *buf)
if (LEN(node->ltag) > 0) {
json_escape_append(buf, STR(node->ltag));
ACL_VSTRING_ADDCH(buf, ':');
if ((json->flag & ACL_JSON_FLAG_ADD_SPACE))
if ((json->flag & ACL_JSON_FLAG_ADD_SPACE)) {
ACL_VSTRING_ADDCH(buf, ' ');
}
}
/* '{' or '[' */
if (node->left_ch != 0)
if (node->left_ch != 0) {
ACL_VSTRING_ADDCH(buf, node->left_ch);
}
}
/* 当节点有标签名时 */
else if (LEN(node->ltag) > 0) {
json_escape_append(buf, STR(node->ltag));
ACL_VSTRING_ADDCH(buf, ':');
if ((json->flag & ACL_JSON_FLAG_ADD_SPACE))
if ((json->flag & ACL_JSON_FLAG_ADD_SPACE)) {
ACL_VSTRING_ADDCH(buf, ' ');
}
switch (node->type & ~ACL_JSON_T_LEAF) {
case ACL_JSON_T_NULL:
@ -537,22 +590,8 @@ ACL_VSTRING *acl_json_build(ACL_JSON *json, ACL_VSTRING *buf)
}
/* 当节点为数组的成员时 */
#if 0
else if (LEN(node->text) > 0 && node->parent
/* 应该依据父节点类型来确定当前节点是否为数组节点
* && node->parent->left_ch != 0)
*/
&& node->parent->type == ACL_JSON_T_ARRAY)
#elif 0
else if (node->parent && node->parent->type == ACL_JSON_T_ARRAY
&& (LEN(node->text) > 0 || (node->type & ACL_JSON_T_A_STRING)))
#else
else if (node->parent && node->parent->type == ACL_JSON_T_ARRAY
&& (node->type & (ACL_JSON_T_A_NULL
| ACL_JSON_T_A_BOOL | ACL_JSON_T_A_NUMBER
| ACL_JSON_T_A_DOUBLE | ACL_JSON_T_A_STRING)))
#endif
{
&& (node->type & ACL_JSON_T_A_TYPES)) {
switch (node->type & ~ACL_JSON_T_LEAF) {
case ACL_JSON_T_A_NULL:
acl_vstring_strcat(buf, "null");
@ -582,35 +621,29 @@ ACL_VSTRING *acl_json_build(ACL_JSON *json, ACL_VSTRING *buf)
/* 当本节点有子节点或虽为叶节点,但该节点的下一个兄弟节点
*
*/
if (acl_ring_size(&node->children) > 0)
if (acl_ring_size(&node->children) > 0) {
continue;
else if (acl_json_node_next(node) != NULL) {
if (node->right_ch > 0)
} else if (acl_json_node_next(node) != NULL) {
if (node->right_ch > 0) {
ACL_VSTRING_ADDCH(buf, node->right_ch);
}
continue;
}
if (node->right_ch > 0)
if (node->right_ch > 0) {
ACL_VSTRING_ADDCH(buf, node->right_ch);
}
/* 当本节点为叶节点且后面没有兄弟节点时,需要一级一级回溯
*
*
*/
while (acl_json_node_next(node) == NULL) {
if (node->parent == json->root)
break;
node = node->parent;
/* right_ch: '}' or ']' */
if (node->right_ch != 0)
ACL_VSTRING_ADDCH(buf, node->right_ch);
}
child_end(json, node, buf);
}
if (json->root->right_ch > 0)
if (json->root->right_ch > 0) {
ACL_VSTRING_ADDCH(buf, json->root->right_ch);
}
ACL_VSTRING_TERMINATE(buf);
return buf;
@ -621,13 +654,15 @@ ACL_VSTRING *acl_json_node_build(ACL_JSON_NODE *node, ACL_VSTRING *buf)
ACL_JSON *json = acl_json_alloc();
ACL_JSON_NODE *first;
if (buf == NULL)
if (buf == NULL) {
buf = acl_vstring_alloc(256);
}
if (node == node->json->root && node->tag_node != NULL)
if (node == node->json->root && node->tag_node != NULL) {
node = node->tag_node;
else
} else {
json->root->left_ch = json->root->right_ch = 0;
}
first = acl_json_node_duplicate(json, node);
acl_json_node_add_child(json->root, first);

View File

@ -374,6 +374,19 @@ public:
*/
int detach();
/**
* json json
* json
* @param yes {bool} json false true
*/
void disable(bool yes);
/**
* json
* @return {bool}
*/
bool disabled() const;
/**
* json json_node
* first_child,

View File

@ -351,6 +351,16 @@ int json_node::detach()
return acl_json_node_delete(node_me_);
}
void json_node::disable(bool yes)
{
acl_json_node_disable(node_me_, yes ? 1 : 0);
}
bool json_node::disabled() const
{
return acl_json_node_disabled(node_me_) != 0;
}
json_node& json_node::get_parent() const
{
if (parent_) {