From afaa17db51ea8e8d64d6b5433149116b3b7a1032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?shuxin=20=E3=80=80=E3=80=80zheng?= Date: Fri, 23 Aug 2024 14:38:30 +0800 Subject: [PATCH 1/4] Format codes and add split in string class. --- lib_acl_cpp/include/acl_cpp/stdlib/json.hpp | 78 +++++++++---------- lib_acl_cpp/include/acl_cpp/stdlib/string.hpp | 17 ++++ .../include/acl_cpp/stdlib/token_tree.hpp | 31 ++++---- .../include/acl_cpp/stdlib/url_coder.hpp | 12 ++- lib_acl_cpp/src/stdlib/json.cpp | 69 ++++++++-------- lib_acl_cpp/src/stdlib/string.cpp | 46 +++++++++++ lib_acl_cpp/src/stdlib/token_tree.cpp | 19 +++-- lib_acl_cpp/src/stdlib/url_coder.cpp | 9 +-- 8 files changed, 166 insertions(+), 115 deletions(-) diff --git a/lib_acl_cpp/include/acl_cpp/stdlib/json.hpp b/lib_acl_cpp/include/acl_cpp/stdlib/json.hpp index 4adddb12e..f46b51450 100644 --- a/lib_acl_cpp/include/acl_cpp/stdlib/json.hpp +++ b/lib_acl_cpp/include/acl_cpp/stdlib/json.hpp @@ -33,27 +33,27 @@ public: * @return {const char*} 返回 json 节点标签名,如果返回空,则说明 * 调用者需要判断返回值 */ - const char* tag_name(void) const; + const char* tag_name() const; /** * 返回该 json 节点的文本标签值,当该值为布尔型或数值型时调用者可 * 自行进行转换 * @return {const char*} 返回空说明没有文本标签值 */ - const char* get_text(void) const; + const char* get_text() const; /** * 当该 json 节点存在子节点时,返回本 json 节点标签对应的 json 子节点 * @return {const json_node*} 返回 NULL 说明不存在子节点 * 注:get_text 与 get_obj 不会同时返回非 NULL */ - json_node* get_obj(void) const; + json_node* get_obj() const; /** * 当 json 节点为字符串类型时,该函数返回字符串内容 * @return {const char*} 返回 NULL 表示该节点非字符串类型 */ - const char* get_string(void) const; + const char* get_string() const; /** * 当 json 节点为长整型类型时,该函数返回长整型值的指针地址 @@ -62,68 +62,68 @@ public: #if defined(_WIN32) || defined(_WIN64) const __int64* get_int64(void) const; #else - const long long int* get_int64(void) const; + const long long int* get_int64() const; #endif /** * 当 json 节点为浮点类型时,该函数返回长整型值的指针地址 * @return {const double*} 当返回 NULL 时表示该对象非浮点类型 */ - const double *get_double(void) const; + const double *get_double() const; /** * 当 json 节点为布尔类型时,该函数返回布尔值的指针地址 * @return {bool*} 当返回 NULL 时表示该对象非布尔类型 */ - const bool* get_bool(void) const; + const bool* get_bool() const; /** * 判断本节点数据是否为字符串类型 * @return {bool} */ - bool is_string(void) const; + bool is_string() const; /** * 判断本节点数据是否为数字类型 * @return {bool} */ - bool is_number(void) const; + bool is_number() const; /** * 判断本节点数据是否为浮点类型 * @return {bool} */ - bool is_double(void) const; + bool is_double() const; /** * 判断本节点数据是否为布尔类型 * @return {bool} */ - bool is_bool(void) const; + bool is_bool() const; /** * 判断本节点数据是否为 null 类型 * @return {bool} */ - bool is_null(void) const; + bool is_null() const; /** * 判断本节点是否为对象类型 * @return {bool} */ - bool is_object(void) const; + bool is_object() const; /** * 判断本节点是否为数组类型 * @return {bool} */ - bool is_array(void) const; + bool is_array() const; /** * 获得该节点类型的描述 * @return {const char*} */ - const char* get_type(void) const; + const char* get_type() const; /** * 当该 json 节点有标签时,本函数用来新的标签值覆盖旧的标签名 @@ -285,8 +285,7 @@ public: * @return {json_node&} return_child 为 true 时创建的新节点的引用, * 否则返回本 json 节点对象的引用 */ - json_node& add_array_text(const char* text, - bool return_child = false); + json_node& add_array_text(const char* text, bool return_child = false); /** * 创建一个 json 数字对象,并将之添加为本 json 节点的子节点 @@ -299,8 +298,7 @@ public: json_node& add_array_number(__int64 value, bool return_child = false); #else - json_node& add_array_number(long long int value, - bool return_child = false); + json_node& add_array_number(long long int value, bool return_child = false); #endif /** @@ -333,7 +331,7 @@ public: * @return {json_node&} 返回本节点的父节点引用,在采用级联方式创建 json * 对象时,本函数常被用于返回父节点 */ - json_node& get_parent(void) const; + json_node& get_parent() const; ///////////////////////////////////////////////////////////////////// @@ -342,14 +340,14 @@ public: * @return {json_node*} 返回空表示没有子节点,返回的非空对象不能 * 在外部 delete,因为内部会自动释放 */ - json_node* first_child(void); + json_node* first_child(); /** * 获得本节点的下一个子节点 * @return {json_node*} 返回空表示遍历过程结束,返回的非空对象不能 * 在外部 delete,因为内部会自动释放 */ - json_node* next_child(void); + json_node* next_child(); /** * 从当前 json 节点的子节点中提取对应标签的 json 子节点 @@ -362,19 +360,19 @@ public: * 返回该 json 节点在整个 json 树中的深度 * @return {int} */ - int depth(void) const; + int depth() const; /** * 返回该 json 节点的下一级子节点的个数 * @return {int} 永远 >= 0 */ - int children_count(void) const; + int children_count() const; /** * 将本节点及其子节点从 json 树中删除,其内存将由 json 对象统一释放 * @return {int} 被释放的节点数量 */ - int detach(void); + int detach(); /** * 当在遍历该 json 节点时,内部会动态产生一些临时 json_node 对象,调用 @@ -382,19 +380,19 @@ public: * next_child 返回的 json_node 节点对象将不再可用,否则会产生内存非法 * 访问 */ - void clear(void); + void clear(); /** * 获得 json 对象的引用 * @return {json&} */ - json& get_json(void) const; + json& get_json() const; /** * 取出对应于 ACL 库中的 json 节点对象 * @return {ACL_JSON_NODE*} 返回节点对象,注:该节点用户不能单独释放 */ - ACL_JSON_NODE* get_json_node(void) const; + ACL_JSON_NODE* get_json_node() const; private: friend class json; @@ -409,7 +407,7 @@ private: /** * 要求该对象必须是动态创建的 */ - ~json_node(void); + ~json_node(); /** * 设置 json 节点 @@ -459,7 +457,7 @@ public: */ json(const json_node& node, dbuf_guard* dbuf = NULL); - ~json(void); + ~json(); /** * 设置是否在解析时自动处理半个汉字的情形 @@ -482,14 +480,14 @@ public: * 判断是否解析完毕 * @return {bool} */ - bool finish(void); + bool finish(); /** * 重置 json 解析器状态,该 json 对象可以用来对多个 json 数据 * 进行解析,在反复使用本 json 解析器前,需要调用本函数重置 * 内部 json 解析器状态,清除上一次的解析结果 */ - void reset(void); + void reset(); /** * 从 json 对象中取得某个标签名的第一个节点 @@ -563,7 +561,7 @@ public: * @return {ACL_JSON*} 该值不可能为空,注意用户可以修改该对象的值, * 但不可以释放该对象 */ - ACL_JSON* get_json(void) const; + ACL_JSON* get_json() const; ///////////////////////////////////////////////////////////////////// @@ -677,7 +675,7 @@ public: * 因为在 json 对象被释放时这些节点会自动被释放,当然用户也可以在 * 不用时调用 reset 来释放这些 json_node 节点对象 */ - json_node& create_array_null(void); + json_node& create_array_null(); /** * 创建一个 json_node 节点容器对象,该对象没有标签, @@ -688,7 +686,7 @@ public: * 不用时调用 reset 来释放这些 json_node 节点对象 */ json_node& create_node(bool as_array = false); - json_node& create_array(void); + json_node& create_array(); /** * 创建一个 json_node 节点对象,该节点对象的格式为:tag_name: {} @@ -744,7 +742,7 @@ public: * 获得根节点对象 * @return {json_node&} */ - json_node& get_root(void); + json_node& get_root(); /** * 开始遍历该 json 对象并获得第一个节点 @@ -752,7 +750,7 @@ public: * 注:返回的节点对象用户不能手工释放,因为该对象被 * 内部库自动释放 */ - json_node* first_node(void); + json_node* first_node(); /** * 遍历该 json 对象的下一个 json 节点 @@ -760,7 +758,7 @@ public: * 注:返回的节点对象用户不能手工释放,因为该对象被 * 内部库自动释放 */ - json_node* next_node(void); + json_node* next_node(); /** * 将 json 对象树转成字符串 @@ -781,7 +779,7 @@ public: * 获得内存池对象指针 * @return {dbuf_guard*} */ - dbuf_guard* get_dbuf(void) const { + dbuf_guard* get_dbuf() const { return dbuf_; } @@ -790,7 +788,7 @@ public: virtual int push_pop(const char* in, size_t len, string* out, size_t max = 0); virtual int pop_end(string* out, size_t max = 0); - virtual void clear(void); + virtual void clear(); private: // 内存池管理对象,适合管理大量小内存 diff --git a/lib_acl_cpp/include/acl_cpp/stdlib/string.hpp b/lib_acl_cpp/include/acl_cpp/stdlib/string.hpp index 58e429949..b7dd894cf 100644 --- a/lib_acl_cpp/include/acl_cpp/stdlib/string.hpp +++ b/lib_acl_cpp/include/acl_cpp/stdlib/string.hpp @@ -1369,6 +1369,23 @@ bool operator == (const acl::string& l, const std::string& r); // std::cout << s << std::endl; std::ostream& operator << (std::ostream& o, const acl::string& s); +/** + * 将字符串进行分割 + * @param str {const char*} 待分割的源字符串 + * @param sep {const char*} 分割的字符串,属于该字符串中的任一个字符都可做为分割符 + * @param out {std::vector&} 存储分割后的字符串结果集 + */ +void split(const char* str, const char* sep, std::vector& out); + +/** + * 将字符串进行分割 + * @param str {const char*} 待分割的源字符串 + * @param sep {const char*} 分割的字符串,属于该字符串中的任一个字符都可做为分割符 + * @param out {std::list&} 存储分割后的字符串结果集 + * @return {size_t} 返回分割后结果集中字符串的个数 + */ +size_t split(const char* str, const char* sep, std::list& out); + } // namespce acl #if __cplusplus >= 201103L // Support c++11 ? diff --git a/lib_acl_cpp/include/acl_cpp/stdlib/token_tree.hpp b/lib_acl_cpp/include/acl_cpp/stdlib/token_tree.hpp index c6c031f8b..6f7dd4df1 100644 --- a/lib_acl_cpp/include/acl_cpp/stdlib/token_tree.hpp +++ b/lib_acl_cpp/include/acl_cpp/stdlib/token_tree.hpp @@ -14,27 +14,25 @@ class token_tree; /** * 256 叉匹配树中的节点对象,为纯私有类 */ -class ACL_CPP_API token_node : public noncopyable -{ +class ACL_CPP_API token_node : public noncopyable { public: /** * 获得该节点对应的键值 * @return {const char*} */ - const char* get_key(void) const; + const char* get_key() const; /** * 获得该节点所绑定的对象地址 * @return {void*} */ - void* get_ctx(void) const; + void* get_ctx() const; /** * 获得该节点所属的匹配树对象 * @return {token_tree*} */ - token_tree* get_tree(void) const - { + token_tree* get_tree() const { return tree_; } @@ -42,16 +40,15 @@ public: * 获得 C 版本的节点对象 * @return {ACL_TOKEN*} */ - ACL_TOKEN* get_token(void) const - { + ACL_TOKEN* get_token() const { return me_; } private: friend class token_tree; // 仅允许 token_tree 构造/析构本类对象 - token_node(void); - ~token_node(void); + token_node(); + ~token_node(); void set_node(ACL_TOKEN* token, token_tree* tree); @@ -66,11 +63,10 @@ private: * 256 叉树最大匹配查找算法,该算法具有通用性及非常高的性能(比哈希性能还高), * 通过将字符串映射到 256 叉树上进行匹配查找 */ -class ACL_CPP_API token_tree : public noncopyable -{ +class ACL_CPP_API token_tree : public noncopyable { public: - token_tree(void); - ~token_tree(void); + token_tree(); + ~token_tree(); /** * 添加一个新的项 @@ -129,20 +125,19 @@ public: * 遍历 256 匹配树时需先调用本方法获得第一个节点对象 * @return {token_node*} */ - const token_node* first_node(void); + const token_node* first_node(); /** * 遍历 256 匹配树时需先调用本方法获得下一个节点对象 * @return {token_node*} */ - const token_node* next_node(void); + const token_node* next_node(); /** * 获得 C 版本的 256 叉树对象 * @return {ACL_TOKEN*} */ - ACL_TOKEN* get_tree(void) const - { + ACL_TOKEN* get_tree() const { return tree_; } diff --git a/lib_acl_cpp/include/acl_cpp/stdlib/url_coder.hpp b/lib_acl_cpp/include/acl_cpp/stdlib/url_coder.hpp index 92afa14fc..d1f9b8da7 100644 --- a/lib_acl_cpp/include/acl_cpp/stdlib/url_coder.hpp +++ b/lib_acl_cpp/include/acl_cpp/stdlib/url_coder.hpp @@ -13,8 +13,7 @@ struct URL_NV char* value; }; -class ACL_CPP_API url_coder : public dbuf_obj -{ +class ACL_CPP_API url_coder : public dbuf_obj { public: /** * 构造函数 @@ -30,7 +29,7 @@ public: */ url_coder(const url_coder& coder, dbuf_guard* dbuf = NULL); - ~url_coder(void); + ~url_coder(); /** * 将存储于 params_ 数组中的数据进行 url 编码 @@ -43,7 +42,7 @@ public: * 获得将数组对象转换为编码后的字符串对象 * @return {const string&} */ - const string& to_string(void) const; + const string& to_string() const; /** * 解析以 URL 编码的字符串 @@ -94,8 +93,7 @@ public: * 获得参数数组对象 * @return {std::vector&} */ - const std::vector& get_params(void) const - { + const std::vector& get_params() const { return params_; } @@ -109,7 +107,7 @@ public: /** * 重置解析器状态,清除内部缓存 */ - void reset(void); + void reset(); private: bool nocase_; diff --git a/lib_acl_cpp/src/stdlib/json.cpp b/lib_acl_cpp/src/stdlib/json.cpp index b7ce309db..f25b0a4de 100644 --- a/lib_acl_cpp/src/stdlib/json.cpp +++ b/lib_acl_cpp/src/stdlib/json.cpp @@ -5,8 +5,7 @@ #include "acl_cpp/stdlib/json.hpp" #endif -namespace acl -{ +namespace acl { json_node::json_node(ACL_JSON_NODE* node, json* json_ptr) : node_me_(node) @@ -21,12 +20,12 @@ json_node::json_node(ACL_JSON_NODE* node, json* json_ptr) acl_assert(dbuf_); } -json_node::~json_node(void) +json_node::~json_node() { delete buf_; } -const char* json_node::tag_name(void) const +const char* json_node::tag_name() const { if (node_me_->ltag && ACL_VSTRING_LEN(node_me_->ltag) > 0) { return acl_vstring_str(node_me_->ltag); @@ -35,7 +34,7 @@ const char* json_node::tag_name(void) const } } -const char* json_node::get_text(void) const +const char* json_node::get_text() const { if (node_me_->text) { if (ACL_VSTRING_LEN(node_me_->text) > 0) { @@ -48,7 +47,7 @@ const char* json_node::get_text(void) const } } -json_node* json_node::get_obj(void) const +json_node* json_node::get_obj() const { if (obj_ != NULL) { return obj_; @@ -62,12 +61,12 @@ json_node* json_node::get_obj(void) const return obj_; } -const char* json_node::get_string(void) const +const char* json_node::get_string() const { return get_text(); } -const acl_int64* json_node::get_int64(void) const +const acl_int64* json_node::get_int64() const { if (!is_number()) { return NULL; @@ -80,7 +79,7 @@ const acl_int64* json_node::get_int64(void) const return &node_val_.n; } -const double* json_node::get_double(void) const +const double* json_node::get_double() const { if (!is_double()) { return NULL; @@ -93,7 +92,7 @@ const double* json_node::get_double(void) const return &node_val_.d; } -const bool* json_node::get_bool(void) const +const bool* json_node::get_bool() const { if (!is_bool()) { return NULL; @@ -107,18 +106,18 @@ const bool* json_node::get_bool(void) const return &node_val_.b; } -bool json_node::is_string(void) const +bool json_node::is_string() const { return (node_me_->type & ACL_JSON_T_A_STRING) || (node_me_->type & ACL_JSON_T_STRING); } -bool json_node::is_number(void) const +bool json_node::is_number() const { return is_double(); } -bool json_node::is_double(void) const +bool json_node::is_double() const { return (node_me_->type & ACL_JSON_T_A_DOUBLE) || (node_me_->type & ACL_JSON_T_DOUBLE) || @@ -126,19 +125,19 @@ bool json_node::is_double(void) const (node_me_->type & ACL_JSON_T_NUMBER); } -bool json_node::is_bool(void) const +bool json_node::is_bool() const { return (node_me_->type & ACL_JSON_T_A_BOOL) || (node_me_->type & ACL_JSON_T_BOOL); } -bool json_node::is_null(void) const +bool json_node::is_null() const { return (node_me_->type & ACL_JSON_T_A_NULL) || (node_me_->type & ACL_JSON_T_NULL); } -bool json_node::is_object(void) const +bool json_node::is_object() const { if (node_me_->type & ACL_JSON_T_OBJ) { return true; @@ -156,7 +155,7 @@ bool json_node::is_object(void) const */ } -bool json_node::is_array(void) const +bool json_node::is_array() const { if (node_me_->type & ACL_JSON_T_ARRAY) { return true; @@ -165,7 +164,7 @@ bool json_node::is_array(void) const } } -const char* json_node::get_type(void) const +const char* json_node::get_type() const { if (is_string()) { return "string"; @@ -347,12 +346,12 @@ json_node& json_node::add_array_null(bool return_child /* = false */) return add_child(json_->create_array_null(), return_child); } -int json_node::detach(void) +int json_node::detach() { return acl_json_node_delete(node_me_); } -json_node& json_node::get_parent(void) const +json_node& json_node::get_parent() const { if (parent_) { return *parent_; @@ -367,7 +366,7 @@ json_node& json_node::get_parent(void) const return *parent_; } -json_node* json_node::first_child(void) +json_node* json_node::first_child() { if (iter_ == NULL) { iter_ = (ACL_ITER*) dbuf_->dbuf_alloc(sizeof(ACL_ITER)); @@ -382,7 +381,7 @@ json_node* json_node::first_child(void) return child; } -json_node* json_node::next_child(void) +json_node* json_node::next_child() { acl_assert(iter_); @@ -409,24 +408,24 @@ json_node* json_node::operator[](const char* tag) return NULL; } -int json_node::depth(void) const +int json_node::depth() const { return node_me_->depth; } -int json_node::children_count(void) const +int json_node::children_count() const { return acl_ring_size(&node_me_->children); } -void json_node::clear(void) +void json_node::clear() { if (buf_) { buf_->clear(); } } -json& json_node::get_json(void) const +json& json_node::get_json() const { return *json_; } @@ -498,7 +497,7 @@ const char* json::update(const char* data) return acl_json_update(json_, data); } -bool json::finish(void) +bool json::finish() { return acl_json_finish(json_) == 0 ? false : true; } @@ -581,7 +580,7 @@ json_node* json::getFirstElementByTags(const char* tags) const return node; } -ACL_JSON* json::get_json(void) const +ACL_JSON* json::get_json() const { return json_; } @@ -649,7 +648,7 @@ json_node& json::create_array_bool(bool value) return *n; } -json_node& json::create_array_null(void) +json_node& json::create_array_null() { ACL_JSON_NODE* node = acl_json_create_array_null(json_); json_node* n = dbuf_->create(node, this); @@ -667,7 +666,7 @@ json_node& json::create_node(bool as_array /* = false */) return *n; } -json_node& json::create_array(void) +json_node& json::create_array() { ACL_JSON_NODE* node = acl_json_create_array(json_); json_node* n = dbuf_->create(node, this); @@ -718,7 +717,7 @@ json_node& json::duplicate_node(const json_node& node) return *n; } -json_node& json::get_root(void) +json_node& json::get_root() { if (root_) { root_->node_me_ = json_->root; @@ -728,7 +727,7 @@ json_node& json::get_root(void) return *root_; } -json_node* json::first_node(void) +json_node* json::first_node() { if (iter_ == NULL) { iter_ = (ACL_ITER*) dbuf_->dbuf_alloc(sizeof(ACL_ITER)); @@ -741,7 +740,7 @@ json_node* json::first_node(void) return n; } -json_node* json::next_node(void) +json_node* json::next_node() { acl_assert(iter_); ACL_JSON_NODE* node = json_->iter_next(iter_, json_); @@ -788,7 +787,7 @@ void json::build_json(string& out, bool add_space /* = false */) const (void) acl_json_build(json_, buf); } -void json::reset(void) +void json::reset() { clear(); dbuf_->dbuf_reset(); @@ -818,7 +817,7 @@ int json::pop_end(string* out acl_unused, size_t max /* = 0 */ acl_unused) return 0; } -void json::clear(void) +void json::clear() { if (buf_) { buf_->clear(); diff --git a/lib_acl_cpp/src/stdlib/string.cpp b/lib_acl_cpp/src/stdlib/string.cpp index fa7053059..fa52432a4 100644 --- a/lib_acl_cpp/src/stdlib/string.cpp +++ b/lib_acl_cpp/src/stdlib/string.cpp @@ -1986,4 +1986,50 @@ std::ostream& operator << (std::ostream& o, const acl::string& s) { return o; } +void split(const char* str, const char* sep, std::vector& out) { + const char* ptr = str, *start = str; + while (*ptr) { + if (strchr(sep, (int) (*ptr)) != NULL) { + if (start < ptr) { + size_t n = ptr - start; + std::string buf; + buf.assign(start, n); + out.push_back(buf); + } + start = ptr + 1; + } + ptr++; + } + + if (*start) { + std::string buf = start; + out.push_back(start); + } +} + +size_t split(const char* str, const char* sep, std::list& out) { + size_t cnt = 0; + const char* ptr = str, *start = str; + while (*ptr) { + if (strchr(sep, (int) (*ptr)) != NULL) { + if (start < ptr) { + size_t n = ptr - start; + std::string buf; + buf.assign(start, n); + out.push_back(buf); + cnt++; + } + start = ptr + 1; + } + ptr++; + } + + if (*start) { + out.push_back(start); + cnt++; + } + + return cnt; +} + } // namespace acl diff --git a/lib_acl_cpp/src/stdlib/token_tree.cpp b/lib_acl_cpp/src/stdlib/token_tree.cpp index 6fc61a41c..fd996ace9 100644 --- a/lib_acl_cpp/src/stdlib/token_tree.cpp +++ b/lib_acl_cpp/src/stdlib/token_tree.cpp @@ -3,17 +3,16 @@ #include "acl_cpp/stdlib/token_tree.hpp" #endif -namespace acl -{ +namespace acl { -token_node::token_node(void) +token_node::token_node() : me_(NULL) , tree_(NULL) , dirty_(false) { } -token_node::~token_node(void) {} +token_node::~token_node() {} void token_node::set_node(ACL_TOKEN* token, token_tree* tree) { @@ -22,7 +21,7 @@ void token_node::set_node(ACL_TOKEN* token, token_tree* tree) dirty_ = true; } -const char* token_node::get_key(void) const +const char* token_node::get_key() const { if (me_ == NULL) { return ""; @@ -34,20 +33,20 @@ const char* token_node::get_key(void) const return key_.c_str(); } -void* token_node::get_ctx(void) const +void* token_node::get_ctx() const { return me_->ctx; } ////////////////////////////////////////////////////////////////////////////// -token_tree::token_tree(void) +token_tree::token_tree() : iter_(NULL) { tree_ = acl_token_new(); } -token_tree::~token_tree(void) +token_tree::~token_tree() { acl_token_tree_destroy(tree_); if (iter_) { @@ -105,7 +104,7 @@ void token_tree::free_delimiters_tab(char* delimiters_tab) acl_token_delim_tab_free(delimiters_tab); } -const token_node* token_tree::first_node(void) +const token_node* token_tree::first_node() { if (iter_ == NULL) { iter_ = (ACL_ITER *) acl_mymalloc(sizeof(ACL_ITER)); @@ -119,7 +118,7 @@ const token_node* token_tree::first_node(void) return &node_; } -const token_node* token_tree::next_node(void) +const token_node* token_tree::next_node() { if (iter_ == NULL) { logger_error("call first_node first!"); diff --git a/lib_acl_cpp/src/stdlib/url_coder.cpp b/lib_acl_cpp/src/stdlib/url_coder.cpp index b7ae4bab8..c5de0ea2b 100644 --- a/lib_acl_cpp/src/stdlib/url_coder.cpp +++ b/lib_acl_cpp/src/stdlib/url_coder.cpp @@ -6,8 +6,7 @@ #include "acl_cpp/stdlib/url_coder.hpp" #endif -namespace acl -{ +namespace acl { void url_coder::init_dbuf(dbuf_guard* dbuf) { @@ -42,7 +41,7 @@ url_coder::url_coder(const url_coder& coder, dbuf_guard* dbuf /* = NULL */) } } -url_coder::~url_coder(void) +url_coder::~url_coder() { reset(); @@ -63,7 +62,7 @@ const url_coder& url_coder::operator =(const url_coder& coder) return *this; } -void url_coder::reset(void) +void url_coder::reset() { params_.clear(); buf_->clear(); @@ -96,7 +95,7 @@ void url_coder::encode(string& buf, bool clean /* = true */) const } } -const string& url_coder::to_string(void) const +const string& url_coder::to_string() const { encode(*buf_); return *buf_; From d0a75a384318a0f36230e2ab0b06e9579f15557e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?shuxin=20=E3=80=80=E3=80=80zheng?= Date: Fri, 23 Aug 2024 18:50:47 +0800 Subject: [PATCH 2/4] Json node can be disabled and won't appear in the json string. --- lib_acl/include/json/acl_json.h | 19 +++ lib_acl/src/json/acl_json.c | 39 +++-- lib_acl/src/json/acl_json_util.c | 169 ++++++++++++-------- lib_acl_cpp/include/acl_cpp/stdlib/json.hpp | 13 ++ lib_acl_cpp/src/stdlib/json.cpp | 10 ++ 5 files changed, 173 insertions(+), 77 deletions(-) diff --git a/lib_acl/include/json/acl_json.h b/lib_acl/include/json/acl_json.h index 591ed93fe..cacf09dc6 100644 --- a/lib_acl/include/json/acl_json.h +++ b/lib_acl/include/json/acl_json.h @@ -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 节点 diff --git a/lib_acl/src/json/acl_json.c b/lib_acl/src/json/acl_json.c index 1314660bf..71315fab6 100644 --- a/lib_acl/src/json/acl_json.c +++ b/lib_acl/src/json/acl_json.c @@ -1,5 +1,4 @@ #include "StdAfx.h" -#include #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 diff --git a/lib_acl/src/json/acl_json_util.c b/lib_acl/src/json/acl_json_util.c index 0c11c2c96..c0cf093cf 100644 --- a/lib_acl/src/json/acl_json_util.c +++ b/lib_acl/src/json/acl_json_util.c @@ -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); diff --git a/lib_acl_cpp/include/acl_cpp/stdlib/json.hpp b/lib_acl_cpp/include/acl_cpp/stdlib/json.hpp index f46b51450..d17895d5a 100644 --- a/lib_acl_cpp/include/acl_cpp/stdlib/json.hpp +++ b/lib_acl_cpp/include/acl_cpp/stdlib/json.hpp @@ -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, diff --git a/lib_acl_cpp/src/stdlib/json.cpp b/lib_acl_cpp/src/stdlib/json.cpp index f25b0a4de..22f81c53b 100644 --- a/lib_acl_cpp/src/stdlib/json.cpp +++ b/lib_acl_cpp/src/stdlib/json.cpp @@ -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_) { From 5a234d4244421e18654c891d965742c3250b512c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?shuxin=20=E3=80=80=E3=80=80zheng?= Date: Fri, 23 Aug 2024 18:52:00 +0800 Subject: [PATCH 3/4] Add json test for testing disable json node. --- lib_acl/samples/json/json7/Makefile | 3 + lib_acl/samples/json/json7/json.txt | 33 ++++++ lib_acl/samples/json/json7/json1.txt | 8 ++ lib_acl/samples/json/json7/json2.txt | 27 +++++ lib_acl/samples/json/json7/main.cpp | 88 +++++++++++++++ lib_acl/samples/json/json7/t.sh | 144 +++++++++++++++++++++++++ lib_acl/samples/json/json7/t1.sh | 32 ++++++ lib_acl/samples/json/json7/valgrind.sh | 3 + 8 files changed, 338 insertions(+) create mode 100644 lib_acl/samples/json/json7/Makefile create mode 100644 lib_acl/samples/json/json7/json.txt create mode 100644 lib_acl/samples/json/json7/json1.txt create mode 100644 lib_acl/samples/json/json7/json2.txt create mode 100644 lib_acl/samples/json/json7/main.cpp create mode 100755 lib_acl/samples/json/json7/t.sh create mode 100755 lib_acl/samples/json/json7/t1.sh create mode 100644 lib_acl/samples/json/json7/valgrind.sh diff --git a/lib_acl/samples/json/json7/Makefile b/lib_acl/samples/json/json7/Makefile new file mode 100644 index 000000000..b450acf6c --- /dev/null +++ b/lib_acl/samples/json/json7/Makefile @@ -0,0 +1,3 @@ +base_path = ../../.. +include ../../Makefile_cpp.in +PROG = json diff --git a/lib_acl/samples/json/json7/json.txt b/lib_acl/samples/json/json7/json.txt new file mode 100644 index 000000000..9520890db --- /dev/null +++ b/lib_acl/samples/json/json7/json.txt @@ -0,0 +1,33 @@ +{ + "name1": "value1", + "name3": "value3", + "name4": "value4", + "name5": [ "value51", "value52", "value53" ], + "name6": "value6", + "name7": { "name71": "value71", "name72": "value72", "name73": "value73" }, + "name8": "value8", + "name10": "value10", + "name11": { + "name111": { + "name1111": "value1111", + "name1112": "value1112", + "name1113": "value1113" }, + "name112": "value112", + "name113": [ + {"name1131": "value1131"}, + {"name1132": "value1132"}, + {"name1133": "value1133"} + ], + "name114": "value114", + "name116": "value116", + "name117": { "name1171":{ "name11711": { "name117111": "value11711" }}}, + "name118": "value118", + "name119": { + "name1191":{ + "name11911": { "name119111": "value11911"}, + "name11912": [{ "name119121": "value119121" }, { "name119122": "value119122" }] + } + }, + "name1110": "value1110" + } +} diff --git a/lib_acl/samples/json/json7/json1.txt b/lib_acl/samples/json/json7/json1.txt new file mode 100644 index 000000000..1f8f5d29c --- /dev/null +++ b/lib_acl/samples/json/json7/json1.txt @@ -0,0 +1,8 @@ +{ + "name113": [ + {"name1131": "value1131"}, + {"name1132": "value1132"}, + {"name1133": "value1133"} + ], + "name117": { "name1171":{ "name11711": { "name117111": "value11711" }}} +} diff --git a/lib_acl/samples/json/json7/json2.txt b/lib_acl/samples/json/json7/json2.txt new file mode 100644 index 000000000..a98eb705f --- /dev/null +++ b/lib_acl/samples/json/json7/json2.txt @@ -0,0 +1,27 @@ +{ "menu name": { + "file": "file", + "value": "File", + "popup": { + "menuitem1": [ + {"value": "New1", "onclick": "CreateNewDoc"}, + {"value": "Open1", "onclick": "OpenDoc"}, + {"value": "Close1", "onclick": "CloseDoc"} + ], + "menuname": "hello world", + "inner": { "value" : "new2", "value" : "open2"}, + "menuitem2": [ + {"value": "New3", "onclick": "CreateNewDoc"}, + {"value": "Open3", "onclick": "OpenDoc"}, + {"value": "Close3", "onclick": "CloseDoc"}, + {"value": "Help3", "onclick": "Help"} + ] + } + }, + "help": "hello world", + "menuitem2": [ + {"value": "New4", "onclick": "CreateNewDoc"}, + {"value": "Open4", "onclick": "OpenDoc"}, + {"value": "Close4", "onclick": "CloseDoc"}, + [{"value": "Save4", "onclick": "SaveDoc"}] + ] +} diff --git a/lib_acl/samples/json/json7/main.cpp b/lib_acl/samples/json/json7/main.cpp new file mode 100644 index 000000000..10d039785 --- /dev/null +++ b/lib_acl/samples/json/json7/main.cpp @@ -0,0 +1,88 @@ +#include +#include +#include +#include "lib_acl.h" + +static void test_json(const char *data, const char *name) +{ + ACL_JSON *json = acl_json_alloc(); + ACL_VSTRING *buf = acl_vstring_alloc(1024); + ACL_ITER iter; + + acl_json_update(json, data); + + if (!acl_json_finish(json)) { + printf("Invalid json!\r\n"); + return; + } + +#define STR acl_vstring_str +#define LEN ACL_VSTRING_LEN +#define EQ !strcmp + + acl_foreach(iter, json) { + ACL_JSON_NODE* node = (ACL_JSON_NODE*) iter.data; + if (LEN(node->ltag) == 0) { + continue; + } + + if (EQ(STR(node->ltag), name)) { + acl_json_node_disable(node, 1); + } + } + + acl_json_build(json, buf); + printf("%s\r\n", STR(buf)); + acl_json_free(json); + acl_vstring_free(buf); +} + +static void usage(const char *procname) +{ + printf("usage: %s -h [help] -f filename -n tag_name\r\n", procname); +} + +int main(int argc, char *argv[]) +{ + char name[256], filename[256], *data; + int ch; + + snprintf(name, sizeof(name), "name"); + snprintf(filename, sizeof(filename), "json.txt"); + + while ((ch = getopt(argc, argv, "hf:n:")) > 0) { + switch (ch) { + case 'h': + usage(argv[0]); + return 0; + case 'f': + snprintf(filename, sizeof(filename), "%s", optarg); + break; + case 'n': + snprintf(name, sizeof(name), "%s", optarg); + break; + default: + break; + } + } + + if (name[0] == 0 || filename[0] == 0) { + usage(argv[0]); + return 0; + } + + data = acl_vstream_loadfile(filename); + if (data == NULL || *data == 0) { + printf("load %s error %s\r\n", filename, acl_last_serror()); + return 1; + } + + test_json(data, name); + acl_myfree(data); + +#ifdef WIN32 + getchar(); +#endif + + return (0); +} diff --git a/lib_acl/samples/json/json7/t.sh b/lib_acl/samples/json/json7/t.sh new file mode 100755 index 000000000..1a2f0058f --- /dev/null +++ b/lib_acl/samples/json/json7/t.sh @@ -0,0 +1,144 @@ +#!/bin/sh + +./json -n name1|jq +echo "------------------------name1-------------------------------------------" + +read ch +./json -n name3|jq +echo "------------------------name3-------------------------------------------" + +read ch +./json -n name4|jq +echo "------------------------name4-------------------------------------------" + +read ch +./json -n name5|jq +echo "------------------------name5-------------------------------------------" + +read ch +./json -n name6|jq +echo "------------------------name6-------------------------------------------" + +read ch +./json -n name7|jq +echo "------------------------name7-------------------------------------------" + +read ch +./json -n name71|jq +echo "------------------------name71------------------------------------------" + +read ch +./json -n name72|jq +echo "------------------------name72------------------------------------------" + +read ch +./json -n name73|jq +echo "------------------------name73------------------------------------------" + +read ch +./json -n name8|jq +echo "------------------------name8-------------------------------------------" + +read ch +./json -n name10|jq +echo "------------------------name10------------------------------------------" + +read ch +./json -n name11|jq +echo "------------------------name11------------------------------------------" + +read ch +./json -n name111|jq +echo "------------------------name111-----------------------------------------" + +read ch +./json -n name1111|jq +echo "------------------------name1111----------------------------------------" + +read ch +./json -n name1112|jq +echo "------------------------name1112----------------------------------------" + +read ch +./json -n name1113|jq +echo "------------------------name1113----------------------------------------" + +read ch +./json -n name112|jq +echo "------------------------name112-----------------------------------------" + +read ch +./json -n name113|jq +echo "------------------------name113-----------------------------------------" + +read ch +./json -n name1131|jq +echo "------------------------name1131----------------------------------------" + +read ch +./json -n name1132|jq +echo "------------------------name1132----------------------------------------" + +read ch +./json -n name1133|jq +echo "------------------------name1133----------------------------------------" + +read ch +./json -n name114|jq +echo "------------------------name114-----------------------------------------" + +read ch +./json -n name116|jq +echo "------------------------name116-----------------------------------------" + +read ch +./json -n name117|jq +echo "------------------------name117-----------------------------------------" + +read ch +./json -n name1171|jq +echo "------------------------name1171----------------------------------------" + +read ch +./json -n name11711|jq +echo "------------------------name11711---------------------------------------" + +read ch +./json -n name118|jq +echo "------------------------name118-----------------------------------------" + +read ch +./json -n name119|jq +echo "------------------------name119-----------------------------------------" + +read ch +./json -n name1191|jq +echo "------------------------name1191----------------------------------------" + +read ch +./json -n name11911|jq +echo "------------------------name11911---------------------------------------" + +read ch +./json -n name119111|jq +echo "------------------------name119111--------------------------------------" + +read ch +./json -n name11912|jq +echo "------------------------name11912---------------------------------------" + +read ch +./json -n name119121|jq +echo "------------------------name119121--------------------------------------" + +read ch +./json -n name119122|jq +echo "------------------------name119122--------------------------------------" + +read ch +./json -n name1110|jq +echo "------------------------name1110----------------------------------------" + +read ch +./json -n name1111|jq +echo "------------------------name1111----------------------------------------" diff --git a/lib_acl/samples/json/json7/t1.sh b/lib_acl/samples/json/json7/t1.sh new file mode 100755 index 000000000..8123f37d1 --- /dev/null +++ b/lib_acl/samples/json/json7/t1.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +./json -f json1.txt -n name113|jq +echo "------------------------name113-----------------------------------------" + +read ch +./json -f json1.txt -n name1131|jq +echo "------------------------name1131----------------------------------------" + +read ch +./json -f json1.txt -n name1132|jq +echo "------------------------name1132----------------------------------------" + +read ch +./json -f json1.txt -n name1133|jq +echo "------------------------name1133----------------------------------------" + +read ch +./json -f json1.txt -n name117|jq +echo "------------------------name117-----------------------------------------" + +read ch +./json -f json1.txt -n name1171|jq +echo "------------------------name1171-----------------------------------------" + +read ch +./json -f json1.txt -n name11711|jq +echo "------------------------name11711----------------------------------------" + +read ch +./json -f json1.txt -n name117111|jq +echo "------------------------name117111---------------------------------------" diff --git a/lib_acl/samples/json/json7/valgrind.sh b/lib_acl/samples/json/json7/valgrind.sh new file mode 100644 index 000000000..af5f0c6e2 --- /dev/null +++ b/lib_acl/samples/json/json7/valgrind.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +valgrind --tool=memcheck --leak-check=yes -v ./json From db529f4ca5e26feb41f9cf9e784eb780f5e81e60 Mon Sep 17 00:00:00 2001 From: zhengshuxin Date: Sat, 24 Aug 2024 22:30:56 +0800 Subject: [PATCH 4/4] Json node can be removed when walling through the json tree. --- lib_acl/include/json/acl_json.h | 28 +++- lib_acl/samples/json/json7/json1.txt | 7 +- lib_acl/samples/json/json7/main.cpp | 20 ++- lib_acl/samples/json/json7/t1.sh | 46 ++++++- lib_acl/src/json/acl_json.c | 73 +++++++++- lib_acl_cpp/include/acl_cpp/stdlib/json.hpp | 15 ++ lib_acl_cpp/samples/json/json15/Makefile | 3 + lib_acl_cpp/samples/json/json15/json.cpp | 86 ++++++++++++ lib_acl_cpp/samples/json/json15/json.txt | 33 +++++ lib_acl_cpp/samples/json/json15/json1.txt | 13 ++ lib_acl_cpp/samples/json/json15/json2.txt | 27 ++++ lib_acl_cpp/samples/json/json15/json3.txt | 5 + lib_acl_cpp/samples/json/json15/json4.txt | 3 + lib_acl_cpp/samples/json/json15/r.sh | 144 ++++++++++++++++++++ lib_acl_cpp/samples/json/json15/stdafx.cpp | 8 ++ lib_acl_cpp/samples/json/json15/stdafx.h | 41 ++++++ lib_acl_cpp/samples/json/json15/t.sh | 144 ++++++++++++++++++++ lib_acl_cpp/samples/json/json15/t1.sh | 72 ++++++++++ lib_acl_cpp/samples/json/json15/t3.sh | 12 ++ lib_acl_cpp/samples/json/json15/valgrind.sh | 3 + lib_acl_cpp/src/stdlib/json.cpp | 38 +++++- 21 files changed, 800 insertions(+), 21 deletions(-) create mode 100644 lib_acl_cpp/samples/json/json15/Makefile create mode 100644 lib_acl_cpp/samples/json/json15/json.cpp create mode 100644 lib_acl_cpp/samples/json/json15/json.txt create mode 100644 lib_acl_cpp/samples/json/json15/json1.txt create mode 100644 lib_acl_cpp/samples/json/json15/json2.txt create mode 100644 lib_acl_cpp/samples/json/json15/json3.txt create mode 100644 lib_acl_cpp/samples/json/json15/json4.txt create mode 100755 lib_acl_cpp/samples/json/json15/r.sh create mode 100644 lib_acl_cpp/samples/json/json15/stdafx.cpp create mode 100644 lib_acl_cpp/samples/json/json15/stdafx.h create mode 100755 lib_acl_cpp/samples/json/json15/t.sh create mode 100755 lib_acl_cpp/samples/json/json15/t1.sh create mode 100755 lib_acl_cpp/samples/json/json15/t3.sh create mode 100644 lib_acl_cpp/samples/json/json15/valgrind.sh diff --git a/lib_acl/include/json/acl_json.h b/lib_acl/include/json/acl_json.h index cacf09dc6..d1b8f5e0e 100644 --- a/lib_acl/include/json/acl_json.h +++ b/lib_acl/include/json/acl_json.h @@ -130,6 +130,20 @@ 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 节点 + * @param node {ACL_JSON_NODE*} json 节点 +* @return {ACL_JSON_NODE*} 返回的下一个 json 节点 + */ +ACL_API ACL_JSON_NODE *acl_json_node_erase(ACL_JSON_NODE *node, ACL_ITER *it); + +/** + * 从当前的 json 节点中删除反向迭代器节点,并返回下一个 json 节点 + * @param node {ACL_JSON_NODE*} json 节点 +* @return {ACL_JSON_NODE*} 返回的前一个 json 节点 + */ +ACL_API ACL_JSON_NODE *acl_json_node_rerase(ACL_JSON_NODE *node, ACL_ITER *it); + /** * 禁止/启用某个 json 节点,被禁止的节点在构造 json 字符串时将不被添加,但在遍历 json 时 * 却可以被获得,以方便再次将其启用 @@ -157,8 +171,7 @@ ACL_API void acl_json_node_append(ACL_JSON_NODE *node1, ACL_JSON_NODE *node2); * @param parent {ACL_JSON_NODE*} 父节点 * @param child {ACL_JSON_NODE*} 子节点 */ -ACL_API void acl_json_node_add_child( - ACL_JSON_NODE *parent, ACL_JSON_NODE *child); +ACL_API void acl_json_node_add_child(ACL_JSON_NODE *parent, ACL_JSON_NODE *child); /** * 将一个 JSON 对象的 JSON 节点复制至 JSON 对象中的一个 JSON 节点中,并返回 @@ -167,8 +180,7 @@ ACL_API void acl_json_node_add_child( * @param from {ACL_JSON_NODE*} 源 JSON 对象的一个 JSON 节点 * @return {ACL_JSON_NODE*} 返回非空对象指针 */ -ACL_API ACL_JSON_NODE *acl_json_node_duplicate( - ACL_JSON *json, ACL_JSON_NODE *from); +ACL_API ACL_JSON_NODE *acl_json_node_duplicate(ACL_JSON *json, ACL_JSON_NODE *from); /** * 获得某个 json 节点的父节点 @@ -191,6 +203,14 @@ ACL_API ACL_JSON_NODE *acl_json_node_next(ACL_JSON_NODE *node); */ ACL_API ACL_JSON_NODE *acl_json_node_prev(ACL_JSON_NODE *node); +/** + * 在遍历 Json 对象过程中,删除当前迭代器指向的 json 节点并返回下一个 json 节点 + * @param json {ACL_JSON*} json 对象 + * @param it {ACL_ITER*} 遍历 json 对象的迭代器 + * @return {ACL_JSON_NODE*} 返回下一个 json 节点 + */ +ACL_API ACL_JSON_NODE *acl_json_erase(ACL_JSON *json, ACL_ITER *it); + /** * 创建一个 json 对象 * @return {ACL_JSON*} 新创建的 json 对象 diff --git a/lib_acl/samples/json/json7/json1.txt b/lib_acl/samples/json/json7/json1.txt index 1f8f5d29c..6bae3a466 100644 --- a/lib_acl/samples/json/json7/json1.txt +++ b/lib_acl/samples/json/json7/json1.txt @@ -4,5 +4,10 @@ {"name1132": "value1132"}, {"name1133": "value1133"} ], - "name117": { "name1171":{ "name11711": { "name117111": "value11711" }}} + "name117": { "name1171":{ "name11711": { "name117111": "value11711" }}}, + "name118": [ + { "name1181": { "name11811": "value11811", "name11812": "value11812", "name11813": "value11813" }}, + { "name1182": "value1182" }, + { "name1183": "value1183" } + ] } diff --git a/lib_acl/samples/json/json7/main.cpp b/lib_acl/samples/json/json7/main.cpp index 10d039785..abd36ba53 100644 --- a/lib_acl/samples/json/json7/main.cpp +++ b/lib_acl/samples/json/json7/main.cpp @@ -3,11 +3,11 @@ #include #include "lib_acl.h" -static void test_json(const char *data, const char *name) +static void test_json(const char *data, ACL_ARGV *names) { ACL_JSON *json = acl_json_alloc(); ACL_VSTRING *buf = acl_vstring_alloc(1024); - ACL_ITER iter; + ACL_ITER iter, iter2; acl_json_update(json, data); @@ -26,8 +26,11 @@ static void test_json(const char *data, const char *name) continue; } - if (EQ(STR(node->ltag), name)) { - acl_json_node_disable(node, 1); + acl_foreach(iter2, names) { + const char *name = (const char*) iter2.data; + if (EQ(STR(node->ltag), name)) { + acl_json_node_disable(node, 1); + } } } @@ -39,12 +42,13 @@ static void test_json(const char *data, const char *name) static void usage(const char *procname) { - printf("usage: %s -h [help] -f filename -n tag_name\r\n", procname); + printf("usage: %s -h [help] -f filename -n tag_names\r\n", procname); } int main(int argc, char *argv[]) { - char name[256], filename[256], *data; + ACL_ARGV *names; + char name[512], filename[256], *data; int ch; snprintf(name, sizeof(name), "name"); @@ -77,7 +81,9 @@ int main(int argc, char *argv[]) return 1; } - test_json(data, name); + names = acl_argv_split(name, ",; \t"); + test_json(data, names); + acl_argv_free(names); acl_myfree(data); #ifdef WIN32 diff --git a/lib_acl/samples/json/json7/t1.sh b/lib_acl/samples/json/json7/t1.sh index 8123f37d1..527ae4286 100755 --- a/lib_acl/samples/json/json7/t1.sh +++ b/lib_acl/samples/json/json7/t1.sh @@ -21,12 +21,52 @@ echo "------------------------name117-----------------------------------------" read ch ./json -f json1.txt -n name1171|jq -echo "------------------------name1171-----------------------------------------" +echo "------------------------name1171----------------------------------------" read ch ./json -f json1.txt -n name11711|jq -echo "------------------------name11711----------------------------------------" +echo "------------------------name11711---------------------------------------" read ch ./json -f json1.txt -n name117111|jq -echo "------------------------name117111---------------------------------------" +echo "------------------------name117111--------------------------------------" + +read ch +./json -f json1.txt -n "name1131,name117111"|jq +echo "------------------------name1131,name117111-----------------------------" + +read ch +./json -f json1.txt -n "name1131,name1132"|jq +echo "------------------------name1131,name1132-------------------------------" + +read ch +./json -f json1.txt -n "name118"|jq +echo "------------------------name118-----------------------------------------" + +read ch +./json -f json1.txt -n "name1181"|jq +echo "------------------------name1181----------------------------------------" + +read ch +./json -f json1.txt -n "name1182"|jq +echo "------------------------name1183----------------------------------------" + +read ch +./json -f json1.txt -n "name1183"|jq +echo "------------------------name1183----------------------------------------" + +read ch +./json -f json1.txt -n "name1181,name1182"|jq +echo "------------------------name1181,name1182-------------------------------" + +read ch +./json -f json1.txt -n "name1181,name1183"|jq +echo "------------------------name1181,name1183-------------------------------" + +read ch +./json -f json1.txt -n "name1183,name1182"|jq +echo "------------------------name1183,name1182-------------------------------" + +read ch +./json -f json1.txt -n "name1181,name1182,name1183"|jq +echo "------------------------name1181,name1182,name1183----------------------" diff --git a/lib_acl/src/json/acl_json.c b/lib_acl/src/json/acl_json.c index 71315fab6..837aa01e9 100644 --- a/lib_acl/src/json/acl_json.c +++ b/lib_acl/src/json/acl_json.c @@ -133,6 +133,26 @@ int acl_json_node_delete(ACL_JSON_NODE *node) return n; } +ACL_JSON_NODE *acl_json_node_erase(ACL_JSON_NODE *node, ACL_ITER *it) +{ + ACL_JSON_NODE *curr = (ACL_JSON_NODE*) it->data; + ACL_JSON_NODE *next = node->iter_next(it, node); + if (curr) { + acl_json_node_delete(curr); + } + return next; +} + +ACL_JSON_NODE *acl_json_node_rerase(ACL_JSON_NODE *node, ACL_ITER *it) +{ + ACL_JSON_NODE *curr = (ACL_JSON_NODE*) it->data; + ACL_JSON_NODE *next = node->iter_prev(it, node); + if (curr) { + acl_json_node_delete(curr); + } + return next; +} + void acl_json_node_disable(ACL_JSON_NODE *node, int yes) { node->disabled = yes ? 1 : (unsigned) 0; @@ -181,8 +201,9 @@ ACL_JSON_NODE *acl_json_node_prev(ACL_JSON_NODE *node) ACL_RING *ring_ptr = acl_ring_pred(&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) { @@ -247,7 +268,6 @@ static ACL_JSON_NODE *json_iter_next(ACL_ITER *it, ACL_JSON *json) } /* 当前节点的兄弟节点遍历完毕,最后遍历当前节点的父节点的兄弟节点 */ - do { if (parent == json->root) { break; @@ -255,8 +275,9 @@ static ACL_JSON_NODE *json_iter_next(ACL_ITER *it, ACL_JSON *json) ring_ptr = acl_ring_succ(&parent->node); parent = acl_json_node_parent(parent); - if (parent == NULL) + if (parent == NULL) { acl_msg_fatal("%s(%d): parent null", __FILE__, __LINE__); + } if (ring_ptr != &parent->children) { it->i++; @@ -267,7 +288,6 @@ static ACL_JSON_NODE *json_iter_next(ACL_ITER *it, ACL_JSON *json) } while (ring_ptr != &json->root->children); /* 遍历完所有节点 */ - it->ptr = it->data = NULL; return NULL; } @@ -346,6 +366,51 @@ static ACL_JSON_NODE *json_iter_prev(ACL_ITER *it, ACL_JSON *json) return NULL; } +ACL_JSON_NODE *acl_json_erase(ACL_JSON *json, ACL_ITER *it) +{ + ACL_RING *ring_ptr; + ACL_JSON_NODE *node, *parent; + + node = (ACL_JSON_NODE*) it->data; + parent = acl_json_node_parent(node); + + /* 查找当前节点的下一个兄弟节点 */ + ring_ptr = acl_ring_succ(&node->node); + if (ring_ptr != &parent->children) { + it->i++; + it->ptr = acl_ring_to_appl(ring_ptr, ACL_JSON_NODE, node); + it->data = it->ptr; + acl_json_node_delete(node); /* 从 json 中删除当前节点 */ + return it->ptr; + } + + acl_json_node_delete(node); /* 从 json 中删除当前节点 */ + + /* 当前节点的兄弟节点遍历完毕,最后遍历当前节点的父节点的兄弟节点 */ + do { + if (parent == json->root) { + break; + } + + ring_ptr = acl_ring_succ(&parent->node); + parent = acl_json_node_parent(parent); + if (parent == NULL) { + acl_msg_fatal("%s(%d): parent null", __FILE__, __LINE__); + } + + if (ring_ptr != &parent->children) { + it->i++; + it->ptr = acl_ring_to_appl(ring_ptr, ACL_JSON_NODE, node); + it->data = it->ptr; + return it->ptr; + } + } while (ring_ptr != &json->root->children); + + /* 遍历完所有节点 */ + it->ptr = it->data = NULL; + return NULL; +} + ACL_JSON *acl_json_alloc(void) { return acl_json_dbuf_alloc(NULL); diff --git a/lib_acl_cpp/include/acl_cpp/stdlib/json.hpp b/lib_acl_cpp/include/acl_cpp/stdlib/json.hpp index d17895d5a..216e64976 100644 --- a/lib_acl_cpp/include/acl_cpp/stdlib/json.hpp +++ b/lib_acl_cpp/include/acl_cpp/stdlib/json.hpp @@ -349,6 +349,14 @@ public: */ json_node* next_child(); + /** + * 在遍历子节点过程中删除释放指定的子节点,并返回下一个子节点 + * @param child {json_node*} 遍历过程中调用 first_child/next_child/remove_child + * 时返回的当前 json 节点的子节点,该节点将被从 Json 对象中删除并释放 + * @return {json_node*} 返回当前节点的下一个子节点 + */ + json_node* free_child(json_node* child); + /** * 从当前 json 节点的子节点中提取对应标签的 json 子节点 * @param tag {const char*} json 子节点的标签名 @@ -773,6 +781,13 @@ public: */ json_node* next_node(); + /** + * 在遍历过程通过本函数删除当前遍历到的 json 节点,并返回下一个 json 节点 + * @param curr {json_node*} 由 first_node/next_node/free_node 返回的节点 + * @return {json_node*} 返回下一个 json 节点 + */ + json_node* free_node(json_node* curr); + /** * 将 json 对象树转成字符串 * @param out {string&} 存储转换结果的缓冲区 diff --git a/lib_acl_cpp/samples/json/json15/Makefile b/lib_acl_cpp/samples/json/json15/Makefile new file mode 100644 index 000000000..581b437de --- /dev/null +++ b/lib_acl_cpp/samples/json/json15/Makefile @@ -0,0 +1,3 @@ +base_path = ../../.. +PROG = json +include ../../Makefile.in diff --git a/lib_acl_cpp/samples/json/json15/json.cpp b/lib_acl_cpp/samples/json/json15/json.cpp new file mode 100644 index 000000000..1053dbd23 --- /dev/null +++ b/lib_acl_cpp/samples/json/json15/json.cpp @@ -0,0 +1,86 @@ +#include "stdafx.h" +#include + +static bool matched(const std::vector& tokens, const char* name) { + for (std::vector::const_iterator cit = tokens.begin(); + cit != tokens.end(); ++cit) { + if (*cit == name) { + return true; + } + } + + return false; +} + +static void usage(const char* procname) { + printf("usage: %s -h [help[ -f json_file -n names -D [remove if matched]\r\n", procname); +} + +int main(int argc, char* argv[]) { + acl::string file; + acl::string names; + bool use_remove = false; + int ch; + + while ((ch = getopt(argc, argv, "hf:n:D")) > 0) { + switch (ch) { + case 'h': + usage(argv[0]); + return 0; + case 'f': + file = optarg; + break; + case 'n': + names = optarg; + break; + case 'D': + use_remove = true; + break; + default: + break; + } + } + + if (file.empty() || names.empty()) { + usage(argv[0]); + return 1; + } + + acl::string buf; + if (!acl::ifstream::load(file, &buf)) { + printf("load %s error %s\r\n", file.c_str(), acl::last_serror()); + return 1; + } + + std::vector tokens; + acl::split(names.c_str(), ",; \t", tokens); + + acl::json json(buf); + if (!json.finish()) { + printf("invalid json: %s\r\n", buf.c_str()); + return 1; + } + + acl::json_node* node = json.first_node(); + while (node) { + const char* tag = node->tag_name(); + if (tag == NULL || *tag == 0) { + node = json.next_node(); + continue; + } + + if (matched(tokens, tag)) { + if (use_remove) { + node = json.free_node(node); + } else { + node->disable(true); + node = json.next_node(); + } + } else { + node = json.next_node(); + } + } + + printf("%s\r\n", json.to_string(NULL, true).c_str()); + return 0; +} diff --git a/lib_acl_cpp/samples/json/json15/json.txt b/lib_acl_cpp/samples/json/json15/json.txt new file mode 100644 index 000000000..9520890db --- /dev/null +++ b/lib_acl_cpp/samples/json/json15/json.txt @@ -0,0 +1,33 @@ +{ + "name1": "value1", + "name3": "value3", + "name4": "value4", + "name5": [ "value51", "value52", "value53" ], + "name6": "value6", + "name7": { "name71": "value71", "name72": "value72", "name73": "value73" }, + "name8": "value8", + "name10": "value10", + "name11": { + "name111": { + "name1111": "value1111", + "name1112": "value1112", + "name1113": "value1113" }, + "name112": "value112", + "name113": [ + {"name1131": "value1131"}, + {"name1132": "value1132"}, + {"name1133": "value1133"} + ], + "name114": "value114", + "name116": "value116", + "name117": { "name1171":{ "name11711": { "name117111": "value11711" }}}, + "name118": "value118", + "name119": { + "name1191":{ + "name11911": { "name119111": "value11911"}, + "name11912": [{ "name119121": "value119121" }, { "name119122": "value119122" }] + } + }, + "name1110": "value1110" + } +} diff --git a/lib_acl_cpp/samples/json/json15/json1.txt b/lib_acl_cpp/samples/json/json15/json1.txt new file mode 100644 index 000000000..6bae3a466 --- /dev/null +++ b/lib_acl_cpp/samples/json/json15/json1.txt @@ -0,0 +1,13 @@ +{ + "name113": [ + {"name1131": "value1131"}, + {"name1132": "value1132"}, + {"name1133": "value1133"} + ], + "name117": { "name1171":{ "name11711": { "name117111": "value11711" }}}, + "name118": [ + { "name1181": { "name11811": "value11811", "name11812": "value11812", "name11813": "value11813" }}, + { "name1182": "value1182" }, + { "name1183": "value1183" } + ] +} diff --git a/lib_acl_cpp/samples/json/json15/json2.txt b/lib_acl_cpp/samples/json/json15/json2.txt new file mode 100644 index 000000000..a98eb705f --- /dev/null +++ b/lib_acl_cpp/samples/json/json15/json2.txt @@ -0,0 +1,27 @@ +{ "menu name": { + "file": "file", + "value": "File", + "popup": { + "menuitem1": [ + {"value": "New1", "onclick": "CreateNewDoc"}, + {"value": "Open1", "onclick": "OpenDoc"}, + {"value": "Close1", "onclick": "CloseDoc"} + ], + "menuname": "hello world", + "inner": { "value" : "new2", "value" : "open2"}, + "menuitem2": [ + {"value": "New3", "onclick": "CreateNewDoc"}, + {"value": "Open3", "onclick": "OpenDoc"}, + {"value": "Close3", "onclick": "CloseDoc"}, + {"value": "Help3", "onclick": "Help"} + ] + } + }, + "help": "hello world", + "menuitem2": [ + {"value": "New4", "onclick": "CreateNewDoc"}, + {"value": "Open4", "onclick": "OpenDoc"}, + {"value": "Close4", "onclick": "CloseDoc"}, + [{"value": "Save4", "onclick": "SaveDoc"}] + ] +} diff --git a/lib_acl_cpp/samples/json/json15/json3.txt b/lib_acl_cpp/samples/json/json15/json3.txt new file mode 100644 index 000000000..437feb084 --- /dev/null +++ b/lib_acl_cpp/samples/json/json15/json3.txt @@ -0,0 +1,5 @@ +[ + { "name1": "value1" }, + { "name2": "value2" }, + { "name3": "value3" } +] diff --git a/lib_acl_cpp/samples/json/json15/json4.txt b/lib_acl_cpp/samples/json/json15/json4.txt new file mode 100644 index 000000000..e905d15f5 --- /dev/null +++ b/lib_acl_cpp/samples/json/json15/json4.txt @@ -0,0 +1,3 @@ +[ + {}, {}, {} +] diff --git a/lib_acl_cpp/samples/json/json15/r.sh b/lib_acl_cpp/samples/json/json15/r.sh new file mode 100755 index 000000000..e72b99386 --- /dev/null +++ b/lib_acl_cpp/samples/json/json15/r.sh @@ -0,0 +1,144 @@ +#!/bin/sh + +./json -D -f json.txt -n name1|jq +echo "------------------------name1-------------------------------------------" + +read ch +./json -D -f json.txt -n name3|jq +echo "------------------------name3-------------------------------------------" + +read ch +./json -D -f json.txt -n name4|jq +echo "------------------------name4-------------------------------------------" + +read ch +./json -D -f json.txt -n name5|jq +echo "------------------------name5-------------------------------------------" + +read ch +./json -D -f json.txt -n name6|jq +echo "------------------------name6-------------------------------------------" + +read ch +./json -D -f json.txt -n name7|jq +echo "------------------------name7-------------------------------------------" + +read ch +./json -D -f json.txt -n name71|jq +echo "------------------------name71------------------------------------------" + +read ch +./json -D -f json.txt -n name72|jq +echo "------------------------name72------------------------------------------" + +read ch +./json -D -f json.txt -n name73|jq +echo "------------------------name73------------------------------------------" + +read ch +./json -D -f json.txt -n name8|jq +echo "------------------------name8-------------------------------------------" + +read ch +./json -D -f json.txt -n name10|jq +echo "------------------------name10------------------------------------------" + +read ch +./json -D -f json.txt -n name11|jq +echo "------------------------name11------------------------------------------" + +read ch +./json -D -f json.txt -n name111|jq +echo "------------------------name111-----------------------------------------" + +read ch +./json -D -f json.txt -n name1111|jq +echo "------------------------name1111----------------------------------------" + +read ch +./json -D -f json.txt -n name1112|jq +echo "------------------------name1112----------------------------------------" + +read ch +./json -D -f json.txt -n name1113|jq +echo "------------------------name1113----------------------------------------" + +read ch +./json -D -f json.txt -n name112|jq +echo "------------------------name112-----------------------------------------" + +read ch +./json -D -f json.txt -n name113|jq +echo "------------------------name113-----------------------------------------" + +read ch +./json -D -f json.txt -n name1131|jq +echo "------------------------name1131----------------------------------------" + +read ch +./json -D -f json.txt -n name1132|jq +echo "------------------------name1132----------------------------------------" + +read ch +./json -D -f json.txt -n name1133|jq +echo "------------------------name1133----------------------------------------" + +read ch +./json -D -f json.txt -n name114|jq +echo "------------------------name114-----------------------------------------" + +read ch +./json -D -f json.txt -n name116|jq +echo "------------------------name116-----------------------------------------" + +read ch +./json -D -f json.txt -n name117|jq +echo "------------------------name117-----------------------------------------" + +read ch +./json -D -f json.txt -n name1171|jq +echo "------------------------name1171----------------------------------------" + +read ch +./json -D -f json.txt -n name11711|jq +echo "------------------------name11711---------------------------------------" + +read ch +./json -D -f json.txt -n name118|jq +echo "------------------------name118-----------------------------------------" + +read ch +./json -D -f json.txt -n name119|jq +echo "------------------------name119-----------------------------------------" + +read ch +./json -D -f json.txt -n name1191|jq +echo "------------------------name1191----------------------------------------" + +read ch +./json -D -f json.txt -n name11911|jq +echo "------------------------name11911---------------------------------------" + +read ch +./json -D -f json.txt -n name119111|jq +echo "------------------------name119111--------------------------------------" + +read ch +./json -D -f json.txt -n name11912|jq +echo "------------------------name11912---------------------------------------" + +read ch +./json -D -f json.txt -n name119121|jq +echo "------------------------name119121--------------------------------------" + +read ch +./json -D -f json.txt -n name119122|jq +echo "------------------------name119122--------------------------------------" + +read ch +./json -D -f json.txt -n name1110|jq +echo "------------------------name1110----------------------------------------" + +read ch +./json -D -f json.txt -n name1111|jq +echo "------------------------name1111----------------------------------------" diff --git a/lib_acl_cpp/samples/json/json15/stdafx.cpp b/lib_acl_cpp/samples/json/json15/stdafx.cpp new file mode 100644 index 000000000..ed09dd603 --- /dev/null +++ b/lib_acl_cpp/samples/json/json15/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : 只包括标准包含文件的源文件 +// json.pch 将成为预编译头 +// stdafx.obj 将包含预编译类型信息 + +#include "stdafx.h" + +// TODO: 在 STDAFX.H 中 +//引用任何所需的附加头文件,而不是在此文件中引用 diff --git a/lib_acl_cpp/samples/json/json15/stdafx.h b/lib_acl_cpp/samples/json/json15/stdafx.h new file mode 100644 index 000000000..da17688be --- /dev/null +++ b/lib_acl_cpp/samples/json/json15/stdafx.h @@ -0,0 +1,41 @@ +// stdafx.h : 标准系统包含文件的包含文件, +// 或是常用但不常更改的项目特定的包含文件 +// + +#pragma once + + +//#include +//#include + +// TODO: 在此处引用程序要求的附加头文件 + +#include "acl_cpp/lib_acl.hpp" +#include "lib_acl.h" + +#ifdef WIN32 + #include + #define snprintf _snprintf +#endif + + +#ifdef DEBUG + +// 以下宏定义用来帮助检查变参中的参数类型是否合法 + +#undef logger +#define logger printf +#undef logger_error +#define logger_error printf +#undef logger_warn +#define logger_warn printf +#undef logger_fatal +#define logger_fatal printf +#undef logger_panic +#define logger_panic printf + +extern void __attribute__((format(printf,3,4))) \ + dummy_debug(int, int, const char*, ...); +#undef logger_debug +#define logger_debug dummy_debug +#endif diff --git a/lib_acl_cpp/samples/json/json15/t.sh b/lib_acl_cpp/samples/json/json15/t.sh new file mode 100755 index 000000000..d512a6f6a --- /dev/null +++ b/lib_acl_cpp/samples/json/json15/t.sh @@ -0,0 +1,144 @@ +#!/bin/sh + +./json -f json.txt -n name1|jq +echo "------------------------name1-------------------------------------------" + +read ch +./json -f json.txt -n name3|jq +echo "------------------------name3-------------------------------------------" + +read ch +./json -f json.txt -n name4|jq +echo "------------------------name4-------------------------------------------" + +read ch +./json -f json.txt -n name5|jq +echo "------------------------name5-------------------------------------------" + +read ch +./json -f json.txt -n name6|jq +echo "------------------------name6-------------------------------------------" + +read ch +./json -f json.txt -n name7|jq +echo "------------------------name7-------------------------------------------" + +read ch +./json -f json.txt -n name71|jq +echo "------------------------name71------------------------------------------" + +read ch +./json -f json.txt -n name72|jq +echo "------------------------name72------------------------------------------" + +read ch +./json -f json.txt -n name73|jq +echo "------------------------name73------------------------------------------" + +read ch +./json -f json.txt -n name8|jq +echo "------------------------name8-------------------------------------------" + +read ch +./json -f json.txt -n name10|jq +echo "------------------------name10------------------------------------------" + +read ch +./json -f json.txt -n name11|jq +echo "------------------------name11------------------------------------------" + +read ch +./json -f json.txt -n name111|jq +echo "------------------------name111-----------------------------------------" + +read ch +./json -f json.txt -n name1111|jq +echo "------------------------name1111----------------------------------------" + +read ch +./json -f json.txt -n name1112|jq +echo "------------------------name1112----------------------------------------" + +read ch +./json -f json.txt -n name1113|jq +echo "------------------------name1113----------------------------------------" + +read ch +./json -f json.txt -n name112|jq +echo "------------------------name112-----------------------------------------" + +read ch +./json -f json.txt -n name113|jq +echo "------------------------name113-----------------------------------------" + +read ch +./json -f json.txt -n name1131|jq +echo "------------------------name1131----------------------------------------" + +read ch +./json -f json.txt -n name1132|jq +echo "------------------------name1132----------------------------------------" + +read ch +./json -f json.txt -n name1133|jq +echo "------------------------name1133----------------------------------------" + +read ch +./json -f json.txt -n name114|jq +echo "------------------------name114-----------------------------------------" + +read ch +./json -f json.txt -n name116|jq +echo "------------------------name116-----------------------------------------" + +read ch +./json -f json.txt -n name117|jq +echo "------------------------name117-----------------------------------------" + +read ch +./json -f json.txt -n name1171|jq +echo "------------------------name1171----------------------------------------" + +read ch +./json -f json.txt -n name11711|jq +echo "------------------------name11711---------------------------------------" + +read ch +./json -f json.txt -n name118|jq +echo "------------------------name118-----------------------------------------" + +read ch +./json -f json.txt -n name119|jq +echo "------------------------name119-----------------------------------------" + +read ch +./json -f json.txt -n name1191|jq +echo "------------------------name1191----------------------------------------" + +read ch +./json -f json.txt -n name11911|jq +echo "------------------------name11911---------------------------------------" + +read ch +./json -f json.txt -n name119111|jq +echo "------------------------name119111--------------------------------------" + +read ch +./json -f json.txt -n name11912|jq +echo "------------------------name11912---------------------------------------" + +read ch +./json -f json.txt -n name119121|jq +echo "------------------------name119121--------------------------------------" + +read ch +./json -f json.txt -n name119122|jq +echo "------------------------name119122--------------------------------------" + +read ch +./json -f json.txt -n name1110|jq +echo "------------------------name1110----------------------------------------" + +read ch +./json -f json.txt -n name1111|jq +echo "------------------------name1111----------------------------------------" diff --git a/lib_acl_cpp/samples/json/json15/t1.sh b/lib_acl_cpp/samples/json/json15/t1.sh new file mode 100755 index 000000000..527ae4286 --- /dev/null +++ b/lib_acl_cpp/samples/json/json15/t1.sh @@ -0,0 +1,72 @@ +#!/bin/sh + +./json -f json1.txt -n name113|jq +echo "------------------------name113-----------------------------------------" + +read ch +./json -f json1.txt -n name1131|jq +echo "------------------------name1131----------------------------------------" + +read ch +./json -f json1.txt -n name1132|jq +echo "------------------------name1132----------------------------------------" + +read ch +./json -f json1.txt -n name1133|jq +echo "------------------------name1133----------------------------------------" + +read ch +./json -f json1.txt -n name117|jq +echo "------------------------name117-----------------------------------------" + +read ch +./json -f json1.txt -n name1171|jq +echo "------------------------name1171----------------------------------------" + +read ch +./json -f json1.txt -n name11711|jq +echo "------------------------name11711---------------------------------------" + +read ch +./json -f json1.txt -n name117111|jq +echo "------------------------name117111--------------------------------------" + +read ch +./json -f json1.txt -n "name1131,name117111"|jq +echo "------------------------name1131,name117111-----------------------------" + +read ch +./json -f json1.txt -n "name1131,name1132"|jq +echo "------------------------name1131,name1132-------------------------------" + +read ch +./json -f json1.txt -n "name118"|jq +echo "------------------------name118-----------------------------------------" + +read ch +./json -f json1.txt -n "name1181"|jq +echo "------------------------name1181----------------------------------------" + +read ch +./json -f json1.txt -n "name1182"|jq +echo "------------------------name1183----------------------------------------" + +read ch +./json -f json1.txt -n "name1183"|jq +echo "------------------------name1183----------------------------------------" + +read ch +./json -f json1.txt -n "name1181,name1182"|jq +echo "------------------------name1181,name1182-------------------------------" + +read ch +./json -f json1.txt -n "name1181,name1183"|jq +echo "------------------------name1181,name1183-------------------------------" + +read ch +./json -f json1.txt -n "name1183,name1182"|jq +echo "------------------------name1183,name1182-------------------------------" + +read ch +./json -f json1.txt -n "name1181,name1182,name1183"|jq +echo "------------------------name1181,name1182,name1183----------------------" diff --git a/lib_acl_cpp/samples/json/json15/t3.sh b/lib_acl_cpp/samples/json/json15/t3.sh new file mode 100755 index 000000000..c693a3240 --- /dev/null +++ b/lib_acl_cpp/samples/json/json15/t3.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +./json -f json3.txt -n name1|jq +echo "------------------------name1-----------------------------------------" + +read ch +./json -f json3.txt -n name2|jq +echo "------------------------name2-----------------------------------------" + +read ch +./json -f json3.txt -n name3|jq +echo "------------------------name3-----------------------------------------" diff --git a/lib_acl_cpp/samples/json/json15/valgrind.sh b/lib_acl_cpp/samples/json/json15/valgrind.sh new file mode 100644 index 000000000..af5f0c6e2 --- /dev/null +++ b/lib_acl_cpp/samples/json/json15/valgrind.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +valgrind --tool=memcheck --leak-check=yes -v ./json diff --git a/lib_acl_cpp/src/stdlib/json.cpp b/lib_acl_cpp/src/stdlib/json.cpp index 22f81c53b..427bc9eea 100644 --- a/lib_acl_cpp/src/stdlib/json.cpp +++ b/lib_acl_cpp/src/stdlib/json.cpp @@ -393,7 +393,9 @@ json_node* json_node::first_child() json_node* json_node::next_child() { - acl_assert(iter_); + if (iter_ == NULL) { + return NULL; + } ACL_JSON_NODE* node = node_me_->iter_next(iter_, node_me_); if (node == NULL) { @@ -404,6 +406,21 @@ json_node* json_node::next_child() return child; } +json_node* json_node::free_child(json_node* child) +{ + if (iter_ == NULL || child == NULL) { + return NULL; + } + + ACL_JSON_NODE* node = acl_json_node_erase(node_me_, iter_); + if (node == NULL) { + return NULL; + } + + json_node* next = dbuf_->create(node, json_); + return next; +} + json_node* json_node::operator[](const char* tag) { json_node* iter = first_child(); @@ -752,7 +769,10 @@ json_node* json::first_node() json_node* json::next_node() { - acl_assert(iter_); + if (iter_ == NULL) { + return NULL; + } + ACL_JSON_NODE* node = json_->iter_next(iter_, json_); if (node == NULL) { return NULL; @@ -762,6 +782,20 @@ json_node* json::next_node() return n; } +json_node* json::free_node(acl::json_node* curr) +{ + if (iter_ == NULL || curr == NULL) { + return NULL; + } + + ACL_JSON_NODE* node = acl_json_erase(json_, iter_); + if (node == NULL) { + return NULL; + } + json_node* next = dbuf_->create(node, this); + return next; +} + const string& json::to_string(string* out /* = NULL */, bool add_space /* = false */) const {