From 3f74c26a144357f436e94224b1742782e3f1da49 Mon Sep 17 00:00:00 2001 From: ubuntu14 Date: Sun, 17 Jan 2016 13:35:12 +0800 Subject: [PATCH] modify redis interface; make socket more safty --- Makefile | 21 +- build_env | 13 + lib_acl/Makefile | 12 +- lib_acl/changes.txt | 19 + lib_acl/include/code/acl_xmlcode.h | 24 +- lib_acl/include/net/acl_sane_socket.h | 28 +- lib_acl/include/xml/acl_xml2.h | 14 +- lib_acl/samples/Makefile.in | 2 +- lib_acl/samples/Makefile_cpp.in | 2 +- lib_acl/samples/vstream_server/main.c | 38 +- lib_acl/samples/xml/xml6/xml.c | 35 +- lib_acl/samples/xml/xml7/Makefile | 3 + lib_acl/samples/xml/xml7/a.xml | 3 + lib_acl/samples/xml/xml7/b.xml | 8 + lib_acl/samples/xml/xml7/cdata.xml | 100 +++++ lib_acl/samples/xml/xml7/xml.c | 90 +++++ lib_acl/src/code/acl_xmlcode.c | 101 +++-- lib_acl/src/code/html_charset.h | 2 +- lib_acl/src/event/events_iocp.c | 5 +- lib_acl/src/event/events_kernel.c | 7 +- lib_acl/src/event/events_poll.c | 7 +- lib_acl/src/event/events_select.c | 7 +- lib_acl/src/event/events_wmsg.c | 5 +- .../src/master/template/acl_multi_server.c | 2 +- .../src/master/template/acl_single_server.c | 2 +- .../src/master/template/acl_trigger_server.c | 2 +- lib_acl/src/net/acl_sane_socket.c | 39 +- lib_acl/src/stdlib/acl_vstream.c | 322 ++++++++++++--- .../src/stdlib/memory/acl_default_malloc.c | 16 +- lib_acl/src/xml/acl_xml2.c | 22 +- lib_acl/src/xml/acl_xml2_parse.c | 2 +- lib_acl/src/xml/acl_xml2_util.c | 111 ++++-- lib_acl/src/xml/acl_xml_util.c | 32 +- lib_acl_cpp/Makefile | 14 +- lib_acl_cpp/changes.txt | 21 + .../acl_cpp/connpool/connect_manager.hpp | 20 +- lib_acl_cpp/include/acl_cpp/db/db_handle.hpp | 8 +- lib_acl_cpp/include/acl_cpp/db/db_pool.hpp | 8 + lib_acl_cpp/include/acl_cpp/mime/mime.hpp | 6 +- .../include/acl_cpp/mime/mime_head.hpp | 9 +- .../include/acl_cpp/queue/queue_manager.hpp | 1 - lib_acl_cpp/include/acl_cpp/redis/redis.hpp | 2 +- .../include/acl_cpp/redis/redis_client.hpp | 2 +- .../acl_cpp/redis/redis_client_cluster.hpp | 2 +- .../acl_cpp/redis/redis_client_pool.hpp | 2 +- .../include/acl_cpp/redis/redis_cluster.hpp | 6 +- .../include/acl_cpp/redis/redis_command.hpp | 12 +- .../acl_cpp/redis/redis_connection.hpp | 6 +- .../include/acl_cpp/redis/redis_geo.hpp | 4 +- .../include/acl_cpp/redis/redis_hash.hpp | 6 +- .../acl_cpp/redis/redis_hyperloglog.hpp | 6 +- .../include/acl_cpp/redis/redis_key.hpp | 6 +- .../include/acl_cpp/redis/redis_list.hpp | 6 +- .../include/acl_cpp/redis/redis_node.hpp | 4 +- .../include/acl_cpp/redis/redis_pubsub.hpp | 6 +- .../include/acl_cpp/redis/redis_result.hpp | 31 +- .../include/acl_cpp/redis/redis_script.hpp | 6 +- .../include/acl_cpp/redis/redis_server.hpp | 30 +- .../include/acl_cpp/redis/redis_set.hpp | 6 +- .../include/acl_cpp/redis/redis_slot.hpp | 10 +- .../include/acl_cpp/redis/redis_string.hpp | 6 +- .../acl_cpp/redis/redis_transaction.hpp | 18 +- .../include/acl_cpp/redis/redis_zset.hpp | 6 +- .../include/acl_cpp/stream/fstream.hpp | 13 +- lib_acl_cpp/samples/Makefile.in | 2 +- lib_acl_cpp/samples/mime/mime/mime.cpp | 3 + lib_acl_cpp/samples/mime/mime_bench/Makefile | 13 + lib_acl_cpp/samples/mime/mime_bench/mime.cpp | 105 +++++ .../samples/mime/mime_bench/stdafx.cpp | 8 + lib_acl_cpp/samples/mime/mime_bench/stdafx.h | 11 + .../samples/mime/mime_bench/valgrind.sh | 3 + .../samples/redis/redis_hash/redis_hash.cpp | 1 + lib_acl_cpp/samples/xml/xml4/cdata.xml | 90 ++++- lib_acl_cpp/samples/xml/xml4/main.cpp | 9 + lib_acl_cpp/samples/xml/xml5/Makefile | 3 + lib_acl_cpp/samples/xml/xml5/main.cpp | 106 +++++ lib_acl_cpp/samples/xml/xml5/stdafx.cpp | 4 + lib_acl_cpp/samples/xml/xml5/stdafx.h | 12 + lib_acl_cpp/samples/xml/xml5/valgrind.sh | 3 + lib_acl_cpp/src/connpool/connect_manager.cpp | 4 + lib_acl_cpp/src/db/db_handle.cpp | 5 +- lib_acl_cpp/src/db/db_mysql.cpp | 12 +- lib_acl_cpp/src/db/db_pool.cpp | 13 + lib_acl_cpp/src/db/db_sqlite.cpp | 7 +- lib_acl_cpp/src/disque/disque.cpp | 18 +- lib_acl_cpp/src/http/http_request_pool.cpp | 4 +- lib_acl_cpp/src/mime/internal/mime_state.cpp | 5 + lib_acl_cpp/src/mime/internal/mime_state.hpp | 2 + .../src/mime/internal/mime_state_parse.cpp | 374 +++++++++--------- lib_acl_cpp/src/mime/mime.cpp | 13 +- lib_acl_cpp/src/mime/mime_head.cpp | 16 +- lib_acl_cpp/src/redis/redis_command.cpp | 102 ++++- lib_acl_cpp/src/redis/redis_geo.cpp | 28 +- lib_acl_cpp/src/redis/redis_list.cpp | 8 +- lib_acl_cpp/src/redis/redis_pubsub.cpp | 8 +- lib_acl_cpp/src/redis/redis_result.cpp | 41 +- lib_acl_cpp/src/redis/redis_script.cpp | 8 +- lib_acl_cpp/src/redis/redis_string.cpp | 12 +- lib_acl_cpp/src/redis/redis_zset.cpp | 54 +-- lib_acl_cpp/src/session/session.cpp | 6 +- lib_acl_cpp/src/stream/fstream.cpp | 27 +- lib_protocol/Makefile | 12 +- lib_protocol/samples/Makefile.in | 2 +- lib_protocol/samples/Makefile_cpp.in | 2 +- test/Makefile.in | 2 +- 105 files changed, 1927 insertions(+), 610 deletions(-) create mode 100644 build_env create mode 100644 lib_acl/samples/xml/xml7/Makefile create mode 100644 lib_acl/samples/xml/xml7/a.xml create mode 100644 lib_acl/samples/xml/xml7/b.xml create mode 100644 lib_acl/samples/xml/xml7/cdata.xml create mode 100644 lib_acl/samples/xml/xml7/xml.c create mode 100644 lib_acl_cpp/samples/mime/mime_bench/Makefile create mode 100644 lib_acl_cpp/samples/mime/mime_bench/mime.cpp create mode 100644 lib_acl_cpp/samples/mime/mime_bench/stdafx.cpp create mode 100644 lib_acl_cpp/samples/mime/mime_bench/stdafx.h create mode 100644 lib_acl_cpp/samples/mime/mime_bench/valgrind.sh create mode 100644 lib_acl_cpp/samples/xml/xml5/Makefile create mode 100644 lib_acl_cpp/samples/xml/xml5/main.cpp create mode 100644 lib_acl_cpp/samples/xml/xml5/stdafx.cpp create mode 100644 lib_acl_cpp/samples/xml/xml5/stdafx.h create mode 100644 lib_acl_cpp/samples/xml/xml5/valgrind.sh diff --git a/Makefile b/Makefile index 13b07c8fb..9c53c971c 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,11 @@ SHELL = /bin/sh -CC = g++ -AR = ar +#CC = g++ +CC = ${ENV_CC} +#AR = ar +AR = ${ENV_AR} ARFL = rv -RANLIB = ranlib +#RANLIB = ranlib +RANLIB = ${ENV_RANLIB} #OSNAME = $(shell uname -sm) #OSTYPE = $(shell uname -p) @@ -28,6 +31,18 @@ MAKE_ARGS = SYSLIB = -lpthread -lz LDFLAGS = -shared +ifeq ($(CC),) + CC = g++ +endif + +ifeq ($(AR),) + AR = ar +endif + +ifeq ($(RANLIB),) + RANLIB = ranlib +endif + ifeq ($(findstring Linux, $(OSNAME)), Linux) ifeq ($(findstring i686, $(OSTYPE)), i686) RPATH = linux32 diff --git a/build_env b/build_env new file mode 100644 index 000000000..0c74b5cd1 --- /dev/null +++ b/build_env @@ -0,0 +1,13 @@ +#!/bin/sh +export ENV_CC=/home3/zsxxsz/tools/buildroot-gcc463_new_ok/usr/bin/mipsel-linux-gcc +export ENV_CPP=/home3/zsxxsz/tools/buildroot-gcc463_new_ok/usr/bin/mipsel-linux-g++ +export ENV_AR=/home3/zsxxsz/tools/buildroot-gcc463_new_ok/usr/bin/mipsel-linux-ar +export ENV_RANLIB=/home3/zsxxsz/tools/buildroot-gcc463_new_ok/usr/bin/mipsel-linux-ranlib +export ENV_LD=/home3/zsxxsz/tools/buildroot-gcc463_new_ok/usr/bin/mipsel-linux-ld +export LD_LIBRARY_PATH=/home3/zsxxsz/tools/buildroot-gcc463_new_ok/usr/lib + +echo "ENV_CC=$ENV_CC" +echo "ENV_CC=$ENV_CPP" +echo "ENV_AR=$ENV_AR" +echo "ENV_RANLIB=$ENV_RANLIB" +echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" diff --git a/lib_acl/Makefile b/lib_acl/Makefile index 5fbda6d88..9a04d99b1 100644 --- a/lib_acl/Makefile +++ b/lib_acl/Makefile @@ -2,10 +2,10 @@ SHELL = /bin/sh #CC = gcc #CC = g++ CC = ${ENV_CC} -AR = ar +AR = ${ENV_AR} ARFL = rv #ARFL = cru -RANLIB = ranlib +RANLIB = ${ENV_RANLIB} FLAGS = ${ENV_FLAGS} @@ -46,6 +46,14 @@ ifeq ($(CC),) CC = gcc endif +ifeq ($(AR),) + AR = ar +endif + +ifeq ($(RANLIB),) + RANLIB = ranlib +endif + ifeq ($(findstring gcc, $(CC)), gcc) CFLAGS += -Wstrict-prototypes endif diff --git a/lib_acl/changes.txt b/lib_acl/changes.txt index e345db4fb..b138d25ec 100644 --- a/lib_acl/changes.txt +++ b/lib_acl/changes.txt @@ -1,5 +1,24 @@ 修改历史列表: +------------------------------------------------------------------------ +526) 2016.1.17 +526.1) feature: acl_default_malloc.c,函数 acl_default_realloc 当输入的地址为 +NULL,则自动切换至 acl_default_malloc 过程 +526.2) feature: acl_vstream.c,函数 acl_vstream_fdopen 会自动判断所给描述符是否 +为监听描述符,避免了用户输入的参数 fdtype 的非法性 +526.3) feature: events_select.c/events_poll.c/events_kernel.c,内部自动判断是否 +为监听描述符,从而降低了事件模块与流模块之间以及其它模块之间的耦合度 + +525) 2016.1.16 +525.1) bugfix: acl_multi_server.c/acl_single_server.c/acl_trigger_server.c,在 +将监控监听套接口的读事件时,应该调用 acl_event_enable_listen,而不是调用 +acl_event_enable_read +525.2) feature: 增加函数 acl_check_socket 用来检查所给套接字是否为监听套接字 + +524) 2016.1.8 +524.1) bugfix: acl_xml_parse.c/acl_xml2_parse.c/acl_xml_util.c/acl_xml2_util.c, +修复了当数据节点为 META, COMMENT, CDATA 时解析与创建 xml 对象时的 BUG + ------------------------------------------------------------------------ 523) 2015.12.28 523.1) acl_read_wait.c 中的函数 acl_read_wait 在 32 位的低版本 LINUX 平台下 diff --git a/lib_acl/include/code/acl_xmlcode.h b/lib_acl/include/code/acl_xmlcode.h index e00c8aacf..93496e89a 100644 --- a/lib_acl/include/code/acl_xmlcode.h +++ b/lib_acl/include/code/acl_xmlcode.h @@ -11,8 +11,28 @@ extern "C" { ACL_API int acl_xml_encode(const char *in, ACL_VSTRING *out); ACL_API int acl_xml_decode(const char *in, ACL_VSTRING *out); -ACL_API const char *acl_xml_encode2(const char *in, size_t ilen, - char **out, size_t *olen); +/** + * xml 字符编码器 + * @param in {const char**} 源串地址的地址,函数返回后该地址记录未被处理的内容地址, + * 如果输出缓冲区足够大,则该地址将指向源的尾部的后一个位置 + * @param ilen {size_t} 源内容的数据长度 + * @param out {char*} 输出缓冲区,用来存储转码后的结果 + * @param olen {size_t} 输出缓冲区的大小 + * @return {size_t} 转码后存储在输出缓冲区内的数据长度(该长度有可能大于源数据长度), + * 当输出缓冲区长度为: + * 1) == 0 时,返回 0 + * 2) == 1 时,返回 0,且最后一个字节被置 '\0' + * 3) > 1 时,最后一个字节被置 '\0',返回值 > 0(不包含最后的 '\0') + * 注: + * 1) 函数返回后 in 的地址会发生改变,指向下一个待处理的地址 + * 2) 调用者在调用前应先保存 in 的地址,在 in 中未被处理的剩余的长度计算方式: + * ilen -= in_saved - in; + * 3) 虽然当 olen > 0 时内部自动会给 out 的尾部置 '\0‘,但返回的数据长度 + * 不包括最后的 '\0' + */ +ACL_API size_t acl_xml_encode2(const char** in, size_t ilen, + char* out, size_t olen); + ACL_API const char *acl_xml_decode2(const char *in, char **out, size_t *size); #ifdef __cplusplus diff --git a/lib_acl/include/net/acl_sane_socket.h b/lib_acl/include/net/acl_sane_socket.h index 28dc6a762..abd08276f 100644 --- a/lib_acl/include/net/acl_sane_socket.h +++ b/lib_acl/include/net/acl_sane_socket.h @@ -9,29 +9,43 @@ extern "C" { /** * 取得套接字连接对方的网络地址, 地址格式为: IP:PORT - * @param sockfd {ACL_SOCKET} 网络套接字 + * @param fd {ACL_SOCKET} 网络套接字 * @param buf {char*} 存储地址的缓冲区,不能为空 * @param bsize {size_t} buf 空间大小 * @return {int} 0: ok; -1: error */ -ACL_API int acl_getpeername(ACL_SOCKET sockfd, char *buf, size_t bsize); +ACL_API int acl_getpeername(ACL_SOCKET fd, char *buf, size_t bsize); /** * 取得套接字连接本地的网络地址, 地址格式为: IP:PORT - * @param sockfd {ACL_SOCKET} 网络套接字 + * @param fd {ACL_SOCKET} 网络套接字 * @param buf {char*} 存储地址的缓冲区,不能为空 * @param bsize {size_t} buf 空间大小 * @return {int} 0: ok; -1: error */ -ACL_API int acl_getsockname(ACL_SOCKET sockfd, char *buf, size_t bsize); +ACL_API int acl_getsockname(ACL_SOCKET fd, char *buf, size_t bsize); /** - * 取得套接字的类型 - * @param sockfd {ACL_SOCKET} 网络套接字 + * 取得套接字的类型:是网络套接字还是域套接字 + * @param fd {ACL_SOCKET} 网络套接字 * @return {int} -1: 表示出错或输入非法或非套接字; >= 0 表示成功获得套接字 * 类型,返回值有 AF_INET 或 AF_UNIX(仅限 UNIX 平台) */ -ACL_API int acl_getsocktype(ACL_SOCKET sockfd); +ACL_API int acl_getsocktype(ACL_SOCKET fd); + +/** + * 检查套接字:是监听套接字还是网络套接字 + * @param sockefd {ACL_SOCKET} 套接字句柄 + * @return {int} 返回 -1 表示该句柄非套接字,1 为监听套接字,0 为非监听套接字 + */ +ACL_API int acl_check_socket(ACL_SOCKET fd); + +/** + * 判断套接字是否为监听套接字 + * @param sockefd {ACL_SOCKET} 套接字句柄 + * @return {int} 返回值 0 表示非监听套接字,非 0 表示为监听套接字 + */ +ACL_API int acl_is_listening_socket(ACL_SOCKET fd); #ifdef __cplusplus } diff --git a/lib_acl/include/xml/acl_xml2.h b/lib_acl/include/xml/acl_xml2.h index a38fb70c3..9c35c64f3 100644 --- a/lib_acl/include/xml/acl_xml2.h +++ b/lib_acl/include/xml/acl_xml2.h @@ -235,6 +235,18 @@ ACL_API ACL_XML2 *acl_xml2_mmap_fd(ACL_FILE_HANDLE fd, size_t size, */ ACL_API size_t acl_xml2_mmap_extend(ACL_XML2 *xml); +/** + * 当采用内存文件映射方式时,此函数用来扩充映射文件的空间大小,因为在初始化时 + * 仅分配较小的空间,在使用过程中如果发现空间不足,则内部自动调用此函数扩展 + * 文件大小,这样既可以满足实际需求,又可以节省磁盘空间 + * @param xml {ACL_XML2*} 采用 acl_xml2_mmap_alloc 方式创建的 xml 对象 + * @param n {size_t} 希望本次扩充的空间大小,如果该值超过最大限制,则返回实际 + * 扩充的空间大小 + * @return {size_t} 扩充后新增加的空间大小,如果返回值为 0,则表示出错或已经 + * 达到空间分配上限购 + */ +ACL_API size_t acl_xml2_mmap_extend_size(ACL_XML2 *xml, size_t n); + /** * 将某一个 ACL_XML2_NODE 节点作为一个 XML 对象的根节点,从而可以方便地遍历出该 * 节点各级子节点(在遍历过程中的所有节点不含本节点自身),该遍历方式有别于单独 @@ -516,7 +528,7 @@ ACL_API void acl_xml2_node_set_text(ACL_XML2_NODE *node, const char *text); /** * 将 xml 对象转成字符串内容 * @param xml {ACL_XML2*} xml 对象 - * @return {const char*} + * @return {const char*} 返回转换后字符串的起始地址 */ ACL_API const char *acl_xml2_build(ACL_XML2* xml); diff --git a/lib_acl/samples/Makefile.in b/lib_acl/samples/Makefile.in index a86ee40cb..7924a4fc9 100644 --- a/lib_acl/samples/Makefile.in +++ b/lib_acl/samples/Makefile.in @@ -1,4 +1,4 @@ -CC = $(MY_ENV_CC) +CC = $(ENV_CC) CFLAGS = -c -g -W -Wall -Wcast-qual \ -Waggregate-return \ diff --git a/lib_acl/samples/Makefile_cpp.in b/lib_acl/samples/Makefile_cpp.in index 82eed1c44..a2ee3bbd7 100644 --- a/lib_acl/samples/Makefile_cpp.in +++ b/lib_acl/samples/Makefile_cpp.in @@ -1,4 +1,4 @@ -CC = $(MY_ENV_CC) +CC = $(ENV_CPP) CFLAGS = -c -g -W \ -Wall \ diff --git a/lib_acl/samples/vstream_server/main.c b/lib_acl/samples/vstream_server/main.c index 442fb683d..8d8227a11 100644 --- a/lib_acl/samples/vstream_server/main.c +++ b/lib_acl/samples/vstream_server/main.c @@ -29,6 +29,7 @@ int main(int argc, char *argv[]) ACL_VSTREAM *server, *client; char addr[64], *buf = NULL, line[128]; int n, i, len, inter = 1000; + int type = 0; double spent; struct timeval begin, end; @@ -50,14 +51,43 @@ int main(int argc, char *argv[]) } } - /* 鐩戝惉鏈湴鏈嶅姟鍦板潃 */ +#if 0 server = acl_vstream_listen(addr, 128); if (server == NULL) { printf("listen %s error %s\r\n", addr, acl_last_serror()); return 1; } +#else + if (strchr(addr, '/') != NULL || !acl_ipv4_addr_valid(addr)) { + n = acl_unix_listen(addr, 128, ACL_BLOCKING); +#if defined(ACL_MACOSX) + type = ACL_VSTREAM_TYPE_LISTEN_UNIX; +#endif + } else { + n = acl_inet_listen(addr, 127, ACL_BLOCKING); +#if defined(ACL_MACOSX) + type = ACL_VSTREAM_TYPE_LISTEN_INET; +#endif + } + if (n == ACL_SOCKET_INVALID) + { + printf("listen %s error %s\r\n", addr, acl_last_serror()); + return 1; + } + server = acl_vstream_fdopen(n, 0, 8192, 0, type); +#endif - printf("listening on %s ...\r\n", addr); + printf("listening on %s ok!\r\n", addr); + n = acl_check_socket(ACL_VSTREAM_SOCK(server)); + if (n == 1) + printf("%d is listening socket\r\n", ACL_VSTREAM_SOCK(server)); + else if (n == 0) + printf("%d is no-listening socket\r\n", ACL_VSTREAM_SOCK(server)); + else if (n == -1) + printf("%d is not socket\r\n", ACL_VSTREAM_SOCK(server)); + + n = acl_is_listening_socket(ACL_VSTREAM_SOCK(server)); + printf("server is listening socket: %s\r\n", n ? "yes" : "no"); /* 鎺ユ敹澶栨潵瀹㈡埛绔繛鎺 */ client = acl_vstream_accept(server, addr, sizeof(addr)); @@ -66,6 +96,8 @@ int main(int argc, char *argv[]) acl_vstream_close(server); return 1; } + printf("client is listening socket: %s\r\n", + acl_is_listening_socket(ACL_VSTREAM_SOCK(client)) ? "yes" : "no"); /* 浠庡鎴风璇诲彇涓琛屾暟鎹紝浠庤岀煡閬撳鎴锋瘡娆″彂閫佹暟鎹殑闀垮害 */ n = acl_vstream_gets_nonl(client, line, sizeof(line)); @@ -87,6 +119,8 @@ int main(int argc, char *argv[]) printf("read error %s\r\n", acl_last_serror()); break; } + buf[n] = 0; + printf("readn: %s\r\n", buf); i++; if (i % inter == 0) { snprintf(line, sizeof(line), "curr: %d, nread: %d", i, n); diff --git a/lib_acl/samples/xml/xml6/xml.c b/lib_acl/samples/xml/xml6/xml.c index dbd887b11..dfc07f784 100644 --- a/lib_acl/samples/xml/xml6/xml.c +++ b/lib_acl/samples/xml/xml6/xml.c @@ -238,6 +238,10 @@ static void walk_xml(ACL_XML3* xml) printf("tag->%s, size: %ld\n", node->ltag, (long) node->ltag_size); + if (node->ltag_size != strlen(node->ltag)) { + printf("ltag_size invalid\r\n"); + exit (1); + } /* 遍历 xml 结点的属性 */ acl_foreach(iter2, node->attr_list) { @@ -275,6 +279,17 @@ static void xml_node_attrs(ACL_XML3_NODE* node, int n) printf("attr-><%s>(size=%ld)=\"<%s>(size=%ld)\"\n", attr->name, (long) attr->name_size, attr->value, (long) attr->value_size); + + if (attr->name_size != strlen(attr->name)) { + printf("%s(%d): name_size invalid\r\n", + __FUNCTION__, __LINE__); + exit (1); + } + if (attr->value_size != strlen(attr->value)) { + printf("%s(%d): value_size invaid\r\n", + __FUNCTION__, __LINE__); + exit (1); + } } } @@ -291,16 +306,28 @@ static void walk_xml_node(ACL_XML3_NODE *node, int n) for (i = 0; i < n; i++) printf("\t"); - printf("tag->%s, size: %ld\n", child->ltag, - (long) child->ltag_size); + printf("tag->%s, size: %ld, %ld\n", child->ltag, + (long) child->ltag_size, (long) strlen(child->ltag)); + + if (child->ltag_size != strlen(child->ltag)) { + printf("%s(%d): ltag_size invalid\r\n", + __FUNCTION__, __LINE__); + exit (1); + } xml_node_attrs(child, n + 1); for (i = 0; i < n + 1; i++) printf("\t"); - printf("text->%s, size: %ld\n", child->text, - (long) child->text_size); + printf("text->%s, size: %ld, %ld\n", child->text, + (long) child->text_size, (long) strlen(child->text)); + + if (child->text_size != strlen(child->text)) { + printf("%s(%d): text_size invalid\r\n", + __FUNCTION__, __LINE__); + exit (1); + } walk_xml_node(child, n + 1); } diff --git a/lib_acl/samples/xml/xml7/Makefile b/lib_acl/samples/xml/xml7/Makefile new file mode 100644 index 000000000..db24eb893 --- /dev/null +++ b/lib_acl/samples/xml/xml7/Makefile @@ -0,0 +1,3 @@ +base_path = ../../.. +include ../../Makefile.in +PROG = xml diff --git a/lib_acl/samples/xml/xml7/a.xml b/lib_acl/samples/xml/xml7/a.xml new file mode 100644 index 000000000..a3a5c39f9 --- /dev/null +++ b/lib_acl/samples/xml/xml7/a.xml @@ -0,0 +1,3 @@ + + hello + diff --git a/lib_acl/samples/xml/xml7/b.xml b/lib_acl/samples/xml/xml7/b.xml new file mode 100644 index 000000000..17f7df5d8 --- /dev/null +++ b/lib_acl/samples/xml/xml7/b.xml @@ -0,0 +1,8 @@ + + XML catalog behavior can be changed by redirecting + queries to the user's own set of catalogs. This can be done by setting + the XML_CATALOG_FILES environment variable to a list + of catalogs. An empty one should deactivate loading the + default /etc/xml/catalog catalog. + + diff --git a/lib_acl/samples/xml/xml7/cdata.xml b/lib_acl/samples/xml/xml7/cdata.xml new file mode 100644 index 000000000..71c375720 --- /dev/null +++ b/lib_acl/samples/xml/xml7/cdata.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + zsx11 + zsx12 + zsx12 + + + zsx21 + zsx22 + zsx22 + + + zsx31 + zsx32 + zsx32 + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib_acl/samples/xml/xml7/xml.c b/lib_acl/samples/xml/xml7/xml.c new file mode 100644 index 000000000..d350ed52f --- /dev/null +++ b/lib_acl/samples/xml/xml7/xml.c @@ -0,0 +1,90 @@ +#include +#include +#include "lib_acl.h" + +static int parse_xml_file(const char *filepath) +{ + int n; + acl_int64 len; + char buf[10240]; + ACL_VSTREAM *in = acl_vstream_fopen(filepath, O_RDONLY, 0600, 8192); + const char* outfile = "./out.xml"; + ACL_VSTREAM *out = acl_vstream_fopen(outfile, O_RDWR | O_CREAT | O_TRUNC, 0600, 8192); + ACL_XML2 *xml; + const char *mmap_file = "./local.map"; + const char* ptr; + + if (in == NULL) { + printf("open %s error %s\r\n", filepath, acl_last_serror()); + return -1; + } + + if (out == NULL) + { + printf("open %s error %s\r\n", outfile, acl_last_serror()); + acl_vstream_close(in); + return -1; + } + + len = acl_vstream_fsize(in); + if (len <= 0) { + printf("fsize %s error %s\r\n", filepath, acl_last_serror()); + acl_vstream_close(in); + acl_vstream_close(out); + return -1; + } + + acl_vstream_printf(">>>file(%s)'s size: %lld\r\n", filepath, len); + + len *= 4; + + xml = acl_xml2_mmap_file(mmap_file, len, 10, 1, NULL); + + len = 0; + while (1) { + n = acl_vstream_read(in, buf, sizeof(buf) - 1); + if (n == ACL_VSTREAM_EOF) + break; + buf[n] = 0; + acl_xml2_update(xml, buf); + len += n; + } + + acl_vstream_close(in); + + acl_vstream_printf(">>read size: %lld\r\n", len); + + ptr = acl_xml2_build(xml); + if (ptr == NULL) + printf("acl_xml2_build error\r\n"); + + len = xml->ptr - ptr; + acl_vstream_printf(">>>build xml's size:%lld\r\n", len); + acl_vstream_printf(">>> ptr: {%s}\r\n", ptr); + + if (acl_vstream_writen(out, ptr, len) == ACL_VSTREAM_EOF) { + printf("write error %s, len: %ld\r\n", + acl_last_serror(), (long) len); + return -1; + } + + acl_vstream_close(out); + acl_xml2_free(xml); + + return 0; +} + +int main(int argc, char *argv[]) +{ + unsigned char ch = -1; + printf("unsigned char: %u\r\n", ch); + if (argc < 2) { + printf("usage: %s filepath\r\n", argv[0]); + return 0; + } + + acl_msg_stdout_enable(1); + parse_xml_file(argv[1]); + + return 0; +} diff --git a/lib_acl/src/code/acl_xmlcode.c b/lib_acl/src/code/acl_xmlcode.c index 086886c40..ffe6823f4 100644 --- a/lib_acl/src/code/acl_xmlcode.c +++ b/lib_acl/src/code/acl_xmlcode.c @@ -48,7 +48,7 @@ static const char *__charmap[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; int acl_xml_encode(const char *in, ACL_VSTRING *out) @@ -190,6 +190,71 @@ int acl_xml_decode(const char *in, ACL_VSTRING *out) /*--------------------------------------------------------------------------*/ +size_t acl_xml_encode2(const char **in, size_t ilen, char *out, size_t olen) +{ + size_t olen_saved = olen; + + if (olen == 0) + return 0; + + while (ilen > 0 && olen > 1) { + unsigned char ch = (unsigned char)(**in); + if (__charmap[ch] != NULL) { + size_t n = strlen(__charmap[ch]); + if (olen < n) + break; + memcpy(out, __charmap[ch], n); + out += n; + olen -= n; + } else { + *out = (char) ch; + out++; + olen--; + } + + (*in)++; + ilen--; + } + + *out = '\0'; + return olen_saved - olen; +} + +#if 0 +const char *acl_xml_encode2(const char *in, size_t ilen, + char **out, size_t *olen) +{ + const unsigned char *ptr = (const unsigned char*) in; + const char *s; + + if (*olen == 0) + return in; + + *olen -= 1; /* reserve space for '\0' */ + + while (ilen > 0 && *olen > 0) { + if ((s = __charmap[*ptr]) != NULL) { + size_t n = strlen(s); + if (*olen < n) + break; + memcpy(*out, s, n); + *out += n; + *olen -= n; + } else if (*olen > 0) { + **out = *ptr; + *out += 1; + *olen -= 1; + } else + break; + ptr++; + ilen--; + } + + **out = '\0'; + return (const char*) ptr; +} +#endif + /* return the left char of in, > 0 when the out buf is not enough */ static size_t copy_buf(char **out, size_t *olen, const char *in, size_t ilen) @@ -204,39 +269,7 @@ static size_t copy_buf(char **out, size_t *olen, const char *in, size_t ilen) return ilen; } -const char *acl_xml_encode2(const char *in, size_t ilen, char **out, size_t *olen) -{ - const unsigned char *ptr = (const unsigned char*) in; - const char *s; - - if (*olen == 0) - return in; - - *olen -= 1; /* reserve space for '\0' */ - - while (ilen > 0) { - if ((s = __charmap[*ptr]) != NULL) { - if (copy_buf(out, olen, s, strlen(s)) > 0) - break; - } else if (*olen > 0) { - **out = *ptr; - *out += 1; - *olen -= 1; - if (*olen == 0) - break; - } else - break; - ptr++; - ilen--; - } - - **out = '\0'; - *out += 1; - - return (const char*) ptr; -} - -static const char* markup_unescape2(const char *in, char **out, size_t *size) +static const char *markup_unescape2(const char *in, char **out, size_t *size) { unsigned int n; char temp[2], buf[7]; diff --git a/lib_acl/src/code/html_charset.h b/lib_acl/src/code/html_charset.h index 4e285c269..83a62de19 100644 --- a/lib_acl/src/code/html_charset.h +++ b/lib_acl/src/code/html_charset.h @@ -8193,7 +8193,7 @@ static const char *html_charmap[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; typedef struct { diff --git a/lib_acl/src/event/events_iocp.c b/lib_acl/src/event/events_iocp.c index 4a73e8296..8378bf82e 100644 --- a/lib_acl/src/event/events_iocp.c +++ b/lib_acl/src/event/events_iocp.c @@ -15,6 +15,7 @@ #include "stdlib/acl_vstream.h" #include "stdlib/acl_fifo.h" #include "stdlib/acl_mystring.h" +#include "net/acl_sane_socket.h" #include "event/acl_events.h" #endif /* ACL_PREPARE_COMPILE */ @@ -217,7 +218,7 @@ static void event_enable_listen(ACL_EVENT *eventp, ACL_VSTREAM *stream, { ACL_EVENT_FDTABLE *fdp = read_enable(eventp, stream, timeout, callback, context); - fdp->listener = 1; + fdp->listener = acl_is_listening_socket(ACL_VSTREAM_SOCK(stream)); } static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream, @@ -225,7 +226,7 @@ static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream, { ACL_EVENT_FDTABLE *fdp = read_enable(eventp, stream, timeout, callback, context); - fdp->listener = 0; + fdp->listener = acl_is_listening_socket(ACL_VSTREAM_SOCK(stream)); } static void event_enable_write(ACL_EVENT *eventp, ACL_VSTREAM *stream, diff --git a/lib_acl/src/event/events_kernel.c b/lib_acl/src/event/events_kernel.c index 338c0e15d..37a3954dc 100644 --- a/lib_acl/src/event/events_kernel.c +++ b/lib_acl/src/event/events_kernel.c @@ -25,6 +25,7 @@ #include "stdlib/acl_debug.h" #include "stdlib/acl_vstream.h" #include "stdlib/acl_fifo.h" +#include "net/acl_sane_socket.h" #include "stdlib/acl_meter_time.h" /* just for performance test */ #include "event/acl_events.h" @@ -220,7 +221,11 @@ static void event_enable_listen(ACL_EVENT *eventp, ACL_VSTREAM *stream, { ACL_EVENT_FDTABLE *fdp = read_enable(eventp, stream, timeout, callback, context); +#if defined(ACL_MACOSX) fdp->listener = 1; +#else + fdp->listener = acl_is_listening_socket(ACL_VSTREAM_SOCK(stream)); +#endif } static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream, @@ -228,7 +233,7 @@ static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream, { ACL_EVENT_FDTABLE *fdp = read_enable(eventp, stream, timeout, callback, context); - fdp->listener = 0; + fdp->listener = acl_is_listening_socket(ACL_VSTREAM_SOCK(stream)); } static void event_enable_write(ACL_EVENT *eventp, ACL_VSTREAM *stream, diff --git a/lib_acl/src/event/events_poll.c b/lib_acl/src/event/events_poll.c index 5cafadbb1..45f9f6c1a 100644 --- a/lib_acl/src/event/events_poll.c +++ b/lib_acl/src/event/events_poll.c @@ -19,6 +19,7 @@ #include "stdlib/acl_msg.h" #include "stdlib/acl_debug.h" #include "stdlib/acl_vstream.h" +#include "net/acl_sane_socket.h" #include "event/acl_events.h" #endif @@ -136,7 +137,11 @@ static void event_enable_listen(ACL_EVENT *eventp, ACL_VSTREAM *stream, { ACL_EVENT_FDTABLE *fdp = read_enable(eventp, stream, timeout, callback, context); +#if defined(ACL_MACOSX) fdp->listener = 1; +#else + fdp->listener = acl_is_listening_socket(ACL_VSTREAM_SOCK(stream)); +#endif } static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream, @@ -144,7 +149,7 @@ static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream, { ACL_EVENT_FDTABLE *fdp = read_enable(eventp, stream, timeout, callback, context); - fdp->listener = 0; + fdp->listener = acl_is_listening_socket(ACL_VSTREAM_SOCK(stream)); } static void event_enable_write(ACL_EVENT *eventp, ACL_VSTREAM *stream, diff --git a/lib_acl/src/event/events_select.c b/lib_acl/src/event/events_select.c index b12e7bc65..f4ca207a3 100644 --- a/lib_acl/src/event/events_select.c +++ b/lib_acl/src/event/events_select.c @@ -23,6 +23,7 @@ #include "stdlib/acl_msg.h" #include "stdlib/acl_debug.h" #include "stdlib/acl_vstream.h" +#include "net/acl_sane_socket.h" #include "event/acl_events.h" #endif @@ -129,7 +130,11 @@ static void event_enable_listen(ACL_EVENT *eventp, ACL_VSTREAM *stream, { ACL_EVENT_FDTABLE *fdp = read_enable(eventp, stream, timeout, callback, context); +#if defined(ACL_MACOSX) fdp->listener = 1; +#else + fdp->listener = acl_is_listening_socket(ACL_VSTREAM_SOCK(stream)); +#endif } static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream, @@ -137,7 +142,7 @@ static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream, { ACL_EVENT_FDTABLE *fdp = read_enable(eventp, stream, timeout, callback, context); - fdp->listener = 0; + fdp->listener = acl_is_listening_socket(ACL_VSTREAM_SOCK(stream)); } static void event_enable_write(ACL_EVENT *eventp, ACL_VSTREAM *stream, diff --git a/lib_acl/src/event/events_wmsg.c b/lib_acl/src/event/events_wmsg.c index b2bbb1cc0..8127c177b 100644 --- a/lib_acl/src/event/events_wmsg.c +++ b/lib_acl/src/event/events_wmsg.c @@ -16,6 +16,7 @@ #include "stdlib/acl_fifo.h" #include "stdlib/acl_mystring.h" #include "stdlib/acl_htable.h" +#include "net/acl_sane_socket.h" #include "event/acl_events.h" #endif /* ACL_PREPARE_COMPILE */ @@ -167,7 +168,7 @@ static void event_enable_listen(ACL_EVENT *eventp, ACL_VSTREAM *stream, { ACL_EVENT_FDTABLE *fdp = read_enable(eventp, stream, timeout, callback, context); - fdp->listener = 1; + fdp->listener = acl_is_listening_socket(ACL_VSTREAM_SOCK(stream)); } static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream, @@ -175,7 +176,7 @@ static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream, { ACL_EVENT_FDTABLE *fdp = read_enable(eventp, stream, timeout, callback, context); - fdp->listener = 0; + fdp->listener = acl_is_listening_socket(ACL_VSTREAM_SOCK(stream)); } static void event_enable_write(ACL_EVENT *eventp, ACL_VSTREAM *stream, diff --git a/lib_acl/src/master/template/acl_multi_server.c b/lib_acl/src/master/template/acl_multi_server.c index 4e422b732..b0d2dfa34 100644 --- a/lib_acl/src/master/template/acl_multi_server.c +++ b/lib_acl/src/master/template/acl_multi_server.c @@ -762,7 +762,7 @@ void acl_multi_server_main(int argc, char **argv, ACL_MULTI_SERVER_FN service,.. acl_msg_fatal("%s(%d)->%s: stream null, fd = %d", __FILE__, __LINE__, myname, fd); - acl_event_enable_read(__eventp, stream, 0, + acl_event_enable_listen(__eventp, stream, 0, __service_accept, stream); acl_close_on_exec(ACL_VSTREAM_SOCK(stream), ACL_CLOSE_ON_EXEC); __listen_streams[i] = stream; diff --git a/lib_acl/src/master/template/acl_single_server.c b/lib_acl/src/master/template/acl_single_server.c index abb7a8016..59d8f1e39 100644 --- a/lib_acl/src/master/template/acl_single_server.c +++ b/lib_acl/src/master/template/acl_single_server.c @@ -671,7 +671,7 @@ void acl_single_server_main(int argc, char **argv, ACL_SINGLE_SERVER_FN service, acl_var_single_rw_timeout, fdtype); __sstreams[i++] = stream; - acl_event_enable_read(__eventp, stream, 0, + acl_event_enable_listen(__eventp, stream, 0, __service_accept, stream); acl_close_on_exec(ACL_VSTREAM_SOCK(stream), ACL_CLOSE_ON_EXEC); } diff --git a/lib_acl/src/master/template/acl_trigger_server.c b/lib_acl/src/master/template/acl_trigger_server.c index 0ddfa3ac8..46a2daf75 100644 --- a/lib_acl/src/master/template/acl_trigger_server.c +++ b/lib_acl/src/master/template/acl_trigger_server.c @@ -694,7 +694,7 @@ void acl_trigger_server_main(int argc, char **argv, ACL_TRIGGER_SERVER_FN servic acl_msg_fatal("%s(%d)->%s: stream null, fd = %d", __FILE__, __LINE__, myname, fd); - acl_event_enable_read(__eventp, stream, 0, + acl_event_enable_listen(__eventp, stream, 0, __service_accept, stream); acl_close_on_exec(ACL_VSTREAM_SOCK(stream), ACL_CLOSE_ON_EXEC); } diff --git a/lib_acl/src/net/acl_sane_socket.c b/lib_acl/src/net/acl_sane_socket.c index 3590c0a1b..3bc70d1a4 100644 --- a/lib_acl/src/net/acl_sane_socket.c +++ b/lib_acl/src/net/acl_sane_socket.c @@ -42,7 +42,7 @@ struct SOCK_ADDR { }; #endif -int acl_getpeername(ACL_SOCKET sockfd, char *buf, size_t size) +int acl_getpeername(ACL_SOCKET fd, char *buf, size_t size) { struct SOCK_ADDR addr; struct sockaddr *sa = (struct sockaddr*) &addr; @@ -50,11 +50,11 @@ int acl_getpeername(ACL_SOCKET sockfd, char *buf, size_t size) char ip[32]; int port; - if (sockfd == ACL_SOCKET_INVALID || buf == NULL || size <= 0) + if (fd == ACL_SOCKET_INVALID || buf == NULL || size <= 0) return -1; memset(&addr, 0, sizeof(addr)); - if (getpeername(sockfd, sa, &len) == -1) + if (getpeername(fd, sa, &len) == -1) return -1; #ifndef ACL_WINDOWS @@ -62,7 +62,7 @@ int acl_getpeername(ACL_SOCKET sockfd, char *buf, size_t size) memset(&addr, 0, sizeof(addr)); len = sizeof(addr); - if (getsockname(sockfd, sa, &len) == -1) + if (getsockname(fd, sa, &len) == -1) return -1; snprintf(buf, size, "%s", addr.sa.un.sun_path); @@ -78,7 +78,7 @@ int acl_getpeername(ACL_SOCKET sockfd, char *buf, size_t size) return 0; } -int acl_getsockname(ACL_SOCKET sockfd, char *buf, size_t size) +int acl_getsockname(ACL_SOCKET fd, char *buf, size_t size) { struct SOCK_ADDR addr; struct sockaddr *sa = (struct sockaddr*) &addr; @@ -86,12 +86,12 @@ int acl_getsockname(ACL_SOCKET sockfd, char *buf, size_t size) char ip[32]; int port; - if (sockfd == ACL_SOCKET_INVALID || buf == NULL || size <= 0) + if (fd == ACL_SOCKET_INVALID || buf == NULL || size <= 0) return -1; memset(&addr, 0, sizeof(addr)); - if (getsockname(sockfd, sa, &len) == -1) + if (getsockname(fd, sa, &len) == -1) return -1; #ifndef ACL_WINDOWS @@ -109,16 +109,16 @@ int acl_getsockname(ACL_SOCKET sockfd, char *buf, size_t size) return 0; } -int acl_getsocktype(ACL_SOCKET sockfd) +int acl_getsocktype(ACL_SOCKET fd) { struct SOCK_ADDR addr; struct sockaddr *sa = (struct sockaddr*) &addr; socklen_t len = sizeof(addr); - if (sockfd == ACL_SOCKET_INVALID) + if (fd == ACL_SOCKET_INVALID) return -1; - if (getsockname(sockfd, sa, &len) == -1) + if (getsockname(fd, sa, &len) == -1) return -1; #ifndef ACL_WINDOWS @@ -129,3 +129,22 @@ int acl_getsocktype(ACL_SOCKET sockfd) return AF_INET; return -1; } + +int acl_check_socket(ACL_SOCKET fd) +{ + int val, ret; + socklen_t len = sizeof(val); + + ret = getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, (void*) &val, &len); + if (ret == -1) + return -1; + else if (val) + return 1; + else + return 0; +} + +int acl_is_listening_socket(ACL_SOCKET fd) +{ + return acl_check_socket(fd) == 1; +} diff --git a/lib_acl/src/stdlib/acl_vstream.c b/lib_acl/src/stdlib/acl_vstream.c index eccc24892..185085aab 100644 --- a/lib_acl/src/stdlib/acl_vstream.c +++ b/lib_acl/src/stdlib/acl_vstream.c @@ -34,6 +34,7 @@ #include "stdlib/acl_array.h" #include "stdlib/acl_iostuff.h" #include "net/acl_sane_inet.h" +#include "net/acl_sane_socket.h" #include "stdlib/acl_vstream.h" #endif @@ -370,8 +371,12 @@ int acl_vstream_nonb_readn(ACL_VSTREAM *fp, char *buf, int size) int flags; #endif - if (fp == NULL || buf == NULL || size <= 0) + if (fp == NULL || buf == NULL || size <= 0) { + acl_msg_error("%s(%d), %s: fp %s, buf %s, size %d", + __FILE__, __LINE__, myname, fp ? "not null" : "null", + buf ? "not null" : "null", size); return ACL_VSTREAM_EOF; + } if (fp->read_cnt < 0) acl_msg_fatal("%s, %s(%d): read_cnt(%d) < 0, fd(%d)", @@ -482,20 +487,22 @@ int acl_vstream_nonb_readn(ACL_VSTREAM *fp, char *buf, int size) int acl_vstream_probe_status(ACL_VSTREAM *fp) { #ifdef ACL_UNIX - const char *myname = "acl_vstream_probe_status"; int flags; #endif int ch; int rw_timeout; - if (fp == NULL) + if (fp == NULL) { + acl_msg_error("%s(%d), %s: fp null", + __FILE__, __LINE__, __FUNCTION__); return -1; + } #ifdef ACL_UNIX flags = fcntl(ACL_VSTREAM_SOCK(fp), F_GETFL, 0); if (flags < 0) { acl_msg_error("%s, %s(%d): fcntl error(%s), fd=%d", - myname, __FILE__, __LINE__, + __FUNCTION__, __FILE__, __LINE__, acl_last_serror(), ACL_VSTREAM_SOCK(fp)); return -1; } @@ -522,7 +529,7 @@ int acl_vstream_probe_status(ACL_VSTREAM *fp) flags = fcntl(ACL_VSTREAM_SOCK(fp), F_SETFL, flags); if (flags < 0) { acl_msg_error("%s, %s(%d): fcntl error(%s), fd=%d", - myname, __FILE__, __LINE__, + __FUNCTION__, __FILE__, __LINE__, acl_last_serror(), ACL_VSTREAM_SOCK(fp)); return -1; } @@ -556,6 +563,12 @@ int acl_vstream_ungetc(ACL_VSTREAM *fp, int ch) { unsigned char c; + if (fp == NULL) { + acl_msg_error("%s(%d), %s: fp null", + __FILE__, __LINE__, __FUNCTION__); + return -1; + } + c = (unsigned char) ch; (void) acl_vstream_unread(fp, &c, 1); return ch; @@ -584,8 +597,18 @@ static void *__vstream_memmove(ACL_VSTREAM *fp, size_t n) int acl_vstream_unread(ACL_VSTREAM *fp, const void *ptr, size_t length) { - size_t capacity = fp->read_ptr - fp->read_buf; - ssize_t k = (ssize_t) (capacity - length); + size_t capacity; + ssize_t k; + + if (fp == NULL || ptr == NULL || length == 0) { + acl_msg_error("%s(%d), %s: fp %s, ptr %s, length %d", + __FILE__, __LINE__, __FUNCTION__, fp ? "not null" + : "null", ptr ? "not null" : "null", (int) length); + return -1; + } + + capacity = fp->read_ptr - fp->read_buf; + k = (ssize_t) (capacity - length); /* 如果读缓冲中前部分空间不足, 则需要调整数据位置或扩充读缓冲区空间 */ @@ -641,9 +664,13 @@ int acl_vstream_bfcp_some(ACL_VSTREAM *fp, void *vptr, size_t maxlen) int n; /* input params error */ - if (fp == NULL || vptr == NULL || maxlen <= 0) - acl_msg_fatal("%s, %s(%d): input error", - myname, __FILE__, __LINE__); + if (fp == NULL || vptr == NULL || maxlen == 0) { + acl_msg_error("%s, %s(%d): input error, fp %s, vptr %s, " + "maxlen %d", myname, __FILE__, __LINE__, fp ? + "not null" : "null", vptr ? "not null" : "null", + (int) maxlen); + return ACL_VSTREAM_EOF; + } /* internal fatal error */ if (fp->read_cnt < 0) @@ -676,11 +703,16 @@ int acl_vstream_bfcp_some(ACL_VSTREAM *fp, void *vptr, size_t maxlen) int acl_vstream_gets(ACL_VSTREAM *fp, void *vptr, size_t maxlen) { + const char *myname = "acl_vstream_gets"; int n, ch; unsigned char *ptr; - if (fp == NULL || vptr == NULL || maxlen <= 0) + if (fp == NULL || vptr == NULL || maxlen <= 0) { + acl_msg_error("%s(%d), %s: fp %s, vptr %s, maxlen %d", + __FILE__, __LINE__, myname, fp ? "not null" : "null", + vptr ? "not null" : "null", (int) maxlen); return ACL_VSTREAM_EOF; + } ptr = (unsigned char *) vptr; for (n = 1; n < (int) maxlen; n++) { @@ -720,6 +752,7 @@ int acl_vstream_gets(ACL_VSTREAM *fp, void *vptr, size_t maxlen) int acl_vstream_readtags(ACL_VSTREAM *fp, void *vptr, size_t maxlen, const char *tag, size_t taglen) { + const char *myname = "acl_vstream_readtags"; int n, ch, matched = 0; unsigned char *ptr; const unsigned char *haystack; @@ -727,7 +760,13 @@ int acl_vstream_readtags(ACL_VSTREAM *fp, void *vptr, size_t maxlen, if (fp == NULL || vptr == NULL || maxlen <= 0 || tag == NULL || taglen <= 0) + { + acl_msg_error("%s(%d), %s: fp %s, vptr %s, maxlen %d, tag %s," + " taglen: %d", __FILE__, __LINE__, myname, + fp ? "not null" : "null", vptr ? "not null" : "null", + (int) maxlen, tag ? tag : "null", (int) taglen); return ACL_VSTREAM_EOF; + } needle_end = (const unsigned char *) tag; @@ -794,11 +833,16 @@ int acl_vstream_readtags(ACL_VSTREAM *fp, void *vptr, size_t maxlen, int acl_vstream_gets_nonl(ACL_VSTREAM *fp, void *vptr, size_t maxlen) { + const char *myname = "acl_vstream_gets_nonl"; int n, ch; unsigned char *ptr; - if (fp == NULL || vptr == NULL || maxlen <= 0) + if (fp == NULL || vptr == NULL || maxlen <= 0) { + acl_msg_error("%s(%d), %s: fp %s, vptr %s, maxlen %d", + __FILE__, __LINE__, myname, fp ? "not null" : "null", + vptr ? "not null" : "null", (int) maxlen); return ACL_VSTREAM_EOF; + } ptr = (unsigned char *) vptr; for (n = 1; n < (int) maxlen; n++) { @@ -844,10 +888,12 @@ int acl_vstream_readn(ACL_VSTREAM *fp, void *buf, size_t size) unsigned char *ptr; int n; - if (fp == NULL || buf == NULL || size == 0) - acl_msg_fatal("%s(%d): fp: %s, buf: %s, size: %d", + if (fp == NULL || buf == NULL || size == 0) { + acl_msg_error("%s(%d): fp %s, buf %s, size %d", myname, __LINE__, fp ? "not null" : "null", buf ? "not null" : "null", (int) size); + return ACL_VSTREAM_EOF; + } ptr = (unsigned char*) buf; @@ -888,11 +934,14 @@ int acl_vstream_read(ACL_VSTREAM *fp, void *buf, size_t size) { const char *myname = "acl_vstream_read"; - if (fp == NULL || buf == NULL || size == 0) - acl_msg_fatal("%s(%d): fp: %s, buf: %s, size: %d", + if (fp == NULL || buf == NULL || size == 0) { + acl_msg_error("%s(%d): fp: %s, buf: %s, size: %d", myname, __LINE__, fp ? "not null" : "null", buf ? "not null" : "null", (int) size); + return ACL_VSTREAM_EOF; + } + if (fp->read_cnt < 0) acl_msg_fatal("%s, %s(%d): read_cnt(%d) < 0", myname, __FILE__, __LINE__, (int) fp->read_cnt); @@ -958,9 +1007,12 @@ int acl_vstream_gets_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf, int *ready) const char *myname = "acl_vstream_gets_peek"; int n; - if (fp == NULL || buf == NULL || ready == NULL) - acl_msg_fatal("%s, %s(%d): invalid input", - myname, __FILE__, __LINE__); + if (fp == NULL || buf == NULL || ready == NULL) { + acl_msg_error("%s, %s(%d): fp %s, buf %s, ready: %s", myname, + __FILE__, __LINE__, fp ? "not null" : "null", buf ? + "not null" : "null", ready ? "not null" : "null"); + return ACL_VSTREAM_EOF; + } *ready = 0; n = (int) LEN(buf); @@ -1025,9 +1077,12 @@ int acl_vstream_gets_nonl_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf, int *ready) const char *myname = "acl_vstream_gets_nonl_peek"; int n; - if (fp == NULL || buf == NULL || ready == NULL) - acl_msg_fatal("%s, %s(%d): invalid input", - myname, __FILE__, __LINE__); + if (fp == NULL || buf == NULL || ready == NULL) { + acl_msg_fatal("%s, %s(%d): fp %s, buf %s, ready: %s", myname, + __FILE__, __LINE__, fp ? "not null" : "null", buf ? + "not null" : "null", ready ? "not null" : "null"); + return ACL_VSTREAM_EOF; + } *ready = 0; n = (int) LEN(buf); @@ -1089,10 +1144,9 @@ int acl_vstream_readn_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf, int cnt_saved = cnt; if (fp == NULL || buf == NULL || cnt <= 0 || ready == NULL) - acl_msg_fatal("%s, %s(%d): invalid input, fp: %s, " - "buf: %s, cnt: %d, ready: %s", myname, __FILE__, - __LINE__, fp ? "not null" : "null", - buf ? "not null" : "null", cnt, + acl_msg_fatal("%s, %s(%d): invalid input, fp: %s, buf: %s, " + "cnt: %d, ready: %s", myname, __FILE__, __LINE__, fp ? + "not null" : "null", buf ? "not null" : "null", cnt, ready ? "not null" : "null"); *ready = 0; @@ -1142,9 +1196,12 @@ int acl_vstream_read_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf) const char *myname = "acl_vstream_read_peek"; int n; - if (fp == NULL || buf == NULL) - acl_msg_fatal("%s, %s(%d): invalid input", - myname, __FILE__, __LINE__); + if (fp == NULL || buf == NULL) { + acl_msg_error("%s, %s(%d): fp %s, buf %s", myname, __FILE__, + __LINE__, fp ? "not null" : "null", + buf ? "not null" : "null"); + return ACL_VSTREAM_EOF; + } n = (int) LEN(buf); @@ -1175,6 +1232,12 @@ int acl_vstream_can_read(ACL_VSTREAM *fp) { const char *myname = "acl_vstream_can_read"; + if (fp == NULL) { + acl_msg_error("%s(%d), %s: fp null", + __FILE__, __LINE__, myname); + return ACL_VSTREAM_EOF; + } + if (fp->read_cnt < 0) acl_msg_fatal("%s, %s(%d): read_cnt(=%d) < 0", myname, __FILE__, __LINE__, (int) fp->read_cnt); @@ -1432,6 +1495,15 @@ TAG_AGAIN: int acl_vstream_write(ACL_VSTREAM *fp, const void *vptr, int dlen) { + const char *myname = "acl_vstream_write"; + + if (fp == NULL || vptr == NULL || dlen <= 0) { + acl_msg_error("%s(%d), %s: fp %s, vptr %s, dlen %d", __FILE__, + __LINE__, myname, fp ? "not null" : "null", + vptr ? "not null" : "null", dlen); + return ACL_VSTREAM_EOF; + } + if (fp->wbuf_dlen > 0) { if (acl_vstream_fflush(fp) == ACL_VSTREAM_EOF) return ACL_VSTREAM_EOF; @@ -1441,6 +1513,15 @@ int acl_vstream_write(ACL_VSTREAM *fp, const void *vptr, int dlen) int acl_vstream_writev(ACL_VSTREAM *fp, const struct iovec *vec, int count) { + const char *myname = "acl_vstream_writev"; + + if (fp == NULL || vec == NULL || count <= 0) { + acl_msg_error("%s(%d), %s: fp %s, vec %s, count %d", __FILE__, + __LINE__, myname, fp ? "not null" : "null", + vec ? "not null" : "null", count); + return ACL_VSTREAM_EOF; + } + if (fp->wbuf_dlen > 0) { if (acl_vstream_fflush(fp) == ACL_VSTREAM_EOF) return ACL_VSTREAM_EOF; @@ -1454,9 +1535,12 @@ int acl_vstream_writevn(ACL_VSTREAM *fp, const struct iovec *vec, int count) int n, i, dlen, k; struct iovec *vect; - if (count <= 0 || vec == NULL) - acl_msg_fatal("%s, %s(%d): invalid input", - myname, __FILE__, __LINE__); + if (fp == NULL || count <= 0 || vec == NULL) { + acl_msg_error("%s, %s(%d): fp %s, vec %s, count %d", myname, + __FILE__, __LINE__, fp ? "not null" : "null", + vec ? "not null" : "null", count); + return ACL_VSTREAM_EOF; + } if (fp->wbuf_dlen > 0) { if (acl_vstream_fflush(fp) == ACL_VSTREAM_EOF) @@ -1509,8 +1593,9 @@ int acl_vstream_vfprintf(ACL_VSTREAM *fp, const char *fmt, va_list ap) int n; if (fp == NULL || fmt == NULL || *fmt == 0) { - acl_msg_error("%s, %s(%d): fmt invalid", - myname, __FILE__, __LINE__); + acl_msg_error("%s, %s(%d): fp %s, fmt %s", + myname, __FILE__, __LINE__, fp ? "not null" : "null", + fmt && *fmt ? "not null" : "null"); return ACL_VSTREAM_EOF; } @@ -1657,8 +1742,12 @@ static int loop_writen(ACL_VSTREAM *fp, const void *vptr, size_t size) int acl_vstream_writen(ACL_VSTREAM *fp, const void *vptr, size_t dlen) { - if (fp == NULL || vptr == NULL || dlen <= 0) + if (fp == NULL || vptr == NULL || dlen == 0) { + acl_msg_error("%s(%d), %s: fp %s, vptr %s, dlen %d", __FILE__, + __LINE__, __FUNCTION__, fp ? "not null" : "null", + vptr ? "not null" : "null", (int) dlen); return ACL_VSTREAM_EOF; + } if (fp->wbuf_dlen > 0) { if (acl_vstream_fflush(fp) == ACL_VSTREAM_EOF) @@ -1669,8 +1758,12 @@ int acl_vstream_writen(ACL_VSTREAM *fp, const void *vptr, size_t dlen) int acl_vstream_buffed_writen(ACL_VSTREAM *fp, const void *vptr, size_t dlen) { - if (fp == NULL || vptr == NULL || dlen == 0) + if (fp == NULL || vptr == NULL || dlen == 0) { + acl_msg_error("%s(%d), %s: fp %s, vptr %s, dlen %d", __FILE__, + __LINE__, __FUNCTION__, fp ? "not null" : "null", + vptr ? "not null" : "null", (int) dlen); return ACL_VSTREAM_EOF; + } if (fp->wbuf == NULL) { fp->wbuf_size = 8192; @@ -1703,8 +1796,9 @@ int acl_vstream_buffed_vfprintf(ACL_VSTREAM *fp, const char *fmt, va_list ap) int n; if (fp == NULL || fmt == NULL || *fmt == 0) { - acl_msg_error("%s, %s(%d): fmt invalid", - myname, __FILE__, __LINE__); + acl_msg_error("%s, %s(%d): fp %s, fmt %s", + myname, __FILE__, __LINE__, fp ? "not null" : "null", + fmt && *fmt ? "not null" : "null"); return ACL_VSTREAM_EOF; } @@ -1837,6 +1931,12 @@ int acl_vstream_fsync(ACL_VSTREAM *fp) void acl_vstream_buffed_space(ACL_VSTREAM *fp) { + const char *myname = "acl_vstream_buffed_space"; + + if (fp == NULL) { + acl_msg_error("%s(%d): fp null", myname, __LINE__); + return; + } if (fp->wbuf == NULL) { fp->wbuf_size = 8192; fp->wbuf_dlen = 0; @@ -1937,11 +2037,24 @@ ACL_VSTREAM *acl_vstream_fdopen(ACL_SOCKET fd, unsigned int oflags, 需要给其分配读缓冲区 */ +#ifdef ACL_MACOSX if ((fdtype & ACL_VSTREAM_TYPE_LISTEN_INET) || (fdtype & ACL_VSTREAM_TYPE_LISTEN_UNIX)) { fdtype |= ACL_VSTREAM_TYPE_LISTEN; } +#endif + + if (acl_is_listening_socket(fd)) { + int ret = acl_getsocktype(fd); + if (ret == AF_INET) + fdtype |= ACL_VSTREAM_TYPE_LISTEN_INET; +#ifndef ACL_WINDOWS + else if (ret == AF_UNIX) + fdtype |= ACL_VSTREAM_TYPE_LISTEN_UNIX; +#endif + fdtype |= ACL_VSTREAM_TYPE_LISTEN; + } fp->read_buf = (unsigned char *) acl_mymalloc(buflen + 1); @@ -1992,6 +2105,10 @@ ACL_VSTREAM *acl_vstream_clone(const ACL_VSTREAM *from) ACL_VSTREAM_CLOSE_HANDLE *handle_from, *handle_to; int i, n; + if (from == NULL) + acl_msg_fatal("%s(%d), %s: from null", + __FILE__, __LINE__, myname); + to = (ACL_VSTREAM *) acl_mycalloc(1, sizeof(ACL_VSTREAM)); memcpy(to, from, sizeof(ACL_VSTREAM)); to->read_buf = (unsigned char *) @@ -2060,14 +2177,22 @@ ACL_VSTREAM *acl_vstream_clone(const ACL_VSTREAM *from) int acl_vstream_set_fdtype(ACL_VSTREAM *fp, int type) { + if (fp == NULL) { + acl_msg_error("%s(%d), %s: fp null", + __FILE__, __LINE__, __FUNCTION__); + return -1; + } + if (type == ACL_VSTREAM_TYPE_FILE) { fp->fread_fn = acl_file_read; fp->fwrite_fn = acl_file_write; fp->fclose_fn = acl_file_close; + return 0; } else if (type == ACL_VSTREAM_TYPE_SOCK) { fp->read_fn = acl_socket_read; fp->write_fn = acl_socket_write; fp->close_fn = acl_socket_close; + return 0; } return -1; @@ -2167,6 +2292,12 @@ void acl_vstream_ctl(ACL_VSTREAM *fp, int name,...) int n; char *ptr; + if (fp == NULL) { + acl_msg_error("%s(%d), %s: fp null", + __FILE__, __LINE__, myname); + return; + } + va_start(ap, name); for (; name != ACL_VSTREAM_CTL_END; name = va_arg(ap, int)) { switch (name) { @@ -2215,9 +2346,11 @@ acl_off_t acl_vstream_fseek2(ACL_VSTREAM *fp, acl_off_t offset, int whence) const char *myname = "acl_vstream_fseek2"; acl_off_t n; - if (fp == NULL || ACL_VSTREAM_FILE(fp) == ACL_FILE_INVALID) - acl_msg_fatal("%s, %s(%d): input error", + if (fp == NULL || ACL_VSTREAM_FILE(fp) == ACL_FILE_INVALID) { + acl_msg_error("%s, %s(%d): input error", myname, __FILE__, __LINE__); + return -1; + } if (fp->type != ACL_VSTREAM_TYPE_FILE) { acl_msg_error("%s, %s(%d): type(%d) not ACL_VSTREAM_TYPE_FILE", @@ -2275,9 +2408,11 @@ acl_off_t acl_vstream_fseek(ACL_VSTREAM *fp, acl_off_t offset, int whence) const char *myname = "acl_vstream_fseek"; acl_off_t n; - if (fp == NULL || ACL_VSTREAM_FILE(fp) == ACL_FILE_INVALID) - acl_msg_fatal("%s, %s(%d): input error", + if (fp == NULL || ACL_VSTREAM_FILE(fp) == ACL_FILE_INVALID) { + acl_msg_error("%s, %s(%d): input error", myname, __FILE__, __LINE__); + return -1; + } if (fp->type != ACL_VSTREAM_TYPE_FILE) { acl_msg_error("%s, %s(%d): type(%d) not ACL_VSTREAM_TYPE_FILE", @@ -2397,6 +2532,12 @@ SYS_SEEK: acl_off_t acl_vstream_ftell(ACL_VSTREAM *fp) { + if (fp == NULL) { + acl_msg_error("%s(%d), %s: fp null", + __FILE__, __LINE__, __FUNCTION__); + return -1; + } + /* 先定位当前位置,然后再减去读缓冲区里的数据长度 */ fp->sys_offset = acl_lseek(ACL_VSTREAM_FILE(fp), 0, SEEK_CUR); fp->offset = fp->sys_offset; @@ -2409,6 +2550,12 @@ int acl_file_ftruncate(ACL_VSTREAM *fp, acl_off_t length) const char *myname = "acl_file_ftruncate"; ACL_FILE_HANDLE hf = ACL_VSTREAM_FILE(fp); + if (fp == NULL) { + acl_msg_error("%s(%d), %s: fp null", + __FILE__, __LINE__, __FUNCTION__); + return -1; + } + /* 参见:C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\crt\src * osfinfo.c * _open_osfhandle: 将ACL_WINDOWS API的文件句柄转换为标准C的文件句柄 @@ -2467,6 +2614,12 @@ int acl_file_ftruncate(ACL_VSTREAM *fp, acl_off_t length) { ACL_FILE_HANDLE hf = ACL_VSTREAM_FILE(fp); + if (fp == NULL) { + acl_msg_error("%s(%d), %s: fp null", + __FILE__, __LINE__, __FUNCTION__); + return -1; + } + return ftruncate(hf, length); } @@ -2529,6 +2682,12 @@ void acl_vstream_reset(ACL_VSTREAM *fp) void acl_vstream_free(ACL_VSTREAM *fp) { + if (fp == NULL) { + acl_msg_error("%s(%d), %s: fp null", + __FILE__, __LINE__, __FUNCTION__); + return; + } + if (fp->nrefer > 0) { /* 设置延迟释放标志位 */ fp->flag |= ACL_VSTREAM_FLAG_DEFER_FREE; @@ -2587,6 +2746,12 @@ int acl_vstream_close(ACL_VSTREAM *fp) const char *myname = "acl_vstream_close"; int ret = 0; + if (fp == NULL) { + acl_msg_error("%s(%d), %s: fp null", + __FILE__, __LINE__, __FUNCTION__); + return -1; + } + if (fp->nrefer > 0) { /* 设置延迟释放标志位 */ fp->flag |= ACL_VSTREAM_FLAG_DEFER_FREE; @@ -2700,6 +2865,13 @@ static void set_sock_addr(struct sockaddr_in *saddr, const char *addr) void acl_vstream_set_local(ACL_VSTREAM *fp, const char *addr) { + if (fp == NULL || addr == NULL) { + acl_msg_error("%s(%d), %s: fp %s, addr %s", + __FILE__, __LINE__, __FUNCTION__, + fp ? "not null" : "null", addr ? addr : "null"); + return; + } + if (fp->addr_local == __empty_string || fp->addr_local == NULL) fp->addr_local = acl_mystrdup(addr); else { @@ -2723,6 +2895,13 @@ void acl_vstream_set_local_addr(ACL_VSTREAM *fp, const struct sockaddr_in *sa) int port; char ip[64], addr[64]; + if (fp == NULL || sa == NULL) { + acl_msg_error("%s(%d), %s: fp %s, sa %s", __FILE__, __LINE__, + __FUNCTION__, fp ? "not null" : "null", + sa ? "not null" : "null"); + return; + } + if (fp->sa_local == NULL) { fp->sa_local_size = sizeof(struct sockaddr_in); fp->sa_local = (struct sockaddr_in*) @@ -2747,6 +2926,13 @@ void acl_vstream_set_local_addr(ACL_VSTREAM *fp, const struct sockaddr_in *sa) void acl_vstream_set_peer(ACL_VSTREAM *fp, const char *addr) { + if (fp == NULL || addr == NULL) { + acl_msg_error("%s(%d), %s: fp %s, addr %s", __FILE__, __LINE__, + __FUNCTION__, fp ? "not null" : "null", + addr ? "not null" : "null"); + return; + } + if (fp->addr_peer == __empty_string || fp->addr_peer == NULL) fp->addr_peer = acl_mystrdup(addr); else { @@ -2770,6 +2956,13 @@ void acl_vstream_set_peer_addr(ACL_VSTREAM *fp, const struct sockaddr_in *sa) int port; char ip[64], addr[64]; + if (fp == NULL || sa == NULL) { + acl_msg_error("%s(%d), %s: fp %s, sa %s", __FILE__, __LINE__, + __FUNCTION__, fp ? "not null" : "null", + sa ? "not null" : "null"); + return; + } + if (fp->sa_peer == NULL) { fp->sa_peer_size = sizeof(struct sockaddr_in); fp->sa_peer = (struct sockaddr_in*) @@ -2794,6 +2987,13 @@ void acl_vstream_set_peer_addr(ACL_VSTREAM *fp, const struct sockaddr_in *sa) void acl_vstream_set_path(ACL_VSTREAM *fp, const char *path) { + if (fp == NULL || path == NULL) { + acl_msg_error("%s(%d), %s: fp %s, path %s", __FILE__, __LINE__, + __FUNCTION__, fp ? "not null" : "null", + path ? "not null" : "null"); + return; + } + if (fp->path == __empty_string || fp->path == NULL) fp->path = acl_mystrdup(path); else { @@ -2804,6 +3004,12 @@ void acl_vstream_set_path(ACL_VSTREAM *fp, const char *path) void acl_vstream_call_close_handles(ACL_VSTREAM *fp) { + if (fp == NULL) { + acl_msg_error("%s(%d), %s: fp null", + __FILE__, __LINE__, __FUNCTION__); + return; + } + if (fp->close_handle_lnk != NULL) { ACL_VSTREAM_CLOSE_HANDLE *close_handle; int i, n = acl_array_size(fp->close_handle_lnk); @@ -2838,9 +3044,12 @@ void acl_vstream_add_close_handle(ACL_VSTREAM *fp, ACL_VSTREAM_CLOSE_HANDLE *close_handle; ACL_ITER iter; - if (fp == NULL) - acl_msg_fatal("%s, %s(%d): fp null", + if (fp == NULL) { + acl_msg_error("%s, %s(%d): fp null", myname, __FILE__, __LINE__); + return; + } + if (fp->close_handle_lnk == NULL) acl_msg_fatal("%s, %s(%d): close_handle_lnk null", myname, __FILE__, __LINE__); @@ -2942,16 +3151,24 @@ const char *acl_vstream_strerror(ACL_VSTREAM *fp) { static char err[] = "input error"; - if (fp == NULL) + if (fp == NULL) { + acl_msg_error("%s(%d), %s: fp null", + __FILE__, __LINE__, __FUNCTION__); return err; + } return fp->errbuf; } int acl_vstream_add_object(ACL_VSTREAM *fp, const char *key, void *obj) { - if (fp == NULL || key == NULL || *key == 0 || obj == NULL) + if (fp == NULL || key == NULL || *key == 0 || obj == NULL) { + acl_msg_error("%s(%d), %s: fp %s, key %s, obj %s", + __FILE__, __LINE__, __FUNCTION__, + fp ? "not null" : "null", key && *key ? key : "null", + obj ? "not null" : "null"); return -1; + } if (fp->objs_table == NULL) fp->objs_table = acl_htable_create(5, ACL_HTABLE_FLAG_KEY_LOWER); @@ -2962,15 +3179,24 @@ int acl_vstream_add_object(ACL_VSTREAM *fp, const char *key, void *obj) int acl_vstream_del_object(ACL_VSTREAM *fp, const char *key) { - if (fp == NULL || fp->objs_table == NULL || key == NULL || *key == 0) + if (fp == NULL || fp->objs_table == NULL || key == NULL || *key == 0) { + acl_msg_error("%s(%d), %s: fp %s, key %s", __FILE__, __LINE__, + __FUNCTION__, fp ? "not null" : "null", + key && *key ? key : "null"); return -1; + } return acl_htable_delete(fp->objs_table, key, NULL); } void *acl_vstream_get_object(ACL_VSTREAM *fp, const char *key) { - if (fp == NULL || fp->objs_table == NULL || key == NULL || *key == 0) + if (fp == NULL || fp->objs_table == NULL || key == NULL || *key == 0) { + acl_msg_error("%s(%d), %s: fp %s, key %s", __FILE__, __LINE__, + __FUNCTION__, fp ? "not null" : "null", + key && *key ? key : "null"); return NULL; + } + return acl_htable_find(fp->objs_table, key); } diff --git a/lib_acl/src/stdlib/memory/acl_default_malloc.c b/lib_acl/src/stdlib/memory/acl_default_malloc.c index 66a43d5e0..ddefb1223 100644 --- a/lib_acl/src/stdlib/memory/acl_default_malloc.c +++ b/lib_acl/src/stdlib/memory/acl_default_malloc.c @@ -173,9 +173,11 @@ void *acl_default_malloc(const char *filename, int line, size_t len) else pname = __FILENAME_UNKNOWN; - if (len < 1) - acl_msg_fatal("%s(%d), %s: malloc: length %ld invalid", + if (len < 1) { + acl_msg_warn("%s(%d), %s: malloc: length %ld invalid", pname, line, myname, (long) len); + len = 128; + } new_len = SPACE_FOR(len); if (new_len <= 0) @@ -240,9 +242,15 @@ void *acl_default_realloc(const char *filename, int line, return acl_default_malloc(pname, line, len); #endif - if (len < 1) - acl_msg_fatal("%s(%d)->%s: realloc: requested length %ld", + if (len < 1) { + acl_msg_warn("%s(%d)->%s: realloc: requested length %ld", pname, line, myname, (long) len); + len = 128; + } + + if (ptr == NULL) + return acl_default_malloc(pname, line, len); + CHECK_IN_PTR(ptr, real_ptr, old_len, pname, line); new_len = SPACE_FOR(len); diff --git a/lib_acl/src/xml/acl_xml2.c b/lib_acl/src/xml/acl_xml2.c index 83fa09dc4..8422200af 100644 --- a/lib_acl/src/xml/acl_xml2.c +++ b/lib_acl/src/xml/acl_xml2.c @@ -497,8 +497,9 @@ size_t acl_xml2_mmap_extend(ACL_XML2 *xml) const char *myname = "acl_xml2_mmap_extend"; size_t n; - if (xml->len >= xml->size) + if (xml->ptr >= xml->addr + xml->size) return 0; + if (xml->block == 0) return 0; @@ -518,6 +519,25 @@ size_t acl_xml2_mmap_extend(ACL_XML2 *xml) n = xml->size - xml->len; if (n > xml->block) n = xml->block; + + return acl_xml2_mmap_extend_size(xml, n); +} + +size_t acl_xml2_mmap_extend_size(ACL_XML2 *xml, size_t size) +{ + const char *myname = "acl_xml2_mmap_extend_size"; + size_t n; + + if (size == 0) + size = xml->block; + + if (xml->ptr >= xml->addr + xml->size) + return 0; + + n = xml->size - xml->len; + if (n > size) + n = size; + xml->len += n; xml->off += n; diff --git a/lib_acl/src/xml/acl_xml2_parse.c b/lib_acl/src/xml/acl_xml2_parse.c index b928d67d1..c545e5a6f 100644 --- a/lib_acl/src/xml/acl_xml2_parse.c +++ b/lib_acl/src/xml/acl_xml2_parse.c @@ -219,7 +219,7 @@ static void cdata_prepare(ACL_XML2 *xml) ACL_XML2_NODE *curr_node = xml->curr_node; char *src, *dst; - if (xml->len <= MIN_LEN || curr_node->ltag_size <= cdata_len) + if (xml->len <= MIN_LEN || curr_node->ltag_size < cdata_len) return; /* compute the max bytes for data copying */ diff --git a/lib_acl/src/xml/acl_xml2_util.c b/lib_acl/src/xml/acl_xml2_util.c index c397bd5e6..9b0273a1d 100644 --- a/lib_acl/src/xml/acl_xml2_util.c +++ b/lib_acl/src/xml/acl_xml2_util.c @@ -1,5 +1,6 @@ #include "StdAfx.h" #include + #ifndef ACL_PREPARE_COMPILE #include "stdlib/acl_vstream.h" @@ -269,19 +270,26 @@ int acl_xml2_removeElementAttr(ACL_XML2_NODE *node, const char *name) return 0; } +/***************************************************************************/ + +#define MIN 1 + static const char *string_copy(const char *in, ACL_XML2 *xml) { - if (xml->len < 1) + if (xml->len < MIN && acl_xml2_mmap_extend(xml) < MIN) return in; - xml->len--; - - while (*in != 0 && xml->len > 0) { + while (*in != 0 && xml->len > MIN) { *xml->ptr++ = *in++; xml->len--; + if (xml->len < MIN && acl_xml2_mmap_extend(xml) < MIN) + return in; } - *xml->ptr++ = 0; + if (xml->len > MIN || acl_xml2_mmap_extend(xml) > MIN) { + *xml->ptr++ = 0; + xml->len--; + } return in; } @@ -293,7 +301,9 @@ void acl_xml2_node_set_text(ACL_XML2_NODE *node, const char *text) node->text = node->xml->ptr; string_copy(text, node->xml); - node->text_size = node->xml->ptr - node->text; + node->text_size = node->xml->ptr - node->text ; + if (node->text_size > 0) + node->text_size--; } ACL_XML2_NODE *acl_xml2_create_node(ACL_XML2 *xml, const char* tag, @@ -306,11 +316,15 @@ ACL_XML2_NODE *acl_xml2_create_node(ACL_XML2 *xml, const char* tag, node->ltag = xml->ptr; string_copy(tag, xml); node->ltag_size = xml->ptr - node->ltag; + if (node->ltag_size > 0) + node->ltag_size--; if (text && *text) { node->text = xml->ptr; string_copy(text, xml); node->text_size = xml->ptr - node->text; + if (node->text_size > 0) + node->text_size--; } return node; @@ -324,11 +338,16 @@ ACL_XML2_ATTR *acl_xml2_node_add_attr(ACL_XML2_NODE *node, const char *name, acl_assert(name && *name); attr->name = node->xml->ptr; string_copy(name, node->xml); + attr->name_size = node->xml->ptr - attr->name; + if (attr->name_size > 0) + attr->name_size--; if (value && *value) { attr->value = node->xml->ptr; string_copy(value, node->xml); attr->value_size = node->xml->ptr - attr->value; + if (attr->value_size > 0) + attr->value_size--; } return attr; @@ -357,6 +376,8 @@ ACL_XML2_ATTR *acl_xml2_addElementAttr(ACL_XML2_NODE *node, attr->value = node->xml->ptr; string_copy(value, node->xml); attr->value_size = node->xml->ptr - attr->value; + if (attr->value_size > 0) + attr->value_size--; return attr; } @@ -364,63 +385,74 @@ ACL_XML2_ATTR *acl_xml2_addElementAttr(ACL_XML2_NODE *node, attr->name = node->xml->ptr; string_copy(name, node->xml); attr->name_size = node->xml->ptr - attr->name; + if (attr->name_size > 0) + attr->name_size--; attr->value = node->xml->ptr; string_copy(value, node->xml); attr->value_size = node->xml->ptr - attr->value; + if (attr->value_size > 0) + attr->value_size--; acl_array_append(node->attr_list, attr); return attr; } +/***************************************************************************/ + static const char *escape_append(ACL_XML2 *xml, const char *in, int quoted) { - const char *left; + const char *next = in, *last = in; + size_t len = strlen(in); - if (xml->len == 0) - return 0; + if (xml->len < MIN && acl_xml2_mmap_extend(xml) < MIN) + return next; if (quoted) { *xml->ptr++ = '"'; xml->len--; } - left = acl_xml_encode2(in, strlen(in), &xml->ptr, &xml->len); - if (*left != 0) - return left; + while (len > 0) { + size_t n = acl_xml_encode2(&next, len, xml->ptr, xml->len); + if (n < MIN && acl_xml2_mmap_extend(xml) < MIN) + return next; + len -= next - last; + last = next; + xml->ptr += n; + xml->len -= n; + } - if (xml->len == 0) - return left; - - xml->ptr--; - xml->len++; + if (xml->len < MIN && acl_xml2_mmap_extend(xml) < MIN) + return next; if (quoted) { *xml->ptr++ = '"'; xml->len--; } - if (xml->len > 0) + if (xml->len >= MIN) *xml->ptr = 0; - return left; + return next; } +#define CHECK_SPACE(x) \ + if ((x)->len < MIN && acl_xml2_mmap_extend((x)) < MIN) \ + break; + static const char *mem_copy(ACL_XML2 *xml, const char *in) { while (*in != 0 && xml->len > 0) { *xml->ptr++ = *in++; xml->len--; + CHECK_SPACE(xml); } return in; } -#define CHECK_SPACE(x) \ - if ((x)->len == 0 && acl_xml2_mmap_extend((x)) == 0) \ - break; - const char *acl_xml2_build(ACL_XML2 *xml) { ACL_XML2_ATTR *attr; @@ -428,9 +460,10 @@ const char *acl_xml2_build(ACL_XML2 *xml) ACL_ITER iter1, iter2; char *res = xml->ptr; - if (xml->len == 0) + if (xml->len < MIN) return xml->addr; + /* reserve one space for the last '\0 */ xml->len--; acl_foreach(iter1, xml) { @@ -438,7 +471,15 @@ const char *acl_xml2_build(ACL_XML2 *xml) CHECK_SPACE(xml); node = (ACL_XML2_NODE*) iter1.data; - if (ACL_XML2_IS_COMMENT(node)) { + + if (ACL_XML2_IS_CDATA(node)) { + mem_copy(xml, "text_size > 0) { + mem_copy(xml, node->text); + CHECK_SPACE(xml); + } + } else if (ACL_XML2_IS_COMMENT(node)) { mem_copy(xml, ""); CHECK_SPACE(xml); - - continue; - } - if (node->flag & ACL_XML2_F_META_QM) { + } else if (node->flag & ACL_XML2_F_META_QM) { mem_copy(xml, "?>"); CHECK_SPACE(xml); - - continue; - } - if (node->flag & ACL_XML2_F_META_EM) { + } else if (node->flag & ACL_XML2_F_META_EM) { *xml->ptr++ = '>'; xml->len--; CHECK_SPACE(xml); - - continue; - } - if (node->text_size == 0) { + } else if (node->text_size == 0) { mem_copy(xml, ">text) > 0) { + acl_vstring_strcat(buf, STR(node->text)); + } + } else if (ACL_XML_IS_COMMENT(node)) { + acl_vstring_strcat(buf, ""); - continue; - } - if (node->flag & ACL_XML_F_META_QM) { + } else if (node->flag & ACL_XML_F_META_QM) { acl_vstring_strcat(buf, "?>"); - continue; - } - if (node->flag & ACL_XML_F_META_EM) { + } else if (node->flag & ACL_XML_F_META_EM) { ACL_VSTRING_ADDCH(buf, '>'); - continue; - } - if (LEN(node->text) == 0) { + } else if (LEN(node->text) == 0) { acl_vstring_strcat(buf, ">ltag), 0, tmp); ACL_VSTRING_ADDCH(buf, '>'); diff --git a/lib_acl_cpp/Makefile b/lib_acl_cpp/Makefile index 6a6f8ba05..916522075 100644 --- a/lib_acl_cpp/Makefile +++ b/lib_acl_cpp/Makefile @@ -1,10 +1,10 @@ SHELL = /bin/sh -CC = ${ENV_CC} #CC = g++ -AR = ar +CC = ${ENV_CPP} +AR = ${ENV_AR} ARFL = rv #ARFL = cru -RANLIB = ranlib +RANLIB = ${ENV_RANLIB} FLAGS = ${ENV_FLAGS} @@ -39,6 +39,14 @@ ifeq ($(CC),) CC = g++ endif +ifeq ($(AR),) + AR = ar +endif + +ifeq ($(RANLIB),) + RANLIB = ranlib +endif + ifeq ($(findstring HAS_POLARSSL, $(FLAGS)), HAS_POLARSSL) CFLAGS += -DHAS_POLARSSL endif diff --git a/lib_acl_cpp/changes.txt b/lib_acl_cpp/changes.txt index a09fa08c9..2cc670a5e 100644 --- a/lib_acl_cpp/changes.txt +++ b/lib_acl_cpp/changes.txt @@ -1,5 +1,26 @@ 修改历史列表: +----------------------------------------------------------------------- +400) 2016.1.15 +400.1) feature: redis 库增加了出错日志输出,便于运行时进行信息调试 + +399) 2016.1.11 +399.1) feature: fstream 类中增加了方法 remove 用于删除文件 + +398) 2016.1.6 +398.1) feature: 增加类 db_guard 用于自动释放从数据库连接池中获取的连接对象 + +397) 2016.1.5 +397.1) feature: db_handle/db_mysql 类在进行查询前优先释放上次的查询结果,以免使用 +者忘记释放而造成内存泄露 + +396) 2016.1.4 +396.1) feature: mime.cpp, mime_head.cpp 支持更多的 Content-Type 类型 + +395) 2016.1.3 +395.1) bugfix: db_mysql.cpp 中调用 __mysql_open 时如果出错记日志时应判断 +每个参数是否为 NULL + ----------------------------------------------------------------------- 394) 2015.12.29 394.1) bugfix: redis_key 类中的 type 函数命令少一个 hash 类型 diff --git a/lib_acl_cpp/include/acl_cpp/connpool/connect_manager.hpp b/lib_acl_cpp/include/acl_cpp/connpool/connect_manager.hpp index 857432514..5be2ffe07 100644 --- a/lib_acl_cpp/include/acl_cpp/connpool/connect_manager.hpp +++ b/lib_acl_cpp/include/acl_cpp/connpool/connect_manager.hpp @@ -18,8 +18,8 @@ class connect_monitor; class ACL_CPP_API connect_manager { public: - connect_manager(); - virtual ~connect_manager(); + connect_manager(void); + virtual ~connect_manager(void); /** * 初始化所有服务器的连接池,该函数内部调用 set 过程添加每个服务的连接池 @@ -53,10 +53,22 @@ public: /** * 设置连接池失败后重试的时间时间隔(秒),该函数可以在程序运行时被调用,内部自动加锁 * @param n {int} 当该值 <= 0 时,若连接池出现问题则会立即被重试 - * @return {void} */ void set_retry_inter(int n); + /** + * 设置连接池中空闲连接的空闲生存周期 + * @param ttl {time_t} 空闲连接的生存周期,当该值 < 0 则表示空闲连接不过期, + * == 0 时表示立刻过期,> 0 表示空闲该时间段后将被释放 + */ + void set_idle_ttl(time_t ttl); + + /** + * 设置自动检查空闲连接的时间间隔,缺省值为 30 秒 + * @param n {int} 时间间隔 + */ + void set_check_inter(int n); + /** * 从连接池集群中删除某个地址的连接池,该函数可以在程序运行过程中 * 被调用,因为内部会自动加锁 @@ -184,6 +196,8 @@ protected: locker lock_; // 访问 pools_ 时的互斥锁 int stat_inter_; // 统计访问量的定时器间隔 int retry_inter_; // 连接池失败后重试的时间间隔 + time_t idle_ttl_; // 空闲连接的生命周期 + int check_inter_; // 检查空闲连接的时间间隔 connect_monitor* monitor_; // 后台检测线程句柄 // 设置除缺省服务之外的服务器集群 diff --git a/lib_acl_cpp/include/acl_cpp/db/db_handle.hpp b/lib_acl_cpp/include/acl_cpp/db/db_handle.hpp index 234796599..324847840 100644 --- a/lib_acl_cpp/include/acl_cpp/db/db_handle.hpp +++ b/lib_acl_cpp/include/acl_cpp/db/db_handle.hpp @@ -383,9 +383,11 @@ public: const db_row* get_first_row() const; /** - * 释放上次查询的结果,当查询完成后,必须调用该函数来释放 - * 不次查询的结果,该函数被多次调用并无害处,因为当第一次 - * 调用时会自动将内部变量 result_ 置空 + * 释放上次查询的结果,当查询完成后,调用该函数来释放上次查询的结果,该函数被 + * 多次调用并无害处,因为当第一次调用时会自动将内部变量 result_ 置空, + * 另外,要求子类必须在每次执行 SQL 查询前先调用此方法,以免用户忘记 + * 调用而造成内存泄露;此外,本类对象在析构时会自动再调用本方法释放可能 + * 未释放的内存 */ void free_result(); diff --git a/lib_acl_cpp/include/acl_cpp/db/db_pool.hpp b/lib_acl_cpp/include/acl_cpp/db/db_pool.hpp index da4ec5f23..c0da71fe8 100644 --- a/lib_acl_cpp/include/acl_cpp/db/db_pool.hpp +++ b/lib_acl_cpp/include/acl_cpp/db/db_pool.hpp @@ -1,6 +1,7 @@ #pragma once #include "acl_cpp/acl_cpp_define.hpp" #include +#include "acl_cpp/db/db_handle.hpp" #include "acl_cpp/connpool/connect_pool.hpp" namespace acl { @@ -58,4 +59,11 @@ public: } }; +class ACL_CPP_API db_guard : public connect_guard +{ +public: + db_guard(db_pool& pool) : connect_guard(pool) {} + ~db_guard(void); +}; + } // namespace acl diff --git a/lib_acl_cpp/include/acl_cpp/mime/mime.hpp b/lib_acl_cpp/include/acl_cpp/mime/mime.hpp index a63e4c59e..0c5e21718 100644 --- a/lib_acl_cpp/include/acl_cpp/mime/mime.hpp +++ b/lib_acl_cpp/include/acl_cpp/mime/mime.hpp @@ -274,11 +274,11 @@ public: /** * 设置邮件头的内容类型: Content-Type: text/plain - * @param ctype {size_t} 主类型 - * @param stype {size_t} 子类型 + * @param ctype {const char*} 主类型 + * @param stype {const char*} 子类型 * @return {mime&} */ - mime& set_type(size_t ctype, size_t stype) + mime& set_type(const char* ctype, const char* stype) { m_primaryHeader.set_type(ctype, stype); return (*this); diff --git a/lib_acl_cpp/include/acl_cpp/mime/mime_head.hpp b/lib_acl_cpp/include/acl_cpp/mime/mime_head.hpp index d19053c48..d58f72ea7 100644 --- a/lib_acl_cpp/include/acl_cpp/mime/mime_head.hpp +++ b/lib_acl_cpp/include/acl_cpp/mime/mime_head.hpp @@ -1,11 +1,10 @@ #pragma once #include "acl_cpp/acl_cpp_define.hpp" +#include "acl_cpp/stdlib/string.hpp" #include namespace acl { -class string; - typedef struct HEADER { char *name; @@ -44,7 +43,7 @@ public: mime_head& add_bcc(const char*); mime_head& add_rcpt(const char*); mime_head& add_header(const char*, const char*); - mime_head& set_type(size_t, size_t); + mime_head& set_type(const char*, const char*); mime_head& set_boundary(const char*); void build_head(string& buf, bool clean); @@ -65,8 +64,8 @@ private: string* m_returnpath; string* m_subject; - size_t m_ctype; - size_t m_stype; + string m_ctype; + string m_stype; }; } // namespace acl diff --git a/lib_acl_cpp/include/acl_cpp/queue/queue_manager.hpp b/lib_acl_cpp/include/acl_cpp/queue/queue_manager.hpp index aebab46b2..f39a78593 100644 --- a/lib_acl_cpp/include/acl_cpp/queue/queue_manager.hpp +++ b/lib_acl_cpp/include/acl_cpp/queue/queue_manager.hpp @@ -61,7 +61,6 @@ public: /** * 从磁盘上删除队列文件, 并释放该文件对象 - * 自己删除该对象 * @param fp {queue_file*} 队列文件对象 * @return {bool} 删除文件是否成功 */ diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis.hpp index 12111296b..f25c70e04 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis.hpp @@ -61,7 +61,7 @@ public: * is set to 0. */ redis(redis_client_cluster* cluster, size_t max_conns = 0); - ~redis() {} + ~redis(void) {} }; } // namespace acl diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_client.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_client.hpp index 0bdafc3e9..34b801b75 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_client.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_client.hpp @@ -35,7 +35,7 @@ public: */ redis_client(const char* addr, int conn_timeout = 60, int rw_timeout = 30, bool retry = true); - ~redis_client(); + ~redis_client(void); /** * 调用本函数设置连接 redis 服务的连接密码 diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_client_cluster.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_client_cluster.hpp index 373d9bce1..fc945f0c9 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_client_cluster.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_client_cluster.hpp @@ -26,7 +26,7 @@ public: * @param max_slot {int} 哈希槽最大值; the max hash-slot value of keys */ redis_client_cluster(int max_slot = 16384); - virtual ~redis_client_cluster(); + virtual ~redis_client_cluster(void); /** * 根据哈希槽值获得对应的连接池; diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_client_pool.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_client_pool.hpp index e9ba257be..ba9a2f7df 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_client_pool.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_client_pool.hpp @@ -28,7 +28,7 @@ public: */ redis_client_pool(const char* addr, size_t count, size_t idx = 0); - virtual ~redis_client_pool(); + virtual ~redis_client_pool(void); /** * 设置连接 redis 服务器的连接密码 diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_cluster.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_cluster.hpp index 584ef10bc..acc5bc708 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_cluster.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_cluster.hpp @@ -19,7 +19,7 @@ public: /** * see redis_command::redis_command() */ - redis_cluster(); + redis_cluster(void); /** * see redis_command::redis_command(redis_client*) @@ -29,9 +29,9 @@ public: /** * see redis_command::redis_command(redis_client_cluster*, size_t) */ - redis_cluster(redis_client_cluster* cluster, size_t max_conns); + redis_cluster(redis_client_cluster* cluster, size_t max_conns = 0); - virtual ~redis_cluster(); + virtual ~redis_cluster(void); /** * 批量添加可用的哈希槽,最后必须以小于 0 的哈希槽值表示结束 diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_command.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_command.hpp index ee5e6472f..791fef738 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_command.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_command.hpp @@ -26,7 +26,7 @@ public: * default constructor. You must set the communication method by * set_client or set_cluster functions. */ - redis_command(); + redis_command(void); /** * 当使用非集群模式时的构造函数,可以使用此构造函数设置 redis 通信类对象。 @@ -51,7 +51,7 @@ public: */ redis_command(redis_client_cluster* cluster, size_t max_conns); - virtual ~redis_command() = 0; + virtual ~redis_command(void) = 0; /** * 在重复使用一个继承于 redis_command 的子类操作 redis 时,需要在 @@ -131,9 +131,9 @@ public: * get memory pool handle be set * @return {dbuf_pool*} */ - dbuf_pool* get_pool() const + dbuf_pool* get_dbuf() const { - return pool_; + return dbuf_; } /** @@ -357,7 +357,7 @@ protected: /************************** common *********************************/ protected: - dbuf_pool* pool_; + dbuf_pool* dbuf_; // 根据键值计算哈希槽值 void hash_slot(const char* key); @@ -397,6 +397,8 @@ private: /************************** respond ********************************/ bool slice_res_; const redis_result* result_; + + void logger_result(const redis_result* result); }; } // namespace acl diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_connection.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_connection.hpp index 1dcb6b650..6d6c7ae51 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_connection.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_connection.hpp @@ -19,7 +19,7 @@ public: /** * see redis_command::redis_command() */ - redis_connection(); + redis_connection(void); /** * see redis_command::redis_command(redis_client*) @@ -29,9 +29,9 @@ public: /** * see redis_command::redis_command(redis_client_cluster*, size_t) */ - redis_connection(redis_client_cluster* cluster, size_t max_conns); + redis_connection(redis_client_cluster* cluster, size_t max_conns = 0); - virtual ~redis_connection(); + virtual ~redis_connection(void); ///////////////////////////////////////////////////////////////////// diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_geo.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_geo.hpp index 98697d25c..4a64e1de0 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_geo.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_geo.hpp @@ -41,7 +41,7 @@ class ACL_CPP_API geo_member public: geo_member(const char* name); geo_member(const geo_member& member); - ~geo_member(); + ~geo_member(void); void set_name(const char* name); const char* get_name() const @@ -108,7 +108,7 @@ public: /** * see redis_command::redis_command(redis_client_cluster*, size_t) */ - redis_geo(redis_client_cluster* cluster, size_t max_conns); + redis_geo(redis_client_cluster* cluster, size_t max_conns = 0); virtual ~redis_geo(); ///////////////////////////////////////////////////////////////////// diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_hash.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_hash.hpp index f3bf5991f..a8caf23fe 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_hash.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_hash.hpp @@ -23,7 +23,7 @@ public: /** * see redis_command::redis_command() */ - redis_hash(); + redis_hash(void); /** * see redis_command::redis_command(redis_client*) @@ -33,9 +33,9 @@ public: /** * see redis_command::redis_command(redis_client_cluster*, size_t) */ - redis_hash(redis_client_cluster* cluster, size_t max_conns); + redis_hash(redis_client_cluster* cluster, size_t max_conns = 0); - virtual ~redis_hash(); + virtual ~redis_hash(void); ///////////////////////////////////////////////////////////////////// diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_hyperloglog.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_hyperloglog.hpp index 039737aad..d66bffe90 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_hyperloglog.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_hyperloglog.hpp @@ -16,7 +16,7 @@ public: /** * see redis_command::redis_command() */ - redis_hyperloglog(); + redis_hyperloglog(void); /** * see redis_command::redis_command(redis_client*) @@ -26,9 +26,9 @@ public: /** * see redis_command::redis_command(redis_client_cluster*, size_t) */ - redis_hyperloglog(redis_client_cluster* cluster, size_t max_conns); + redis_hyperloglog(redis_client_cluster* cluster, size_t max_conns = 0); - virtual ~redis_hyperloglog(); + virtual ~redis_hyperloglog(void); /** * 将任意数量的元素添加到指定的 HyperLogLog 里面 diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_key.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_key.hpp index f0d681a5d..20f3b4c06 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_key.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_key.hpp @@ -27,7 +27,7 @@ public: /** * see redis_command::redis_command() */ - redis_key(); + redis_key(void); /** * see redis_command::redis_command(redis_client*) @@ -37,9 +37,9 @@ public: /** * see redis_command::redis_command(redis_client_cluster*, size_t) */ - redis_key(redis_client_cluster* cluster, size_t max_conns); + redis_key(redis_client_cluster* cluster, size_t max_conns = 0); - virtual ~redis_key(); + virtual ~redis_key(void); /** * 删除一个或一组 KEY,对于变参的接口,则要求最后一个参数必须以 NULL 结束 diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_list.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_list.hpp index 841368770..c315dfa06 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_list.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_list.hpp @@ -13,7 +13,7 @@ public: /** * see redis_command::redis_command() */ - redis_list(); + redis_list(void); /** * see redis_command::redis_command(redis_client*) @@ -23,9 +23,9 @@ public: /** * see redis_command::redis_command(redis_client_cluster*, size_t) */ - redis_list(redis_client_cluster* cluster, size_t max_conns); + redis_list(redis_client_cluster* cluster, size_t max_conns = 0); - virtual ~redis_list(); + virtual ~redis_list(void); ///////////////////////////////////////////////////////////////////// diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_node.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_node.hpp index f3c0963ff..e02f4130c 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_node.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_node.hpp @@ -19,8 +19,8 @@ public: * 当使用此构造函数实例化类对象时,需要调用 set_id 和 set_addr 方法设置 * 该 redis 结点的唯一标识符及服务监听地址,同时还可调用其它的 set_xxx 设置方法 */ - redis_node(); - ~redis_node(); + redis_node(void); + ~redis_node(void); /** * 除了在构造函数中的参数中传入该结点的 ID 标识符外,还可以通过此函数设置 diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_pubsub.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_pubsub.hpp index 13980c942..982ebb6ba 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_pubsub.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_pubsub.hpp @@ -17,7 +17,7 @@ public: /** * see redis_command::redis_command() */ - redis_pubsub(); + redis_pubsub(void); /** * see redis_command::redis_command(redis_client*) @@ -27,9 +27,9 @@ public: /** * see redis_command::redis_command(redis_client_cluster*, size_t) */ - redis_pubsub(redis_client_cluster* cluster, size_t max_conns); + redis_pubsub(redis_client_cluster* cluster, size_t max_conns = 0); - virtual ~redis_pubsub(); + virtual ~redis_pubsub(void); ///////////////////////////////////////////////////////////////////// diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_result.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_result.hpp index ba1e3ea70..77c9d44a6 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_result.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_result.hpp @@ -28,7 +28,7 @@ class redis_client; class ACL_CPP_API redis_result { public: - redis_result(dbuf_pool* pool); + redis_result(dbuf_pool* dbuf); /** * 重载了 new/delete 操作符,在 new 新对象时,使内存的分配在 @@ -45,7 +45,7 @@ public: * @return {redis_result_t} * defined above REDIS_RESULT_ */ - redis_result_t get_type() const + redis_result_t get_type(void) const { return result_type_; } @@ -61,7 +61,7 @@ public: * REDIS_RESULT_STRING: > 0 时表示该字符串数据被切分成非连接内存块的个数 * REDIS_RESULT_ARRAY: children_->size() */ - size_t get_size() const; + size_t get_size(void) const; /** * 当返回值为 REDIS_RESULT_INTEGER 类型时,本方法返回对应的 32 位整数值 @@ -104,7 +104,7 @@ public: * @return {const char*} 返回空串 "" 表示没有出错信息 * there was no error information if empty string returned */ - const char* get_error() const; + const char* get_error(void) const; /** * 返回对应下标的数据(当数据类型非 REDIS_RESULT_ARRAY 时) @@ -124,7 +124,7 @@ public: * return all data's array if the type isn't REDIS_RESULT_ARRAY * @return {const char**} */ - const char** gets_argv() const + const char** gets_argv(void) const { return (const char**) argv_; } @@ -134,7 +134,7 @@ public: * return all length's array if the type isn't REDIS_RESULT_ARRAY * @return {const size_t*} */ - const size_t* get_lens() const + const size_t* get_lens(void) const { return lens_; } @@ -144,7 +144,7 @@ public: * return the total length of all data for no REDIS_RESULT_ARRAY * @return {size_t} */ - size_t get_length() const; + size_t get_length(void) const; /** * 当数据类型为 REDIS_RESULT_STRING 类型时,该函数将按内存块存放的数据 @@ -182,16 +182,23 @@ public: * get the memory pool object set in constructor * @return {dbuf_pool*} */ - dbuf_pool* get_pool() + dbuf_pool* get_dbuf(void) { - return pool_; + return dbuf_; } + /** + * 将整个对象转换成字符串 + * @param out {string&} 存储结果(以追加方式添加) + * @return {const string&} + */ + const string& to_string(string& out) const; + private: - ~redis_result(); + ~redis_result(void); friend class redis_client; - void clear(); + void clear(void); redis_result& set_type(redis_result_t type); redis_result& set_size(size_t size); @@ -200,7 +207,7 @@ private: private: redis_result_t result_type_; - dbuf_pool* pool_; + dbuf_pool* dbuf_; size_t size_; size_t idx_; diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_script.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_script.hpp index c77e13739..410e1c3ba 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_script.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_script.hpp @@ -16,7 +16,7 @@ public: /** * see redis_command::redis_command() */ - redis_script(); + redis_script(void); /** * see redis_command::redis_command(redis_client*) @@ -26,9 +26,9 @@ public: /** * see redis_command::redis_command(redis_client_cluster*, size_t) */ - redis_script(redis_client_cluster* cluster, size_t max_conns); + redis_script(redis_client_cluster* cluster, size_t max_conns = 0); - virtual ~redis_script(); + virtual ~redis_script(void); ///////////////////////////////////////////////////////////////////// diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_server.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_server.hpp index 26da7c254..0e932f1d3 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_server.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_server.hpp @@ -16,7 +16,7 @@ public: /** * see redis_command::redis_command() */ - redis_server(); + redis_server(void); /** * see redis_command::redis_command(redis_client*) @@ -26,9 +26,9 @@ public: /** * see redis_command::redis_command(redis_client_cluster*, size_t) */ - redis_server(redis_client_cluster* cluster, size_t max_conns); + redis_server(redis_client_cluster* cluster, size_t max_conns = 0); - virtual ~redis_server(); + virtual ~redis_server(void); ///////////////////////////////////////////////////////////////////// @@ -39,7 +39,7 @@ public: * BGREWRITEAOF 成功之前不会被修改 * @return {bool} */ - bool bgrewriteaof(); + bool bgrewriteaof(void); /** * 在后台异步(Asynchronously)保存当前数据库的数据到磁盘,BGSAVE 命令执行之后 @@ -48,7 +48,7 @@ public: * LASTSAVE 命令查看相关信息,判断 BGSAVE 命令是否执行成功 * @return {bool} */ - bool bgsave(); + bool bgsave(void); /** * 返回 CLIENT SETNAME 命令为连接设置的名字 @@ -92,13 +92,13 @@ public: * 重置 INFO 命令中的某些统计数据 * @return {bool} 重置是否成功 */ - bool config_resetstat(); + bool config_resetstat(void); /** * 对启动 Redis 服务器时所指定的 redis.conf 文件进行改写 * @return {bool} 重写配置是否成功 */ - bool config_rewrite(); + bool config_rewrite(void); /** * 动态地调整 Redis 服务器的配置而无需重启服务 @@ -112,21 +112,21 @@ public: * 返回当前数据库的 key 的数量 * @return {int} 返回 -1 表示出错 */ - int dbsize(); + int dbsize(void); /** * 清空整个 Redis 服务器的数据(删除所有数据库的所有 key ) * @return {bool} * 注:此命令要慎用,以免造成误操作 */ - bool flushall(); + bool flushall(void); /** * 清空当前数据库中的所有 key * @return {bool} * 注:此命令要慎用,以免造成误操作 */ - bool flushdb(); + bool flushdb(void); /** * 返回关于 Redis 服务器的各种信息和统计数值 @@ -139,14 +139,14 @@ public: * 返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示 * @return {time_t} */ - time_t lastsave(); + time_t lastsave(void); /** * 实时打印出 Redis 服务器接收到的命令,调试用; 调用本命令后可以循环调用下面的 * get_command 方法获得服务器收到的命令 * @return {bool} */ - bool monitor(); + bool monitor(void); /** * 调用 monitor 方法后需要调用本方法获得服务器收到的命令,可以循环调用本方法 @@ -161,7 +161,7 @@ public: * 以 RDB 文件的形式保存到硬盘 * @return {bool} */ - bool save(); + bool save(void); /** * 停止所有客户端连接将数据保存至磁盘后服务器程序退出 @@ -188,13 +188,13 @@ public: * 可以查看当前日志的数量 * @return {int} */ - int slowlog_len(); + int slowlog_len(void); /** * 可以清空 slow log * @return {bool} */ - bool slowlog_reset(); + bool slowlog_reset(void); /** * 返回当前服务器时间 diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_set.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_set.hpp index a0f8e228d..7c6de8c3a 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_set.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_set.hpp @@ -15,7 +15,7 @@ public: /** * see redis_command::redis_command() */ - redis_set(); + redis_set(void); /** * see redis_command::redis_command(redis_client*) @@ -25,9 +25,9 @@ public: /** * see redis_command::redis_command(redis_client_cluster*, size_t) */ - redis_set(redis_client_cluster* cluster, size_t max_conns); + redis_set(redis_client_cluster* cluster, size_t max_conns = 0); - virtual ~redis_set(); + virtual ~redis_set(void); ///////////////////////////////////////////////////////////////////// diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_slot.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_slot.hpp index 865802e99..7e3c96f57 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_slot.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_slot.hpp @@ -25,7 +25,7 @@ public: const char* ip, int port); redis_slot(const redis_slot& node); - ~redis_slot(); + ~redis_slot(void); /** * 将一个 redis 哈希槽从结点添加至当前结点中 @@ -50,7 +50,7 @@ public: * get the ip of the current node * @return {const char*} */ - const char* get_ip() const + const char* get_ip(void) const { return ip_; } @@ -60,7 +60,7 @@ public: * get the port of the current node * @return {int} */ - int get_port() const + int get_port(void) const { return port_; } @@ -70,7 +70,7 @@ public: * get the min hash slot of the current node * @return {size_t} */ - size_t get_slot_min() const + size_t get_slot_min(void) const { return slot_min_; } @@ -80,7 +80,7 @@ public: * get the max hash slot of the current node * @return {size_t} */ - size_t get_slot_max() const + size_t get_slot_max(void) const { return slot_max_; } diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_string.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_string.hpp index a6ca94db6..5fb117dd0 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_string.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_string.hpp @@ -21,7 +21,7 @@ public: /** * see redis_command::redis_command() */ - redis_string(); + redis_string(void); /** * see redis_command::redis_command(redis_client*) @@ -31,8 +31,8 @@ public: /** * see redis_command::redis_command(redis_client_cluster*, size_t) */ - redis_string(redis_client_cluster* cluster, size_t max_conns); - virtual ~redis_string(); + redis_string(redis_client_cluster* cluster, size_t max_conns = 0); + virtual ~redis_string(void); ///////////////////////////////////////////////////////////////////// diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_transaction.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_transaction.hpp index 48a2f25bf..3ee8e294c 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_transaction.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_transaction.hpp @@ -16,7 +16,7 @@ public: /** * see redis_command::redis_command() */ - redis_transaction(); + redis_transaction(void); /** * see redis_command::redis_command(redis_client*) @@ -26,9 +26,9 @@ public: /** * see redis_command::redis_command(redis_client_cluster*, size_t) */ - redis_transaction(redis_client_cluster* cluster, size_t max_conns); + redis_transaction(redis_client_cluster* cluster, size_t max_conns = 0); - virtual ~redis_transaction(); + virtual ~redis_transaction(void); ///////////////////////////////////////////////////////////////////// @@ -51,7 +51,7 @@ public: * @return {bool} 操作是否成功 * if success of this operation */ - bool unwatch(); + bool unwatch(void); /** * 标记一个事务块的开始,事务块内的多条命令会按照先后顺序被放进一个队列当中, @@ -60,7 +60,7 @@ public: * @return {bool} 操作是否成功 * if success of this operation */ - bool multi(); + bool multi(void); /** * 执行所有事务块内的命令,假如某个(或某些) key 正处于 WATCH 命令的监视之下, @@ -72,7 +72,7 @@ public: * @return {bool} 操作是否成功 * if success of this operation */ - bool exec(); + bool exec(void); /** * 取消事务,放弃执行事务块内的所有命令,如果正在使用 WATCH 命令监视某个(或某些) @@ -80,7 +80,7 @@ public: * discard all commands issued after MULTI * @return {bool} */ - bool discard(); + bool discard(void); /** * 在 multi 和 exec 之间可多次调用本函数执行多条 redis 客户端命令 @@ -117,7 +117,7 @@ public: * get the result array's length after EXEC * @return {size_t} */ - size_t get_size() const; + size_t get_size(void) const; /** * 获取指定下标的对应的命令的执行结果对象 @@ -136,7 +136,7 @@ public: * get all the commands issued between MULTI and EXEC * @return {const std::vector&} */ - const std::vector& get_commands() const + const std::vector& get_commands(void) const { return cmds_; } diff --git a/lib_acl_cpp/include/acl_cpp/redis/redis_zset.hpp b/lib_acl_cpp/include/acl_cpp/redis/redis_zset.hpp index 47a0bdcfd..fbd1709f4 100644 --- a/lib_acl_cpp/include/acl_cpp/redis/redis_zset.hpp +++ b/lib_acl_cpp/include/acl_cpp/redis/redis_zset.hpp @@ -16,7 +16,7 @@ public: /** * see redis_command::redis_command() */ - redis_zset(); + redis_zset(void); /** * see redis_command::redis_command(redis_client*) @@ -26,8 +26,8 @@ public: /** * see redis_command::redis_command(redis_client_cluster*, size_t) */ - redis_zset(redis_client_cluster* cluster, size_t max_conns); - virtual ~redis_zset(); + redis_zset(redis_client_cluster* cluster, size_t max_conns = 0); + virtual ~redis_zset(void); ///////////////////////////////////////////////////////////////////// diff --git a/lib_acl_cpp/include/acl_cpp/stream/fstream.hpp b/lib_acl_cpp/include/acl_cpp/stream/fstream.hpp index 21b99e1f7..74e1491f2 100644 --- a/lib_acl_cpp/include/acl_cpp/stream/fstream.hpp +++ b/lib_acl_cpp/include/acl_cpp/stream/fstream.hpp @@ -44,13 +44,22 @@ public: */ bool create(const char* path); + /** + * 将本类对象对应的文件从磁盘上删除,该函数只有当内部知道文件路径 + * 时才能正确删除文件,否则无法删除 + * @return {bool} 删除文件是否成功 + */ + bool remove(void); + #if defined(_WIN32) || defined(_WIN64) /** * 根据系统的文件句柄打开 fstream 文件流对象 * @param fh 系统文件句柄 * @param oflags 打开标志位 + * @param path {const char*} 非 NULL 时当被作为该文件句柄的文件路径 + * 来存储,以便于 file_path, remove 使用 */ - void open(void* fh, unsigned int oflags); + void open(void* fh, unsigned int oflags, const char* path = NULL); /** * 移动文件指针位置 @@ -86,7 +95,7 @@ public: */ void* file_handle() const; #else - void open(int fh, unsigned int oflags); + void open(int fh, unsigned int oflags, const char* path = NULL); long long int fseek(long long int offset, int whence); long long int ftell(); bool ftruncate(long long int length); diff --git a/lib_acl_cpp/samples/Makefile.in b/lib_acl_cpp/samples/Makefile.in index 6cce1bb84..f511de69d 100644 --- a/lib_acl_cpp/samples/Makefile.in +++ b/lib_acl_cpp/samples/Makefile.in @@ -1,4 +1,4 @@ -CC = ${ENV_CC} +CC = ${ENV_CPP} FLAGS = ${ENV_FLAGS} CFLAGS = -c -g -W \ diff --git a/lib_acl_cpp/samples/mime/mime/mime.cpp b/lib_acl_cpp/samples/mime/mime/mime.cpp index 3e4a4abec..713fad834 100644 --- a/lib_acl_cpp/samples/mime/mime/mime.cpp +++ b/lib_acl_cpp/samples/mime/mime/mime.cpp @@ -140,6 +140,9 @@ static void mime_test1(acl::mime& mime, const char* path, bool htmlFirst) header_out(&mime); mime.mime_debug("./var"); + printf(">>>ctype: %s, stype: %s\r\n", + mime.get_ctype(), mime.get_stype()); + buf = "./var/"; buf += path; mime.save_as(buf.c_str()); diff --git a/lib_acl_cpp/samples/mime/mime_bench/Makefile b/lib_acl_cpp/samples/mime/mime_bench/Makefile new file mode 100644 index 000000000..318c1d11f --- /dev/null +++ b/lib_acl_cpp/samples/mime/mime_bench/Makefile @@ -0,0 +1,13 @@ +base_path = ../../.. +include ../../Makefile.in +#Path for SunOS +ifeq ($(findstring SunOS, $(UNIXNAME)), SunOS) + EXTLIBS = -liconv +endif +ifeq ($(findstring FreeBSD, $(UNIXNAME)), FreeBSD) + EXTLIBS = -L/usr/local/lib -liconv +endif +ifeq ($(findstring Darwin, $(UNIXNAME)), Darwin) + EXTLIBS += -L/usr/lib -liconv +endif +PROG = mime diff --git a/lib_acl_cpp/samples/mime/mime_bench/mime.cpp b/lib_acl_cpp/samples/mime/mime_bench/mime.cpp new file mode 100644 index 000000000..56d00c177 --- /dev/null +++ b/lib_acl_cpp/samples/mime/mime_bench/mime.cpp @@ -0,0 +1,105 @@ +// mime.cpp : 定义控制台应用程序的入口点。 +// + +#include "stdafx.h" +#include "lib_acl.h" +#ifndef WIN32 +#include +#endif +#include +#include +#include +#include "acl_cpp/stdlib/string.hpp" +#include "acl_cpp/stream/ifstream.hpp" +#include "acl_cpp/stream/ofstream.hpp" +#include "acl_cpp/stdlib/charset_conv.hpp" +#include "acl_cpp/stdlib/log.hpp" +#include "acl_cpp/mime/mime.hpp" +#include "acl_cpp/mime/mime_body.hpp" +#include "acl_cpp/mime/rfc2047.hpp" +#include "acl_cpp/mime/mime_attach.hpp" + +using namespace std; +using namespace acl; + +static void mime_test3(acl::mime& mime, const char* path, int count) +{ + // 以下仅解析邮件头部分 + + acl::string buf; + + if (acl::ifstream::load(path, &buf) == false) + { + printf("load %s error %s\n", path, strerror(errno)); + return; + } + + char info[256]; + for (int i = 0; i < count; i++) + { + // 开始邮件解析过程 + mime.update(buf.c_str(), buf.length()); + // 必须调用 update_end + mime.update_end(); + mime.reset(); + + if (i % 100 == 0) + { + snprintf(info, sizeof(info), "n: %d, i: %d, size: %ld", + count, i, (long) buf.length()); + ACL_METER_TIME(info); + } + } +} + +////////////////////////////////////////////////////////////////////////// + +static void usage(const char* procname) +{ + + printf("usage: %s [options]\r\n" + " -h [help]\r\n" + " -n count\r\n" + " -f mail_file\r\n", procname); +} + +int main(int argc, char* argv[]) +{ + char ch; + int count = 1; + acl::string path("test11.eml"); + + while ((ch = (char) getopt(argc, argv, "hn:f:")) > 0) + { + switch (ch) + { + case 'h': + usage(argv[0]); + return (0); + case 'n': + count = atoi(optarg); + break; + case 'f': + path = optarg; + break; + default: + break; + } + } + + acl::log::stdout_open(true); + logger_open("test.log", "mime", "all:1"); + + acl::mime mime; + + ////////////////////////////////////////////////////////////////////// + + mime_test3(mime, path.c_str(), count); + + ////////////////////////////////////////////////////////////////////// + + printf("enter any key to exit\r\n"); + logger_close(); + getchar(); + return 0; +} diff --git a/lib_acl_cpp/samples/mime/mime_bench/stdafx.cpp b/lib_acl_cpp/samples/mime/mime_bench/stdafx.cpp new file mode 100644 index 000000000..67afc1309 --- /dev/null +++ b/lib_acl_cpp/samples/mime/mime_bench/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : 只包括标准包含文件的源文件 +// mime.pch 将成为预编译头 +// stdafx.obj 将包含预编译类型信息 + +#include "stdafx.h" + +// TODO: 在 STDAFX.H 中 +//引用任何所需的附加头文件,而不是在此文件中引用 diff --git a/lib_acl_cpp/samples/mime/mime_bench/stdafx.h b/lib_acl_cpp/samples/mime/mime_bench/stdafx.h new file mode 100644 index 000000000..c5947907a --- /dev/null +++ b/lib_acl_cpp/samples/mime/mime_bench/stdafx.h @@ -0,0 +1,11 @@ +// stdafx.h : 标准系统包含文件的包含文件, +// 或是常用但不常更改的项目特定的包含文件 +// + +#pragma once + +// +//#include +//#include + +// TODO: 在此处引用程序要求的附加头文件 diff --git a/lib_acl_cpp/samples/mime/mime_bench/valgrind.sh b/lib_acl_cpp/samples/mime/mime_bench/valgrind.sh new file mode 100644 index 000000000..f5c8915c0 --- /dev/null +++ b/lib_acl_cpp/samples/mime/mime_bench/valgrind.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +valgrind --tool=memcheck --leak-check=yes --show-reachable=yes -v ./mime -s -f test2.eml diff --git a/lib_acl_cpp/samples/redis/redis_hash/redis_hash.cpp b/lib_acl_cpp/samples/redis/redis_hash/redis_hash.cpp index 581cd384a..7b390049a 100644 --- a/lib_acl_cpp/samples/redis/redis_hash/redis_hash.cpp +++ b/lib_acl_cpp/samples/redis/redis_hash/redis_hash.cpp @@ -412,6 +412,7 @@ int main(int argc, char* argv[]) } acl::acl_cpp_init(); + acl::log::stdout_open(true); acl::redis_client_cluster cluster; cluster.set(addr.c_str(), 100, conn_timeout, rw_timeout); diff --git a/lib_acl_cpp/samples/xml/xml4/cdata.xml b/lib_acl_cpp/samples/xml/xml4/cdata.xml index dde69f7b3..71c375720 100644 --- a/lib_acl_cpp/samples/xml/xml4/cdata.xml +++ b/lib_acl_cpp/samples/xml/xml4/cdata.xml @@ -1,5 +1,6 @@ - + + - + + + + + + + + + + + + + zsx11 + zsx12 + zsx12 + + + zsx21 + zsx22 + zsx22 + + + zsx31 + zsx32 + zsx32 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib_acl_cpp/samples/xml/xml4/main.cpp b/lib_acl_cpp/samples/xml/xml4/main.cpp index 8daf54722..49f23913d 100644 --- a/lib_acl_cpp/samples/xml/xml4/main.cpp +++ b/lib_acl_cpp/samples/xml/xml4/main.cpp @@ -87,6 +87,10 @@ static void test_parse(const char* filepath) //printf("[%s]\r\n", xml.to_string()); printf("------------- xml node walk -----------------------\r\n"); xml_node_walk(xml.get_root(), 0); + + printf("------------- build xml ---------------------------\r\n"); + printf("%s\r\n", xml.to_string()); + printf("------------- build xml end -----------------------\r\n"); } static void test_parse_mmap(const char* filepath) @@ -103,6 +107,11 @@ static void test_parse_mmap(const char* filepath) xml.update(buf.c_str()); printf("------------- xml node walk -----------------------\r\n"); xml_node_walk(xml.get_root(), 0); + printf("------------- xml node walk end -------------------\r\n"); + + printf("------------- build xml ---------------------------\r\n"); + printf("%s\r\n", xml.to_string()); + printf("------------- build xml end -----------------------\r\n"); } static void usage(const char* procname) diff --git a/lib_acl_cpp/samples/xml/xml5/Makefile b/lib_acl_cpp/samples/xml/xml5/Makefile new file mode 100644 index 000000000..9950e1715 --- /dev/null +++ b/lib_acl_cpp/samples/xml/xml5/Makefile @@ -0,0 +1,3 @@ +base_path = ../../.. +PROG = xml +include ../../Makefile.in diff --git a/lib_acl_cpp/samples/xml/xml5/main.cpp b/lib_acl_cpp/samples/xml/xml5/main.cpp new file mode 100644 index 000000000..a32139be0 --- /dev/null +++ b/lib_acl_cpp/samples/xml/xml5/main.cpp @@ -0,0 +1,106 @@ +#include "stdafx.h" + +static void attr_print(const acl::xml_attr& attr, int depth) +{ + for (int i = 0; i < depth; i++) + printf("\t"); + + printf("%s=\"%s\"\r\n", attr.get_name(), attr.get_value()); +} + +static void node_attr_print(const acl::xml_node& node, int depth) +{ + const acl::xml_attr* attr = node.first_attr(); + while (attr) + { + attr_print(*attr, depth); + attr = node.next_attr(); + } +} + +static void xml_node_print(const acl::xml_node& node, int depth) +{ + for (int i = 0; i < depth; i++) + printf("\t"); + + printf("tag: %s\r\n", node.tag_name()); + + const char* txt = node.text(); + for (int i = 0; i < depth; i++) + printf("\t"); + printf("text: {%s}\r\n", txt ? txt : ""); + + node_attr_print(node, depth + 1); +} + +static void xml_node_walk(acl::xml_node& node, int depth) +{ + acl::xml_node* child = node.first_child(); + + while (child) + { + xml_node_print(*child, depth); + xml_node_walk(*child, depth + 1); + child = node.next_child(); + } +} + +static void test_build(void) +{ + const char* local_file = "./local.map"; + acl::xml2 xml(local_file, 1024000); + acl::xml_node& root = xml.get_root(); + char txt[102400]; + + memset(txt, 'x', sizeof(txt)); + txt[sizeof(txt) - 1] = 0; + + root.add_child("users", true) + .add_child("user", true) + .add_attr("name", "zsxxsz") + .add_attr("age", 100) + .set_text(txt) + .get_parent() + .add_child("user", true) + .add_attr("name", "zsx1") + .add_attr("age", 102); + + acl::xml_node& node = xml.create_node("name", "value"); + (void) node; + + acl::string buf; + xml.build_xml(buf); + + printf("%s\r\n", buf.c_str()); + printf("-------------- walk xml node ------------------------\r\n"); + xml_node_walk(xml.get_root(), 0); + printf("-------------- walk xml node end --------------------\r\n"); + printf("-------------- print xml ----------------------------\r\n"); + printf("[%s]\r\n", xml.to_string()); + printf("-------------- print xml end ------------------------\r\n"); +} + +static void usage(const char* procname) +{ + printf("usage: %s -h[help]\r\n", procname); +} + +int main(int argc, char* argv[]) +{ + int ch; + + while ((ch = getopt(argc, argv, "h")) > 0) + { + switch (ch) + { + case 'h': + usage(argv[0]); + return 0; + default: + break; + } + } + + test_build(); + return 0; +} diff --git a/lib_acl_cpp/samples/xml/xml5/stdafx.cpp b/lib_acl_cpp/samples/xml/xml5/stdafx.cpp new file mode 100644 index 000000000..a7dbd1b53 --- /dev/null +++ b/lib_acl_cpp/samples/xml/xml5/stdafx.cpp @@ -0,0 +1,4 @@ +#include "stdafx.h" + +// TODO: 在 STDAFX.H 中 +// 引用任何所需的附加头文件,而不是在此文件中引用 diff --git a/lib_acl_cpp/samples/xml/xml5/stdafx.h b/lib_acl_cpp/samples/xml/xml5/stdafx.h new file mode 100644 index 000000000..fe77279be --- /dev/null +++ b/lib_acl_cpp/samples/xml/xml5/stdafx.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +// TODO: 在此处引用程序需要的其他头文件 + +#include "lib_acl.h" +#include "acl_cpp/lib_acl.hpp" + +#if !defined(_WIN32) && !defined(_WIN64) +#include +#endif diff --git a/lib_acl_cpp/samples/xml/xml5/valgrind.sh b/lib_acl_cpp/samples/xml/xml5/valgrind.sh new file mode 100644 index 000000000..3a9d3bb09 --- /dev/null +++ b/lib_acl_cpp/samples/xml/xml5/valgrind.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +valgrind --tool=memcheck --leak-check=yes -v ./xml diff --git a/lib_acl_cpp/src/connpool/connect_manager.cpp b/lib_acl_cpp/src/connpool/connect_manager.cpp index 999fea754..2d847eeb5 100644 --- a/lib_acl_cpp/src/connpool/connect_manager.cpp +++ b/lib_acl_cpp/src/connpool/connect_manager.cpp @@ -159,6 +159,10 @@ connect_pool& connect_manager::set(const char* addr, size_t count, connect_pool* pool = create_pool(key, count, pools_.size() - 1); pool->set_retry_inter(retry_inter_); pool->set_timeout(conn_timeout, rw_timeout); + if (idle_ttl_ >= 0) + pool->set_idle_ttl(idle_ttl_); + if (check_inter_ > 0) + pool->set_check_inter(check_inter_); pools_.push_back(pool); lock_.unlock(); diff --git a/lib_acl_cpp/src/db/db_handle.cpp b/lib_acl_cpp/src/db/db_handle.cpp index 6e0fa1fd5..40f6eca8e 100644 --- a/lib_acl_cpp/src/db/db_handle.cpp +++ b/lib_acl_cpp/src/db/db_handle.cpp @@ -249,6 +249,7 @@ db_handle::~db_handle() { if (id_) acl_myfree(id_); + free_result(); } bool db_handle::open() @@ -373,7 +374,7 @@ void db_handle::free_result() const db_row* db_handle::operator [](size_t idx) const { if (result_ == NULL) - return (NULL); + return NULL; if (idx >= result_->length()) return (NULL); return (*result_)[idx]; @@ -389,7 +390,7 @@ size_t db_handle::length() const bool db_handle::empty() const { - return (length() == 0 ? true : false); + return length() == 0 ? true : false; } db_handle& db_handle::set_id(const char* id) diff --git a/lib_acl_cpp/src/db/db_mysql.cpp b/lib_acl_cpp/src/db/db_mysql.cpp index 473abe298..9c12318c8 100644 --- a/lib_acl_cpp/src/db/db_mysql.cpp +++ b/lib_acl_cpp/src/db/db_mysql.cpp @@ -581,8 +581,11 @@ bool db_mysql::dbopen(const char* charset /* = NULL */) { logger_error("connect mysql error(%s), db_host=%s, db_port=%d," " db_unix=%s, db_name=%s, db_user=%s, db_pass=%s", - __mysql_error(conn_), db_host ? db_host : "null", db_port, - db_unix ? db_unix : "null", dbname_, dbuser_, + __mysql_error(conn_), + db_host ? db_host : "null", db_port, + db_unix ? db_unix : "null", + dbname_ ? dbname_ : "null", + dbuser_ ? dbuser_ : "null", dbpass_ ? dbpass_ : "null"); __mysql_close(conn_); @@ -701,6 +704,9 @@ bool db_mysql::tbl_exists(const char* tbl_name) bool db_mysql::sql_select(const char* sql) { + // 优先调用基类方法释放上次的查询结果 + free_result(); + if (sane_mysql_query(sql) == false) return false; MYSQL_RES *my_res = __mysql_store_result(conn_); @@ -729,6 +735,8 @@ bool db_mysql::sql_select(const char* sql) bool db_mysql::sql_update(const char* sql) { + free_result(); + if (sane_mysql_query(sql) == false) return false; int ret = (int) __mysql_affected_rows(conn_); diff --git a/lib_acl_cpp/src/db/db_pool.cpp b/lib_acl_cpp/src/db/db_pool.cpp index 6f8865ee4..0cb223c37 100644 --- a/lib_acl_cpp/src/db/db_pool.cpp +++ b/lib_acl_cpp/src/db/db_pool.cpp @@ -24,4 +24,17 @@ db_handle* db_pool::peek_open(const char* charset /* = NULL */) return NULL; } +////////////////////////////////////////////////////////////////////////////// + +db_guard::~db_guard(void) +{ + if (conn_) + { + db_handle* db = (db_handle*) conn_; + db->free_result(); + pool_.put(conn_, keep_); + conn_ = NULL; + } +} + } // namespace acl diff --git a/lib_acl_cpp/src/db/db_sqlite.cpp b/lib_acl_cpp/src/db/db_sqlite.cpp index 6d08f4f62..5edeeac82 100644 --- a/lib_acl_cpp/src/db/db_sqlite.cpp +++ b/lib_acl_cpp/src/db/db_sqlite.cpp @@ -227,6 +227,7 @@ db_sqlite::~db_sqlite(void) { close(); delete conv_; + free_result(); } const char* db_sqlite::version() const @@ -468,11 +469,7 @@ bool db_sqlite::sql_update(const char* sql) bool db_sqlite::exec_sql(const char* sql) { // 必须将上次的查询结果删除 - if (result_) - { - logger_warn("You forgot free result of last query"); - free_result(); - } + free_result(); if (sql == NULL || *sql == 0) { diff --git a/lib_acl_cpp/src/disque/disque.cpp b/lib_acl_cpp/src/disque/disque.cpp index 681024455..ecc627684 100644 --- a/lib_acl_cpp/src/disque/disque.cpp +++ b/lib_acl_cpp/src/disque/disque.cpp @@ -63,8 +63,8 @@ const char* disque::addjob(const char* name, const void* job, size_t job_len, if (args != NULL && args->empty() == false) argc += args->size() * 2; - const char** argv = (const char**) pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + const char** argv = (const char**) dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = "ADDJOB"; lens[0] = sizeof("ADDJOB") - 1; @@ -101,7 +101,7 @@ const char* disque::addjob(const char* name, const void* job, size_t job_len, lens[i] = cit->first.length(); i++; - char* tmp = (char*) pool_->dbuf_alloc(INT_LEN); + char* tmp = (char*) dbuf_->dbuf_alloc(INT_LEN); safe_snprintf(tmp, INT_LEN, "%d", cit->second); argv[i] = tmp; lens[i] = strlen(tmp); @@ -182,8 +182,8 @@ const std::vector* disque::getjob(const std::vector& names, { size_t argc = 2 + names.size() + 4; - const char** argv = (const char**) pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + const char** argv = (const char**) dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = "GETJOB"; lens[0] = sizeof("GETJOB") - 1; @@ -195,7 +195,7 @@ const std::vector* disque::getjob(const std::vector& names, lens[i] = sizeof("TIMEOUT") - 1; i++; - char* tmp = (char*) pool_->dbuf_alloc(INT_LEN); + char* tmp = (char*) dbuf_->dbuf_alloc(INT_LEN); safe_snprintf(tmp, INT_LEN, "%d", (int) timeout); argv[i] = tmp; lens[i] = strlen(tmp); @@ -208,7 +208,7 @@ const std::vector* disque::getjob(const std::vector& names, lens[i] = sizeof("COUNT") - 1; i++; - char* tmp = (char*) pool_->dbuf_alloc(INT_LEN); + char* tmp = (char*) dbuf_->dbuf_alloc(INT_LEN); safe_snprintf(tmp, INT_LEN, "%d", (int) count); argv[i] = tmp; lens[i] = strlen(tmp); @@ -395,8 +395,8 @@ int disque::deljob(const std::vector& job_ids) int disque::jobs_bat(const std::vector& job_ids, const char* cmd) { size_t argc = 1 + job_ids.size(); - const char** argv = (const char**) pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + const char** argv = (const char**) dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = cmd; lens[0] = strlen(cmd); diff --git a/lib_acl_cpp/src/http/http_request_pool.cpp b/lib_acl_cpp/src/http/http_request_pool.cpp index 03169ce52..120104afd 100644 --- a/lib_acl_cpp/src/http/http_request_pool.cpp +++ b/lib_acl_cpp/src/http/http_request_pool.cpp @@ -29,7 +29,7 @@ connect_client* http_request_pool::create_connect() return req; } -///////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// http_guard::http_guard(http_request_pool& pool) : connect_guard(pool) @@ -41,7 +41,7 @@ http_guard::~http_guard(void) if (conn_) { http_request* req = (http_request*) conn_; - pool_.put(conn_, keep_& req->keep_alive()); + pool_.put(conn_, keep_ & req->keep_alive()); conn_ = NULL; } } diff --git a/lib_acl_cpp/src/mime/internal/mime_state.cpp b/lib_acl_cpp/src/mime/internal/mime_state.cpp index e556441a6..21f616fcc 100644 --- a/lib_acl_cpp/src/mime/internal/mime_state.cpp +++ b/lib_acl_cpp/src/mime/internal/mime_state.cpp @@ -151,6 +151,11 @@ static void mime_node_free(MIME_NODE *node) if (node->charset) acl_myfree(node->charset); + if (node->ctype_s) + acl_myfree(node->ctype_s); + if (node->stype_s) + acl_myfree(node->stype_s); + acl_vstring_free(node->buffer); if (node->boundary) acl_vstring_free(node->boundary); diff --git a/lib_acl_cpp/src/mime/internal/mime_state.hpp b/lib_acl_cpp/src/mime/internal/mime_state.hpp index 501ae9d93..1420d1844 100644 --- a/lib_acl_cpp/src/mime/internal/mime_state.hpp +++ b/lib_acl_cpp/src/mime/internal/mime_state.hpp @@ -39,6 +39,8 @@ struct MIME_NODE /* 通用头 */ int ctype; /**< MIME_CTYPE_XXX */ int stype; /**< MIME_STYPE_XXX */ + char *ctype_s; + char *stype_s; char *charset; char *header_name; diff --git a/lib_acl_cpp/src/mime/internal/mime_state_parse.cpp b/lib_acl_cpp/src/mime/internal/mime_state_parse.cpp index 0b168d9a3..b7ca0e34e 100644 --- a/lib_acl_cpp/src/mime/internal/mime_state_parse.cpp +++ b/lib_acl_cpp/src/mime/internal/mime_state_parse.cpp @@ -29,7 +29,7 @@ typedef struct MIME_ENCODING { int domain; /* subset of encoding */ } MIME_ENCODING; -static const MIME_ENCODING mime_encoding_map[] = { /* RFC 2045 */ +static const MIME_ENCODING mime_encoding_map[] = { /* RFC 2045 */ { "7bit", MIME_ENC_7BIT, MIME_ENC_7BIT }, /* domain */ { "8bit", MIME_ENC_8BIT, MIME_ENC_8BIT }, /* domain */ { "binary", MIME_ENC_BINARY, MIME_ENC_BINARY }, /* domain */ @@ -61,20 +61,28 @@ static void mime_content_type(MIME_NODE *node, const HEADER_OPTS *header_info) if ((tok_count = PARSE_CONTENT_TYPE_HEADER(state, &cp)) <= 0) { /* - * other/whatever. - */ + * other/whatever. + */ node->ctype = MIME_CTYPE_OTHER; return; } /* tok_count > 0 */ + if (state->token[0].type == HEADER_TOK_TOKEN) + node->ctype_s = acl_mystrdup(state->token[0].u.value); + if (tok_count >= 3 && state->token[1].type == '/' + && state->token[2].type == HEADER_TOK_TOKEN) + { + node->stype_s = acl_mystrdup(state->token[2].u.value); + } + /* - * message/whatever body parts start with another block of message - * headers that we may want to look at. The partial and external-body - * subtypes cannot be subjected to 8-bit -> 7-bit conversion, so we - * must properly recognize them. - */ + * message/whatever body parts start with another block of message + * headers that we may want to look at. The partial and external-body + * subtypes cannot be subjected to 8-bit -> 7-bit conversion, so we + * must properly recognize them. + */ if (TOKEN_MATCH(state->token[0], "message")) { node->ctype = MIME_CTYPE_MESSAGE; node->stype = MIME_STYPE_OTHER; @@ -89,9 +97,9 @@ static void mime_content_type(MIME_NODE *node, const HEADER_OPTS *header_info) } /* - * multipart/digest has default content type message/rfc822, - * multipart/whatever has default content type text/plain. - */ + * multipart/digest has default content type message/rfc822, + * multipart/whatever has default content type text/plain. + */ else if (TOKEN_MATCH(state->token[0], "multipart")) { node->ctype = MIME_CTYPE_MULTIPART; if (tok_count >= 3 && state->token[1].type == '/') { @@ -113,14 +121,14 @@ static void mime_content_type(MIME_NODE *node, const HEADER_OPTS *header_info) } /* - * Yes, this is supposed to capture multiple boundary strings, - * which are illegal and which could be used to hide content in - * an implementation dependent manner. The code below allows us - * to find embedded message headers as long as the sender uses - * only one of these same-level boundary strings. - * - * Yes, this is supposed to ignore the boundary value type. - */ + * Yes, this is supposed to capture multiple boundary strings, + * which are illegal and which could be used to hide content + * in an implementation dependent manner. The code below allows + * us to find embedded message headers as long as the sender + * uses only one of these same-level boundary strings. + * + * Yes, this is supposed to ignore the boundary value type. + */ while ((tok_count = PARSE_CONTENT_TYPE_HEADER(state, &cp)) >= 0) { if (tok_count < 3 || state->token[1].type != '=') continue; @@ -136,10 +144,10 @@ static void mime_content_type(MIME_NODE *node, const HEADER_OPTS *header_info) } /* - * text/whatever. Right now we don't really care if it is plain or - * not, but we may want to recognize subtypes later, and then this - * code can serve as an example. - */ + * text/whatever. Right now we don't really care if it is plain or + * not, but we may want to recognize subtypes later, and then this + * code can serve as an example. + */ else if (TOKEN_MATCH(state->token[0], "text")) { node->ctype = MIME_CTYPE_TEXT; if (tok_count >= 3 && state->token[1].type == '/') { @@ -228,10 +236,10 @@ static void mime_content_encoding(MIME_NODE *node, header_token(state->token, 1, state->token_buffer, ptr, (char *) 0, 0) /* - * Do content-transfer-encoding header. Never set the encoding domain to - * something other than 7bit, 8bit or binary, even if we don't recognize - * the input. - */ + * Do content-transfer-encoding header. Never set the encoding domain + * to something other than 7bit, 8bit or binary, even if we don't + * recognize the input. + */ cp = STR(node->buffer) + strlen(header_info->name) + 1; if (PARSE_CONTENT_ENCODING_HEADER(state, &cp) > 0 && state->token[0].type == HEADER_TOK_TOKEN) @@ -296,9 +304,9 @@ void mime_state_downgrade(MIME_STATE *state, int rec_type, } /* - * Insert a soft line break when the output reaches a critical length - * before we reach a hard line break. - */ + * Insert a soft line break when the output reaches a critical length + * before we reach a hard line break. + */ for (cp = CU_CHAR_PTR(text); cp < CU_CHAR_PTR(text + len); cp++) { /* Critical length before hard line break. */ if (LEN(node->buffer) > 72) { @@ -314,10 +322,10 @@ void mime_state_downgrade(MIME_STATE *state, int rec_type, } /* - * Flush output after a hard line break (i.e. the end of a REC_TYPE_NORM - * record). Fix trailing whitespace as per the RFC: in the worst case, - * the output length will grow from 73 characters to 75 characters. - */ + * Flush output after a hard line break (i.e. the end of a REC_TYPE_NORM + * record). Fix trailing whitespace as per the RFC: in the worst case, + * the output length will grow from 73 characters to 75 characters. + */ if (rec_type == REC_TYPE_NORM) { if (LEN(node->buffer) > 0 && ((ch = END(node->buffer)[-1]) == ' ' || ch == '\t')) @@ -338,7 +346,7 @@ static ACL_FIFO *mail_addr_add(ACL_FIFO *addr_list, const char *addr) mail_addr = (MAIL_ADDR*) acl_mycalloc(1, sizeof(MAIL_ADDR)); mail_addr->addr = acl_mystrdup(addr); acl_fifo_push(addr_list, mail_addr); - return (addr_list); + return addr_list; } static void mail_rcpt(MIME_NODE *node, const HEADER_OPTS *header_info) @@ -374,7 +382,7 @@ static void mail_rcpt(MIME_NODE *node, const HEADER_OPTS *header_info) static void mail_from(MIME_NODE *node, const HEADER_OPTS *header_info) { - //MIME_STATE *state = node->state; + /* MIME_STATE *state = node->state; */ TOK822 *tree; TOK822 **addr_list; TOK822 **tpp; @@ -467,8 +475,8 @@ static void mime_header_line(MIME_NODE *node) mail_rcpt(node, header_info); } else if ((header_info->flags & HDR_OPT_SENDER)) { /* 分析发件人地址: From, Sender, - * Replyto, Returnpath - */ + * Replyto, Returnpath + */ mail_from(node, header_info); } else if ((header_info->flags & HDR_OPT_SUBJECT)) { mail_subject(node, header_info); @@ -505,7 +513,7 @@ static int mime_state_head(MIME_STATE *state, const char *s, int n) MIME_NODE *node = state->curr_node; if (n <= 0) - return (n); + return n; /* 如果还未找到换行符,则继续 */ @@ -523,7 +531,7 @@ static int mime_state_head(MIME_STATE *state, const char *s, int n) s++; } - return (n); + return n; } /* 如果数据以换行开始, 说明当前的邮件头结束 */ @@ -542,14 +550,14 @@ static int mime_state_head(MIME_STATE *state, const char *s, int n) /* 略过开头无用的空行 */ if (node->valid_line == 0) - return (0); + return 0; /* 如果当前结点为 multipart 格式, 则重置 state->curr_bound */ if (node->boundary != NULL) state->curr_bound = STR(node->boundary); state->curr_status = MIME_S_BODY; node->body_begin = state->curr_off; - return (n - 1); + return n - 1; } if (*s == '\r') { state->curr_off++; @@ -557,12 +565,12 @@ static int mime_state_head(MIME_STATE *state, const char *s, int n) /* XXX: 出现了 \n\r\r 现象 */ node->last_ch = '\r'; node->last_lf = 0; - return (n - 1); + return n - 1; } node->last_ch = '\r'; /* 返回, 以期待下一个字符为 '\n' */ - return (n - 1); + return n - 1; } /* 清除 '\n' */ @@ -585,7 +593,8 @@ static int mime_state_head(MIME_STATE *state, const char *s, int n) } s++; } - return (n); + + return n; } /* 处理头部的上一行数据 */ @@ -594,101 +603,102 @@ static int mime_state_head(MIME_STATE *state, const char *s, int n) mime_header_line(node); node->valid_line++; } - return (n); + + return n; } // 分析 multipart 部分体, 当匹配到一个完整的分隔符后则表明该部分数据体分析完毕 -static int mime_bound_body(const char *boundary, MIME_NODE *node, - const char *s, int n, int *finish) +static int mime_bound_body(MIME_STATE *state, const char *boundary, + MIME_NODE *node, const char *s, int n, int *finish) { - const unsigned char *cp; + const unsigned char *cp, *end = (const unsigned char*) s + n; const unsigned char *startn = NULL; + size_t bound_len = strlen(boundary); - for (cp = (const unsigned char *) s; - cp < (const unsigned char *) s + n; cp++) - { + for (cp = (const unsigned char *) s; cp < end; cp++) { // 记录下 \r\n 的位置 if (*cp == '\r') - node->last_cr_pos = node->state->curr_off; + node->last_cr_pos = state->curr_off; else if (*cp == '\n') - node->last_lf_pos = node->state->curr_off; + node->last_lf_pos = state->curr_off; - node->state->curr_off++; - if (node->bound_ptr) { - if (*cp == *node->bound_ptr) { - node->bound_ptr++; - if (*node->bound_ptr == 0) { - - /* 说明完全匹配 */ - *finish = 1; - - node->body_end = node->state->curr_off - - (off_t) strlen(node->state->curr_bound); - node->body_data_end = node->body_end; - - // 因为 body_end 记录的是某个结点最后的位置,其中会包含 - // 根据协议附加的 \r\n,所以真实数据的结束位置 body_data_end - // 得是去掉这些数据后的位置 - if (node->last_lf_pos + (off_t) strlen(boundary) - == node->state->curr_off - 1) - { - node->body_data_end--; - if (node->last_cr_pos + 1 == node->last_lf_pos) - node->body_data_end--; - } - - if (startn > (const unsigned char *) s) { - - /* 将匹配之前的数据拷贝 */ - APPEND(node->body, (const char*) s, - (const char*) startn - s); - } - node->bound_ptr = NULL; - cp++; - break; - } - } else { - /* 说明之前的匹配失效,需要重新匹配, - * 但必须将之前匹配的字符拷贝 - */ + state->curr_off++; + if (node->bound_ptr != NULL) { + if (*cp != *node->bound_ptr) { + // 说明之前的匹配失效,需要重新匹配, + // 但必须将之前匹配的字符拷贝 if (node->bound_ptr > boundary) { APPEND(node->body, boundary, node->bound_ptr - boundary); } + node->bound_ptr = NULL; - } - } - if (!node->bound_ptr) { - if (*cp == *boundary) { - node->bound_ptr = boundary + 1; - + } else if (*++node->bound_ptr == 0) { /* 说明完全匹配 */ - if (*node->bound_ptr == 0) { - node->body_end = node->state->curr_off - - (off_t) strlen(node->state->curr_bound); - node->body_data_end = node->body_end; + *finish = 1; - // 因为 body_end 记录的是某个结点最后的位置,其中会包含 - // 根据协议附加的 \r\n,所以真实数据的结束位置 body_data_end - // 得是去掉这些数据后的位置 - if (node->last_lf_pos + (off_t) strlen(boundary) - == node->state->curr_off - 1) - { + node->body_end = state->curr_off + - (off_t) strlen(state->curr_bound); + node->body_data_end = node->body_end; + + // 因为 body_end 记录的是某个结点最后的位置, + // 其中会包含, 根据协议附加的 \r\n,所以真实 + // 数据的结束位置 body_data_end 是去掉这些数据 + // 后的位置 + if (node->last_lf_pos + (off_t) bound_len + == state->curr_off - 1) + { + node->body_data_end--; + if (node->last_cr_pos + 1 == node->last_lf_pos) node->body_data_end--; - if (node->last_cr_pos + 1 == node->last_lf_pos) - node->body_data_end--; - } - *finish = 1; - node->bound_ptr = NULL; - cp++; - break; } - startn = cp; - } else { - ADDCH(node->body, *cp); - } + + if (startn > (const unsigned char *) s) { + /* 将匹配之前的数据拷贝 */ + APPEND(node->body, (const char*) s, + (const char*) startn - s); + } + node->bound_ptr = NULL; + cp++; + break; + } else + continue; } + + // --> node->bound_ptr == NULL + + if (*cp != *boundary) { + ADDCH(node->body, *cp); + continue; + } + + node->bound_ptr = boundary + 1; + + /* 说明完全匹配 */ + if (*node->bound_ptr == 0) { + node->body_end = state->curr_off + - (off_t) strlen(state->curr_bound); + node->body_data_end = node->body_end; + + // body_end 记录的是某个结点最后的位置,其中会包含 + // 根据协议附加的 \r\n,所以真实数据的结束位置 + // body_data_end 是去掉这些数据后的位置 + if (node->last_lf_pos + (off_t) strlen(boundary) + == node->state->curr_off - 1) + { + node->body_data_end--; + if (node->last_cr_pos + 1 == node->last_lf_pos) + node->body_data_end--; + } + + *finish = 1; + node->bound_ptr = NULL; + cp++; + break; + } + + startn = cp; } return (int) (n - ((const char*) cp - s)); @@ -709,24 +719,27 @@ static int mime_state_body(MIME_STATE *state, const char *s, int n) APPEND(state->curr_node->body, s, n); state->curr_off += n; - /* 因为 curr_off 指向的是下一个偏移位置,所以 body_end = curr_off - 1 */ + /* 因为 curr_off 指向下一个偏移位置,所以 + * body_end = curr_off - 1 + */ state->curr_node->body_end = state->curr_off - 1; - state->curr_node->body_data_end = state->curr_node->body_end; // add by zsx, 2012.5.28 - return (0); + state->curr_node->body_data_end = state->curr_node->body_end; + return 0; } - n = mime_bound_body(state->curr_bound, state->curr_node, s, n, &finish); + n = mime_bound_body(state, state->curr_bound, + state->curr_node, s, n, &finish); if (finish) state->curr_status = MIME_S_BODY_BOUND_CRLF; - return (n); + return n; } // 查找分隔符后的 "\r\n" static int mime_state_body_bound_crlf(MIME_STATE *state, const char *s, int n) { if (n <= 0) - return (n); + return n; /* 如果不是分隔符的最后两个 "--" 则说明还由其它结点由本分隔符分隔 */ @@ -735,7 +748,7 @@ static int mime_state_body_bound_crlf(MIME_STATE *state, const char *s, int n) state->curr_node->last_ch = '\n'; state->curr_off++; - state->curr_node->bound_end = state->curr_node->state->curr_off; + state->curr_node->bound_end = state->curr_off; /* state->curr_node->body_end = state->curr_node->bound_end @@ -756,12 +769,13 @@ static int mime_state_body_bound_crlf(MIME_STATE *state, const char *s, int n) /* xxx: 本结点不应为根结点 */ state->curr_status = MIME_S_TERM; } else if (state->curr_node->parent == state->root) { - /* 说明根结点的一级子结点都结束, 则整封邮件分析完毕 */ + /* 说明根结点的一级子结点都结束, + * 则整封邮件分析完毕 */ state->curr_status = MIME_S_TERM; } else { - /* 说明本结点为根结点的二级或以上结点, 同时说明 - * 本结点的父结点已经结束, 下一步需要找出本结点的 - * 爷爷结点的分隔符 + /* 说明本结点为根结点的二级或以上结点, 同时 + * 说明本结点的父结点已经结束, 下一步需要找 + * 出本结点的爷爷结点的分隔符 */ /* 只有根结点 root 的父结点为 NULL */ @@ -769,48 +783,55 @@ static int mime_state_body_bound_crlf(MIME_STATE *state, const char *s, int n) acl_assert(state->curr_node->parent->boundary); state->curr_node = state->curr_node->parent; - state->curr_bound = STR(state->curr_node->parent->boundary); + state->curr_bound = + STR(state->curr_node->parent->boundary); state->curr_status = MIME_S_MULTI_BOUND; state->curr_node->bound_ptr = NULL; } - } else { - acl_assert(state->curr_node != NULL); - MIME_NODE *node = mime_node_new(state); - - node->header_begin = state->curr_off; - if (state->curr_node->boundary != NULL) { - acl_assert(state->curr_bound == STR(state->curr_node->boundary)); - mime_node_add_child(state->curr_node, node); - } else { - acl_assert(state->curr_node->parent->boundary != NULL); - acl_assert(state->curr_bound == STR(state->curr_node->parent->boundary)); - mime_node_add_child(state->curr_node->parent, node); - } - state->curr_node = node; - state->curr_status = MIME_S_HEAD; - state->curr_node->last_ch = 0; - state->curr_node->last_lf = 0; + return n - 1; } - return (n - 1); + + acl_assert(state->curr_node != NULL); + + MIME_NODE *node = mime_node_new(state); + + node->header_begin = state->curr_off; + if (state->curr_node->boundary != NULL) { + acl_assert(state->curr_bound == + STR(state->curr_node->boundary)); + mime_node_add_child(state->curr_node, node); + } else { + acl_assert(state->curr_node->parent->boundary != NULL); + acl_assert(state->curr_bound == + STR(state->curr_node->parent->boundary)); + mime_node_add_child(state->curr_node->parent, node); + } + + state->curr_node = node; + state->curr_status = MIME_S_HEAD; + state->curr_node->last_ch = 0; + state->curr_node->last_lf = 0; + + return n - 1; } else if (*s == '\r') { state->curr_node->last_cr_pos = state->curr_off; state->curr_node->last_ch = '\r'; state->curr_off++; state->use_crlf = 1; /* 期待下一个字符为 '\n' */ - return (n - 1); + return n - 1; } else if (*s == '-') { state->curr_off++; if (state->curr_node->bound_term[0] == '-') { state->curr_node->bound_term[1] = '-'; /* 期待下一个字符为 '\r' 或 '\n' */ - return (n - 1); + return n - 1; } else { /* 期待下一个字符为 '-' */ state->curr_node->bound_term[0] = '-'; - return (n - 1); + return n - 1; } } else { /* XXX: 分隔符后非法字符 ? */ @@ -826,14 +847,14 @@ static int mime_state_body_bound_crlf(MIME_STATE *state, const char *s, int n) state->curr_status = MIME_S_HEAD; state->curr_node->last_ch = 0; state->curr_node->last_lf = 0; - return (n - 1); + return n - 1; } } static int mime_state_multi_bound(MIME_STATE *state, const char *s, int n) { MIME_NODE *node = state->curr_node; - const unsigned char *cp; + const unsigned char *cp, *end = (const unsigned char*) s + n; //const unsigned char *startn = NULL; acl_assert(state->curr_bound != NULL); @@ -842,9 +863,7 @@ static int mime_state_multi_bound(MIME_STATE *state, const char *s, int n) const char *boundary = state->curr_bound; - for (cp = (const unsigned char *) s; - cp < (const unsigned char *) s + n; cp++) - { + for (cp = (const unsigned char *) s; cp < end; cp++) { // 记录下 \r\n 的位置 if (*cp == '\r') node->last_cr_pos = state->curr_off; @@ -852,27 +871,20 @@ static int mime_state_multi_bound(MIME_STATE *state, const char *s, int n) node->last_lf_pos = state->curr_off; state->curr_off++; - if (node->bound_ptr) { - if (*cp == *node->bound_ptr) { - node->bound_ptr++; - if (*node->bound_ptr == 0) { - - /* 说明完全匹配 */ - - state->curr_status = MIME_S_MULTI_BOUND_CRLF; - node->bound_ptr = NULL; - cp++; - break; - } - } else { - - /* 说明之前的匹配失效,需要重新匹配, - * 但必须将之前匹配的字符拷贝 - */ - + if (node->bound_ptr != NULL) { + if (*cp != *node->bound_ptr) { + // 说明之前的匹配失效,需要重新匹配, + // 但必须将之前匹配的字符拷贝 node->bound_ptr = NULL; + } else if (*++node->bound_ptr == 0) { + // 说明完全匹配 + state->curr_status = MIME_S_MULTI_BOUND_CRLF; + node->bound_ptr = NULL; + cp++; + break; } } + if (!node->bound_ptr && *cp == *boundary) { node->bound_ptr = boundary + 1; @@ -915,18 +927,18 @@ static int mime_state_multi_bound_crlf(MIME_STATE *state, const char *s, int n) node->bound_ptr = NULL; node->last_ch = 0; node->last_lf = 0; - return (n - 1); + return n - 1; } else if (*s == '\r') { state->curr_node->last_cr_pos = state->curr_off; state->curr_node->last_ch = '\r'; state->curr_off++; state->use_crlf = 1; /* 期待下一个字符为 '\n' */ - return (n - 1); + return n - 1; } else { /* xxx */ state->curr_off += n; - return (0); + return 0; } } @@ -934,7 +946,7 @@ static int mime_state_term(MIME_STATE *state, const char *s, int n) { (void) s; state->curr_off += n; - return (0); + return 0; } static struct MIME_STATUS_MACHINE status_tab[] = { @@ -952,7 +964,7 @@ int mime_state_update(MIME_STATE *state, const char *ptr, int n) while (n > 0) { int ret = status_tab[state->curr_status].callback(state, s, n); if (state->curr_status == MIME_S_TERM) - return (1); + return 1; acl_assert(ret >= 0); if (ret == 0) break; @@ -960,5 +972,5 @@ int mime_state_update(MIME_STATE *state, const char *ptr, int n) n = ret; } - return (0); + return 0; } diff --git a/lib_acl_cpp/src/mime/mime.cpp b/lib_acl_cpp/src/mime/mime.cpp index 135b24388..cd7da0f30 100644 --- a/lib_acl_cpp/src/mime/mime.cpp +++ b/lib_acl_cpp/src/mime/mime.cpp @@ -117,7 +117,7 @@ void mime::primary_head_finish() MIME_NODE* node = m_pMimeState->root; - m_primaryHeader.set_type(node->ctype, node->stype); + m_primaryHeader.set_type(node->ctype_s, node->stype_s); // 针对邮件主头部 ACL_ITER iter; @@ -806,9 +806,8 @@ void mime::mime_debug(const char* save_path, bool decode /* = true */) if (save_path == NULL) return; - logger("ctype: %s, stype: %s\r\n", - mime_ctype_name(state->root->ctype), - mime_stype_name(state->root->stype)); + printf("primary node ctype: %s, stype: %s\r\n", + get_ctype(), get_stype()); state_dummy.root = state->root; mime_state_foreach_init(&state_dummy); @@ -817,9 +816,9 @@ void mime::mime_debug(const char* save_path, bool decode /* = true */) acl_foreach(iter, &state_dummy) { MIME_NODE *node = (MIME_NODE*) iter.data; - const char* ctype = mime_ctype_name(node->ctype); - const char* stype = mime_stype_name(node->stype); - printf("ctype: %s, stype: %s\r\n", ctype, stype); + printf("child node->ctype: %s, stype: %s\r\n", + node->ctype_s ? node->ctype_s : "null", + node->stype_s ? node->stype_s : "null"); if (node->boundary) printf(">>boundary: %s\r\n", diff --git a/lib_acl_cpp/src/mime/mime_head.cpp b/lib_acl_cpp/src/mime/mime_head.cpp index 9370303ab..8c8dd546c 100644 --- a/lib_acl_cpp/src/mime/mime_head.cpp +++ b/lib_acl_cpp/src/mime/mime_head.cpp @@ -11,6 +11,8 @@ const static std::list __dummyList; const static std::list __dummyHeaderList; mime_head::mime_head() + : m_ctype(16) + , m_stype(16) { m_rcpts = NULL; m_tos = NULL; @@ -23,8 +25,6 @@ mime_head::mime_head() m_returnpath = NULL; m_subject = NULL; m_boundary = NULL; - m_ctype = MIME_CTYPE_OTHER; - m_stype = MIME_STYPE_OTHER; } mime_head::~mime_head() @@ -100,12 +100,12 @@ mime_head& mime_head::reset() const char* mime_head::get_ctype() const { - return mime_ctype_name(m_ctype); + return m_ctype.c_str(); } const char* mime_head::get_stype() const { - return mime_stype_name(m_stype); + return m_stype.c_str(); } const acl::string& mime_head::sender() const @@ -283,10 +283,12 @@ mime_head& mime_head::add_header(const char* name, const char* value) return (*this); } -mime_head& mime_head::set_type(size_t ctype, size_t stype) +mime_head& mime_head::set_type(const char* ctype, const char* stype) { - m_ctype = ctype; - m_stype = stype; + if (ctype && *ctype) + m_ctype = ctype; + if (stype && *stype) + m_stype = stype; return (*this); } diff --git a/lib_acl_cpp/src/redis/redis_command.cpp b/lib_acl_cpp/src/redis/redis_command.cpp index 2356920af..b4fe2db23 100644 --- a/lib_acl_cpp/src/redis/redis_command.cpp +++ b/lib_acl_cpp/src/redis/redis_command.cpp @@ -32,7 +32,7 @@ redis_command::redis_command() , slice_res_(false) , result_(NULL) { - pool_ = new dbuf_pool(); + dbuf_ = new dbuf_pool(); addr_[0] = 0; } @@ -54,7 +54,7 @@ redis_command::redis_command(redis_client* conn) , slice_res_(false) , result_(NULL) { - pool_ = new dbuf_pool(); + dbuf_ = new dbuf_pool(); if (conn != NULL) set_client_addr(*conn); else @@ -76,7 +76,7 @@ redis_command::redis_command(redis_client_cluster* cluster, size_t max_conns) , slice_res_(false) , result_(NULL) { - pool_ = new dbuf_pool(); + dbuf_ = new dbuf_pool(); addr_[0] = 0; if (cluster != NULL) @@ -101,7 +101,7 @@ redis_command::~redis_command() acl_myfree(argv_lens_); delete request_buf_; delete request_obj_; - pool_->destroy(); + dbuf_->destroy(); } void redis_command::reset(bool save_slot /* = false */) @@ -113,7 +113,7 @@ void redis_command::clear(bool save_slot /* = false */) { if (used_ > 0) { - pool_->dbuf_reset(); + dbuf_->dbuf_reset(); result_ = NULL; } if (!save_slot) @@ -272,7 +272,7 @@ const char* redis_command::result_value(size_t i, size_t* len /* = NULL */) cons // 大内存有可能被切片成多个不连续的小内存 size = child->get_length(); size++; - char* buf = (char*) pool_->dbuf_alloc(size); + char* buf = (char*) dbuf_->dbuf_alloc(size); size = child->argv_to_string(buf, size); if (len) *len = size; @@ -287,7 +287,7 @@ const redis_result* redis_command::get_result() const // 分析重定向信息,获得重定向的服务器地址 const char* redis_command::get_addr(const char* info) { - char* cmd = pool_->dbuf_strdup(info); + char* cmd = dbuf_->dbuf_strdup(info); char* slot = strchr(cmd, ' '); if (slot == NULL) return NULL; @@ -399,9 +399,9 @@ const redis_result* redis_command::run(redis_client_cluster* cluster, { // 根据请求过程是否采用内存分片方式调用不同的请求过程 if (slice_req_) - result_ = conn->run(pool_, *request_obj_, nchild); + result_ = conn->run(dbuf_, *request_obj_, nchild); else - result_ = conn->run(pool_, *request_buf_, nchild); + result_ = conn->run(dbuf_, *request_buf_, nchild); // 如果连接异常断开,则需要进行重试 if (conn->eof()) @@ -553,7 +553,7 @@ const redis_result* redis_command::run(redis_client_cluster* cluster, acl_doze(redirect_sleep_); } - result_ = conn->run(pool_, "ASKING\r\n", 0); + result_ = conn->run(dbuf_, "ASKING\r\n", 0); if (result_ == NULL) { logger_error("ASKING's reply null"); @@ -626,9 +626,9 @@ const redis_result* redis_command::run(size_t nchild /* = 0 */) else if (conn_ != NULL) { if (slice_req_) - result_ = conn_->run(pool_, *request_obj_, nchild); + result_ = conn_->run(dbuf_, *request_obj_, nchild); else - result_ = conn_->run(pool_, *request_buf_, nchild); + result_ = conn_->run(dbuf_, *request_buf_, nchild); return result_; } else @@ -640,6 +640,22 @@ const redis_result* redis_command::run(size_t nchild /* = 0 */) ///////////////////////////////////////////////////////////////////////////// +void redis_command::logger_result(const redis_result* result) +{ + if (result == NULL) + { + logger_error("result NULL"); + return; + } + + string res; + result->to_string(res); + + logger_error("result type: %d, error: %s, res: [%s], req: [%s]", + result->get_type(), result_error(), res.c_str(), + request_buf_ ? request_buf_->c_str() : "slice request"); +} + int redis_command::get_number(bool* success /* = NULL */) { const redis_result* result = run(); @@ -647,6 +663,7 @@ int redis_command::get_number(bool* success /* = NULL */) { if (success) *success = false; + logger_result(result); return -1; } if (success) @@ -661,6 +678,7 @@ long long int redis_command::get_number64(bool* success /* = NULL */) { if (success) *success = false; + logger_result(result); return -1; } if (success) @@ -674,7 +692,10 @@ int redis_command::get_number(std::vector& out) const redis_result* result = run(); if (result == NULL || result->get_type() != REDIS_RESULT_ARRAY) + { + logger_result(result); return -1; + } size_t size; const redis_result** children = result->get_children(&size); @@ -698,7 +719,10 @@ int redis_command::get_number64(std::vector& out) const redis_result* result = run(); if (result == NULL || result->get_type() != REDIS_RESULT_ARRAY) + { + logger_result(result); return -1; + } size_t size; const redis_result** children = result->get_children(&size); @@ -720,7 +744,10 @@ bool redis_command::check_status(const char* success /* = "OK" */) { const redis_result* result = run(); if (result == NULL || result->get_type() != REDIS_RESULT_STATUS) + { + logger_result(result); return false; + } const char* status = result->get_status(); if (status == NULL || *status == '\0') @@ -737,7 +764,10 @@ int redis_command::get_status(std::vector& out) const redis_result* result = run(); if (result == NULL || result->get_type() != REDIS_RESULT_ARRAY) + { + logger_result(result); return -1; + } size_t size; const redis_result** children = result->get_children(&size); @@ -759,14 +789,22 @@ int redis_command::get_status(std::vector& out) const char* redis_command::get_status() { const redis_result* result = run(); - return result == NULL ? "" : result->get_status(); + if (result == NULL || result->get_type() != REDIS_RESULT_STATUS) + { + logger_result(result); + return ""; + } + return result->get_status(); } int redis_command::get_string(string& buf) { const redis_result* result = run(); if (result == NULL || result->get_type() != REDIS_RESULT_STRING) + { + logger_result(result); return -1; + } return result->argv_to_string(buf); } @@ -774,7 +812,10 @@ int redis_command::get_string(string* buf) { const redis_result* result = run(); if (result == NULL || result->get_type() != REDIS_RESULT_STRING) + { + logger_result(result); return -1; + } if (buf == NULL) return (int) result->get_length(); return result->argv_to_string(*buf); @@ -784,7 +825,10 @@ int redis_command::get_string(char* buf, size_t size) { const redis_result* result = run(); if (result == NULL || result->get_type() != REDIS_RESULT_STRING) + { + logger_result(result); return -1; + } return result->argv_to_string(buf, size); } @@ -797,7 +841,11 @@ int redis_command::get_strings(std::vector* out) { const redis_result* result = run(); if (result == NULL || result->get_type() != REDIS_RESULT_ARRAY) + { + logger_result(result); return -1; + } + if (out == NULL) return (int) result->get_size(); @@ -842,7 +890,10 @@ int redis_command::get_strings(std::list* out) { const redis_result* result = run(); if (result == NULL || result->get_type() != REDIS_RESULT_ARRAY) + { + logger_result(result); return -1; + } if (out == NULL) return (int) result->get_size(); @@ -880,7 +931,10 @@ int redis_command::get_strings(std::map& out) const redis_result* result = run(); if (result == NULL || result->get_type() != REDIS_RESULT_ARRAY) + { + logger_result(result); return -1; + } if (result->get_size() == 0) return 0; @@ -930,7 +984,10 @@ int redis_command::get_strings(std::vector& names, const redis_result* result = run(); if (result == NULL || result->get_type() != REDIS_RESULT_ARRAY) + { + logger_result(result); return -1; + } if (result->get_size() == 0) return 0; @@ -982,7 +1039,10 @@ int redis_command::get_strings(std::vector& names, const redis_result* result = run(); if (result == NULL || result->get_type() != REDIS_RESULT_ARRAY) + { + logger_result(result); return -1; + } if (result->get_size() == 0) return 0; @@ -1007,7 +1067,7 @@ int redis_command::get_strings(std::vector& names, continue; } len = rr->get_length() + 1; - nbuf = (char*) pool_->dbuf_alloc(len); + nbuf = (char*) dbuf_->dbuf_alloc(len); rr->argv_to_string(nbuf, len); i++; @@ -1018,7 +1078,7 @@ int redis_command::get_strings(std::vector& names, continue; } len = rr->get_length() + 1; - vbuf = (char*) pool_->dbuf_alloc(len); + vbuf = (char*) dbuf_->dbuf_alloc(len); rr->argv_to_string(vbuf, len); i++; @@ -1206,20 +1266,20 @@ void redis_command::build_request2(size_t argc, const char* argv[], size_t lens[ #define BLEN 32 - char* buf = (char*) pool_->dbuf_alloc(BLEN); + char* buf = (char*) dbuf_->dbuf_alloc(BLEN); int len = safe_snprintf(buf, BLEN, "*%lu\r\n", (unsigned long) argc); request_obj_->put(buf, len); for (size_t i = 0; i < argc; i++) { - buf = (char*) pool_->dbuf_alloc(BLEN); + buf = (char*) dbuf_->dbuf_alloc(BLEN); len = safe_snprintf(buf, BLEN, "$%lu\r\n", (unsigned long) lens[i]); request_obj_->put(buf, len); request_obj_->put(argv[i], lens[i]); - buf = (char*) pool_->dbuf_strdup("\r\n"); + buf = (char*) dbuf_->dbuf_strdup("\r\n"); request_obj_->put(buf, 2); } } @@ -1442,7 +1502,7 @@ void redis_command::build(const char* cmd, const char* key, char* buf4int; for (size_t j = 0; j < argc; j++) { - buf4int = (char*) pool_->dbuf_alloc(INT_LEN); + buf4int = (char*) dbuf_->dbuf_alloc(INT_LEN); (void) safe_snprintf(buf4int, INT_LEN, "%d", names[j]); argv_[i] = buf4int; argv_lens_[i] = strlen(argv_[i]); @@ -1579,7 +1639,7 @@ void redis_command::build(const char* cmd, const char* key, char* buf4int; for (size_t j = 0; j < argc; j++) { - buf4int = (char*) pool_->dbuf_alloc(INT_LEN); + buf4int = (char*) dbuf_->dbuf_alloc(INT_LEN); safe_snprintf(buf4int, INT_LEN, "%d", names[j]); argv_[i] = buf4int; argv_lens_[i] = strlen(argv_[i]); @@ -1672,7 +1732,7 @@ void redis_command::build(const char* cmd, const char* key, char* buf4int; for (size_t j = 0; j < argc; j++) { - buf4int = (char*) pool_->dbuf_alloc(INT_LEN); + buf4int = (char*) dbuf_->dbuf_alloc(INT_LEN); safe_snprintf(buf4int, INT_LEN, "%d", names[j]); argv_[i] = buf4int; argv_lens_[i] = strlen(argv_[i]); diff --git a/lib_acl_cpp/src/redis/redis_geo.cpp b/lib_acl_cpp/src/redis/redis_geo.cpp index d9b5f9f01..c842db80f 100644 --- a/lib_acl_cpp/src/redis/redis_geo.cpp +++ b/lib_acl_cpp/src/redis/redis_geo.cpp @@ -89,12 +89,12 @@ int redis_geo::geoadd(const char* key, const char* member, argv[1] = key; lens[1] = strlen(key); - char* buf = (char*) pool_->dbuf_alloc(BUFLEN); + char* buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", longitude); argv[2] = buf; lens[2] = strlen(buf); - buf = (char*) pool_->dbuf_alloc(BUFLEN); + buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", latitude); argv[3] = buf; lens[3] = strlen(buf); @@ -112,8 +112,8 @@ int redis_geo::geoadd(const char* key, size_t size, const char* members[], { size_t argc = 2 + 3 * size; const char** argv = (const char**) - pool_->dbuf_alloc(argc * sizeof(char*)); - size_t *lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t *lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = "GEOADD"; lens[0] = sizeof("GEOADD") - 1; @@ -123,13 +123,13 @@ int redis_geo::geoadd(const char* key, size_t size, const char* members[], for (size_t i = 0, n = 2; i < size; i++) { - char* buf = (char*) pool_->dbuf_alloc(BUFLEN); + char* buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", longitudes[i]); argv[n] = buf; lens[n] = strlen(argv[n]); n++; - buf = (char*) pool_->dbuf_alloc(BUFLEN); + buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", latitudes[i]); argv[n] = buf; lens[n] = strlen(argv[n]); @@ -169,8 +169,8 @@ int redis_geo::geoadd(const char* key, const std::vector& members, size_t argc = 2 + 3 * members.size(); const char** argv = (const char**) - pool_->dbuf_alloc(argc * sizeof(char*)); - size_t *lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t *lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = "GEOADD"; lens[0] = sizeof("GEOADD") - 1; @@ -181,13 +181,13 @@ int redis_geo::geoadd(const char* key, const std::vector& members, size_t size = members.size(); for (size_t i = 0, n = 2; i < size; i++) { - char* buf = (char*) pool_->dbuf_alloc(BUFLEN); + char* buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", longitudes[i]); argv[n] = buf; lens[n] = strlen(argv[n]); n++; - buf = (char*) pool_->dbuf_alloc(BUFLEN); + buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", latitudes[i]); argv[n] = buf; lens[n] = strlen(argv[n]); @@ -377,19 +377,19 @@ const std::vector& redis_geo::georadius(const char* key, lens[argc] = strlen(key); argc++; - char* buf = (char*) pool_->dbuf_alloc(BUFLEN); + char* buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", longitude); argv[argc] = buf; lens[argc] = strlen(buf); argc++; - buf = (char*) pool_->dbuf_alloc(BUFLEN); + buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", latitude); argv[argc] = buf; lens[argc] = strlen(buf); argc++; - buf = (char*) pool_->dbuf_alloc(BUFLEN); + buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", radius); argv[argc] = buf; lens[argc] = strlen(buf); @@ -475,7 +475,7 @@ const std::vector& redis_geo::georadiusbymember(const char* key, lens[argc] = strlen(member); argc++; - char* buf = (char*) pool_->dbuf_alloc(BUFLEN); + char* buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", radius); argv[argc] = buf; lens[argc] = strlen(buf); diff --git a/lib_acl_cpp/src/redis/redis_list.cpp b/lib_acl_cpp/src/redis/redis_list.cpp index bc82fa534..168123b66 100644 --- a/lib_acl_cpp/src/redis/redis_list.cpp +++ b/lib_acl_cpp/src/redis/redis_list.cpp @@ -356,8 +356,8 @@ bool redis_list::bpop(const char* cmd, const std::vector& keys, size_t timeout, std::pair& result) { size_t argc = 2 + keys.size(); - const char** args = (const char**) pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + const char** args = (const char**) dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); args[0] = cmd; lens[0] = strlen(cmd); @@ -384,8 +384,8 @@ bool redis_list::bpop(const char* cmd, const std::vector& keys, size_t timeout, std::pair& result) { size_t argc = 2 + keys.size(); - const char** args = (const char**) pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + const char** args = (const char**) dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); args[0] = cmd; lens[0] = strlen(cmd); diff --git a/lib_acl_cpp/src/redis/redis_pubsub.cpp b/lib_acl_cpp/src/redis/redis_pubsub.cpp index 055a80c65..4f49ae5c9 100644 --- a/lib_acl_cpp/src/redis/redis_pubsub.cpp +++ b/lib_acl_cpp/src/redis/redis_pubsub.cpp @@ -142,8 +142,8 @@ int redis_pubsub::punsubscribe(const std::vector& patterns) int redis_pubsub::subop(const char* cmd, const std::vector& channels) { size_t argc = 1 + channels.size(); - const char** argv = (const char**) pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t *) pool_->dbuf_alloc(argc * sizeof(size_t)); + const char** argv = (const char**) dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t *) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = cmd; lens[0] = strlen(cmd); @@ -179,8 +179,8 @@ int redis_pubsub::subop(const char* cmd, const std::vector& channel int redis_pubsub::subop(const char* cmd, const std::vector& channels) { size_t argc = 1 + channels.size(); - const char** argv = (const char**) pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t *) pool_->dbuf_alloc(argc * sizeof(size_t)); + const char** argv = (const char**) dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t *) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = cmd; lens[0] = strlen(cmd); diff --git a/lib_acl_cpp/src/redis/redis_result.cpp b/lib_acl_cpp/src/redis/redis_result.cpp index 594fb382e..fb33ea1bd 100644 --- a/lib_acl_cpp/src/redis/redis_result.cpp +++ b/lib_acl_cpp/src/redis/redis_result.cpp @@ -7,9 +7,9 @@ namespace acl { -redis_result::redis_result(dbuf_pool* pool) +redis_result::redis_result(dbuf_pool* dbuf) : result_type_(REDIS_RESULT_NIL) -, pool_(pool) +, dbuf_(dbuf) , size_(0) , idx_(0) , argv_(NULL) @@ -18,7 +18,7 @@ redis_result::redis_result(dbuf_pool* pool) , children_size_(10) , children_idx_(0) { - acl_assert(pool_ != NULL); + acl_assert(dbuf_ != NULL); } redis_result::~redis_result() @@ -75,8 +75,8 @@ redis_result& redis_result::put(const char* buf, size_t len) } if (argv_ == NULL) { - argv_ = (const char**) pool_->dbuf_alloc(sizeof(char*) * size_); - lens_ = (size_t*) pool_->dbuf_alloc(sizeof(size_t) * size_); + argv_ = (const char**) dbuf_->dbuf_alloc(sizeof(char*) * size_); + lens_ = (size_t*) dbuf_->dbuf_alloc(sizeof(size_t) * size_); } argv_[idx_] = buf; @@ -229,7 +229,7 @@ int redis_result::argv_to_string(char* buf, size_t size) const redis_result& redis_result::put(const redis_result* rr, size_t idx) { if (children_ == NULL) - children_ = (const redis_result**) pool_->dbuf_alloc( + children_ = (const redis_result**) dbuf_->dbuf_alloc( sizeof(redis_result*) * children_size_); else if (idx == 0) children_idx_ = 0; @@ -243,7 +243,7 @@ redis_result& redis_result::put(const redis_result* rr, size_t idx) children_size_ *= 2; const redis_result** children =(const redis_result**) - pool_->dbuf_calloc(sizeof(redis_result*) * children_size_); + dbuf_->dbuf_calloc(sizeof(redis_result*) * children_size_); for (size_t i = 0; i < children_idx_; i++) children[i] = children_[i]; @@ -268,4 +268,31 @@ const redis_result** redis_result::get_children(size_t* size) const return children_; } +const string& redis_result::to_string(string& out) const +{ + redis_result_t type = get_type(); + if (type != REDIS_RESULT_ARRAY) + { + string buf; + argv_to_string(buf); + out += buf; + out += "\r\n"; + return out; + } + + size_t size; + const redis_result** children = get_children(&size); + if (children == NULL) + return out; + + for (size_t i = 0; i < size; i++) + { + const redis_result* rr = children[i]; + if (rr != NULL) + rr->to_string(out); + } + + return out; +} + } // namespace acl diff --git a/lib_acl_cpp/src/redis/redis_script.cpp b/lib_acl_cpp/src/redis/redis_script.cpp index d0574eacc..78e4cc33b 100644 --- a/lib_acl_cpp/src/redis/redis_script.cpp +++ b/lib_acl_cpp/src/redis/redis_script.cpp @@ -374,8 +374,8 @@ const redis_result* redis_script::eval_cmd(const char* cmd, { size_t argc = 3 + keys.size() + args.size(); const char** argv = (const char**) - pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = cmd; lens[0] = strlen(cmd); @@ -419,8 +419,8 @@ const redis_result* redis_script::eval_cmd(const char* cmd, { size_t argc = 3 + keys.size() + args.size(); const char** argv = (const char**) - pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = cmd; lens[0] = strlen(cmd); diff --git a/lib_acl_cpp/src/redis/redis_string.cpp b/lib_acl_cpp/src/redis/redis_string.cpp index 45a0809a5..33b40887c 100644 --- a/lib_acl_cpp/src/redis/redis_string.cpp +++ b/lib_acl_cpp/src/redis/redis_string.cpp @@ -528,8 +528,8 @@ int redis_string::bitop(const char* op, const char* destkey, const std::vector& keys) { size_t argc = 3 + keys.size(); - const char** argv = (const char**) pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + const char** argv = (const char**) dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = "BITOP"; lens[0] = sizeof("BITOP") - 1; @@ -555,8 +555,8 @@ int redis_string::bitop(const char* op, const char* destkey, const std::vector& keys) { size_t argc = 3 + keys.size(); - const char** argv = (const char**) pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + const char** argv = (const char**) dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = "BITOP"; lens[0] = sizeof("BITOP") - 1; @@ -582,8 +582,8 @@ int redis_string::bitop(const char* op, const char* destkey, const char* keys[], size_t size) { size_t argc = 3 + size; - const char** argv = (const char**) pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + const char** argv = (const char**) dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = "BITOP"; lens[0] = sizeof("BITOP") - 1; diff --git a/lib_acl_cpp/src/redis/redis_zset.cpp b/lib_acl_cpp/src/redis/redis_zset.cpp index dbd016632..009c839a0 100644 --- a/lib_acl_cpp/src/redis/redis_zset.cpp +++ b/lib_acl_cpp/src/redis/redis_zset.cpp @@ -34,8 +34,8 @@ int redis_zset::zadd(const char* key, const std::map& members) { size_t argc = 2 + members.size() * 2; const char** argv = (const char**) - pool_->dbuf_alloc(argc * sizeof(char*)); - size_t *lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t *lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = "ZADD"; lens[0] = sizeof("ZADD") - 1; @@ -48,7 +48,7 @@ int redis_zset::zadd(const char* key, const std::map& members) std::map::const_iterator cit = members.begin(); for (; cit != members.end(); ++cit) { - buf = (char*) pool_->dbuf_alloc(BUFLEN); + buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", cit->second); argv[i] = buf; @@ -70,8 +70,8 @@ int redis_zset::zadd(const char* key, { size_t argc = 2 + members.size() * 2; const char** argv = (const char**) - pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = "ZADD"; lens[0] = sizeof("ZADD") - 1; @@ -84,7 +84,7 @@ int redis_zset::zadd(const char* key, std::vector >::const_iterator cit; for (cit = members.begin(); cit != members.end(); ++cit) { - buf = (char*) pool_->dbuf_alloc(BUFLEN); + buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", (*cit).second); argv[i] = buf; lens[i] = strlen(buf); @@ -105,8 +105,8 @@ int redis_zset::zadd(const char* key, { size_t argc = 2 + members.size() * 2; const char** argv = (const char**) - pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = "ZADD"; lens[0] = sizeof("ZADD") - 1; @@ -120,7 +120,7 @@ int redis_zset::zadd(const char* key, for (cit = members.begin(); cit != members.end(); ++cit) { - buf = (char*) pool_->dbuf_alloc(BUFLEN); + buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", (*cit).second); argv[i] = buf; lens[i] = strlen(buf); @@ -145,8 +145,8 @@ int redis_zset::zadd(const char* key, const std::vector& members, size_t argc = 2 + scores.size() * 2; const char** argv = (const char**) - pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = "ZADD"; lens[0] = sizeof("ZADD") - 1; @@ -159,7 +159,7 @@ int redis_zset::zadd(const char* key, const std::vector& members, for (size_t i = 0; i < size; i++) { - buf = (char*) pool_->dbuf_alloc(BUFLEN); + buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", scores[i]); argv[j] = buf; lens[j] = strlen(buf); @@ -184,8 +184,8 @@ int redis_zset::zadd(const char* key, const std::vector& members, size_t argc = 2 + scores.size() * 2; const char** argv = (const char**) - pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = "ZADD"; lens[0] = sizeof("ZADD") - 1; @@ -198,7 +198,7 @@ int redis_zset::zadd(const char* key, const std::vector& members, for (size_t i = 0; i < size; i++) { - buf = (char*) pool_->dbuf_alloc(BUFLEN); + buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", scores[i]); argv[j] = buf; lens[j] = strlen(buf); @@ -219,8 +219,8 @@ int redis_zset::zadd(const char* key, const char* members[], double scores[], { size_t argc = 2 + size * 2; const char** argv = (const char**) - pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = "ZADD"; lens[0] = sizeof("ZADD") - 1; @@ -233,7 +233,7 @@ int redis_zset::zadd(const char* key, const char* members[], double scores[], for (size_t i = 0; i < size; i++) { - buf = (char*) pool_->dbuf_alloc(BUFLEN); + buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", scores[i]); argv[j] = buf; lens[j] = strlen(buf); @@ -254,8 +254,8 @@ int redis_zset::zadd(const char* key, const char* members[], { size_t argc = 2 + size * 2; const char** argv = (const char**) - pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = "ZADD"; lens[0] = sizeof("ZADD") - 1; @@ -269,7 +269,7 @@ int redis_zset::zadd(const char* key, const char* members[], for (size_t i = 0; i < size; i++) { - buf = (char*) pool_->dbuf_alloc(BUFLEN); + buf = (char*) dbuf_->dbuf_alloc(BUFLEN); len = safe_snprintf(buf, BUFLEN, "%.8f", scores[i]); argv[j] = buf; lens[j] = len; @@ -848,8 +848,8 @@ int redis_zset::zstore(const char* cmd, const char* dst, size_t argc = num * 2 + 6; const char** argv = (const char**) - pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = cmd; lens[0] = strlen(cmd); @@ -877,7 +877,7 @@ int redis_zset::zstore(const char* cmd, const char* dst, char* buf; for (cit = keys.begin(); cit != keys.end(); ++cit) { - buf = (char*) pool_->dbuf_alloc(BUFLEN); + buf = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(buf, BUFLEN, "%.8f", cit->second); argv[i] = buf; @@ -929,8 +929,8 @@ int redis_zset::zstore(const char* cmd, const char* dst, argc += 2; const char** argv = (const char**) - pool_->dbuf_alloc(argc * sizeof(char*)); - size_t* lens = (size_t*) pool_->dbuf_alloc(argc * sizeof(size_t)); + dbuf_->dbuf_alloc(argc * sizeof(char*)); + size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t)); argv[0] = cmd; lens[0] = strlen(cmd); @@ -962,7 +962,7 @@ int redis_zset::zstore(const char* cmd, const char* dst, std::vector::const_iterator cit2 = weights->begin(); for (; cit2 != weights->end(); ++cit2) { - score = (char*) pool_->dbuf_alloc(BUFLEN); + score = (char*) dbuf_->dbuf_alloc(BUFLEN); safe_snprintf(score, BUFLEN, "%.8f", *cit2); argv[i] = score; lens[i] = strlen(score); diff --git a/lib_acl_cpp/src/session/session.cpp b/lib_acl_cpp/src/session/session.cpp index 6e9740f0c..8d782b5ae 100644 --- a/lib_acl_cpp/src/session/session.cpp +++ b/lib_acl_cpp/src/session/session.cpp @@ -14,11 +14,11 @@ session::session(time_t ttl /* = 0 */, const char* sid /* = NULL */) , ttl_(ttl) , dirty_(false) { - struct timeval tv; - - (void) gettimeofday(&tv, NULL); if (sid == NULL || *sid == 0) { + struct timeval tv; + + (void) gettimeofday(&tv, NULL); sid_.format("acl.%d.%d.%d", (int) tv.tv_sec, (int) tv.tv_usec, rand()); sid_.todo_ = TODO_NUL; diff --git a/lib_acl_cpp/src/stream/fstream.cpp b/lib_acl_cpp/src/stream/fstream.cpp index 79a342337..77dee2584 100644 --- a/lib_acl_cpp/src/stream/fstream.cpp +++ b/lib_acl_cpp/src/stream/fstream.cpp @@ -13,7 +13,8 @@ fstream::~fstream() close(); } -void fstream::open(ACL_FILE_HANDLE fh, unsigned int oflags) +void fstream::open(ACL_FILE_HANDLE fh, unsigned int oflags, + const char* path /* = NULL */) { open_stream(true); // 调用基类方法先创建空流对象 @@ -29,11 +30,14 @@ void fstream::open(ACL_FILE_HANDLE fh, unsigned int oflags) stream_->oflags = oflags; opened_ = true; eof_ = false; + + if (path && *path) + acl_vstream_set_path(stream_, path); } bool fstream::open(const char* path, unsigned int oflags, int mode) { - if (path == NULL) + if (path == NULL || *path == 0) return false; ACL_FILE_HANDLE fh; @@ -58,6 +62,21 @@ bool fstream::open(const char* path, unsigned int oflags, int mode) return true; } +bool fstream::remove(void) +{ + const char* filepath = file_path(); + if (filepath == NULL || *filepath == 0) + return false; + +#if defined(_WIN32) || defined(_WIN64) + // WINDOWS 下必须先关闭文件句柄 + close(); + return ::_unlink(filepath) == 0 ? true : false; +#else + return ::unlink(filepath) == 0 ? true : false; +#endif +} + const char* fstream::file_path() const { return stream_ ? stream_->path : NULL; @@ -89,7 +108,9 @@ acl_off_t fstream::ftell() bool fstream::ftruncate(acl_off_t length) { - fseek(0, SEEK_SET); // 需要先将文件指针移到开始位置 + // 需要先将文件指针移到开始位置 + if (fseek(0, SEEK_SET) < 0) + return false; return acl_file_ftruncate(stream_, length) == 0 ? true : false; } diff --git a/lib_protocol/Makefile b/lib_protocol/Makefile index b293a870c..9bfcaa9a8 100644 --- a/lib_protocol/Makefile +++ b/lib_protocol/Makefile @@ -2,10 +2,10 @@ SHELL = /bin/sh CC = gcc #CC = g++ CC = ${ENV_CC} -AR = ar +AR = ${ENV_AR} ARFL = rv #ARFL = cru -RANLIB = ranlib +RANLIB = ${ENV_RANLIB} CFLAGS = -c -g -W \ -O3 \ @@ -38,6 +38,14 @@ ifeq ($(CC),) CC = gcc endif +ifeq ($(AR),) + AR = ar +endif + +ifeq ($(RANLIB),) + RANLIB = ranlib +endif + ifeq ($(findstring gcc, $(CC)), gcc) CFLAGS += -Wstrict-prototypes endif diff --git a/lib_protocol/samples/Makefile.in b/lib_protocol/samples/Makefile.in index 431cd7dc8..eb5c1ae2c 100644 --- a/lib_protocol/samples/Makefile.in +++ b/lib_protocol/samples/Makefile.in @@ -1,4 +1,4 @@ -CC = $(MY_ENV_CC) +CC = $(ENV_CC) CFLAGS = -c -g -W \ -Wall \ diff --git a/lib_protocol/samples/Makefile_cpp.in b/lib_protocol/samples/Makefile_cpp.in index 4e8928953..c1469c2da 100644 --- a/lib_protocol/samples/Makefile_cpp.in +++ b/lib_protocol/samples/Makefile_cpp.in @@ -1,4 +1,4 @@ -CC = $(MY_ENV_CC) +CC = $(ENV_CPP) CFLAGS = -c -g -W \ -Wall \ diff --git a/test/Makefile.in b/test/Makefile.in index e15946b3e..fe11110c7 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1,4 +1,4 @@ -CC = ${MY_ENV_CC} +CC = ${ENV_CPP} CFLAGS = -c -g -W \ -O3 \