improving performance and fixed some bugs

This commit is contained in:
ubuntu14 2016-02-05 10:10:24 +08:00
parent 54d00a0cdb
commit af1d5bd90e
85 changed files with 5134 additions and 1333 deletions

View File

@ -690,6 +690,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "json12", "lib_acl_cpp\sampl
{FE724EF7-3763-4E78-BDF5-BCBC075719FD} = {FE724EF7-3763-4E78-BDF5-BCBC075719FD}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "net_tools", "app\net_tools\net_tools_vc2012.vcxproj", "{45276293-D169-4D73-8930-F255C09DA976}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "httpd_upload", "app\wizard_demo\httpd_upload\httpd_upload_vc2012.vcxproj", "{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}"
ProjectSection(ProjectDependencies) = postProject
{6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC} = {6EC1F44E-6A6A-48E9-B699-D7E89B63C8DC}
{B40213C2-507C-4C7F-A6E1-B850C9BDC27B} = {B40213C2-507C-4C7F-A6E1-B850C9BDC27B}
{FE724EF7-3763-4E78-BDF5-BCBC075719FD} = {FE724EF7-3763-4E78-BDF5-BCBC075719FD}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Mixed Platforms = Debug|Mixed Platforms
@ -3314,6 +3323,61 @@ Global
{20299269-7A1C-45CB-8807-861745A55F82}.Template|Win32.Build.0 = DebugDll|Win32
{20299269-7A1C-45CB-8807-861745A55F82}.Template|x64.ActiveCfg = DebugDll|x64
{20299269-7A1C-45CB-8807-861745A55F82}.Template|x64.Build.0 = DebugDll|x64
{45276293-D169-4D73-8930-F255C09DA976}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Debug|Win32.ActiveCfg = Debug|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Debug|Win32.Build.0 = Debug|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Debug|x64.ActiveCfg = Debug|Win32
{45276293-D169-4D73-8930-F255C09DA976}.DebugDll|Mixed Platforms.ActiveCfg = Debug|Win32
{45276293-D169-4D73-8930-F255C09DA976}.DebugDll|Mixed Platforms.Build.0 = Debug|Win32
{45276293-D169-4D73-8930-F255C09DA976}.DebugDll|Win32.ActiveCfg = Debug|Win32
{45276293-D169-4D73-8930-F255C09DA976}.DebugDll|Win32.Build.0 = Debug|Win32
{45276293-D169-4D73-8930-F255C09DA976}.DebugDll|x64.ActiveCfg = Debug|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Release|Mixed Platforms.Build.0 = Release|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Release|Win32.ActiveCfg = Release|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Release|Win32.Build.0 = Release|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Release|x64.ActiveCfg = Release|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Releasedll|Mixed Platforms.ActiveCfg = Release|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Releasedll|Mixed Platforms.Build.0 = Release|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Releasedll|Win32.ActiveCfg = Release|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Releasedll|Win32.Build.0 = Release|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Releasedll|x64.ActiveCfg = Release|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Template|Mixed Platforms.ActiveCfg = Release|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Template|Mixed Platforms.Build.0 = Release|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Template|Win32.ActiveCfg = Release|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Template|Win32.Build.0 = Release|Win32
{45276293-D169-4D73-8930-F255C09DA976}.Template|x64.ActiveCfg = Release|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Debug|Win32.ActiveCfg = Debug|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Debug|Win32.Build.0 = Debug|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Debug|x64.ActiveCfg = Debug|x64
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Debug|x64.Build.0 = Debug|x64
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.DebugDll|Mixed Platforms.ActiveCfg = DebugDll|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.DebugDll|Mixed Platforms.Build.0 = DebugDll|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.DebugDll|Win32.ActiveCfg = DebugDll|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.DebugDll|Win32.Build.0 = DebugDll|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.DebugDll|x64.ActiveCfg = DebugDll|x64
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.DebugDll|x64.Build.0 = DebugDll|x64
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Release|Mixed Platforms.Build.0 = Release|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Release|Win32.ActiveCfg = Release|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Release|Win32.Build.0 = Release|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Release|x64.ActiveCfg = Release|x64
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Release|x64.Build.0 = Release|x64
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Releasedll|Mixed Platforms.ActiveCfg = ReleaseDll|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Releasedll|Mixed Platforms.Build.0 = ReleaseDll|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Releasedll|Win32.ActiveCfg = ReleaseDll|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Releasedll|Win32.Build.0 = ReleaseDll|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Releasedll|x64.ActiveCfg = ReleaseDll|x64
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Releasedll|x64.Build.0 = ReleaseDll|x64
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Template|Mixed Platforms.ActiveCfg = DebugDll|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Template|Mixed Platforms.Build.0 = DebugDll|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Template|Win32.ActiveCfg = DebugDll|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Template|Win32.Build.0 = DebugDll|Win32
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Template|x64.ActiveCfg = DebugDll|x64
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}.Template|x64.Build.0 = DebugDll|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -3392,6 +3456,7 @@ Global
{84376B60-FF20-4FD0-967E-C568FC2FBC53} = {3CC8D45A-8E3F-4F5C-A7DF-4D8027E4EA9C}
{C8535C82-3DCB-472E-9E8F-DA769D9375B1} = {3CC8D45A-8E3F-4F5C-A7DF-4D8027E4EA9C}
{1C02A405-3726-4410-80DF-91D60736352B} = {3CC8D45A-8E3F-4F5C-A7DF-4D8027E4EA9C}
{45276293-D169-4D73-8930-F255C09DA976} = {3CC8D45A-8E3F-4F5C-A7DF-4D8027E4EA9C}
{3C74E826-5E72-48A1-9DFD-777F4A7C9E1F} = {D232833B-57A9-4167-B37C-A4594953F93D}
{B59C7CB6-5708-4522-B833-CEB160AA4817} = {D232833B-57A9-4167-B37C-A4594953F93D}
{2DABFAD1-114B-4F96-9185-DC0C56A3662D} = {C799E376-2F01-4877-AF18-7F3CC8B95792}
@ -3420,6 +3485,7 @@ Global
{2425D8B1-FE96-4D7F-BDB0-48C932935D96} = {B6BE4E77-F69D-43B0-BE8A-77A8AA61A89E}
{AFC106A8-C78A-43C6-BA55-1B7EB541F559} = {B6BE4E77-F69D-43B0-BE8A-77A8AA61A89E}
{1A38C49B-F712-4115-980B-6DBD632D25CF} = {1C02A405-3726-4410-80DF-91D60736352B}
{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F} = {1C02A405-3726-4410-80DF-91D60736352B}
{B2FAA9AA-0F95-4EAC-A95A-B1F8B476F81A} = {3C576B18-D253-4CA2-986E-7173C2978AC3}
{ADEF5A5D-403A-4A2B-ACAA-FA022BBCA5C3} = {3C576B18-D253-4CA2-986E-7173C2978AC3}
{BEAAA294-B25E-47D2-BF42-C8C833D3D238} = {3C576B18-D253-4CA2-986E-7173C2978AC3}

View File

@ -68,14 +68,16 @@ bool mime_builder::save_as(acl::ofstream& fp)
acl::string buf;
if (attachs_.empty())
{
header_.set_type(MIME_CTYPE_TEXT, body_html_ ?
MIME_STYPE_HTML : MIME_STYPE_PLAIN);
//header_.set_type(MIME_CTYPE_TEXT, body_html_ ?
// MIME_STYPE_HTML : MIME_STYPE_PLAIN);
header_.set_type("text", body_html_ ? "html" : "plain");
header_.add_header("Content-Transfer-Encoding", "base64");
}
else
{
header_.set_type(MIME_CTYPE_MULTIPART,
MIME_STYPE_MIXED);
//header_.set_type(MIME_CTYPE_MULTIPART,
// MIME_STYPE_MIXED);
header_.set_type("multipart", "mixed");
delimeter_.format("------=_Part_%d_%ld.%ld", getpid(),
acl_pthread_self(), time(NULL));
header_.set_boundary(delimeter_.c_str());

View File

@ -1,8 +1,10 @@
.PHONY = all clean
all:
@(cd httpd_upload; make)
@(cd httpd_download; make)
clean:
@(cd httpd_upload; make clean)
@(cd httpd_download; make clean)
rb rebuild: clean all

View File

@ -0,0 +1,5 @@
include ./Makefile.in
ifeq ($(findstring FreeBSD, $(UNIXNAME)), FreeBSD)
EXTLIBS += -L/usr/local/lib -liconv
endif
PROG = httpd_upload

View File

@ -0,0 +1,116 @@
CC = g++
CFLAGS = -c -g -W -Wall -Wcast-qual -Wcast-align \
-Waggregate-return -Wno-long-long \
-Wpointer-arith -Werror -Wshadow -O3 \
-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -D_USE_FAST_MACRO
###########################################################
#Check system:
# Linux, SunOS, Solaris, BSD variants, AIX, HP-UX
SYSLIB = -lpthread -lz
CHECKSYSRES = @echo "Unknow system type!";exit 1
UNIXNAME = $(shell uname -sm)
OSTYPE = $(shell uname -p)
RPATH = linux64
ifeq ($(CC),)
CC = gcc
endif
# For FreeBSD
ifeq ($(findstring FreeBSD, $(UNIXNAME)), FreeBSD)
ifeq ($(findstring gcc, $(CC)), gcc)
CFLAGS += -Wstrict-prototypes
endif
CFLAGS += -DFREEBSD -D_REENTRANT
SYSLIB = -lcrypt -lpthread -lz
RPATH = freebsd
endif
# For Darwin
ifeq ($(findstring Darwin, $(UNIXNAME)), Darwin)
CFLAGS += -DMACOSX -Wno-invalid-source-encoding \
-Wno-extended-offsetof
UNIXTYPE = MACOSX
SYSLIB += -liconv -rdynamic
RPATH = macos
endif
#Path for Linux
ifeq ($(findstring Linux, $(UNIXNAME)), Linux)
ifeq ($CC, "gcc")
CFLAGS += -Wstrict-prototypes
endif
ifeq ($(findstring i686, $(OSTYPE)), i686)
RPATH = linux32
endif
ifeq ($(findstring x86_64, $(OSTYPE)), x86_64)
RPATH = linux64
endif
CFLAGS += -DLINUX2 -D_REENTRANT
SYSLIB += -lcrypt
endif
#Path for SunOS
ifeq ($(findstring SunOS, $(UNIXNAME)), SunOS)
ifeq ($(findstring 86, $(UNIXNAME)), 86)
SYSLIB += -lsocket -lnsl -lrt
endif
ifeq ($(findstring sun4u, $(UNIXNAME)), sun4u)
SYSLIB += -lsocket -lnsl -lrt
endif
ifeq ($CC, "gcc")
CFLAGS += -Wstrict-prototypes
endif
CFLAGS += -DSUNOS5 -D_REENTRANT
RPATH = sunos_x86
endif
#Path for HP-UX
ifeq ($(findstring HP-UX, $(UNIXNAME)), HP-UX)
ifeq ($CC, "gcc")
CFLAGS += -Wstrict-prototypes
endif
CFLAGS += -DHP_UX -DHPUX11
PLAT_NAME=hp-ux
endif
#Find system type.
ifneq ($(SYSPATH),)
CHECKSYSRES = @echo "System is $(shell uname -sm)"
endif
###########################################################
CFLAGS += -I../../../lib_acl/include -I../../../lib_protocol/include -I../../../lib_acl_cpp/include
EXTLIBS =
LDFLAGS = -L../../../lib_acl_cpp/lib -l_acl_cpp -L../../../lib_protocol/lib -l_protocol -L../../../lib_acl/lib -l_acl \
$(EXTLIBS) $(SYSLIB)
COMPILE = $(CC) $(CFLAGS)
LINK = $(CC) $(OBJ) $(LDFLAGS)
###########################################################
OBJ_PATH = .
#Project's objs
SRC = $(wildcard *.cpp)
OBJ = $(patsubst %.cpp, $(OBJ_PATH)/%.o, $(notdir $(SRC)))
$(OBJ_PATH)/%.o: %.cpp
$(COMPILE) $< -o $@
.PHONY = all clean
all: RM $(OBJ)
$(LINK) -o $(PROG)
@echo ""
@echo "All ok! Output:$(PROG)"
@echo ""
RM:
rm -f $(PROG)
clean:
rm -f $(PROG)
rm -f $(OBJ)
install:
cp $(PROG) ../../../dist/master/libexec/$(RPATH)/
cp $(PROG).cf ../../../dist/master/conf/service/
###########################################################

View File

@ -0,0 +1,358 @@
#include "stdafx.h"
#include "master_service.h"
#include "http_servlet.h"
http_servlet::http_servlet(acl::socket_stream* stream, acl::session* session)
: acl::HttpServlet(stream, session)
, read_body_(false)
, req_(NULL)
, res_(NULL)
, content_length_(0)
, read_length_(0)
, mime_(NULL)
{
}
http_servlet::~http_servlet(void)
{
}
bool http_servlet::doError(acl::HttpServletRequest&,
acl::HttpServletResponse& res)
{
res.setStatus(400);
res.setContentType("text/html; charset=");
// 发送 http 响应头
if (res.sendHeader() == false)
return false;
// 发送 http 响应体
acl::string buf;
buf.format("<root error='some error happened!' />\r\n");
(void) res.getOutputStream().write(buf);
return false;
}
bool http_servlet::doOther(acl::HttpServletRequest&,
acl::HttpServletResponse& res, const char* method)
{
res.setStatus(400);
res.setContentType("text/html; charset=");
// 发送 http 响应头
if (res.sendHeader() == false)
return false;
// 发送 http 响应体
acl::string buf;
buf.format("<root error='unkown request method %s' />\r\n", method);
(void) res.getOutputStream().write(buf);
return false;
}
bool http_servlet::run(void)
{
if (read_body_ == false)
return doRun();
else if (req_ == NULL)
{
logger_error("req_ null");
return false;
}
else if (res_ == NULL)
{
logger_error("res_ null");
return false;
}
else
return doBody(*req_, *res_);
}
bool http_servlet::doGet(acl::HttpServletRequest& req,
acl::HttpServletResponse& res)
{
return doPost(req, res);
}
bool http_servlet::doPost(acl::HttpServletRequest& req,
acl::HttpServletResponse& res)
{
res.setContentType("text/xml; charset=gbk") // 设置响应字符集
.setKeepAlive(req.isKeepAlive()) // 设置是否保持长连接
.setContentEncoding(true) // 自动支持压缩传输
.setChunkedTransferEncoding(true); // 采用 chunk 传输方式
// 获得 HTTP 请求的数据类型,正常的参数类型,即 name&value 方式
// 还是 MIME 数据类型,还是数据流类型
acl::http_request_t request_type = req.getRequestType();
if (request_type != acl::HTTP_REQUEST_MULTIPART_FORM)
{
acl::string buf;
buf.format("<root error='should acl::HTTP_REQUEST_MULTIPART_FORM' />\r\n");
(void) res.write(buf);
(void) res.write(NULL, 0);
return false;
}
// 先获得 Content-Type 对应的 http_ctype 对象
mime_ = req.getHttpMime();
if (mime_ == NULL)
{
logger_error("http_mime null");
(void) doReply(req, res, "http_mime null");
return false;
}
// 获得数据体的长度
content_length_ = req.getContentLength();
if (content_length_ <= 0)
{
logger_error("body empty");
(void) doReply(req, res, "body empty");
return false;
}
acl::string filepath;
#if defined(_WIN32) || defined(_WIN64)
filepath.format("%s\\mime_file", var_cfg_var_path);
#else
filepath.format("%s/mime_file", var_cfg_var_path);
#endif
if (fp_.open_write(filepath) == false)
{
logger_error("open %s error %s",
filepath.c_str(), acl::last_serror());
(void) doReply(req, res, "open file error");
return false;
}
// 设置原始文件存入路径
mime_->set_saved_path(filepath);
req_ = &req;
res_ = &res;
read_body_ = true;
// 直接返回,从而触发异步读 HTTP 数据体过程
return true;
}
void http_servlet::reset(void)
{
read_body_ = false;
req_ = NULL;
res_ = NULL;
content_length_ = 0;
read_length_ = 0;
mime_ = NULL;
fp_.close();
}
bool http_servlet::doBody(acl::HttpServletRequest& req,
acl::HttpServletResponse& res)
{
// 当未读完数据体时,需要异步读 HTTP 请求数据体
if (content_length_ > read_length_)
{
if (doUpload(req, res) == false)
return false;
}
if (content_length_ > read_length_)
return true;
// 当已经读完 HTTP 请求数据体时,则开始分析上传的数据
bool ret = doParse(req, res);
// 处理完毕,需重置 HTTP 会话状态,以便于处理下一个 HTTP 请求
reset();
return ret;
}
bool http_servlet::doUpload(acl::HttpServletRequest& req,
acl::HttpServletResponse& res)
{
// 获得输入流
acl::istream& in = req.getInputStream();
acl::string buf;
bool finish = false;
//logger(">>>>>>>>>>read: %lld, total: %lld<<<<<",
// read_length_, content_length_);
// 读取 HTTP 客户端请求数据
while (content_length_ > read_length_)
{
if (in.read_peek(buf, true) == false)
break;
//if (buf.empty())
// break;
// printf(">>>size: %ld, space: %ld\r\n",
// (long) buf.size(), (long) buf.capacity());
if (fp_.write(buf) == -1)
{
logger_error("write error %s", acl::last_serror());
(void) doReply(req, res, "write error");
return false;
}
read_length_ += buf.size();
// 将读得到的数据输入至解析器进行解析
if (!finish && mime_->update(buf, buf.size()) == true)
finish = true;
}
if (in.eof())
{
logger_error("read error");
return false;
}
return true;
}
bool http_servlet::doParse(acl::HttpServletRequest& req,
acl::HttpServletResponse& res)
{
const char* ptr = req.getParameter("name1");
if (ptr)
param1_ = ptr;
ptr = req.getParameter("name2");
if (ptr)
param2_ = ptr;
ptr = req.getParameter("name3");
if (ptr)
param3_ = ptr;
acl::string path;
// 遍历所有的 MIME 结点,找出其中为文件结点的部分进行转储
const std::list<acl::http_mime_node*>& nodes = mime_->get_nodes();
std::list<acl::http_mime_node*>::const_iterator cit = nodes.begin();
for (; cit != nodes.end(); ++cit)
{
const char* name = (*cit)->get_name();
if (name == NULL)
continue;
acl::http_mime_t mime_type = (*cit)->get_mime_type();
if (mime_type == acl::HTTP_MIME_FILE)
{
const char* filename = (*cit)->get_filename();
if (filename == NULL)
{
logger("filename null");
continue;
}
// 有的浏览器如IE上传文件时会带着文件路径所以
// 需要先将路径去掉
filename = acl_safe_basename(filename);
#if defined(_WIN32) || defined(_WIN64)
path.format("%s\\%s", var_cfg_var_path, filename);
#else
path.format("%s/%s", var_cfg_var_path, filename);
#endif
(void) (*cit)->save(path.c_str());
if (strcmp(name, "file1") == 0)
{
file1_ = filename;
fsize1_ = get_fsize(var_cfg_var_path, filename);
}
else if (strcmp(name, "file2") == 0)
{
file2_ = filename;
fsize2_ = get_fsize(var_cfg_var_path, filename);
}
else if (strcmp(name, "file3") == 0)
{
file3_ = filename;
fsize3_ = get_fsize(var_cfg_var_path, filename);
}
}
}
// 查找上载的某个文件并转储
const acl::http_mime_node* node = mime_->get_node("file1");
if (node && node->get_mime_type() == acl::HTTP_MIME_FILE)
{
ptr = node->get_filename();
if (ptr)
{
// 有的浏览器如IE上传文件时会带着文件路径所以
// 需要先将路径去掉
ptr = acl_safe_basename(ptr);
#if defined(_WIN32) || defined(_WIN64)
path.format("%s\\1_%s", var_cfg_var_path, ptr);
#else
path.format("%s/1_%s", var_cfg_var_path, ptr);
#endif
(void) node->save(path.c_str());
}
}
return doReply(req, res, "OK");
}
bool http_servlet::doReply(acl::HttpServletRequest& req,
acl::HttpServletResponse& res, const char* info)
{
// 创建 xml 格式的数据体
acl::xml1 body;
body.get_root().add_child("root", true)
.add_child("content_type", true)
.add_attr("type", (int) req.getRequestType())
.get_parent()
.add_child("info", true)
.set_text(info)
.get_parent()
.add_child("params", true)
.add_child("param", true)
.add_attr("name1", param1_)
.get_parent()
.add_child("param", true)
.add_attr("name2", param2_)
.get_parent()
.add_child("param", true)
.add_attr("name3", param3_)
.get_parent()
.add_child("files", true)
.add_child("file", true)
.add_attr("filename", file1_)
.add_attr("fsize", fsize1_)
.get_parent()
.add_child("file", true)
.add_attr("filename", file2_)
.add_attr("fsize", fsize2_)
.get_parent()
.add_child("file", true)
.add_attr("filename", file3_)
.add_attr("fsize", fsize3_);
acl::string buf;
body.build_xml(buf);
logger(">>%s<<", buf.c_str());
return res.write(buf) && res.write(NULL, 0);
}
long long http_servlet::get_fsize(const char* dir, const char* filename)
{
acl::string path;
#if defined(_WIN32) || defined(_WIN64)
path.format("%s\\%s", dir, filename);
#else
path.format("%s/%s", dir, filename);
#endif
acl::ifstream in;
if (in.open_read(path) == false)
{
logger_error("open %s error %s", path.c_str(), acl::last_serror());
return -1;
}
return in.fsize();
}

View File

@ -0,0 +1,49 @@
#pragma once
class http_servlet : public acl::HttpServlet
{
public:
http_servlet(acl::socket_stream* stream, acl::session* session);
~http_servlet();
bool run(void);
protected:
virtual bool doError(acl::HttpServletRequest&,
acl::HttpServletResponse& res);
virtual bool doOther(acl::HttpServletRequest&,
acl::HttpServletResponse& res, const char* method);
virtual bool doGet(acl::HttpServletRequest& req,
acl::HttpServletResponse& res);
virtual bool doPost(acl::HttpServletRequest& req,
acl::HttpServletResponse& res);
private:
bool doBody(acl::HttpServletRequest&, acl::HttpServletResponse&);
bool doUpload(acl::HttpServletRequest&, acl::HttpServletResponse&);
bool doParse(acl::HttpServletRequest&, acl::HttpServletResponse&);
bool doReply(acl::HttpServletRequest&, acl::HttpServletResponse&,
const char* info);
void reset(void);
long long get_fsize(const char* dir, const char* filename);
private:
bool read_body_;
acl::HttpServletRequest* req_;
acl::HttpServletResponse* res_;
acl::ofstream fp_;
long long content_length_;
long long read_length_;
acl::http_mime* mime_;
acl::string param1_;
acl::string param2_;
acl::string param3_;
acl::string file1_;
acl::string file2_;
acl::string file3_;
long long fsize1_;
long long fsize2_;
long long fsize3_;
};

View File

@ -0,0 +1,136 @@
service httpd_upload {
# 进程是否禁止运行
master_disable = no
# 服务地址及端口号
# for master_type = inet
# master_service = 127.0.0.1:5001
# for master_type = unix
# master_service = echo.sock
# for master_type = sock
master_service = 127.0.0.1:5001, 5002, :5003, echo.sock, echo2.sock
# 服务监听为域套接口
# master_service = aio_echo.sock
# 服务类型
# master_type = inet
# master_type = unix
master_type = sock
# 当子进程异常退出时如果该值非空则将子进程异常退出的消息通知该服务
# master_notify_addr = 127.0.0.1:5801
# 邮件通知接收者
# master_notify_recipients = zhengshuxin@hotmail.com
# 是否允许延迟接受客户端连接如果为0则表示关闭该功能如果大于0则表示打开此功能
# 并且此值代表延迟接受连接的超时值超过此值时如果客户端依然没有发来数据则操作
# 系统会在系统层直接关闭该连接
# master_defer_accept = 0
# 是否只允许私有访问, 如果为 y, 则域套接口创建在 {install_path}/var/log/private/ 目录下,
# 如果为 n, 则域套接口创建在 {install_path}/var/log/public/ 目录下,
master_private = n
master_unpriv = n
# 是否需要 chroot: n -- no, y -- yes
master_chroot = n
# 每隔多长时间触发一次单位为秒(仅对 trigger 模式有效)
master_wakeup = -
# 最大进程数
master_maxproc = 1
# 预启动进程数该值不得大于 master_maxproc
# master_prefork = 0
# 进程程序名
master_command = httpd_upload
# 进程日志记录文件
master_log = {install_path}/var/log/httpd_upload
# 调试日志方式格式tag:level; tag:level; tab:level, all:1; 101:2
# master_debug =
# 进程启动参数只能为: -u [是否允许以某普通用户的身份运行]
# master_args =
# 传递给服务子进程的环境变量, 可以通过 getenv("SERVICE_ENV") 获得此值
# master_env = mempool_limit:512000000
# master_env = logme:FALSE, priority:E_LOG_INFO, action:E_LOG_PER_DAY, flush:sync_flush, imit_size:512,\
# sync_action:E_LOG_SEM, sem_name:/tmp/ioctl_echo.sem
# 当启动多个子进程实例时该开关控制多个子进程在接收连接时是否向 acl_master 发送消息报告自己的状态
# master_status_notify = 1
# 是否允许产生 core 文件
# ioctl_enable_core = 1
# 每个进程实例处理连接数的最大次数超过此值后进程实例主动退出
ioctl_use_limit = 100
# 每个进程实例的空闲超时时间超过此值后进程实例主动退出
ioctl_idle_limit = 120
# 记录进程PID的位置(对于多进程实例来说没有意义)
ioctl_pid_dir = {install_path}/var/pid
# 进程运行时所在的路径
ioctl_queue_dir = {install_path}/var
# 读写超时时间, 单位为秒
ioctl_rw_timeout = 120
# 读缓冲区的缓冲区大小
ioctl_buf_size = 8192
# 每次 accept 时的循环接收的最大次数
ioctl_max_accept = 25
# 在并发访问量非常低的情况下如访问量在 10 / 以下时可以找开此值(即赋为1)
# 以加速事件循环过程, 从而防止服务进程阻塞在 select 上的时间过长而影响访问速度
# ioctl_enable_dog = 1
# 进程运行时的用户身份
ioctl_owner = root
# select 进行循环时的时间间隔
# 单位为秒
ioctl_delay_sec = 1
# 单位为微秒
ioctl_delay_usec = 500
# 采用事件循环的方式: select(default), poll, kernel(epoll/devpoll/kqueue)
ioctl_event_mode = kernel
# 事件引擎检查所有空闲描述符的时间间隔(毫秒)
# ioctl_check_inter = 100
# 当启用 master_dispatch 连接分开服务后该配置指定 master_dispatch 所监听的
# 域套接口的全路径这样本子进程就可以从 master_dispatch 获得客户端连接
# ioctl_dispatch_addr = {install_path}/var/private/dispatch.sock
# ioctl_dispatch_addr 开启后下面参数控制本服务进程发给前端 master_dispatch 的服务标识信息
# ioctl_dispatch_type = default
# 线程池的最大线程数
ioctl_max_threads = 250
# 线程池中工作线程等待任务时间间隔(毫秒)
# ioctl_schedule_wait = 50
# 线程任务调度的时间间隔大于此值(毫秒)后记警告日志
# ioctl_schedule_warn = 100
# 线程处理任务拥堵数超过此阀值后记警告日志设为 0 则内部只有当拥堵任务数超过总线程数的 10 倍时才报警
# ioctl_qlen_warn = 0
# 线程的堆栈空间大小单位为字节0表示使用系统缺省值
ioctl_stacksize = 0
# 允许访问 udserver 的客户端IP地址范围
# ioctl_access_allow = 127.0.0.1:255.255.255.255, 127.0.0.1:127.0.0.1
ioctl_access_allow = all
# acl_master 退出时如果该值置1则该程序不等所有连接处理完毕便立即退出
ioctl_quick_abort = 1
############################################################################
# 应用自己的配置选项
# mysql 服务地址
# mysql_dbaddr = /tmp/mysql.sock
# mysql_dbaddr = 10.0.250.199:3306
# 连接 mysql 数据库的连接池的最大值
# mysql_dbmax = 200
# ping mysql 连接的间隔时间, 以秒为单位
# mysql_dbping = 10
# mysql 连接空闲的时间间隔, 以秒为单位
# mysql_dbtimeout = 30
# 数据库名称
# mysql_dbname = ioctl_db
# 数据库访问用户
# mysql_dbuser = ioctl_user
# 数据库用户访问密码
# mysql_dbpass = 111111
# 是否输出当前内存的状态信息
# debug_mem = 1
# 是否在一个线程中连接读
# loop_read = 1
}

View File

@ -0,0 +1,27 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "httpd_upload", "httpd_upload.vcproj", "{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
DebugDll = DebugDll
Release = Release
ReleaseDll = ReleaseDll
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Debug.ActiveCfg = Debug|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Debug.Build.0 = Debug|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.DebugDll.ActiveCfg = DebugDll|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.DebugDll.Build.0 = DebugDll|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Release.ActiveCfg = Release|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Release.Build.0 = Release|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.ReleaseDll.ActiveCfg = ReleaseDll|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.ReleaseDll.Build.0 = ReleaseDll|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,289 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="httpd_upload"
ProjectGUID="{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;VC2003"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="lib_acl_cpp_vc2003d.lib lib_acl_vc2003d.lib lib_protocol_vc2003d.lib"
OutputFile="$(OutDir)/httpd_upload.exe"
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\..\dist\lib\win32"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/httpd_upload.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;VC2003"
RuntimeLibrary="0"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="lib_acl_cpp_vc2003.lib lib_acl_vc2003.lib lib_protocol_vc2003.lib"
OutputFile="$(OutDir)/httpd_upload.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\dist\lib\win32"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="ReleaseDll|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;VC2003;ACL_CPP_DLL"
RuntimeLibrary="2"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="lib_acl_cpp.lib lib_acl.lib lib_protocol.lib"
OutputFile="$(OutDir)/httpd_upload.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\dist\lib\win32"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"
CommandLine="copy ..\..\..\dist\lib\win32\lib_acl.dll $(OutDir)\ /Y
copy ..\..\..\dist\lib\win32\lib_acl_cpp.dll $(OutDir)\ /Y
copy ..\..\..\dist\lib\win32\lib_protocol.dll $(OutDir)\ /Y"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="DebugDll|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;VC2003;ACL_CPP_DLL"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="lib_acl_cpp_d.lib lib_acl_d.lib lib_protocol_d.lib"
OutputFile="$(OutDir)/httpd_upload.exe"
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\..\dist\lib\win32"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/httpd_upload.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"
CommandLine="copy ..\..\..\dist\lib\win32\lib_acl_d.dll $(OutDir)\ /Y
copy ..\..\..\dist\lib\win32\lib_acl_cpp.dll $(OutDir)\ /Y
copy ..\..\..\dist\lib\win32\lib_protocol_d.dll $(OutDir)\ /Y"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Ô´Îļþ"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\http_servlet.cpp">
</File>
<File
RelativePath=".\main.cpp">
</File>
<File
RelativePath=".\master_service.cpp">
</File>
<File
RelativePath=".\stdafx.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
<FileConfiguration
Name="ReleaseDll|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
<FileConfiguration
Name="DebugDll|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Í·Îļþ"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\http_servlet.h">
</File>
<File
RelativePath=".\master_service.h">
</File>
<File
RelativePath=".\stdafx.h">
</File>
</Filter>
<Filter
Name="×ÊÔ´Îļþ"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
<File
RelativePath=".\ReadMe.txt">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "httpd_upload", "httpd_upload_vc2008.vcproj", "{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
DebugDll|Win32 = DebugDll|Win32
Release|Win32 = Release|Win32
ReleaseDll|Win32 = ReleaseDll|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Debug|Win32.ActiveCfg = Debug|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Debug|Win32.Build.0 = Debug|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.DebugDll|Win32.ActiveCfg = DebugDll|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.DebugDll|Win32.Build.0 = DebugDll|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Release|Win32.ActiveCfg = Release|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Release|Win32.Build.0 = Release|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.ReleaseDll|Win32.ActiveCfg = ReleaseDll|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.ReleaseDll|Win32.Build.0 = ReleaseDll|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,425 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="httpd_upload"
ProjectGUID="{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="lib_acl_cpp_vc2008d.lib lib_acl_vc2008d.lib lib_protocol_vc2008d.lib"
OutputFile="$(OutDir)/httpd_upload.exe"
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\..\dist\lib\win32"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/httpd_upload.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="0"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="lib_acl_cpp_vc2008.lib lib_acl_vc2008.lib lib_protocol_vc2008.lib"
OutputFile="$(OutDir)/httpd_upload.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\dist\lib\win32"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="ReleaseDll|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
CommandLine="copy ..\..\..\dist\lib\win32\lib_acl.dll $(OutDir)\ /Y&#x0D;&#x0A;copy ..\..\..\dist\lib\win32\lib_acl_cpp.dll $(OutDir)\ /Y&#x0D;&#x0A;copy ..\..\..\dist\lib\win32\lib_protocol.dll $(OutDir)\ /Y&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;ACL_CPP_DLL"
RuntimeLibrary="2"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="lib_acl_cpp.lib lib_acl.lib lib_protocol.lib"
OutputFile="$(OutDir)/httpd_upload.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\dist\lib\win32"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="DebugDll|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
CommandLine="copy ..\..\..\dist\lib\win32\lib_acl_d.dll $(OutDir)\ /Y&#x0D;&#x0A;copy ..\..\..\dist\lib\win32\lib_acl_cpp.dll $(OutDir)\ /Y&#x0D;&#x0A;copy ..\..\..\dist\lib\win32\lib_protocol_d.dll $(OutDir)\ /Y&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;ACL_CPP_DLL"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="lib_acl_cpp_d.lib lib_acl_d.lib lib_protocol_d.lib"
OutputFile="$(OutDir)/httpd_upload.exe"
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\..\dist\lib\win32"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/httpd_upload.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Ô´Îļþ"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\http_servlet.cpp"
>
</File>
<File
RelativePath=".\main.cpp"
>
</File>
<File
RelativePath=".\master_service.cpp"
>
</File>
<File
RelativePath=".\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="ReleaseDll|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="DebugDll|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Í·Îļþ"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\http_servlet.h"
>
</File>
<File
RelativePath=".\master_service.h"
>
</File>
<File
RelativePath=".\stdafx.h"
>
</File>
</Filter>
<Filter
Name="×ÊÔ´Îļþ"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<File
RelativePath=".\ReadMe.txt"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "httpd_upload", "httpd_upload_vc2010.vcxproj", "{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
DebugDll|Win32 = DebugDll|Win32
Release|Win32 = Release|Win32
ReleaseDll|Win32 = ReleaseDll|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Debug|Win32.ActiveCfg = Debug|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Debug|Win32.Build.0 = Debug|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.DebugDll|Win32.ActiveCfg = DebugDll|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.DebugDll|Win32.Build.0 = DebugDll|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Release|Win32.ActiveCfg = Release|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Release|Win32.Build.0 = Release|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.ReleaseDll|Win32.ActiveCfg = ReleaseDll|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.ReleaseDll|Win32.Build.0 = ReleaseDll|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,202 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="DebugDll|Win32">
<Configuration>DebugDll</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="ReleaseDll|Win32">
<Configuration>ReleaseDll</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<ProjectName>httpd_upload</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'">$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'">$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'">true</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>lib_acl_cpp_vc2010d.lib;lib_acl_vc2010d.lib;lib_protocol_vc2010d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)httpd_upload.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\..\dist\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)httpd_upload.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>lib_acl_cpp_vc2010.lib;lib_acl_vc2010.lib;lib_protocol_vc2010.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)httpd_upload.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\..\dist\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;ACL_CPP_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>lib_acl_cpp.lib;lib_acl.lib;lib_protocol.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)httpd_upload.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\..\dist\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PreBuildEvent>
<Command>copy ..\..\..\dist\lib\win32\lib_acl.dll $(OutDir) /Y
copy ..\..\..\dist\lib\win32\lib_acl_cpp.dll $(OutDir) /Y
copy ..\..\..\dist\lib\win32\lib_protocol.dll $(OutDir) /Y</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;ACL_CPP_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>lib_acl_cpp_d.lib;lib_acl_d.lib;lib_protocol_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)httpd_upload.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\..\dist\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)httpd_upload.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PreBuildEvent>
<Command>copy ..\..\..\dist\lib\win32\lib_acl_d.dll $(OutDir) /Y
copy ..\..\..\dist\lib\win32\lib_acl_cpp.dll $(OutDir) /Y
copy ..\..\..\dist\lib\win32\lib_protocol_d.dll $(OutDir) /Y</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="http_servlet.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="master_service.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="http_servlet.h" />
<ClInclude Include="master_service.h" />
<ClInclude Include="stdafx.h" />
</ItemGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="源文件">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="头文件">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="资源文件">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="http_servlet.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="master_service.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="http_servlet.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="master_service.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="stdafx.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,37 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "httpd_upload", "httpd_upload_vc2012.vcxproj", "{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
DebugDll|Win32 = DebugDll|Win32
DebugDll|x64 = DebugDll|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
ReleaseDll|Win32 = ReleaseDll|Win32
ReleaseDll|x64 = ReleaseDll|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Debug|Win32.ActiveCfg = Debug|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Debug|Win32.Build.0 = Debug|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Debug|x64.ActiveCfg = Debug|x64
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Debug|x64.Build.0 = Debug|x64
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.DebugDll|Win32.ActiveCfg = DebugDll|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.DebugDll|Win32.Build.0 = DebugDll|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.DebugDll|x64.ActiveCfg = DebugDll|x64
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.DebugDll|x64.Build.0 = DebugDll|x64
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Release|Win32.ActiveCfg = Release|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Release|Win32.Build.0 = Release|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Release|x64.ActiveCfg = Release|x64
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.Release|x64.Build.0 = Release|x64
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.ReleaseDll|Win32.ActiveCfg = ReleaseDll|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.ReleaseDll|Win32.Build.0 = ReleaseDll|Win32
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.ReleaseDll|x64.ActiveCfg = ReleaseDll|x64
{58FE3581-C997-4BD5-9AC6-AEEB54A43D2C}.ReleaseDll|x64.Build.0 = ReleaseDll|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,365 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="DebugDll|Win32">
<Configuration>DebugDll</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="DebugDll|x64">
<Configuration>DebugDll</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="ReleaseDll|Win32">
<Configuration>ReleaseDll</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="ReleaseDll|x64">
<Configuration>ReleaseDll</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4A800922-CFB0-49B7-8A7B-A3C457BB2C7F}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<ProjectName>httpd_upload</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDll|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDll|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>.\</OutDir>
<IntDir>Debug\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>.\</OutDir>
<IntDir>Debug\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>Release\</OutDir>
<IntDir>Release\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>.\</OutDir>
<IntDir>Release\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'">
<OutDir>.\</OutDir>
<IntDir>ReleaseDll\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>.\</OutDir>
<IntDir>ReleaseDll\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'">
<OutDir>.\</OutDir>
<IntDir>DebugDll\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDll|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>.\</OutDir>
<IntDir>DebugDll\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>lib_acl_cpp_vc2012d.lib;lib_acl_vc2012d.lib;lib_protocol_vc2012d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)httpd_upload.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\..\dist\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)httpd_upload.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>lib_acl_cpp_vc2012d.lib;lib_acl_vc2012d.lib;lib_protocol_vc2012d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)httpd_upload.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\..\dist\lib\win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)httpd_upload.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<StackReserveSize>20240000</StackReserveSize>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>lib_acl_cpp_vc2012.lib;lib_acl_vc2012.lib;lib_protocol_vc2012.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)httpd_upload.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\..\dist\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<AdditionalIncludeDirectories>..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>lib_acl_cpp_vc2012.lib;lib_protocol_vc2012.lib;lib_acl_vc2012.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)httpd_upload.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\..\dist\lib\win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;ACL_CPP_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>lib_acl_cpp.lib;lib_acl.lib;lib_protocol.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)httpd_upload.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\..\dist\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PreBuildEvent>
<Command>copy ..\..\..\dist\lib\win32\lib_acl.dll $(OutDir) /Y
copy ..\..\..\dist\lib\win32\lib_acl_cpp.dll $(OutDir) /Y
copy ..\..\..\dist\lib\win32\lib_protocol.dll $(OutDir) /Y</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|x64'">
<ClCompile>
<AdditionalIncludeDirectories>..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;NDEBUG;_CONSOLE;ACL_CPP_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>lib_acl_cpp.lib;lib_acl.lib;lib_protocol.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)httpd_upload.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\..\dist\lib\win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
<PreBuildEvent>
<Command>copy ..\..\..\dist\lib\win64\lib_acl.dll $(OutDir) /Y
copy ..\..\..\dist\lib\win64\lib_acl_cpp.dll $(OutDir) /Y
copy ..\..\..\dist\lib\win64\lib_protocol.dll $(OutDir) /Y</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;ACL_CPP_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>lib_acl_cpp_d.lib;lib_acl_d.lib;lib_protocol_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)httpd_upload.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\..\dist\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)httpd_upload.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PreBuildEvent>
<Command>copy ..\..\..\dist\lib\win32\lib_acl_d.dll $(OutDir) /Y
copy ..\..\..\dist\lib\win32\lib_acl_cpp.dll $(OutDir) /Y
copy ..\..\..\dist\lib\win32\lib_protocol_d.dll $(OutDir) /Y</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDll|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\lib_acl_cpp\include;..\..\..\lib_acl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;_DEBUG;_CONSOLE;ACL_CPP_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>lib_acl_cpp_d.lib;lib_acl_d.lib;lib_protocol_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)httpd_upload.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\..\dist\lib\win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)httpd_upload.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
</Link>
<PreBuildEvent>
<Command>copy ..\..\..\dist\lib\win64\lib_acl_d.dll $(OutDir) /Y
copy ..\..\..\dist\lib\win64\lib_acl_cpp.dll $(OutDir) /Y
copy ..\..\..\dist\lib\win64\lib_protocol_d.dll $(OutDir) /Y</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="http_servlet.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="master_service.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='DebugDll|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='DebugDll|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='ReleaseDll|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="http_servlet.h" />
<ClInclude Include="master_service.h" />
<ClInclude Include="stdafx.h" />
</ItemGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="源文件">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="头文件">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="资源文件">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="http_servlet.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="master_service.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="http_servlet.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="master_service.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="stdafx.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,77 @@
#include "stdafx.h"
#include "master_service.h"
int main(int argc, char* argv[])
{
// 初始化 acl 库
acl::acl_cpp_init();
master_service& ms = acl::singleton2<master_service>::get_instance();
// 设置配置参数表
ms.set_cfg_int(var_conf_int_tab);
ms.set_cfg_int64(var_conf_int64_tab);
ms.set_cfg_str(var_conf_str_tab);
ms.set_cfg_bool(var_conf_bool_tab);
// 开始运行
if (argc >= 2 && strcmp(argv[1], "alone") == 0)
{
// 日志输出至标准输出
acl::log::stdout_open(true);
// 监听的地址列表格式ip:port1,ip:port2,...
const char* addrs = ":8888";
printf("listen on: %s\r\n", addrs);
// 测试时设置该值 > 0 则指定服务器处理客户端连接过程的
// 会话总数(一个连接从接收到关闭称之为一个会话),当
// 处理的连接会话数超过此值,测试过程结束;如果该值设
// 为 0则测试过程永远不结束
unsigned int count = 5;
// 测试过程中指定线程池最大线程个数
unsigned int max_threads = 100;
// 单独运行方式
if (argc >= 3)
ms.run_alone(addrs, argv[2], count, max_threads);
else
ms.run_alone(addrs, NULL, count, max_threads);
printf("Enter any key to exit now\r\n");
getchar();
}
else
{
#ifdef WIN32
// 日志输出至标准输出
acl::log::stdout_open(true);
// 监听的地址列表格式ip:port1,ip:port2,...
const char* addrs = "127.0.0.1:8888";
printf("listen on: %s\r\n", addrs);
// 测试时设置该值 > 0 则指定服务器处理客户端连接过程的
// 会话总数(一个连接从接收到关闭称之为一个会话),当
// 处理的连接会话数超过此值,测试过程结束;如果该值设
// 为 0则测试过程永远不结束
unsigned int count = 0;
// 测试过程中指定线程池最大线程个数
unsigned int max_threads = 100;
// 单独运行方式
ms.run_alone(addrs, NULL, count, max_threads);
printf("Enter any key to exit now\r\n");
getchar();
#else
// acl_master 控制模式运行
ms.run_daemon(argc, argv);
#endif
}
return 0;
}

View File

@ -0,0 +1,129 @@
#include "stdafx.h"
#include "http_servlet.h"
#include "master_service.h"
//////////////////////////////////////////////////////////////////////////////
// ÅäÖÃÄÚÈÝÏî
char *var_cfg_var_path;
char *var_cfg_redis_addrs;
acl::master_str_tbl var_conf_str_tab[] = {
{ "var_path", "var", &var_cfg_var_path },
{ "redis_addrs", "127.0.0.1:6379", &var_cfg_redis_addrs },
{ 0, 0, 0 }
};
int var_cfg_use_redis_session;
acl::master_bool_tbl var_conf_bool_tab[] = {
{ "use_redis_session", 1, &var_cfg_use_redis_session },
{ 0, 0, 0 }
};
int var_cfg_conn_timeout;
int var_cfg_rw_timeout;
int var_cfg_max_threads;
acl::master_int_tbl var_conf_int_tab[] = {
{ "rw_timeout", 120, &var_cfg_rw_timeout, 0, 0 },
{ "ioctl_max_threads", 128, &var_cfg_max_threads, 0, 0 },
{ 0, 0 , 0 , 0, 0 }
};
long long int var_cfg_int64;
acl::master_int64_tbl var_conf_int64_tab[] = {
{ "int64", 120, &var_cfg_int64, 0, 0 },
{ 0, 0 , 0 , 0, 0 }
};
//////////////////////////////////////////////////////////////////////////////
master_service::master_service()
{
redis_ = NULL;
}
master_service::~master_service()
{
}
bool master_service::thread_on_read(acl::socket_stream* conn)
{
http_servlet* servlet = (http_servlet*) conn->get_ctx();
if (servlet == NULL)
logger_fatal("servlet null!");
return servlet->run();
}
bool master_service::thread_on_accept(acl::socket_stream* conn)
{
logger("connect from %s, fd: %d", conn->get_peer(true),
conn->sock_handle());
conn->set_rw_timeout(var_cfg_rw_timeout);
acl::session* session;
if (var_cfg_use_redis_session)
session = new acl::redis_session(*redis_, var_cfg_max_threads);
else
session = new acl::memcache_session("127.0.0.1:11211");
http_servlet* servlet = new http_servlet(conn, session);
conn->set_ctx(servlet);
return true;
}
bool master_service::thread_on_timeout(acl::socket_stream* conn)
{
logger("read timeout from %s, fd: %d", conn->get_peer(),
conn->sock_handle());
return false;
}
void master_service::thread_on_close(acl::socket_stream* conn)
{
logger("disconnect from %s, fd: %d", conn->get_peer(),
conn->sock_handle());
http_servlet* servlet = (http_servlet*) conn->get_ctx();
acl::session* session = &servlet->getSession();
delete session;
delete servlet;
}
void master_service::thread_on_init()
{
}
void master_service::thread_on_exit()
{
}
void master_service::proc_on_init()
{
// create redis cluster for session cluster
redis_ = new acl::redis_client_cluster;
redis_->init(NULL, var_cfg_redis_addrs, var_cfg_max_threads,
var_cfg_conn_timeout, var_cfg_rw_timeout);
acl_make_dirs(var_cfg_var_path, 0755);
}
void master_service::proc_on_exit()
{
delete redis_;
}
bool master_service::proc_exit_timer(size_t nclients, size_t nthreads)
{
if (nclients == 0)
{
logger("clients count: %d, threads count: %d",
(int) nclients, (int) nthreads);
return true;
}
return false;
}

View File

@ -0,0 +1,94 @@
#pragma once
////////////////////////////////////////////////////////////////////////////////
// 配置内容项
extern char *var_cfg_var_path;
extern acl::master_str_tbl var_conf_str_tab[];
extern acl::master_bool_tbl var_conf_bool_tab[];
extern acl::master_int_tbl var_conf_int_tab[];
extern acl::master_int64_tbl var_conf_int64_tab[];
////////////////////////////////////////////////////////////////////////////////
//class acl::socket_stream;
class master_service : public acl::master_threads
{
public:
master_service();
~master_service();
protected:
/**
*
* @param stream {socket_stream*}
* @return {bool} false
* false
*/
virtual bool thread_on_read(acl::socket_stream* stream);
/**
* 线线
*
* @param stream {socket_stream*}
* @return {bool} false
* thread_main
*/
virtual bool thread_on_accept(acl::socket_stream* stream);
/**
* IO true
*
* @param stream {socket_stream*}
* @return {bool} false
* thread_main
*/
virtual bool thread_on_timeout(acl::socket_stream* stream);
/**
* 线
* @param stream {socket_stream*}
*/
virtual void thread_on_close(acl::socket_stream* stream);
/**
* 线线
*/
virtual void thread_on_init();
/**
* 线线退
*/
virtual void thread_on_exit();
/**
*
*
*/
virtual void proc_on_init();
/**
* 退退
* 1) true 退
* 2) 退
* 3) (ioctl_quick_abort) 0
* 退
* 4) 退
* @param ncleints {size_t}
* @param nthreads {size_t} 线线
* @return {bool} false 退
* 退
*/
virtual bool proc_exit_timer(size_t nclients, size_t nthreads);
/**
* 退
*/
virtual void proc_on_exit();
private:
// redis 集群对象
acl::redis_client_cluster* redis_;
};

View File

@ -0,0 +1,8 @@
// stdafx.cpp : 只包括标准包含文件的源文件
// master_threads.pch 将成为预编译头
// stdafx.obj 将包含预编译类型信息
#include "stdafx.h"
// TODO: 在 STDAFX.H 中
//引用任何所需的附加头文件,而不是在此文件中引用

View File

@ -0,0 +1,19 @@
// stdafx.h : 标准系统包含文件的包含文件,
// 或是常用但不常更改的项目特定的包含文件
//
#pragma once
//#include <iostream>
//#include <tchar.h>
// TODO: 在此处引用程序要求的附加头文件
#include "acl_cpp/lib_acl.hpp"
#include "lib_acl.h"
#ifdef WIN32
#define snprintf _snprintf
#endif

View File

@ -0,0 +1,18 @@
<html>
<head>
<meta content="text/html; charset=gb2312" http-equiv="Content-Type">
</head>
<body>
<form enctype="multipart/form-data" method=POST action="http://192.168.65.152:8888/cgi-bin/test/upload?name1=中国人">
<!--
<form enctype="multipart/form-data" method=POST action="/cgi-bin/test/upload?name1=中国人">
-->
<input type=hidden name="name2" value="美国人"><br>
<input type=hidden name="name3" value="英国人"><br>
文件一:<input type=file name="file1" value=""><br>
文件二:<input type=file name="file2" value=""><br>
文件三:<input type=file name="file3" value=""><br>
<br><input type=submit name="submit", value="提交"><br>
</form>
</body>
</html>

View File

@ -0,0 +1,3 @@
#!/bin/sh
valgrind --tool=memcheck --leak-check=yes -v ./httpd_upload alone httpd_upload.cf

View File

@ -1,6 +1,16 @@
修改历史列表:
------------------------------------------------------------------------
528) 2016.2.1
528.1) feature: acl_vstring.c, 优化代码结构
527) 2016.1.30
527.1) feature: acl_vstring.c 增加了 acl_vstring_mmap_alloc用于支持以内存
文件映射方式管理内存
527.2) feature&safety: acl_vstring.c 真正支持限定最大使用空间功能
527.3) samples/mmap_string: 该示例用于测试以内存文件映射方式使用 acl_vstring
的功能
526) 2016.1.17
526.1) feature: acl_default_malloc.c函数 acl_default_realloc 当输入的地址为
NULL则自动切换至 acl_default_malloc 过程

View File

@ -39,6 +39,8 @@
#ifdef ACL_UNIX
# include <assert.h>
# include <sys/types.h>
# ifndef acl_assert
# define acl_assert assert
# endif

View File

@ -10,13 +10,13 @@ extern "C" {
typedef struct ACL_VBUF ACL_VBUF;
typedef int (*ACL_VBUF_GET_READY_FN) (ACL_VBUF *);
typedef int (*ACL_VBUF_PUT_READY_FN) (ACL_VBUF *);
typedef int (*ACL_VBUF_SPACE_FN) (ACL_VBUF *, int);
typedef int (*ACL_VBUF_SPACE_FN) (ACL_VBUF *, ssize_t);
struct ACL_VBUF {
int flags; /* status, see below */
unsigned flags; /* status, see below */
unsigned char *data; /* variable-length buffer */
int len; /* buffer length */
int cnt; /* bytes left to read/write */
ssize_t len; /* buffer length */
ssize_t cnt; /* bytes left to read/write */
unsigned char *ptr; /* read/write position */
ACL_VBUF_GET_READY_FN get_ready; /* read buffer empty action */
ACL_VBUF_PUT_READY_FN put_ready; /* write buffer full action */
@ -41,26 +41,29 @@ struct ACL_VBUF {
#define ACL_VBUF_FLAG_ERR (1<<0) /* some I/O error */
#define ACL_VBUF_FLAG_EOF (1<<1) /* end of data */
#define ACL_VBUF_FLAG_TIMEOUT (1<<2) /* timeout error */
#define ACL_VBUF_FLAG_BAD (ACL_VBUF_FLAG_ERR | ACL_VBUF_FLAG_EOF | ACL_VBUF_FLAG_TIMEOUT)
#define ACL_VBUF_FLAG_BAD \
(ACL_VBUF_FLAG_ERR | ACL_VBUF_FLAG_EOF | ACL_VBUF_FLAG_TIMEOUT)
#define ACL_VBUF_FLAG_FIXED (1<<3) /* fixed-size buffer */
#define acl_vbuf_error(v) ((v)->flags & ACL_VBUF_FLAG_ERR)
#define acl_vbuf_eof(v) ((v)->flags & ACL_VBUF_FLAG_EOF)
#define acl_vbuf_error(v) ((v)->flags & ACL_VBUF_FLAG_BAD)
#define acl_vbuf_eof(v) ((v)->flags & ACL_VBUF_FLAG_EOF)
#define acl_vbuf_timeout(v) ((v)->flags & ACL_VBUF_FLAG_TIMEOUT)
#define acl_vbuf_clearerr(v) ((v)->flags &= ~ACL_VBUF_FLAG_BAD)
#define acl_vbuf_clearerr(v) ((v)->flags &= ~ACL_VBUF_FLAG_BAD)
/*
* Buffer I/O-like operations and results.
*/
#define ACL_VBUF_GET(v) ((v)->cnt < 0 ? ++(v)->cnt, \
(int) *(v)->ptr++ : acl_vbuf_get(v))
#define ACL_VBUF_PUT(v,c) ((v)->cnt > 0 ? --(v)->cnt, \
(int) (*(v)->ptr++ = (c)) : acl_vbuf_put((v),(c)))
#define ACL_VBUF_GET(v) ((v)->cnt < 0 ? ++(v)->cnt, \
(int) *(v)->ptr++ : acl_vbuf_get(v))
#define ACL_VBUF_PUT(v,c) ((v)->cnt > 0 ? --(v)->cnt, \
(int) (*(v)->ptr++ = (c)) : acl_vbuf_put((v),(c)))
#define ACL_VBUF_SPACE(v,n) ((v)->space((v),(n)))
#define ACL_VBUF_CHARAT(v, offset) ((int) (v).data[offset])
#define ACL_VBUF_CHARAT(v, offset) ((int) (v).data[offset])
#define ACL_VBUF_EOF (-1) /* no more space or data */
#define ACL_VBUF_EOF (-1) /* no more space or data */
ACL_API int acl_vbuf_get(ACL_VBUF *);
ACL_API int acl_vbuf_put(ACL_VBUF *, int);
@ -73,4 +76,3 @@ ACL_API int acl_vbuf_write(ACL_VBUF *, const char *, int);
#endif
#endif

View File

@ -15,10 +15,11 @@ extern "C" {
* ACL_VBUFACL_VSTRING
*/
typedef struct ACL_VSTRING {
ACL_VBUF vbuf;
int maxlen;
ACL_VBUF vbuf;
ssize_t maxlen;
ACL_SLICE_POOL *slice;
ACL_DBUF_POOL *dbuf;
ACL_DBUF_POOL *dbuf;
ACL_FILE_HANDLE fd;
} ACL_VSTRING;
/**
@ -61,6 +62,16 @@ ACL_API ACL_VSTRING *acl_vstring_slice_alloc(ACL_SLICE_POOL *slice, size_t len);
*/
ACL_API ACL_VSTRING *acl_vstring_dbuf_alloc(ACL_DBUF_POOL *dbuf, size_t len);
/**
* ACL_VSTRING
* @param fd {ACL_FILE_HANDLE}
* @param max_len {ssize_t}
* @param init_len {ssize_t}
* @return {ACL_VSTRING*} ACL_VSTRING
*/
ACL_API ACL_VSTRING *acl_vstring_mmap_alloc(ACL_FILE_HANDLE fd,
ssize_t max_len, ssize_t init_len);
/**
* ACL_VSTRING ,
* @param vp {ACL_VSTRING*}
@ -373,8 +384,14 @@ ACL_API const ACL_VSTRING *acl_buffer_gets(ACL_VSTRING *vp,
*/
#define ACL_VSTRING_TERMINATE(vp) { \
if ((vp)->vbuf.cnt <= 0) \
ACL_VSTRING_SPACE((vp),1); \
*(vp)->vbuf.ptr = 0; \
ACL_VSTRING_SPACE((vp), 1); \
if ((vp)->vbuf.cnt > 0) \
*(vp)->vbuf.ptr = 0; \
else if ((vp)->vbuf.ptr > (vp)->vbuf.data) { \
(vp)->vbuf.ptr--; \
*(vp)->vbuf.ptr = 0; \
(vp)->vbuf.cnt++; \
} \
}
/**
@ -385,6 +402,7 @@ ACL_API const ACL_VSTRING *acl_buffer_gets(ACL_VSTRING *vp,
#define ACL_VSTRING_RESET(vp) { \
(vp)->vbuf.ptr = (vp)->vbuf.data; \
(vp)->vbuf.cnt = (vp)->vbuf.len; \
acl_vbuf_clearerr(&(vp)->vbuf); \
}
/**

View File

@ -22,8 +22,8 @@ struct ACL_XML2_ATTR {
char *name; /**< 属性名 */
char *value; /**< 属性值 */
size_t name_size; /**< 属性名长度 */
size_t value_size; /**< 属性值长度 */
ssize_t name_size; /**< 属性名长度 */
ssize_t value_size; /**< 属性值长度 */
/* private */
int quote; /**< 非 0 表示 ' 或 " */
@ -34,12 +34,12 @@ struct ACL_XML2_ATTR {
struct ACL_XML2_NODE {
char *ltag; /**< 左标签名 */
char *rtag; /**< 右标签名 */
size_t ltag_size; /**< 左标签名长度 */
size_t rtag_size; /**< 右标签名长度 */
ssize_t ltag_size; /**< 左标签名长度 */
ssize_t rtag_size; /**< 右标签名长度 */
const char *id; /**< ID标识符, 只有在 xml->id_table
id */
char *text; /**< 文本显示内容 */
size_t text_size; /**< 文件数据长度 */
ssize_t text_size; /**< 文件数据长度 */
ACL_ARRAY *attr_list; /**< 属性(ACL_XML2_ATTR)列表 */
ACL_XML2_NODE *parent; /**< 父节点 */
@ -111,17 +111,10 @@ struct ACL_XML2 {
ACL_XML2_NODE *root; /**< XML 根节点 */
/* private */
char *addr; /**< 内存起始地址 */
char *ptr; /**< 内存地址 */
size_t size; /**< addr 内存映射区的大小 */
size_t len; /**< addr 内存映射区剩余大小 */
char *mm_file; /**< 非空时指定内存映射文件名 */
char *mm_addr; /**< 内存映射起始地址 */
ACL_FILE_HANDLE fd; /**< 采用内存映射方式时的文件句柄 */
size_t off; /**< 当前内存映射文件的实际映射大小 */
size_t block; /**< len 自增时的自增块长度大小 */
int keep_open; /**< 文件句柄是否一直打开 */
ACL_FILE_HANDLE fd; /** 保存由本对象打开的文件句柄 */
ACL_VSTRING *vbuf; /**< 基于内存映射文件的缓冲区 */
ACL_VSTRING *vbuf_inner; /**< 内部创建的缓冲区对象 */
char dummy[1];
ACL_HTABLE *id_table; /**< id 标识符哈希表 */
ACL_XML2_NODE *curr_node; /**< 当前正在处理的 XML 节点 */
@ -179,73 +172,44 @@ ACL_API int acl_xml2_is_complete(ACL_XML2 *xml, const char *tag);
/**
* xml
* @param addr {char*}
* @param size {ssize_t} addr
* @param vbuf {ACL_VSTRING*}
* @return {ACL_XML2*} xml
*/
ACL_API ACL_XML2 *acl_xml2_alloc(char *addr, size_t size);
ACL_API ACL_XML2 *acl_xml2_alloc(ACL_VSTRING *vbuf);
/**
* xml xml
* @param addr {char*}
* @param size {ssize_t} addr
* @param vbuf {ACL_VSTRING*}
* @param dbuf {ACL_DBUF_POOL*} NULL xml
* xml
* @return {ACL_XML2*} xml
*/
ACL_API ACL_XML2 *acl_xml2_dbuf_alloc(char *addr, size_t size,
ACL_DBUF_POOL *dbuf);
ACL_API ACL_XML2 *acl_xml2_dbuf_alloc(ACL_VSTRING *vbuf, ACL_DBUF_POOL *dbuf);
/**
* xml xml
* @param filepath {const char*}
* @param size {size_t}
* @param block {size_t}
* size
* @param keep_open {int} xml
*
* @param max_len {size_t}
* @param init_len {size_t}
* @param dbuf {ACL_DBUF_POOL*} NULL xml
* xml
* @return {ACL_XML2*} xml
*/
ACL_API ACL_XML2 *acl_xml2_mmap_file(const char *filepath, size_t size,
size_t block, int keep_open, ACL_DBUF_POOL *dbuf);
ACL_API ACL_XML2 *acl_xml2_mmap_file(const char *filepath, size_t max_len,
size_t init_len, ACL_DBUF_POOL *dbuf);
/**
* xml xml
* @param fd {ACL_FILE_HANDLE} xml
* xml
* @param size {size_t}
* @param block {size_t}
* size
* @param fd {ACL_FILE_HANDLE} xml
* xml
* @param max_len {size_t}
* @param init_len {size_t}
* @param dbuf {ACL_DBUF_POOL*} NULL xml
* xml
* @return {ACL_XML2*} xml
*/
ACL_API ACL_XML2 *acl_xml2_mmap_fd(ACL_FILE_HANDLE fd, size_t size,
size_t block, ACL_DBUF_POOL *dbuf);
/**
*
* 使
*
* @param xml {ACL_XML2*} acl_xml2_mmap_alloc xml
* @return {size_t} 0
*
*/
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_API ACL_XML2 *acl_xml2_mmap_fd(ACL_FILE_HANDLE fd, size_t max_len,
size_t init_len, ACL_DBUF_POOL *dbuf);
/**
* ACL_XML2_NODE XML 便

View File

@ -729,6 +729,7 @@ copy $(TargetName).pdb ..\dist\lib\win64\$(TargetName).pdb /Y
<ClInclude Include=".\src\private\sem.h" />
<ClInclude Include=".\src\private\thread.h" />
<ClInclude Include=".\include\lib_acl.h" />
<ClInclude Include="include\code\acl_xmlcode.h" />
<ClInclude Include="include\stdlib\unix\acl_trace.h" />
<ClInclude Include="include\xml\acl_xml2.h" />
<ClInclude Include="include\xml\acl_xml3.h" />
@ -885,4 +886,4 @@ copy $(TargetName).pdb ..\dist\lib\win64\$(TargetName).pdb /Y
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -1533,6 +1533,9 @@
<ClInclude Include="include\xml\acl_xml3.h">
<Filter>Header Files\xml</Filter>
</ClInclude>
<ClInclude Include="include\code\acl_xmlcode.h">
<Filter>Header Files\code</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include=".\changes.txt">
@ -1545,4 +1548,4 @@
<Filter>doc</Filter>
</Text>
</ItemGroup>
</Project>
</Project>

View File

@ -0,0 +1,2 @@
include ../Makefile.in
PROG = string

View File

@ -0,0 +1,110 @@
#include "lib_acl.h"
static void incr_string(ACL_VSTRING *vp, int len, const char* s, int debug)
{
int i;
printf("max: %ld, len: %ld, cnt: %ld\r\n", (long) vp->maxlen,
vp->vbuf.len, vp->vbuf.cnt);
for (i = 0; i < len; i++)
ACL_VSTRING_ADDCH(vp, 'x');
if (s && *s)
acl_vstring_sprintf_append(vp, "%s", s);
else
ACL_VSTRING_TERMINATE(vp);
if (debug)
printf("[%s]\r\n", acl_vstring_str(vp));
printf("len: %ld, %ld, max: %ld\r\n", (long) strlen(acl_vstring_str(vp)),
(long) ACL_VSTRING_LEN(vp), (long) vp->maxlen);
printf("Enter any key to continue ...\r\n\r\n");
getchar();
ACL_VSTRING_RESET(vp);
}
static void test_string(ACL_FILE_HANDLE fd, ssize_t max, int debug)
{
ACL_VSTRING *vp = acl_vstring_mmap_alloc(fd, 1, max);
const char *s = "hello world!";
printf("-------------------------------------------------------\r\n");
incr_string(vp, max - 1, NULL, debug);
printf("-------------------------------------------------------\r\n");
incr_string(vp, max - 1 - strlen(s), s, debug);
printf("-------------------------------------------------------\r\n");
incr_string(vp, max, NULL, debug);
printf("-------------------------------------------------------\r\n");
incr_string(vp, max + 2, NULL, debug);
printf("-------------------------------------------------------\r\n");
acl_vstring_strcat(vp, s);
incr_string(vp, max - strlen(s) - 1, NULL, debug);
printf("-------------------------------------------------------\r\n");
acl_vstring_strcat(vp, s);
incr_string(vp, max, NULL, debug);
printf("-------------------------------------------------------\r\n");
acl_vstring_strcat(vp, s);
incr_string(vp, max + 10, NULL, debug);
acl_vstring_free(vp);
}
static void usage(const char* procname)
{
printf("usage: %s -h[help] -f filename -n max_size -d [debug]\r\n", procname);
}
int main(int argc, char *argv[])
{
char filename[256];
int ch, debug = 0;
ssize_t max = 8192;
ACL_FILE_HANDLE fd;
snprintf(filename, sizeof(filename), "mmap.local");
while ((ch = getopt(argc, argv, "hf:n:d")) > 0) {
switch (ch) {
case 'h':
usage(argv[0]);
return 0;
case 'f':
snprintf(filename, sizeof(filename), "%s", optarg);
break;
case 'n':
max = atol(optarg);
break;
case 'd':
debug = 1;
break;
default:
break;
}
}
acl_msg_stdout_enable(1);
printf("filename: %s, max size: %ld\r\n", filename, (long) max);
fd = acl_file_open(filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
if (fd == ACL_FILE_INVALID) {
printf("open %s error %s\r\n", filename, acl_last_serror());
return 1;
}
test_string(fd, max, debug);
acl_file_close(fd);
return 0;
}

View File

@ -0,0 +1,3 @@
#!/bin/sh
valgrind --tool=memcheck --leak-check=yes -v ./string -n 102400

View File

@ -0,0 +1,11 @@
#!/bin/sh
./xml -s -d data1 -P
./xml -s -d data2 -P
./xml -s -d data3 -P
./xml -s -d data4 -P
./xml -s -d data5 -P
./xml -s -d data6 -P
./xml -s -d data7 -P
./xml -s -d data8 -P
./xml -s -d data9 -P

View File

@ -73,8 +73,8 @@ static const char* __data4 = "<?xml version=\"1.0\" encoding=\"gb2312\"?>\r\n"
" </tags1>\r\n"
" <tags2>\r\n"
" <tags21/>\r\n"
" <tags22/>\r\n"
" <tags23/>\r\n"
" <tags22 />\r\n"
" <tags23 />\r\n"
" <module name=\"mail_ud_user\" />\r\n"
" </tags2>\r\n"
" <tag3>\r\n"
@ -133,12 +133,16 @@ static const char* __data7 = "<?xml version=\"1.0\" encoding=\"gb2312\"?>\r\n"
static const char* __data8 = "<?xml version=\"1.0\" encoding=\"gb2312\"?>\r\n"
"<root> hello world! </root>\r\n";
static const char *__data9 =
"<?xml version=\"1.0\"?>\r\n"
"<?xml-stylesheet type=\"text/xsl\">\r\n";
static void parse_xml_benchmark(int once, int max, const char *data)
{
int i;
size_t size = strlen(data) * 4;
const char *mmap_file = "./local.map";
ACL_XML2 *xml = acl_xml2_mmap_file(mmap_file, size, 1024, 1, NULL);
ACL_XML2 *xml = acl_xml2_mmap_file(mmap_file, size, 1, NULL);
acl_xml2_slash(xml, 1);
@ -202,7 +206,7 @@ static int parse_xml_file(const char *filepath)
}
len *= 4;
xml = acl_xml2_mmap_file(mmap_file, len, 1024, 1, NULL);
xml = acl_xml2_mmap_file(mmap_file, len, 1, NULL);
ACL_METER_TIME("-------------begin--------------");
while (1) {
@ -244,8 +248,8 @@ static void walk_xml(ACL_XML2* xml)
for (i = 1; i < node->depth; i++)
printf("\t");
printf("tag->%s, size: %ld\n", node->ltag,
(long) node->ltag_size);
printf("%s(%d): tag->%s, size: %ld\n", __FUNCTION__, __LINE__,
node->ltag, (long) node->ltag_size);
/* 遍历 xml 结点的属性 */
acl_foreach(iter2, node->attr_list) {
@ -254,13 +258,14 @@ static void walk_xml(ACL_XML2* xml)
for (i = 1; i < node->depth + 1; i++)
printf("\t");
printf("attr->%s=\"%s\"\n", attr->name, attr->value);
printf("%s(%d): attr->%s=\"%s\"\n", __FUNCTION__,
__LINE__, attr->name, attr->value);
}
for (i = 1; i < node->depth + 1; i++)
printf("\t");
printf("text->%s, size: %ld\n", node->text,
(long) node->text_size);
printf("%s(%d): text->%s, size: %ld\n", __FUNCTION__,
__LINE__, node->text, (long) node->text_size);
}
printf("-------------- walk_xml end -------------------\r\n");
@ -280,9 +285,26 @@ static void xml_node_attrs(ACL_XML2_NODE* node, int n)
for (i = 0; i < n; i++)
printf("\t");
printf("attr->%s(%ld)=\"%s(%ld)\"\n",
attr->name, (long) attr->name_size,
attr->value, (long) attr->value_size);
printf("%s(%d): attr->%s(%ld, %ld)=\"%s(%ld, %ld)\"\n",
__FUNCTION__, __LINE__, attr->name,
(long) attr->name_size, (long) strlen(attr->name),
attr->value, (long) attr->value_size,
(long) strlen(attr->value));
if ((size_t) attr->name_size != strlen(attr->name)) {
printf("%s(%d): name_size invalie: %ld, %ld, %s\r\n",
__FUNCTION__, __LINE__,
(long) attr->name_size,
(long) strlen(attr->name), attr->name);
assert(0);
}
if ((size_t) attr->value_size != strlen(attr->value)) {
printf("%s(%d): value_size invalie, value: %s, "
"len: %ld, %ld\r\n", __FUNCTION__, __LINE__,
attr->value, (long) attr->value_size,
(long) strlen(attr->value));
assert(0);
}
}
}
@ -299,16 +321,33 @@ static void walk_xml_node(ACL_XML2_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("%s(%d): tag->%s, size: %ld, %ld\n", __FUNCTION__,
__LINE__, child->ltag, (long) child->ltag_size,
(long) strlen(child->ltag));
if ((size_t) child->ltag_size != strlen(child->ltag)) {
printf("%s(%d): ltag_size invalid, ltag: %s, "
"len: %ld, %ld\r\n", __FUNCTION__, __LINE__,
child->ltag, (long) child->ltag_size,
(long) strlen(child->ltag));
assert(0);
}
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("%s(%d): text->%s, size: %ld, %ld\n", __FUNCTION__,
__LINE__, child->text, (long) child->text_size,
(long) strlen(child->text));
if ((size_t) child->text_size != strlen(child->text)) {
printf("%s(%d): text_size invalid: %ld, %ld, "
"text: %s\r\n", __FUNCTION__, __LINE__,
(long) child->text_size,
(long) strlen(child->text), child->text);
assert(0);
}
walk_xml_node(child, n + 1);
}
@ -321,7 +360,8 @@ static void list_xml_tags(ACL_XML2 *xml)
printf("-------------- list xml's all tags --------------------\r\n");
acl_foreach(iter, xml) {
ACL_XML2_NODE *node = (ACL_XML2_NODE*) iter.data;
printf(">>tag: %s\n", node->ltag);
printf("%s(%d): tag: %s\n", __FUNCTION__, __LINE__,
node->ltag);
}
printf("-------------- list xml's all tags end ----------------\r\n");
@ -406,7 +446,7 @@ static ACL_XML2 *get_xml(int once, const char *data,
const char* root, int multi_root)
{
size_t size = strlen(data) * 4;
char *addr = (char*) acl_mymalloc(size);
ACL_VSTRING *vbuf = acl_vstring_alloc(size);
ACL_XML2 *xml;
const char *left;
@ -416,7 +456,7 @@ static ACL_XML2 *get_xml(int once, const char *data,
printf("Enter any key to continue ...\r\n");
getchar();
xml = acl_xml2_alloc(addr, size);
xml = acl_xml2_alloc(vbuf);
acl_xml2_multi_root(xml, multi_root);
acl_xml2_decode_enable(xml, 1);
acl_xml2_slash(xml, 1);
@ -506,11 +546,19 @@ static void parse_xml(int once, const char *data,
printf("----------------- build xml -------------------------\r\n");
ptr = acl_xml2_build(xml);
printf("%s\r\n", ptr);
printf("%s, len: %ld, %ld\r\n", ptr, (long) strlen(ptr),
(long) (acl_vstring_end(xml->vbuf) - ptr));
if (strlen(ptr) != (size_t) (acl_vstring_end(xml->vbuf) - ptr)) {
printf("%s(%d): invalid xml size: %ld, %ld\r\n", __FUNCTION__,
__LINE__, (long) strlen(ptr),
(long) (acl_vstring_end(xml->vbuf) - ptr));
assert(0);
}
printf("----------------- build xml end ---------------------\r\n");
/* 释放 xml 对象 */
acl_myfree(xml->addr);
acl_vstring_free(xml->vbuf);
left = acl_xml2_free(xml);
printf("Free all node ok, total(%d), left is: %d\n", total, left);
@ -532,10 +580,10 @@ static void test1(void)
ACL_XML2_NODE *node;
const char *encoding, *type, *href;
size_t size = strlen(data) * 3;
char *addr = acl_mymalloc(size);
ACL_VSTRING *buf = acl_vstring_alloc(size);
const char *ptr;
xml = acl_xml2_alloc(addr, size);
xml = acl_xml2_alloc(buf);
printf("------------------------------------------------------\r\n");
@ -575,17 +623,22 @@ static void test1(void)
ptr = acl_xml2_build(xml);
printf("%s\r\n", ptr);
printf("----------------- build xml end ---------------------\r\n");
acl_myfree(addr);
acl_vstring_free(buf);
acl_xml2_free(xml);
}
static void build_xml(void)
{
size_t size = 1024;
char *addr = acl_mymalloc(size);
ACL_XML2 *xml = acl_xml2_alloc(addr, size);
size_t size = 2000;
ACL_VSTRING *vbuf = acl_vstring_alloc(size);
ACL_XML2 *xml = acl_xml2_alloc(vbuf);
ACL_XML2_NODE *node1, *node2, *node3;
const char *buf;
const char* pp = "<users name=\"users list\">text1<user name=\"user11\" value=\"zsx11\">text11<age name=\"user111\" value=\"zsx111\">text111</age></user><user name=\"value2\" value=\"zsx2\">text2</user><user name=\"value3\" value=\"zsx3\">text3</user></users>";
/*
vbuf->maxlen = size;
*/
node1 = acl_xml2_create_node(xml, "users", "text1");
acl_xml2_node_add_child(xml->root, node1);
@ -609,10 +662,28 @@ static void build_xml(void)
printf("--------------------xml string-------------------\r\n");
buf = acl_xml2_build(xml);
printf("%s\n", buf);
printf("[%s]\n", buf);
if (strlen(buf) != (size_t) (acl_vstring_end(xml->vbuf) - buf)) {
printf("invalid length: %ld, %ld, %p\r\n", (long) strlen(buf),
(long) (acl_vstring_end(xml->vbuf) - buf),
acl_vstring_end(xml->vbuf));
assert(0);
}
printf("length: %ld, %ld\r\n", (long) strlen(buf),
(long) (acl_vstring_end(xml->vbuf) - buf));
if (strcmp(pp, buf) == 0)
printf(">>>>>>>>OK<<<<<<<<<<<\r\n");
else {
printf(">>>>>>>>Error<<<<<<<<\r\n");
assert(0);
}
printf("--------------------xml string end---------------\r\n");
acl_myfree(addr);
acl_vstring_free(vbuf);
acl_xml2_free(xml);
printf("Enter any key to continue ...\r\n");
@ -630,7 +701,7 @@ static void usage(const char *procname)
" -m[if enable multiple root xml node, default: no]\r\n"
" -p[print] data1|data2|data3|data4|data5|data6|data7\r\n"
" -P [if parse one xml with one data]\r\n"
" -d[parse] data1|data2|data3|data4|data5|data6|data7\r\n",
" -d[parse] data1|data2|data3|data4|data5|data6|data7|data8|data9\r\n",
procname);
}
@ -646,7 +717,7 @@ int main(int argc, char *argv[])
const char* root = "root";
char filepath[256];
acl_msg_stdout_enable(1);
// acl_msg_stdout_enable(1);
filepath[0] = 0;
@ -695,6 +766,9 @@ int main(int argc, char *argv[])
} else if (strcasecmp(optarg, "data8") == 0) {
data = __data8;
root = "root";
} else if (strcasecmp(optarg, "data9") == 0) {
data = __data9;
root = "root";
}
break;
case 'p':
@ -714,6 +788,8 @@ int main(int argc, char *argv[])
printf("%s\n", __data7);
else if (strcasecmp(optarg, "data8") == 0)
printf("%s\n", __data8);
else if (strcasecmp(optarg, "data9") == 0)
printf("%s\n", __data9);
return (0);
case 'f':
snprintf(filepath, sizeof(filepath), "%s", optarg);
@ -744,9 +820,7 @@ int main(int argc, char *argv[])
if (build)
build_xml();
#ifdef ACL_MS_WINDOWS
printf("ok, enter any key to exit ...\n");
printf("----OK, ENTER ANY KEY TO EXIT ----\n");
getchar();
#endif
return 0;
}

View File

@ -0,0 +1,778 @@
#include <sys/mman.h>
#include <sys/stat.h>
#include "lib_acl.h"
static const char *__data1 =
"<?xml version=\"1.0\"?>\r\n"
"<?xml-stylesheet type=\"text/xsl\"\r\n"
"\thref=\"http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl\"?>\r\n"
"\t<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2//EN\"\r\n"
"\t\"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\" [\r\n"
" <!ENTITY xmllint \"<command>xmllint</command>\">\r\n"
"]>\r\n"
"<root name='root1' id='root_id_1'>\r\n"
" <user name='user11\"' value='zsx11' id='id11'> user zsx11 </user>\r\n"
" <user name='user12' value='zsx12' id='id12'> user zsx12 \r\n"
" <age year='1972'>my age</age>\r\n"
" <other>\r\n"
" <email name='zsxxsz@263.net'/>"
" <phone>"
" <mobile number='111111'> mobile number </mobile>"
" <office number='111111'> office number </office>"
" </phone>"
" </other>"
" </user>\r\n"
" <user name='user13' value='zsx13' id='id13'> user zsx13 </user>\r\n"
"</root>\r\n"
"<root name='root2' id='root_id_2'>\r\n"
" <user name='user21' value='zsx21' id='id21'> user zsx21 </user>\r\n"
" <user name='user22' value='zsx22' id='id22'> user zsx22 \r\n"
" <!-- date should be the date of the latest change or the release version -->\r\n"
" <age year='1972'>my age</age>\r\n"
" </user>\r\n"
" <user name='user23' value='zsx23' id='id23'> user zsx23 </user>\r\n"
"</root>\r\n"
"<root name = 'root3' id = 'root_id_3'>\r\n"
" <user name = 'user31' value = 'zsx31' id = 'id31'> user zsx31 </user>\r\n"
" <user name = 'user32' value = 'zsx32' id = 'id32'> user zsx32 </user>\r\n"
" <user name = 'user33' value = 'zsx33' id = 'id33'> user zsx33 \r\n"
" <age year = '1978' month = '12' day = '11'> bao bao </age>\r\n"
" </user>\r\n"
" <!-- still a bit buggy output, will talk to docbook-xsl upstream to fix this -->\r\n"
" <!-- <releaseinfo>This is release 0.5 of the xmllint Manual.</releaseinfo> -->\r\n"
" <!-- <edition>0.5</edition> -->\r\n"
" <user name = 'user34' value = 'zsx34' id = 'id34'> user zsx34 </user>\r\n"
"</root>\r\n";
static const char *__data2 =
"<?xml version=\"1.0\"?>\r\n"
"<?xml-stylesheet type=\"text/xsl\"\r\n"
" href=\"http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl\"?>\r\n"
"<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2//EN\"\r\n"
" \"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\" [\r\n"
" <!ENTITY xmllint \"<command>xmllint</command>\">\r\n"
"]>\r\n"
"<root>test\r\n"
" <!-- <edition> - <!--0.5--> - </edition> -->\r\n"
" <user>zsx\r\n"
" <age>38</age>\r\n"
" </user>\r\n"
"</root>\r\n"
"<!-- <edition><!-- 0.5 --></edition> -->\r\n"
"<!-- <edition>0.5</edition> -->\r\n"
"<!-- <edition> -- 0.5 -- </edition> -->\r\n"
"<root name='root' id='root_id'>test</root>\r\n";
static const char *__data3 = \
"<root id='tt' >hello <root2> hi </root2></root><br/>\r\n";
static const char* __data4 = "<?xml version=\"1.0\" encoding=\"gb2312\"?>\r\n"
"<request action=\"get_location\" sid=\"YOU_CAN_GEN_SID\" user=\"admin@test.com\">\r\n"
" <tags1>\r\n"
" <module name=\"mail_ud_user\" />\r\n"
" </tags1>\r\n"
" <tags2>\r\n"
" <tags21/>\r\n"
" <tags22/>\r\n"
" <tags23/>\r\n"
" <module name=\"mail_ud_user\" />\r\n"
" </tags2>\r\n"
" <tag3>\r\n"
" <module name=\"mail_ud_user\"></module>\r\n"
" </tag3>\r\n"
" <tag4>\r\n"
" <module name=\"mail_ud_user\"/>\r\n"
" </tag4>\r\n"
"</request>\r\n"
"<!-- <edition> -- 0.5 -- </edition> -->\r\n"
"<!-- <edition> -- 0.5 -- </edition> -->\r\n"
"<!-- <edition> -- 0.5 -- </edition> -->\r\n";
static const char* __data5 = "<?xml version=\"1.0\" encoding=\"gb2312\"?>\r\n"
"<request action=\"get_location\" sid=\"YOU_CAN_GEN_SID\" user=\"admin@test.com\">\r\n"
" <tag3>\r\n"
" <module name=\"mail_ud_user\" />\r\n"
" </tag3>\r\n"
" <tag4>\r\n"
" <module name=\"mail_ud_user\" />\r\n"
" </tag4>\r\n"
"</request>\r\n";
static const char* __data6 = "<?xml version=\"1.0\" encoding=\"gb2312\"?>\r\n"
"<request action=\"get_location\" sid=\"YOU_CAN_GEN_SID\" user=\"admin@test.com\">\r\n"
" <tags2>\r\n"
" <tags21>\r\n"
" <tags22>\r\n"
" <tags23 />\r\n"
" <tags24 />\r\n"
" <tags25>\r\n"
" <tags26/>\r\n"
" <tags27>\r\n"
" <tags28/>\r\n"
" <tags29>\r\n"
" <tags30>\r\n"
" </tags2>\r\n"
"</request>\r\n";
static const char* __data7 = "<?xml version=\"1.0\" encoding=\"gb2312\"?>\r\n"
"<request action=\"get_location\" sid=\"YOU_CAN_GEN_SID\" user=\"admin@test.com\">\r\n"
" <tags2>\r\n"
" <tags22>\r\n"
" <tags23>\r\n"
" <tags24>\r\n"
" <tags25/>\r\n"
" <tags26/>\r\n"
" <tags27>\r\n"
" <tags28>\r\n"
" <tags29/>\r\n"
" <tags30>\r\n"
" <tags31>\r\n"
" </tags2>\r\n"
"</request>\r\n";
static const char* __data8 = "<?xml version=\"1.0\" encoding=\"gb2312\"?>\r\n"
"<root> hello world! </root>\r\n";
static void parse_xml_benchmark(int once, int max, const char *data)
{
int i;
size_t size = strlen(data) * 4;
const char *mmap_file = "./local.map";
ACL_XML2 *xml = acl_xml2_mmap_file(mmap_file, size, 1, NULL);
acl_xml2_slash(xml, 1);
ACL_METER_TIME("-------------bat begin--------------");
for (i = 0; i < max; i++) {
const char *ptr = data;
if (once) {
acl_xml2_parse(xml, ptr);
} else {
/* 每次仅输入一个字节来分析 xml 数据 */
while (*ptr != 0) {
char ch2[2];
ch2[0] = *ptr;
ch2[1] = 0;
acl_xml2_parse(xml, ch2);
ptr++;
}
}
/*
if (i < 2 || i == 4) {
printf("--------- dump xml --------------\n");
acl_xml_dump(xml, ACL_VSTREAM_OUT);
printf("--------- data src --------------\n");
printf("%s", data);
printf("--------- dump end --------------\n");
}
*/
acl_xml2_reset(xml);
}
ACL_METER_TIME("-------------bat end--------------");
acl_xml2_free(xml);
printf("--------------benchmark_max: %d--------------\r\n", max);
printf("Enter any key to continue ...\r\n");
getchar();
}
static int parse_xml_file(const char *filepath)
{
int n;
acl_int64 len;
char buf[10240];
ACL_VSTREAM *fp = acl_vstream_fopen(filepath, O_RDONLY, 0600, 8192);
ACL_XML2 *xml;
const char *mmap_file = "./local.map";
if (fp == NULL) {
printf("open %s error %s\r\n", filepath, acl_last_serror());
return -1;
}
len = acl_vstream_fsize(fp);
if (len <= 0) {
printf("fsize %s error %s\r\n", filepath, acl_last_serror());
acl_vstream_close(fp);
return -1;
}
len *= 4;
xml = acl_xml2_mmap_file(mmap_file, len, 1, NULL);
ACL_METER_TIME("-------------begin--------------");
while (1) {
n = acl_vstream_read(fp, buf, sizeof(buf) - 1);
if (n == ACL_VSTREAM_EOF)
break;
buf[n] = 0;
acl_xml2_update(xml, buf);
}
ACL_METER_TIME("-------------end--------------");
acl_vstream_close(fp);
if (acl_xml2_is_complete(xml, "root"))
printf("Xml is complete OK, filepath: %s\r\n", filepath);
else
printf("Xml is not complete, filepath: %s\r\n", filepath);
acl_xml2_free(xml);
printf("Enter any key to continue ...\r\n");
getchar();
return 0;
}
static void walk_xml(ACL_XML2* xml)
{
ACL_ITER iter1;
/* 从根结点开始遍历 xml 对象的所有结点 */
printf("-------------- walk_xml -----------------------\r\n");
acl_foreach(iter1, xml) {
int i;
ACL_ITER iter2;
ACL_XML2_NODE *node = (ACL_XML2_NODE*) iter1.data;
for (i = 1; i < node->depth; i++)
printf("\t");
printf("tag->%s, size: %ld\n", node->ltag,
(long) node->ltag_size);
/* 遍历 xml 结点的属性 */
acl_foreach(iter2, node->attr_list) {
ACL_XML2_ATTR *attr = (ACL_XML2_ATTR*) iter2.data;
for (i = 1; i < node->depth + 1; i++)
printf("\t");
printf("attr->%s=\"%s\"\n", attr->name, attr->value);
}
for (i = 1; i < node->depth + 1; i++)
printf("\t");
printf("text->%s, size: %ld\n", node->text,
(long) node->text_size);
}
printf("-------------- walk_xml end -------------------\r\n");
printf("Enter any key to continue ...\r\n");
getchar();
}
static void xml_node_attrs(ACL_XML2_NODE* node, int n)
{
int i;
ACL_ITER iter;
acl_foreach(iter, node->attr_list) {
ACL_XML2_ATTR *attr = (ACL_XML2_ATTR*) iter.data;
for (i = 0; i < n; i++)
printf("\t");
printf("attr->%s(%ld)=\"%s(%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 invalie\r\n",
__FUNCTION__, __LINE__);
exit (1);
}
}
}
static void walk_xml_node(ACL_XML2_NODE *node, int n)
{
ACL_ITER iter;
/* 遍历结点的子结点 */
acl_foreach(iter, node) {
int i;
ACL_XML2_NODE *child = (ACL_XML2_NODE*) iter.data;
for (i = 0; i < n; i++)
printf("\t");
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, %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);
}
}
static void list_xml_tags(ACL_XML2 *xml)
{
ACL_ITER iter;
printf("-------------- list xml's all tags --------------------\r\n");
acl_foreach(iter, xml) {
ACL_XML2_NODE *node = (ACL_XML2_NODE*) iter.data;
printf(">>tag: %s\n", node->ltag);
}
printf("-------------- list xml's all tags end ----------------\r\n");
printf("Enter any key to continue ...\r\n");
getchar();
}
static void test_getElementsByTagName(ACL_XML2 *xml, const char *tag)
{
ACL_ARRAY *a;
ACL_ITER iter;
printf("--------- acl_xml2_getElementsByTagName ------------\n");
a = acl_xml2_getElementsByTagName(xml, tag);
if (a) {
/* 遍历结果集 */
acl_foreach(iter, a) {
ACL_XML2_NODE *node = (ACL_XML2_NODE*) iter.data;
printf("tag->%s, text: %s\n", node->ltag, node->text);
xml_node_attrs(node, 1);
walk_xml_node(node, 1);
}
/* 释放数组对象 */
acl_xml2_free_array(a);
}
else
printf(">>> not exist, tag: %s\r\n", tag);
printf("--------- acl_xml2_getElementsByTagName end --------\n");
printf("Enter any key to continue ...\r\n");
getchar();
}
static ACL_XML2_NODE *test_getElementById(ACL_XML2 *xml, const char *id)
{
ACL_ITER iter1;
ACL_XML2_NODE *node = acl_xml2_getElementById(xml, id);
printf("--------------- acl_xml2_getElementById ---------------\r\n");
if (node == NULL) {
printf(">>>id: %s not found\r\n", id);
return NULL;
}
printf("tag-> %s, text: %s\n", node->ltag, node->text);
/* 遍历该 xml 结点的属性 */
acl_foreach(iter1, node->attr_list) {
ACL_XML2_ATTR *attr = (ACL_XML2_ATTR*) iter1.data;
printf("\tattr_name: %s, attr_value: %s\n",
attr->name, attr->value);
}
printf("----------- the id2_2's next node is ------------\n");
node = acl_xml2_node_next(node);
if (node) {
printf("-------------- walk node ----------------\n");
/* 遍历该 xml 结点的属性 */
acl_foreach(iter1, node->attr_list) {
ACL_XML2_ATTR *attr = (ACL_XML2_ATTR*) iter1.data;
printf("\tattr_name: %s, attr_value: %s\n",
attr->name, attr->value);
}
} else
printf("-------------- null node ----------------\n");
printf("Enter any key to continue ...\r\n");
getchar();
return node;
}
static ACL_XML2 *get_xml(int once, const char *data,
const char* root, int multi_root)
{
size_t size = strlen(data) * 4;
ACL_VSTRING *vbuf = acl_vstring_alloc(size);
ACL_XML2 *xml;
const char *left;
printf("--------------------- xml data ------------------------\r\n");
printf("{%s}\r\n", data);
printf("--------------------- xml data end --------------------\r\n");
printf("Enter any key to continue ...\r\n");
getchar();
xml = acl_xml2_alloc(vbuf);
acl_xml2_multi_root(xml, multi_root);
acl_xml2_decode_enable(xml, 1);
acl_xml2_slash(xml, 1);
if (once) {
/* 一次性地分析完整 xml 数据 */
ACL_METER_TIME("-------------once begin--------------");
left = acl_xml2_parse(xml, data);
} else {
/* 每次仅输入一个字节来分析 xml 数据 */
ACL_METER_TIME("-------------stream begin--------------");
while (*data != 0) {
char ch2[2];
ch2[0] = *data;
ch2[1] = 0;
left = acl_xml2_parse(xml, ch2);
data++;
}
}
ACL_METER_TIME("-------------end--------------");
printf("---------------- left data ----------------------------\r\n");
printf("{%s}\r\n", left ? left : "empty");
printf("---------------- left data end ------------------------\r\n");
printf("Enter any key to continue ...\r\n");
getchar();
if (acl_xml2_is_complete(xml, root))
printf(">> Yes, the xml complete\n");
else
printf(">> No, the xml not complete, root tag: %s\n", root);
printf("Enter any key to continue ...\r\n");
getchar();
return xml;
}
static void parse_xml(int once, const char *data,
const char* root, int multi_root)
{
ACL_XML2 *xml = get_xml(once, data, root, multi_root);
ACL_XML2_NODE *node;
int total = xml->node_cnt, left;
const char *ptr;
/* 遍历所有 xml 节点 */
walk_xml(xml);
/* 递归遍历 root 节点的所有子节点 */
printf("-------------------- walk root node -------------------\r\n");
walk_xml_node(xml->root, 0);
printf("-------------------- walk root node end ---------------\r\n");
printf("Enter any key to continue ...\r\n");
getchar();
/* 根据标签名获得 xml 结点集合 */
/* 查询属性名为 name, 属性值为 user 的所有 xml 结点的集合 */
test_getElementsByTagName(xml, "user");
/* 查询属性名为 name, 属性值为 user2_1 的所有 xml 结点的集合 */
test_getElementsByTagName(xml, "user2_1");
/* 查询属性名为 id, 属性值为 id2_2 的所有 xml 结点集合 */
(void) test_getElementById(xml, "id2_2");
/* 查询属性名为 id, 属性值为 id2_3 的所有 xml 结点集合 */
node = test_getElementById(xml, "id2_3");
if (node) {
int ndel = 0, node_cnt;
/* 删除该结点及其子结点 */
printf(">>>before delete %s, total: %d\n",
node->ltag, xml->node_cnt);
ndel = acl_xml2_node_delete(node);
node_cnt = xml->node_cnt;
printf(">>>after delete id2_3(%d deleted), total: %d\n",
ndel, node_cnt);
}
node = test_getElementById(xml, "id2_3");
list_xml_tags(xml);
printf("----------------- build xml -------------------------\r\n");
(void) ptr;
//ptr = acl_xml2_build(xml);
//printf("%s, len: %ld, %ld\r\n", ptr, (long) strlen(ptr),
// (long) (acl_vstring_end(xml->vbuf) - ptr));
printf("----------------- build xml end ---------------------\r\n");
/* 释放 xml 对象 */
acl_vstring_free(xml->vbuf);
left = acl_xml2_free(xml);
printf("Free all node ok, total(%d), left is: %d\n", total, left);
printf("Enter any key to continue ...\r\n");
getchar();
}
static void test1(void)
{
const char* data = "<?xml version=\"1.0\" encoding=\"gb2312\"?>\r\n"
"<?xml-stylesheet type=\"text/xsl\"\r\n"
"\thref=\"http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl\"?>\r\n"
"<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2//EN\"\r\n"
"\t\"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\" [\r\n"
" <!ENTITY xmllint \"<command>xmllint</command>\">\r\n"
"]>\r\n"
"<root name1 = \"value1\" name2 = \"val\\ue2\" name3 = \"v\\al'ue3\">hello world!</root>\r\n";
ACL_XML2 *xml;
ACL_XML2_NODE *node;
const char *encoding, *type, *href;
size_t size = strlen(data) * 3;
ACL_VSTRING *vbuf = acl_vstring_alloc(size);
const char *ptr;
xml = acl_xml2_alloc(vbuf);
printf("------------------------------------------------------\r\n");
printf("%s\r\n", data);
acl_xml2_update(xml, data);
printf("--------------- walk_xml_node ------------------------\r\n");
walk_xml_node(xml->root, 0);
printf("--------------- walk_xml_node end --------------------\r\n");
printf("Enter any key to continue ...\r\n");
getchar();
printf("----------------- lookup meta data -------------------\r\n");
encoding = acl_xml2_getEncoding(xml);
type = acl_xml2_getType(xml);
node = acl_xml2_getElementMeta(xml, "xml-stylesheet");
if (node)
href = acl_xml2_getElementAttrVal(node, "href");
else
href = NULL;
printf("xml encoding: %s\r\n", encoding ? encoding : "null");
printf("xml type: %s\r\n", type ? type : "null");
printf("xml href: %s\r\n", href ? href : "null");
printf("----------------- lookup meta data end ---------------\r\n");
printf("Enter any key to continue ...\r\n");
getchar();
test_getElementsByTagName(xml, "root");
printf("----------------- build xml -------------------------\r\n");
(void) ptr;
//ptr = acl_xml2_build(xml);
//printf("%s\r\n", ptr);
printf("----------------- build xml end ---------------------\r\n");
acl_vstring_free(vbuf);
acl_xml2_free(xml);
}
#if 0
static void build_xml(void)
{
size_t size = 1024;
char *addr = acl_mymalloc(size);
ACL_XML2 *xml = acl_xml2_alloc(addr, size);
ACL_XML2_NODE *node1, *node2, *node3;
const char *buf;
node1 = acl_xml2_create_node(xml, "users", "text1");
acl_xml2_node_add_child(xml->root, node1);
(void) acl_xml2_node_add_attr(node1, "name", "users list");
node2 = acl_xml2_create_node(xml, "user", "text11");
acl_xml2_node_add_child(node1, node2);
acl_xml2_node_add_attrs(node2, "name", "user11", "value", "zsx11", NULL);
node3 = acl_xml2_create_node(xml, "age", "text111");
acl_xml2_node_add_child(node2, node3);
acl_xml2_node_add_attrs(node3, "name", "user111", "value", "zsx111", NULL);
node2 = acl_xml2_create_node(xml, "user", "text2");
acl_xml2_node_add_child(node1, node2);
acl_xml2_node_add_attrs(node2, "name", "value2", "value", "zsx2", NULL);
node2 = acl_xml2_create_node(xml, "user", "text3");
acl_xml2_node_add_child(node1, node2);
acl_xml2_node_add_attrs(node2, "name", "value3", "value", "zsx3", NULL);
printf("--------------------xml string-------------------\r\n");
buf = acl_xml2_build(xml);
printf("%s\n", buf);
printf("length: %ld, %ld\r\n", (long) strlen(buf),
(long) (xml->ptr - buf));
printf("--------------------xml string end---------------\r\n");
acl_myfree(addr);
acl_xml2_free(xml);
printf("Enter any key to continue ...\r\n");
getchar();
}
#endif
static void usage(const char *procname)
{
printf("usage: %s -h[help]\r\n"
" -s[parse once]\r\n"
" -b benchmark_max\r\n"
" -B build_xml\r\n"
" -t [if test one xml]\r\n"
" -f xml_file\r\n"
" -m[if enable multiple root xml node, default: no]\r\n"
" -p[print] data1|data2|data3|data4|data5|data6|data7\r\n"
" -P [if parse one xml with one data]\r\n"
" -d[parse] data1|data2|data3|data4|data5|data6|data7\r\n",
procname);
}
#ifdef WIN32
#define snprintf _snprintf
#endif
int main(int argc, char *argv[])
{
int ch, once = 0, multi_root = 0, benchmark_max = 0;
int parse_one = 0, build = 0, test_one = 0;
const char *data = __data1;
const char* root = "root";
char filepath[256];
acl_msg_stdout_enable(1);
filepath[0] = 0;
while ((ch = getopt(argc, argv, "hsp:d:mb:f:PBt")) > 0) {
switch (ch) {
case 'h':
usage(argv[0]);
return (0);
case 't':
test_one = 1;
break;
case 'm':
multi_root = 1;
break;
case 's':
once = 1;
break;
case 'b':
benchmark_max = atoi(optarg);
break;
case 'P':
parse_one = 1;
break;
case 'B':
build = 1;
break;
case 'd':
if (strcasecmp(optarg, "data2") == 0) {
data = __data2;
root = "root";
} else if (strcasecmp(optarg, "data3") == 0) {
data = __data3;
root = "root";
} else if (strcasecmp(optarg, "data4") == 0) {
data = __data4;
root = "request";
} else if (strcasecmp(optarg, "data5") == 0) {
data = __data5;
root = "request";
} else if (strcasecmp(optarg, "data6") == 0) {
data = __data6;
root = "request";
} else if (strcasecmp(optarg, "data7") == 0) {
data = __data7;
root = "request";
} else if (strcasecmp(optarg, "data8") == 0) {
data = __data8;
root = "root";
}
break;
case 'p':
if (strcasecmp(optarg, "data1") == 0)
printf("%s\n", __data1);
else if (strcasecmp(optarg, "data2") == 0)
printf("%s\n", __data2);
else if (strcasecmp(optarg, "data3") == 0)
printf("%s\n", __data3);
else if (strcasecmp(optarg, "data4") == 0)
printf("%s\n", __data4);
else if (strcasecmp(optarg, "data5") == 0)
printf("%s\n", __data5);
else if (strcasecmp(optarg, "data6") == 0)
printf("%s\n", __data6);
else if (strcasecmp(optarg, "data7") == 0)
printf("%s\n", __data7);
else if (strcasecmp(optarg, "data8") == 0)
printf("%s\n", __data8);
return (0);
case 'f':
snprintf(filepath, sizeof(filepath), "%s", optarg);
break;
default:
break;
}
}
if (benchmark_max > 0)
parse_xml_benchmark(once, benchmark_max, data);
if (test_one)
{
test1();
printf("Enter any key to continue ...\r\n");
getchar();
}
if (parse_one)
parse_xml(once, data, root, multi_root);
if (filepath[0] != 0)
parse_xml_file(filepath);
if (build)
{
//build_xml();
}
#ifdef ACL_MS_WINDOWS
printf("ok, enter any key to exit ...\n");
getchar();
#endif
return 0;
}

View File

@ -38,7 +38,7 @@ static int parse_xml_file(const char *filepath)
len *= 4;
xml = acl_xml2_mmap_file(mmap_file, len, 10, 1, NULL);
xml = acl_xml2_mmap_file(mmap_file, len, 10, NULL);
len = 0;
while (1) {
@ -58,8 +58,9 @@ static int parse_xml_file(const char *filepath)
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);
len = acl_vstring_end(xml->vbuf) - ptr;
acl_vstream_printf(">>>build xml's size:%lld, strlen: %ld\r\n",
len, (long) strlen(ptr));
acl_vstream_printf(">>> ptr: {%s}\r\n", ptr);
if (acl_vstream_writen(out, ptr, len) == ACL_VSTREAM_EOF) {

View File

@ -22,6 +22,7 @@
#include "stdlib/acl_msg.h"
#include "stdlib/acl_ring.h"
#include "stdlib/acl_vstream.h"
#include "net/acl_sane_socket.h"
#include "event/acl_events.h"
#endif
@ -42,36 +43,34 @@ typedef struct EVENT_EPOLL_THR {
int handle;
} EVENT_EPOLL_THR;
static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream,
static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *fp,
int timeout, ACL_EVENT_NOTIFY_RDWR callback, void *context)
{
const char *myname = "event_enable_read";
EVENT_EPOLL_THR *event_thr = (EVENT_EPOLL_THR *) eventp;
EVENT_EPOLL_THR *evthr = (EVENT_EPOLL_THR *) eventp;
ACL_EVENT_FDTABLE *fdp;
ACL_SOCKET sockfd;
ACL_SOCKET fd;
struct epoll_event ev;
int fd_ready;
if (ACL_VSTREAM_BFRD_CNT(stream) > 0
|| (stream->flag & ACL_VSTREAM_FLAG_BAD))
{
if (ACL_VSTREAM_BFRD_CNT(fp) > 0 || (fp->flag & ACL_VSTREAM_FLAG_BAD)) {
fd_ready = 1;
} else
fd_ready = 0;
sockfd = ACL_VSTREAM_SOCK(stream);
fdp = (ACL_EVENT_FDTABLE*) stream->fdp;
fd = ACL_VSTREAM_SOCK(fp);
fdp = (ACL_EVENT_FDTABLE*) fp->fdp;
if (fdp == NULL) {
fdp = event_fdtable_alloc();
fdp->listener = 0;
fdp->stream = stream;
stream->fdp = (void *) fdp;
fdp->stream = fp;
fp->fdp = (void *) fdp;
} else if (fdp->flag & EVENT_FDTABLE_FLAG_WRITE)
acl_msg_panic("%s(%d), %s: fd %d: multiple I/O request",
__FILE__, __LINE__, myname, sockfd);
__FILE__, __LINE__, myname, fd);
else {
fdp->listener = 0;
fdp->stream = stream;
fdp->stream = fp;
}
if (fdp->r_callback != callback || fdp->r_context != context) {
@ -93,7 +92,7 @@ static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream,
return;
}
stream->nrefer++;
fp->nrefer++;
fdp->flag = EVENT_FDTABLE_FLAG_READ | EVENT_FDTABLE_FLAG_EXPT;
#if 0
@ -104,67 +103,76 @@ static void event_enable_read(ACL_EVENT *eventp, ACL_VSTREAM *stream,
ev.data.u64 = 0; /* avoid valgrind warning */
ev.data.ptr = fdp;
THREAD_LOCK(&event_thr->event.tb_mutex);
THREAD_LOCK(&evthr->event.tb_mutex);
fdp->fdidx = eventp->fdcnt;
eventp->fdtabs[eventp->fdcnt++] = fdp;
if (fd_ready) {
if (epoll_ctl(event_thr->handle, EPOLL_CTL_ADD,
sockfd, &ev) < 0)
{
if (epoll_ctl(evthr->handle, EPOLL_CTL_ADD, fd, &ev) < 0) {
if (errno == EEXIST)
acl_msg_warn("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
else
acl_msg_fatal("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
myname, acl_last_serror(), fd);
else if (errno == EBADF && acl_getsocktype(fd) < 0) {
acl_msg_error("%s: epool_ctl: %s, fd: %d",
myname, acl_last_serror(), fd);
ACL_VSTREAM_SET_SOCK(fp, ACL_SOCKET_INVALID);
fp->flag |= ACL_VSTREAM_FLAG_ERR;
} else
acl_msg_fatal("%s: epoll_ctl: %s, fd: %d, "
"epfd: %d", myname, acl_last_serror(),
fd, evthr->handle);
}
THREAD_UNLOCK(&event_thr->event.tb_mutex);
THREAD_UNLOCK(&evthr->event.tb_mutex);
if (event_thr->event.blocked && event_thr->event.evdog
&& event_dog_client(event_thr->event.evdog) != stream)
if (evthr->event.blocked && evthr->event.evdog
&& event_dog_client(evthr->event.evdog) != fp)
{
event_dog_notify(event_thr->event.evdog);
event_dog_notify(evthr->event.evdog);
}
} else {
THREAD_UNLOCK(&event_thr->event.tb_mutex);
if (epoll_ctl(event_thr->handle, EPOLL_CTL_ADD,
sockfd, &ev) < 0)
{
if (errno == EEXIST)
acl_msg_warn("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
else
acl_msg_fatal("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
}
return;
}
THREAD_UNLOCK(&evthr->event.tb_mutex);
if (epoll_ctl(evthr->handle, EPOLL_CTL_ADD, fd, &ev) < 0) {
if (errno == EEXIST)
acl_msg_warn("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), fd);
else if (errno == EBADF && acl_getsocktype(fd) < 0) {
acl_msg_error("%s: epool_ctl: %s, fd: %d",
myname, acl_last_serror(), fd);
ACL_VSTREAM_SET_SOCK(fp, ACL_SOCKET_INVALID);
fp->flag |= ACL_VSTREAM_FLAG_ERR;
} else
acl_msg_fatal("%s: epoll_ctl: %s, fd: %d, epfd: %d",
myname, acl_last_serror(), fd, evthr->handle);
}
}
static void event_enable_listen(ACL_EVENT *eventp, ACL_VSTREAM *stream,
static void event_enable_listen(ACL_EVENT *eventp, ACL_VSTREAM *fp,
int timeout, ACL_EVENT_NOTIFY_RDWR callback, void *context)
{
const char *myname = "event_enable_listen";
EVENT_EPOLL_THR *event_thr = (EVENT_EPOLL_THR *) eventp;
EVENT_EPOLL_THR *evthr = (EVENT_EPOLL_THR *) eventp;
ACL_EVENT_FDTABLE *fdp;
ACL_SOCKET sockfd;
ACL_SOCKET fd;
struct epoll_event ev;
sockfd = ACL_VSTREAM_SOCK(stream);
fdp = (ACL_EVENT_FDTABLE*) stream->fdp;
fd = ACL_VSTREAM_SOCK(fp);
fdp = (ACL_EVENT_FDTABLE*) fp->fdp;
if (fdp == NULL) {
fdp = event_fdtable_alloc();
fdp->stream = stream;
fdp->stream = fp;
fdp->listener = 1;
stream->fdp = (void *) fdp;
fp->fdp = (void *) fdp;
} else if (fdp->flag & EVENT_FDTABLE_FLAG_WRITE)
acl_msg_panic("%s(%d)->%s: fd %d: multiple I/O request",
__FILE__, __LINE__, myname, sockfd);
__FILE__, __LINE__, myname, fd);
else {
fdp->stream = stream;
fdp->stream = fp;
fdp->listener = 1;
}
@ -185,57 +193,57 @@ static void event_enable_listen(ACL_EVENT *eventp, ACL_VSTREAM *stream,
return;
fdp->flag = EVENT_FDTABLE_FLAG_READ | EVENT_FDTABLE_FLAG_EXPT;
stream->nrefer++;
fp->nrefer++;
ev.events = EPOLLIN | EPOLLHUP | EPOLLERR;
ev.data.u64 = 0; /* avoid valgrind warning */
ev.data.ptr = fdp;
THREAD_LOCK(&event_thr->event.tb_mutex);
THREAD_LOCK(&evthr->event.tb_mutex);
fdp->fdidx = eventp->fdcnt;
eventp->fdtabs[eventp->fdcnt++] = fdp;
THREAD_UNLOCK(&event_thr->event.tb_mutex);
THREAD_UNLOCK(&evthr->event.tb_mutex);
if (epoll_ctl(event_thr->handle, EPOLL_CTL_ADD, sockfd, &ev) < 0) {
if (epoll_ctl(evthr->handle, EPOLL_CTL_ADD, fd, &ev) < 0) {
if (errno == EEXIST)
acl_msg_warn("%s: epool_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
myname, acl_last_serror(), fd);
else
acl_msg_fatal("%s: epool_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
myname, acl_last_serror(), fd);
}
}
static void event_enable_write(ACL_EVENT *eventp, ACL_VSTREAM *stream,
static void event_enable_write(ACL_EVENT *eventp, ACL_VSTREAM *fp,
int timeout, ACL_EVENT_NOTIFY_RDWR callback, void *context)
{
const char *myname = "event_enable_write";
EVENT_EPOLL_THR *event_thr = (EVENT_EPOLL_THR *) eventp;
EVENT_EPOLL_THR *evthr = (EVENT_EPOLL_THR *) eventp;
ACL_EVENT_FDTABLE *fdp;
ACL_SOCKET sockfd;
ACL_SOCKET fd;
struct epoll_event ev;
int fd_ready;
if ((stream->flag & ACL_VSTREAM_FLAG_BAD))
if ((fp->flag & ACL_VSTREAM_FLAG_BAD))
fd_ready = 1;
else
fd_ready = 0;
sockfd = ACL_VSTREAM_SOCK(stream);
fdp = (ACL_EVENT_FDTABLE*) stream->fdp;
fd = ACL_VSTREAM_SOCK(fp);
fdp = (ACL_EVENT_FDTABLE*) fp->fdp;
if (fdp == NULL) {
fdp = event_fdtable_alloc();
fdp->listener = 0;
fdp->stream = stream;
stream->fdp = (void *) fdp;
fdp->stream = fp;
fp->fdp = (void *) fdp;
} else if (fdp->flag & EVENT_FDTABLE_FLAG_READ)
acl_msg_panic("%s(%d)->%s: fd %d: multiple I/O request",
__FILE__, __LINE__, myname, sockfd);
__FILE__, __LINE__, myname, fd);
else {
fdp->listener = 0;
fdp->stream = stream;
fdp->stream = fp;
}
if (fdp->w_callback != callback || fdp->w_context != context) {
@ -255,43 +263,51 @@ static void event_enable_write(ACL_EVENT *eventp, ACL_VSTREAM *stream,
return;
fdp->flag = EVENT_FDTABLE_FLAG_WRITE | EVENT_FDTABLE_FLAG_EXPT;
stream->nrefer++;
fp->nrefer++;
ev.events = EPOLLIN | EPOLLHUP | EPOLLERR;
ev.data.u64 = 0; /* avoid valgrind warning */
ev.data.ptr = fdp;
THREAD_LOCK(&event_thr->event.tb_mutex);
THREAD_LOCK(&evthr->event.tb_mutex);
fdp->fdidx = eventp->fdcnt;
eventp->fdtabs[eventp->fdcnt++] = fdp;
if (fd_ready) {
if (epoll_ctl(event_thr->handle, EPOLL_CTL_ADD,
sockfd, &ev) < 0)
{
if (epoll_ctl(evthr->handle, EPOLL_CTL_ADD, fd, &ev) < 0) {
if (errno == EEXIST)
acl_msg_warn("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
else
acl_msg_fatal("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
myname, acl_last_serror(), fd);
else if (errno == EBADF && acl_getsocktype(fd) < 0) {
acl_msg_error("%s: epool_ctl: %s, fd: %d",
myname, acl_last_serror(), fd);
ACL_VSTREAM_SET_SOCK(fp, ACL_SOCKET_INVALID);
fp->flag |= ACL_VSTREAM_FLAG_ERR;
} else
acl_msg_fatal("%s: epoll_ctl: %s, fd: %d, "
"epfd: %d", myname, acl_last_serror(),
fd, evthr->handle);
}
THREAD_UNLOCK(&event_thr->event.tb_mutex);
} else {
THREAD_UNLOCK(&event_thr->event.tb_mutex);
THREAD_UNLOCK(&evthr->event.tb_mutex);
return;
}
if (epoll_ctl(event_thr->handle, EPOLL_CTL_ADD,
sockfd, &ev) < 0)
{
if (errno == EEXIST)
acl_msg_warn("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
else
acl_msg_fatal("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
}
THREAD_UNLOCK(&evthr->event.tb_mutex);
if (epoll_ctl(evthr->handle, EPOLL_CTL_ADD, fd, &ev) < 0) {
if (errno == EEXIST)
acl_msg_warn("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), fd);
else if (errno == EBADF && acl_getsocktype(fd) < 0) {
acl_msg_error("%s: epool_ctl: %s, fd: %d",
myname, acl_last_serror(), fd);
ACL_VSTREAM_SET_SOCK(fp, ACL_SOCKET_INVALID);
fp->flag |= ACL_VSTREAM_FLAG_ERR;
} else
acl_msg_fatal("%s: epoll_ctl: %s, fd: %d, epfd: %d",
myname, acl_last_serror(), fd, evthr->handle);
}
}
@ -356,7 +372,7 @@ static void event_disable_readwrite(ACL_EVENT *eventp, ACL_VSTREAM *stream)
acl_msg_warn("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
else
acl_msg_fatal("%s: epoll_ctl: %s, fd: %d",
acl_msg_error("%s: epoll_ctl: %s, fd: %d",
myname, acl_last_serror(), sockfd);
}

View File

@ -1035,7 +1035,7 @@ int acl_vstream_gets_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf, int *ready)
if (fp->read_ready) {
if (read_once(fp) <= 0) {
n = (int) LEN(buf) - n;
return n > 0 ? n : ACL_VSTREAM_EOF;
return n >= 0 ? n : ACL_VSTREAM_EOF;
}
}
@ -1106,7 +1106,7 @@ int acl_vstream_gets_nonl_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf, int *ready)
if (read_once(fp) <= 0) {
n = (int) LEN(buf) - n;
return n > 0 ? n : ACL_VSTREAM_EOF;
return n >= 0 ? n : ACL_VSTREAM_EOF;
}
}
@ -1168,7 +1168,7 @@ int acl_vstream_readn_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf,
if (fp->read_ready) {
if (read_once(fp) <= 0) {
int n = cnt_saved - cnt;
return n > 0 ? n : ACL_VSTREAM_EOF;
return n >= 0 ? n : ACL_VSTREAM_EOF;
}
}
@ -1219,7 +1219,7 @@ int acl_vstream_read_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf)
if (fp->read_ready) {
if (read_once(fp) <= 0) {
n = (int) LEN(buf) - n;
return n > 0 ? n : ACL_VSTREAM_EOF;
return n >= 0 ? n : ACL_VSTREAM_EOF;
}
}

View File

@ -17,9 +17,14 @@
#include "stdlib/acl_mymalloc.h"
#include "stdlib/acl_msg.h"
#include "stdlib/acl_sys_patch.h"
#include "stdlib/acl_vbuf_print.h"
#include "stdlib/acl_vstring.h"
#ifdef ACL_UNIX
#include <sys/mman.h>
#endif
#endif
#include "charmap.h"
@ -28,25 +33,41 @@
/* vstring_extend - variable-length string buffer extension policy */
static void vstring_extend(ACL_VBUF *bp, int incr)
static int vstring_extend(ACL_VBUF *bp, ssize_t incr)
{
const char *myname = "vstring_extend";
unsigned used = (unsigned) (bp->ptr - bp->data);
int new_len;
ACL_VSTRING *vp = (ACL_VSTRING *) bp->ctx;
ssize_t used = (unsigned) (bp->ptr - bp->data), new_len;
ACL_VSTRING *vp = (ACL_VSTRING *) bp;
if (vp->maxlen > 0 && (int) ACL_VSTRING_LEN(vp) > vp->maxlen)
acl_msg_warn("%s(%d), %s: reached the maxlen: %d",
__FILE__, __LINE__, myname, vp->maxlen);
if (vp->maxlen > 0 && (ssize_t) ACL_VSTRING_LEN(vp) >= vp->maxlen) {
ACL_VSTRING_AT_OFFSET(vp, vp->maxlen - 1);
ACL_VSTRING_TERMINATE(vp);
acl_msg_warn("%s(%d), %s: overflow maxlen: %ld, %ld",
__FILE__, __LINE__, myname, (long) vp->maxlen,
(long) ACL_VSTRING_LEN(vp));
bp->flags |= ACL_VBUF_FLAG_EOF;
return ACL_VBUF_EOF;
}
#ifdef ACL_WINDOWS
if (vp->fd == ACL_FILE_INVALID && (bp->flags & ACL_VBUF_FLAG_FIXED))
#else
if (vp->fd < 0 && (bp->flags & ACL_VBUF_FLAG_FIXED))
#endif
{
acl_msg_warn("%s(%d), %s: can't extend fixed buffer",
__FILE__, __LINE__, myname);
return ACL_VBUF_EOF;
}
/*
* Note: vp->vbuf.len is the current buffer size (both on entry and on
* exit of this routine). We round up the increment size to the buffer
* size to avoid silly little buffer increments. With really large
* strings we might want to abandon the length doubling strategy, and go
* to fixed increments.
* strings we might want to abandon the length doubling strategy, and
* go to fixed increments.
*/
/* new_len = bp->len + (bp->len > incr ? bp->len : incr); */
#ifdef INCR_NO_DOUBLE
/* below come from redis-server/sds.c/sdsMakeRoomFor, which can
* avoid memory double growing too large --- 2015.2.2, zsx
*/
@ -55,6 +76,12 @@ static void vstring_extend(ACL_VBUF *bp, int incr)
new_len *= 2;
else
new_len += MAX_PREALLOC;
#else
new_len = bp->len + (bp->len > incr ? bp->len : incr);
#endif
if (vp->maxlen > 0 && new_len > vp->maxlen)
new_len = vp->maxlen;
if (vp->slice)
bp->data = (unsigned char *) acl_slice_pool_realloc(
@ -65,11 +92,24 @@ static void vstring_extend(ACL_VBUF *bp, int incr)
vp->dbuf, new_len);
memcpy(bp->data, data, used);
acl_dbuf_pool_free(vp->dbuf, data);
} else if (vp->fd != ACL_FILE_INVALID) {
acl_off_t off = new_len - 1;
if (acl_lseek(vp->fd, off, SEEK_SET) != (acl_off_t) off)
acl_msg_fatal("lseek failed: %s, off: %lld",
acl_last_serror(), off);
if (acl_file_write(vp->fd, "\0", 1, 0, NULL, NULL)
== ACL_VSTREAM_EOF)
{
acl_msg_fatal("write error: %s", acl_last_serror());
}
} else
bp->data = (unsigned char *) acl_myrealloc(bp->data, new_len);
bp->len = new_len;
bp->ptr = bp->data + used;
bp->cnt = bp->len - used;
return 0;
}
/* vstring_buf_get_ready - vbuf callback for read buffer empty condition */
@ -84,21 +124,21 @@ static int vstring_buf_get_ready(ACL_VBUF *buf acl_unused)
static int vstring_buf_put_ready(ACL_VBUF *bp)
{
vstring_extend(bp, 0);
return 0;
return vstring_extend(bp, 0);
}
/* vstring_buf_space - vbuf callback to reserve space */
static int vstring_buf_space(ACL_VBUF *bp, int len)
static int vstring_buf_space(ACL_VBUF *bp, ssize_t len)
{
int need;
ssize_t need;
if (len < 0)
acl_msg_panic("vstring_buf_space: bad length %d", len);
acl_msg_panic("vstring_buf_space: bad length %ld", (long) len);
if ((need = len - bp->cnt) > 0)
vstring_extend(bp, need);
return 0;
return vstring_extend(bp, need);
else
return 0;
}
void acl_vstring_init(ACL_VSTRING *vp, size_t len)
@ -117,7 +157,7 @@ void acl_vstring_init(ACL_VSTRING *vp, size_t len)
vp->vbuf.get_ready = vstring_buf_get_ready;
vp->vbuf.put_ready = vstring_buf_put_ready;
vp->vbuf.space = vstring_buf_space;
vp->vbuf.ctx = vp;
vp->vbuf.ctx = NULL;
vp->maxlen = 0;
vp->slice = NULL;
}
@ -129,6 +169,14 @@ void acl_vstring_free_buf(ACL_VSTRING *vp)
if (vp->slice)
acl_slice_pool_free(__FILE__, __LINE__, vp->vbuf.data);
#ifdef ACL_UNIX
if (vp->fd != ACL_FILE_INVALID) {
if (vp->maxlen > 0 && munmap(vp->vbuf.data, vp->maxlen) < 0)
acl_msg_error("%s(%d), %s: munmap error %s",
__FILE__, __LINE__, __FUNCTION__,
acl_last_serror());
}
#endif
else if (vp->dbuf == NULL)
acl_myfree(vp->vbuf.data);
vp->vbuf.data = NULL;
@ -162,6 +210,7 @@ ACL_VSTRING *acl_vstring_slice_alloc(ACL_SLICE_POOL *slice, size_t len)
vp->vbuf.data = (unsigned char *) acl_mymalloc(len);
}
vp->fd = ACL_FILE_INVALID;
vp->vbuf.flags = 0;
vp->vbuf.len = (int) len;
ACL_VSTRING_RESET(vp);
@ -169,8 +218,9 @@ ACL_VSTRING *acl_vstring_slice_alloc(ACL_SLICE_POOL *slice, size_t len)
vp->vbuf.get_ready = vstring_buf_get_ready;
vp->vbuf.put_ready = vstring_buf_put_ready;
vp->vbuf.space = vstring_buf_space;
vp->vbuf.ctx = vp;
vp->vbuf.ctx = NULL;
vp->maxlen = 0;
return vp;
}
@ -179,12 +229,14 @@ ACL_VSTRING *acl_vstring_dbuf_alloc(ACL_DBUF_POOL *dbuf, size_t len)
ACL_VSTRING *vp;
if (len < 1)
acl_msg_panic("acl_vstring_alloc: bad length %d", (int) len);
len = 64;
if (dbuf) {
vp = (ACL_VSTRING*) acl_dbuf_pool_alloc(dbuf, sizeof(*vp));
vp->dbuf = dbuf;
vp->slice = NULL;
vp->vbuf.data = (unsigned char *) acl_dbuf_pool_alloc(dbuf, len);
vp->vbuf.data = (unsigned char *)
acl_dbuf_pool_alloc(dbuf, len);
} else {
vp = (ACL_VSTRING *) acl_mymalloc(sizeof(*vp));
vp->slice = NULL;
@ -192,6 +244,7 @@ ACL_VSTRING *acl_vstring_dbuf_alloc(ACL_DBUF_POOL *dbuf, size_t len)
vp->vbuf.data = (unsigned char *) acl_mymalloc(len);
}
vp->fd = ACL_FILE_INVALID;
vp->vbuf.flags = 0;
vp->vbuf.len = (int) len;
ACL_VSTRING_RESET(vp);
@ -199,8 +252,60 @@ ACL_VSTRING *acl_vstring_dbuf_alloc(ACL_DBUF_POOL *dbuf, size_t len)
vp->vbuf.get_ready = vstring_buf_get_ready;
vp->vbuf.put_ready = vstring_buf_put_ready;
vp->vbuf.space = vstring_buf_space;
vp->vbuf.ctx = vp;
vp->vbuf.ctx = NULL;
vp->maxlen = 0;
return vp;
}
static void vstring_buf_init(ACL_VSTRING *vp, ssize_t init_len)
{
if (acl_lseek(vp->fd, init_len, SEEK_SET) != init_len)
acl_msg_fatal("lseek failed: %s, off: %ld",
acl_last_serror(), (long) init_len);
if (acl_file_write(vp->fd, "\0", 1, 0, NULL, NULL) == ACL_VSTREAM_EOF)
acl_msg_fatal("write error: %s", acl_last_serror());
#ifdef ACL_UNIX
vp->vbuf.data = (unsigned char*) mmap(NULL, vp->maxlen,
PROT_READ | PROT_WRITE, MAP_SHARED, vp->fd, 0);
if (vp->vbuf.data == MAP_FAILED)
acl_msg_fatal("mmap error: %s", acl_last_serror());
#else
acl_msg_fatal("%s: not supported yet!", __FUNCTION__);
#endif
}
ACL_VSTRING *acl_vstring_mmap_alloc(ACL_FILE_HANDLE fd,
ssize_t max_len, ssize_t init_len)
{
const char *myname = "acl_vstring_mmap_alloc";
ACL_VSTRING *vp;
if (init_len < 1)
acl_msg_panic("%s: bad length %ld", myname, (long) init_len);
if (max_len < init_len)
max_len = init_len;
vp = (ACL_VSTRING *) acl_mymalloc(sizeof(*vp));
vp->fd = fd;
vp->slice = NULL;
vp->dbuf = NULL;
vp->vbuf.flags = 0;
vp->vbuf.len = init_len;
vp->vbuf.get_ready = vstring_buf_get_ready;
vp->vbuf.put_ready = vstring_buf_put_ready;
vp->vbuf.space = vstring_buf_space;
vp->vbuf.ctx = NULL;
vp->maxlen = max_len;
vstring_buf_init(vp, init_len);
ACL_VSTRING_RESET(vp);
vp->vbuf.data[0] = 0;
return vp;
}
@ -208,15 +313,16 @@ ACL_VSTRING *acl_vstring_dbuf_alloc(ACL_DBUF_POOL *dbuf, size_t len)
void acl_vstring_free(ACL_VSTRING *vp)
{
if (vp->slice) {
if (vp->vbuf.data)
acl_slice_pool_free(__FILE__, __LINE__, vp->vbuf.data);
acl_vstring_free_buf(vp);
if (vp->slice)
acl_slice_pool_free(__FILE__, __LINE__, vp);
} else if (vp->dbuf == NULL) {
if (vp->vbuf.data)
acl_myfree(vp->vbuf.data);
#ifdef ACL_UNIX
else if (vp->fd != ACL_FILE_INVALID)
acl_myfree(vp);
#endif
else if (vp->dbuf == NULL)
acl_myfree(vp);
}
}
/* acl_vstring_ctl - modify memory management policy */
@ -235,8 +341,8 @@ void acl_vstring_ctl(ACL_VSTRING *vp,...)
case ACL_VSTRING_CTL_MAXLEN:
vp->maxlen = va_arg(ap, int);
if (vp->maxlen < 0)
acl_msg_panic("%s: bad max length %d",
myname, vp->maxlen);
acl_msg_panic("%s: bad max length %ld",
myname, (long) vp->maxlen);
break;
}
}
@ -258,52 +364,36 @@ ACL_VSTRING *acl_vstring_truncate(ACL_VSTRING *vp, size_t len)
ACL_VSTRING *acl_vstring_strcpy(ACL_VSTRING *vp, const char *src)
{
ACL_VSTRING_RESET(vp);
while (*src) {
ACL_VSTRING_ADDCH(vp, *src);
src++;
}
ACL_VSTRING_TERMINATE(vp);
return vp;
return acl_vstring_memcpy(vp, src, strlen(src));
}
/* acl_vstring_strncpy - copy string of limited length */
ACL_VSTRING *acl_vstring_strncpy(ACL_VSTRING *vp, const char *src, size_t len)
{
ACL_VSTRING_RESET(vp);
size_t n = strlen(src);
while (len-- > 0 && *src) {
ACL_VSTRING_ADDCH(vp, *src);
src++;
}
ACL_VSTRING_TERMINATE(vp);
return vp;
if (n > len)
n = len;
return acl_vstring_memcpy(vp, src, n);
}
/* acl_vstring_strcat - append string */
ACL_VSTRING *acl_vstring_strcat(ACL_VSTRING *vp, const char *src)
{
while (*src) {
ACL_VSTRING_ADDCH(vp, *src);
src++;
}
ACL_VSTRING_TERMINATE(vp);
return vp;
return acl_vstring_memcat(vp, src, strlen(src));
}
/* acl_vstring_strncat - append string of limited length */
ACL_VSTRING *acl_vstring_strncat(ACL_VSTRING *vp, const char *src, size_t len)
{
while (len-- > 0 && *src) {
ACL_VSTRING_ADDCH(vp, *src);
src++;
}
ACL_VSTRING_TERMINATE(vp);
return vp;
size_t n = strlen(src);
if (n > len)
n = len;
return acl_vstring_memcat(vp, src, n);
}
/* acl_vstring_memcpy - copy buffer of limited length */
@ -313,10 +403,27 @@ ACL_VSTRING *acl_vstring_memcpy(ACL_VSTRING *vp, const char *src, size_t len)
ACL_VSTRING_RESET(vp);
if (len > 0) {
ACL_VSTRING_SPACE(vp, (int) len);
memcpy(acl_vstring_str(vp), src, len);
ACL_VSTRING_AT_OFFSET(vp, (int) len);
ssize_t n;
ACL_VSTRING_SPACE(vp, (ssize_t) len);
n = acl_vstring_avail(vp);
if ((size_t) n >= len)
n = (ssize_t) len;
else
acl_msg_warn("%s(%d): space not enough, avail: %ld, "
"len: %ld", __FUNCTION__, __LINE__,
(long) n, (long) len);
if (n > 0) {
memcpy(acl_vstring_str(vp), src, n);
ACL_VSTRING_AT_OFFSET(vp, n);
} else
acl_msg_warn("%s(%d): no space, avail: 0, len: %ld",
__FUNCTION__, __LINE__, (long) len);
}
ACL_VSTRING_TERMINATE(vp);
return vp;
}
@ -336,19 +443,34 @@ ACL_VSTRING *acl_vstring_memmove(ACL_VSTRING *vp, const char *src, size_t len)
ACL_VSTRING_AT_OFFSET(vp, (int) len);
ACL_VSTRING_TERMINATE(vp);
return vp;
} else {
/* 说明不是同一内存区间的数据移动 */
char *ptr = acl_mymalloc(len);
memcpy(ptr, src, len);
acl_myfree(vp->vbuf.data);
vp->vbuf.data = (unsigned char *) ptr;
vp->vbuf.len = (int) len;
ACL_VSTRING_AT_OFFSET(vp, (int) len);
ACL_VSTRING_TERMINATE(vp);
vp->maxlen = 0;
return vp;
}
/* 说明不是同一内存区间的数据移动 */
acl_vstring_free_buf(vp);
if (vp->slice != NULL)
vp->vbuf.data = (unsigned char *) acl_slice_pool_alloc(
__FILE__, __LINE__, vp->slice, len);
else if (vp->dbuf != NULL)
vp->vbuf.data = (unsigned char *)
acl_dbuf_pool_alloc(vp->dbuf, len);
#ifdef ACL_UNIX
else if (vp->fd != ACL_FILE_INVALID) {
if (len > (size_t) vp->maxlen)
vp->maxlen = (ssize_t) len;
vstring_buf_init(vp, len);
}
#endif
else
vp->vbuf.data = acl_mymalloc(len);
memcpy(vp->vbuf.data, src, len);
vp->vbuf.len = (ssize_t) len;
ACL_VSTRING_AT_OFFSET(vp, len);
ACL_VSTRING_TERMINATE(vp);
return vp;
}
/* acl_vstring_memcat - append buffer of limited length */
@ -356,11 +478,28 @@ ACL_VSTRING *acl_vstring_memmove(ACL_VSTRING *vp, const char *src, size_t len)
ACL_VSTRING *acl_vstring_memcat(ACL_VSTRING *vp, const char *src, size_t len)
{
if (len > 0) {
ACL_VSTRING_SPACE(vp, (int) len);
memcpy(acl_vstring_end(vp), src, len);
len += ACL_VSTRING_LEN(vp);
ACL_VSTRING_AT_OFFSET(vp, (int) len);
ssize_t n;
ACL_VSTRING_SPACE(vp, (ssize_t) len);
n = acl_vstring_avail(vp);
if ((size_t) n >= len)
n = (ssize_t) len;
else
acl_msg_warn("%s(%d): space not enough, avail: %ld, "
"len: %ld", __FUNCTION__, __LINE__,
(long) n, (long) len);
if (n > 0 ) {
memcpy(acl_vstring_end(vp), src, n);
n += ACL_VSTRING_LEN(vp);
ACL_VSTRING_AT_OFFSET(vp, n);
} else
acl_msg_warn("%s(%d): no space, avail: 0, len: %ld",
__FUNCTION__, __LINE__, (long) len);
}
ACL_VSTRING_TERMINATE(vp);
return vp;
}
@ -509,7 +648,7 @@ ACL_VSTRING *acl_vstring_insert(ACL_VSTRING *vp, size_t start,
const char *buf, size_t len)
{
const char *myname = "acl_vstring_insert";
size_t new_len;
size_t new_len, n;
/*
* Sanity check.
@ -522,13 +661,21 @@ ACL_VSTRING *acl_vstring_insert(ACL_VSTRING *vp, size_t start,
* Move the existing content and copy the new content.
*/
new_len = ACL_VSTRING_LEN(vp) + len;
ACL_VSTRING_SPACE(vp, (int) len);
memmove(acl_vstring_str(vp) + start + len,
acl_vstring_str(vp) + start,
ACL_VSTRING_LEN(vp) - start);
memcpy(acl_vstring_str(vp) + start, buf, len);
ACL_VSTRING_AT_OFFSET(vp, (int) new_len);
ACL_VSTRING_TERMINATE(vp);
ACL_VSTRING_SPACE(vp, (ssize_t) len);
n = acl_vstring_avail(vp);
if (len > (size_t) n)
len = n;
if (len > 0) {
memmove(acl_vstring_str(vp) + start + len,
acl_vstring_str(vp) + start,
ACL_VSTRING_LEN(vp) - start);
memcpy(acl_vstring_str(vp) + start, buf, len);
ACL_VSTRING_AT_OFFSET(vp, (int) new_len);
ACL_VSTRING_TERMINATE(vp);
}
return vp;
}
@ -536,17 +683,26 @@ ACL_VSTRING *acl_vstring_insert(ACL_VSTRING *vp, size_t start,
ACL_VSTRING *acl_vstring_prepend(ACL_VSTRING *vp, const char *buf, size_t len)
{
ssize_t new_len;
ssize_t new_len, n;
/*
* Move the existing content and copy the new content.
*/
new_len = (ssize_t) (ACL_VSTRING_LEN(vp) + len);
ACL_VSTRING_SPACE(vp, (int) len);
memmove(acl_vstring_str(vp) + len, acl_vstring_str(vp), ACL_VSTRING_LEN(vp));
memcpy(acl_vstring_str(vp), buf, len);
ACL_VSTRING_AT_OFFSET(vp, new_len);
ACL_VSTRING_TERMINATE(vp);
n = acl_vstring_avail(vp);
if (len > (size_t) n)
len = (size_t) n;
if (len > 0) {
memmove(acl_vstring_str(vp) + len, acl_vstring_str(vp),
ACL_VSTRING_LEN(vp));
memcpy(acl_vstring_str(vp), buf, len);
ACL_VSTRING_AT_OFFSET(vp, new_len);
ACL_VSTRING_TERMINATE(vp);
}
return vp;
}

View File

@ -57,12 +57,12 @@ static int vstring_buf_put_ready(ACL_VBUF *bp)
return (0);
}
static int vstring_buf_space(ACL_VBUF *bp, int len)
static int vstring_buf_space(ACL_VBUF *bp, ssize_t len)
{
int need;
ssize_t need;
if (len < 0)
acl_msg_panic("vstring_buf_space: bad length %d", len);
acl_msg_panic("vstring_buf_space: bad length %ld", (long) len);
if ((need = len - bp->cnt) > 0)
vstring_extend(bp, need);
return (0);

View File

@ -32,9 +32,9 @@ ACL_XML2_ATTR *acl_xml2_attr_alloc(ACL_XML2_NODE *node)
acl_dbuf_pool_calloc(node->xml->dbuf, sizeof(ACL_XML2_ATTR));
attr->node = node;
attr->name = node->xml->addr;
attr->name = node->xml->dummy;
attr->name_size = 0;
attr->value = node->xml->addr;
attr->value = node->xml->dummy;
attr->value_size = 0;
attr->quote = 0;
attr->backslash = 0;
@ -132,12 +132,12 @@ ACL_XML2_NODE *acl_xml2_node_alloc(ACL_XML2 *xml)
node->xml = xml;
node->status = ACL_XML2_S_NXT;
node->ltag = xml->addr;
node->rtag = xml->addr;
node->ltag = xml->dummy;
node->rtag = xml->dummy;
node->ltag_size = 0;
node->rtag_size = 0;
node->text = xml->addr;
node->text = xml->dummy;
node->text_size = 0;
node->attr_list = acl_array_dbuf_create(100, xml->dbuf);
@ -396,13 +396,8 @@ void acl_xml2_decode_enable(ACL_XML2 *xml, int on)
xml->flag &= ~ACL_XML2_FLAG_XML_DECODE;
}
ACL_XML2 *acl_xml2_alloc(char *buf, size_t size)
{
return acl_xml2_dbuf_alloc(buf, size, NULL);
}
ACL_XML2 *acl_xml2_mmap_file(const char *filepath, size_t size, size_t block,
int keep_open, ACL_DBUF_POOL *dbuf)
ACL_XML2 *acl_xml2_mmap_file(const char *filepath, size_t max_len,
size_t init_len, ACL_DBUF_POOL *dbuf)
{
const char *myname = "acl_xml2_mmap_alloc";
ACL_FILE_HANDLE fd;
@ -417,157 +412,45 @@ ACL_XML2 *acl_xml2_mmap_file(const char *filepath, size_t size, size_t block,
return NULL;
}
xml = acl_xml2_mmap_fd(fd, size, block, dbuf);
xml = acl_xml2_mmap_fd(fd, max_len, init_len, dbuf);
if (xml == NULL) {
acl_file_close(fd);
return NULL;
}
if (!keep_open) {
acl_file_close(fd);
fd = ACL_FILE_INVALID;
}
xml->keep_open = keep_open;
xml->mm_file = acl_dbuf_pool_strdup(xml->dbuf, filepath);
/* save the fd will be closed in acl_vstring_free */
xml->fd = fd;
return xml;
}
ACL_XML2 *acl_xml2_mmap_fd(ACL_FILE_HANDLE fd, size_t size,
size_t block, ACL_DBUF_POOL *dbuf)
ACL_XML2 *acl_xml2_mmap_fd(ACL_FILE_HANDLE fd, size_t max_len,
size_t init_len, ACL_DBUF_POOL *dbuf)
{
#ifdef ACL_UNIX
size_t off = block - 1;
ACL_XML2 *xml;
char *addr;
ACL_VSTRING *vbuf = acl_vstring_mmap_alloc(fd, max_len, init_len);
acl_assert(size > 0);
acl_assert(block > 0);
if (block > size)
block = size;
if (acl_lseek(fd, off, SEEK_SET) != (acl_off_t) off) {
acl_msg_error("%s(%d), %s: lseek error: %s, block: %lu",
__FILE__, __LINE__, __FUNCTION__, acl_last_serror(),
(unsigned long) off);
if (vbuf == NULL)
return NULL;
}
if (acl_file_write(fd, "\0", 1, 0, NULL, NULL) == ACL_VSTREAM_EOF)
{
acl_msg_error("%s(%d), %s: write error: %s",
__FILE__, __LINE__, __FUNCTION__, acl_last_serror());
return NULL;
}
addr = (char*) mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
acl_msg_error("%s(%d), %s: mmap error: %s, size: %lu",
__FILE__, __LINE__, __FUNCTION__,
acl_last_serror(), (unsigned long) size);
return NULL;
}
xml = acl_xml2_dbuf_alloc(addr, size, dbuf);
xml->mm_file = NULL;
xml->fd = fd;
xml->mm_addr = addr;
xml->block = block;
xml->off = off;
xml->keep_open = 1;
xml->len = xml->off + 1;
xml = acl_xml2_dbuf_alloc(vbuf, dbuf);
xml->vbuf_inner = vbuf;
return xml;
}
ACL_XML2 *acl_xml2_alloc(ACL_VSTRING *buf)
{
#ifdef ACL_WINDOWS
if (buf->fd == ACL_FILE_INVALID)
#else
(void) fd;
(void) size;
(void) block;
(void) dbuf;
acl_msg_error("%s(%d), %s: not implement yet!",
__FILE__, __LINE__, __FUNCTION__);
return NULL;
if (buf->fd < 0)
#endif
buf->vbuf.flags |= ACL_VBUF_FLAG_FIXED;
return acl_xml2_dbuf_alloc(buf, NULL);
}
size_t acl_xml2_mmap_extend(ACL_XML2 *xml)
{
const char *myname = "acl_xml2_mmap_extend";
size_t n;
if (xml->ptr >= xml->addr + xml->size)
return 0;
if (xml->block == 0)
return 0;
if (xml->fd == ACL_FILE_INVALID) {
if (xml->mm_file == NULL || *xml->mm_file == 0)
return 0;
xml->fd = acl_file_open(xml->mm_file, O_CREAT | O_RDWR, 0600);
if (xml->fd == ACL_FILE_INVALID) {
acl_msg_error("%s(%d), %s: open %s error: %s",
__FILE__, __LINE__, myname,
xml->mm_file, acl_last_serror());
return 0;
}
}
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;
if (acl_lseek(xml->fd, xml->off, SEEK_SET) != (acl_off_t) xml->off)
{
acl_msg_error("%s(%d), %s: lseek error: %s",
__FILE__, __LINE__, myname, acl_last_serror());
acl_file_close(xml->fd);
xml->fd = ACL_FILE_INVALID;
return 0;
}
if (acl_file_write(xml->fd, "\0", 1, 0, NULL, NULL) == ACL_VSTREAM_EOF)
{
acl_msg_error("%s(%d), %s: write error: %s",
__FILE__, __LINE__, myname, acl_last_serror());
acl_file_close(xml->fd);
xml->fd = ACL_FILE_INVALID;
return 0;
}
if (!xml->keep_open) {
acl_file_close(xml->fd);
xml->fd = ACL_FILE_INVALID;
}
return n;
}
ACL_XML2 *acl_xml2_dbuf_alloc(char *buf, size_t size, ACL_DBUF_POOL *dbuf)
ACL_XML2 *acl_xml2_dbuf_alloc(ACL_VSTRING *vbuf, ACL_DBUF_POOL *dbuf)
{
ACL_XML2 *xml;
@ -580,54 +463,41 @@ ACL_XML2 *acl_xml2_dbuf_alloc(char *buf, size_t size, ACL_DBUF_POOL *dbuf)
xml->dbuf_inner = NULL;
}
xml->dbuf = dbuf;
xml->dbuf_keep = sizeof(ACL_XML2);
xml->addr = buf;
xml->size = size;
xml->len = size;
xml->ptr = xml->addr;
*xml->ptr++ = 0;
xml->flag |= ACL_XML2_FLAG_MULTI_ROOT;
xml->fd = ACL_FILE_INVALID;
xml->dbuf = dbuf;
xml->vbuf = vbuf;
xml->vbuf_inner = NULL;
xml->dummy[0] = '\0';
xml->dbuf_keep = sizeof(ACL_XML2);
xml->flag |= ACL_XML2_FLAG_MULTI_ROOT;
xml->mm_file = NULL;
xml->fd = ACL_FILE_INVALID;
xml->off = size - 1;
xml->block = size;
xml->iter_head = xml_iter_head;
xml->iter_next = xml_iter_next;
xml->iter_tail = xml_iter_tail;
xml->iter_prev = xml_iter_prev;
xml->iter_head = xml_iter_head;
xml->iter_next = xml_iter_next;
xml->iter_tail = xml_iter_tail;
xml->iter_prev = xml_iter_prev;
xml->id_table = acl_htable_create(100, 0);
xml->root = acl_xml2_node_alloc(xml);
xml->node_cnt = 1;
xml->id_table = acl_htable_create(100, 0);
xml->root = acl_xml2_node_alloc(xml);
xml->node_cnt = 1;
return xml;
}
int acl_xml2_free(ACL_XML2 *xml)
{
const char *myname = "acl_xml2_free";
int node_cnt = xml->node_cnt;
acl_htable_free(xml->id_table, NULL);
if (xml->fd != ACL_FILE_INVALID) {
acl_file_close(xml->fd);
xml->fd = ACL_FILE_INVALID;
}
#ifdef ACL_UNIX
if (xml->mm_addr != NULL && munmap(xml->mm_addr, xml->size) < 0)
acl_msg_error("%s(%d), %s: munmap error: %s",
__FILE__, __LINE__, myname, acl_last_serror());
#ifdef ACL_UNIX
if (xml->fd >= 0)
#else
if (xml->fd != ACL_FILE_INVALID)
#endif
acl_file_close(xml->fd);
if (xml->mm_file != NULL) {
acl_dbuf_pool_free(xml->dbuf, xml->mm_file);
xml->mm_file = NULL;
}
if (xml->vbuf_inner != NULL)
acl_vstring_free(xml->vbuf_inner);
if (xml->dbuf_inner != NULL)
acl_dbuf_pool_destroy(xml->dbuf_inner);
@ -642,12 +512,7 @@ void acl_xml2_reset(ACL_XML2 *xml)
if (xml->dbuf_inner != NULL)
acl_dbuf_pool_reset(xml->dbuf_inner, xml->dbuf_keep);
if (xml->fd != ACL_FILE_INVALID || xml->mm_file != NULL)
xml->len = xml->off + 1;
else
xml->len = xml->size;
xml->ptr = xml->addr;
ACL_VSTRING_RESET(xml->vbuf);
xml->root = acl_xml2_node_alloc(xml);
xml->depth = 0;
xml->node_cnt = 1;

View File

@ -14,6 +14,8 @@
#include "stdlib/acl_mystring.h"
#include "stdlib/acl_msg.h"
#include "stdlib/acl_sys_patch.h"
#include "stdlib/acl_vbuf.h"
#include "stdlib/acl_vstring.h"
#include "code/acl_xmlcode.h"
#include "xml/acl_xml2.h"
@ -35,6 +37,14 @@
#define SKIP_WHILE(cond, ptr) { while(*(ptr) && (cond)) (ptr)++; }
#define SKIP_SPACE(ptr) { while(IS_SPACE(*(ptr))) (ptr)++; }
#define STR acl_vstring_str
#define LEN ACL_VSTRING_LEN
#define END(x) acl_vstring_end((x)->vbuf)
#define ADD(x, ch) ACL_VSTRING_ADDCH((x)->vbuf, (ch))
#define APPEND(x, y) acl_vstring_strcat((x)->vbuf, (y))
#define TERM(x) ACL_VSTRING_TERMINATE((x)->vbuf)
#define NO_SPACE(x) acl_vbuf_eof(&((x)->vbuf->vbuf))
/* 状态机数据结构类型 */
struct XML_STATUS_MACHINE {
@ -45,8 +55,6 @@ struct XML_STATUS_MACHINE {
const char *(*callback) (ACL_XML2*, const char*);
};
#define MIN_LEN 2
static void xml_parse_check_self_closed(ACL_XML2 *xml)
{
if ((xml->curr_node->flag & ACL_XML2_F_LEAF) == 0) {
@ -115,14 +123,13 @@ static const char *xml_parse_left_em(ACL_XML2 *xml, const char *data)
data++;
} else {
if (xml->curr_node->meta[1] == '-') {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
if (xml->curr_node->ltag == xml->addr)
xml->curr_node->ltag = xml->ptr;
if (xml->curr_node->ltag == xml->dummy)
xml->curr_node->ltag = END(xml);
xml->len--;
*xml->ptr++ = '-';
ADD(xml, '-');
xml->curr_node->meta[1] = 0;
}
@ -139,6 +146,9 @@ static const char *xml_parse_cdata(ACL_XML2 *xml, const char *data)
int ch;
while ((ch = *data) != 0) {
if (NO_SPACE(xml))
return data;
data++;
if (ch == '>') {
@ -147,112 +157,48 @@ static const char *xml_parse_cdata(ACL_XML2 *xml, const char *data)
{
curr_node->status = ACL_XML2_S_MEND;
curr_node->text_size =
xml->ptr - curr_node->text;
if (xml->len > MIN_LEN) {
*xml->ptr++ = 0;
xml->len--;
}
END(xml) - curr_node->text;
ADD(xml, '\0');
return data;
}
if (curr_node->meta[0] == ']') {
if (xml->len > MIN_LEN) {
*xml->ptr++ = curr_node->meta[0];
xml->len--;
}
ADD(xml, curr_node->meta[0]);
curr_node->meta[0] = 0;
}
if (curr_node->meta[1] == ']') {
if (xml->len > MIN_LEN) {
*xml->ptr++ = curr_node->meta[1];
xml->len--;
}
ADD(xml, curr_node->meta[1]);
curr_node->meta[1] = 0;
}
} else if (ch == ']') {
if (curr_node->meta[0] == ']') {
if (curr_node->meta[1] == ']') {
if (xml->len < MIN_LEN)
return data;
*xml->ptr++ = ']';
xml->len--;
ADD(xml, ']');
} else
curr_node->meta[1] = ']';
} else if (curr_node->meta[1] == ']') {
curr_node->meta[0] = ']';
curr_node->meta[1] = 0;
if (xml->len < MIN_LEN)
return data;
*xml->ptr++ = ']';
xml->len--;
ADD(xml, ']');
} else
curr_node->meta[0] = ']';
} else if (curr_node->meta[0] == ']') {
if (xml->len < MIN_LEN)
return data;
*xml->ptr++ = ']';
xml->len--;
ADD(xml, ']');
curr_node->meta[0] = 0;
if (curr_node->meta[1] == ']') {
if (xml->len < MIN_LEN)
return data;
*xml->ptr++ = ']';
xml->len--;
ADD(xml, ']');
curr_node->meta[1] = 0;
}
} else {
if (xml->len < MIN_LEN)
return data;
*xml->ptr++ = ch;
xml->len--;
ADD(xml, ch);
}
}
*xml->ptr = 0;
TERM(xml);
return data;
}
static void cdata_prepare(ACL_XML2 *xml)
{
size_t cdata_len = sizeof("[CDATA[") - 1, len, max, i;
ACL_XML2_NODE *curr_node = xml->curr_node;
char *src, *dst;
if (xml->len <= MIN_LEN || curr_node->ltag_size < cdata_len)
return;
/* compute the max bytes for data copying */
max = xml->len - MIN_LEN;
len = curr_node->ltag_size - cdata_len;
if (len > max)
len = max;
src = curr_node->ltag + cdata_len; /* src is at the end of ltag */
curr_node->text = src + 1; /* one space for '\0' of ltag */
/* moving data reverse in the same memory won't override the data */
dst = src + len; /* one space after the data end */
src = dst - 1;
xml->ptr = dst + 1;
xml->len -= len;
for (i = 0; i < len; i++)
*dst-- = *src--;
/* terminate the ltag string */
curr_node->ltag_size = cdata_len;
curr_node->ltag[curr_node->ltag_size] = 0;
#if 0
if (xml->len < MIN_LEN)
return;
*xml->ptr++ = last_ch;
xml->len--;
#endif
}
#define CDATA_SIZE (sizeof("[CDATA[") - 1)
#define IS_CDATA(x) (*(x) == '[' \
&& (*(x + 1) == 'C' || *(x + 1) == 'c') \
@ -269,61 +215,35 @@ static const char *xml_parse_meta_tag(ACL_XML2 *xml, const char *data)
if (*data == 0)
return data;
if (xml->curr_node->ltag == xml->addr)
xml->curr_node->ltag = xml->ptr;
if (xml->curr_node->ltag == xml->dummy)
xml->curr_node->ltag = END(xml);
while ((ch = *data) != 0) {
#if 0
if (IS_SPACE(ch) || ch == '>') {
if (xml->len < MIN_LEN)
return data;
data++;
xml->curr_node->ltag_size =
xml->ptr - xml->curr_node->ltag;
if (IS_CDATA(xml->curr_node->ltag)) {
cdata_prepare(xml, ch);
xml->curr_node->status = ACL_XML2_S_CDATA;
xml->curr_node->flag |= ACL_XML2_F_CDATA;
} else {
if (xml->len < MIN_LEN)
return data;
*xml->ptr++ = 0;
xml->len--;
xml->curr_node->status = ACL_XML2_S_MTXT;
}
break;
}
#else
if (xml->ptr - xml->curr_node->ltag >= (ssize_t) CDATA_SIZE
if (END(xml) - xml->curr_node->ltag >= (ssize_t) CDATA_SIZE
&& IS_CDATA(xml->curr_node->ltag))
{
xml->curr_node->ltag_size =
xml->ptr - xml->curr_node->ltag;
cdata_prepare(xml);
END(xml) - xml->curr_node->ltag;
ADD(xml, '\0');
xml->curr_node->text = END(xml);
xml->curr_node->status = ACL_XML2_S_CDATA;
xml->curr_node->flag |= ACL_XML2_F_CDATA;
break;
} else if (IS_SPACE(ch) || ch == '>') {
xml->curr_node->ltag_size =
xml->ptr - xml->curr_node->ltag;
if (xml->len < MIN_LEN)
END(xml) - xml->curr_node->ltag;
if (NO_SPACE(xml))
return data;
ADD(xml, '\0');
data++;
*xml->ptr++ = 0;
xml->len--;
xml->curr_node->status = ACL_XML2_S_MTXT;
break;
}
#endif
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
ADD(xml, ch);
data++;
xml->len--;
*xml->ptr++ = ch;
}
return data;
@ -332,13 +252,12 @@ static const char *xml_parse_meta_tag(ACL_XML2 *xml, const char *data)
static char *xml_meta_attr_name(ACL_XML2_ATTR *attr, char *data)
{
int ch;
ACL_XML2 *xml = attr->node->xml;
SKIP_SPACE(data);
if (*data == 0)
return data;
if (attr->name == xml->addr)
if (attr->name == attr->node->xml->dummy)
attr->name = data;
while ((ch = *data) != 0) {
@ -370,7 +289,7 @@ static char *xml_meta_attr_value(ACL_XML2_ATTR *attr, char *data)
if (*data == 0)
return data;
if (attr->value == xml->addr)
if (attr->value == xml->dummy)
attr->value = data;
while ((ch = *data) != 0) {
@ -387,14 +306,13 @@ static char *xml_meta_attr_value(ACL_XML2_ATTR *attr, char *data)
data++;
}
if ((xml->flag & ACL_XML2_FLAG_XML_DECODE) && attr->value_size > 0
&& xml->len > 0)
{
if ((xml->flag & ACL_XML2_FLAG_XML_DECODE) && attr->value_size > 0) {
const char *ptr = attr->value;
attr->value = xml->ptr;
(void) acl_xml_decode2(ptr, &xml->ptr, &xml->len);
attr->value_size = xml->ptr - attr->value - 1;
attr->value = END(xml);
(void) acl_xml_decode(ptr, xml->vbuf);
attr->value_size = END(xml) - attr->value;
ADD(xml, '\0'); /* skip one byte */
}
return data;
@ -406,7 +324,7 @@ static void xml_meta_attr(ACL_XML2_NODE *node)
char *ptr;
int ch;
if (node->text == node->xml->addr || *node->text == 0)
if (node->text == node->xml->dummy || *node->text == 0)
return;
ptr = node->text;
@ -425,7 +343,7 @@ static void xml_meta_attr(ACL_XML2_NODE *node)
break;
}
node->text = node->xml->addr;
node->text = node->xml->dummy;
node->text_size = 0;
}
@ -433,58 +351,54 @@ static const char *xml_parse_meta_text(ACL_XML2 *xml, const char *data)
{
int ch;
if (xml->curr_node->text == xml->addr)
if (xml->curr_node->text == xml->dummy)
SKIP_SPACE(data);
if (*data == 0)
return data;
if (xml->curr_node->text == xml->addr)
xml->curr_node->text = xml->ptr;
if (xml->curr_node->text == xml->dummy)
xml->curr_node->text = END(xml);
while ((ch = *data) != 0) {
if (xml->curr_node->quote) {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
if (ch == xml->curr_node->quote)
xml->curr_node->quote = 0;
xml->len--;
*xml->ptr++ = ch;
ADD(xml, ch);
} else if (IS_QUOTE(ch)) {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
if (xml->curr_node->quote == 0)
xml->curr_node->quote = ch;
xml->len--;
*xml->ptr++ = ch;
ADD(xml, ch);
} else if (ch == '<') {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
xml->curr_node->nlt++;
xml->len--;
*xml->ptr++ = ch;
ADD(xml, ch);
} else if (ch != '>') {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
xml->len--;
*xml->ptr++ = ch;
ADD(xml, ch);
} else if (xml->curr_node->nlt == 0) {
char *last;
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
data++;
xml->len--;
xml->curr_node->text_size = xml->ptr -
xml->curr_node->text;
*xml->ptr++ = 0;
xml->curr_node->text_size =
END(xml) - xml->curr_node->text;
xml->curr_node->status = ACL_XML2_S_MEND;
ADD(xml, '\0');
data++;
if ((xml->curr_node->flag & ACL_XML2_F_META_QM) == 0)
break;
last = xml->ptr - 1;
last = END(xml) - 1;
while (last > xml->curr_node->text) {
if (*last == '?') {
*last = 0;
@ -500,11 +414,10 @@ static const char *xml_parse_meta_text(ACL_XML2 *xml, const char *data)
xml_meta_attr(xml->curr_node);
break;
} else {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
xml->curr_node->nlt--;
xml->len--;
*xml->ptr++ = ch;
ADD(xml, ch);
}
data++;
@ -512,14 +425,14 @@ static const char *xml_parse_meta_text(ACL_XML2 *xml, const char *data)
if (xml->curr_node->status == ACL_XML2_S_MEND
&& (xml->flag & ACL_XML2_FLAG_XML_DECODE)
&& xml->curr_node->text_size > 0 && xml->len > 0)
&& xml->curr_node->text_size > 0 && !NO_SPACE(xml))
{
const char *txt = xml->curr_node->text;
xml->curr_node->text = xml->ptr;
(void) acl_xml_decode2(txt, &xml->ptr, &xml->len);
xml->curr_node->text_size = xml->ptr
- xml->curr_node->text - 1;
xml->curr_node->text = END(xml);
(void) acl_xml_decode(txt, xml->vbuf);
xml->curr_node->text_size = END(xml) - xml->curr_node->text;
ADD(xml, '\0'); /* skip one byte */
}
return data;
@ -529,68 +442,60 @@ static const char *xml_parse_meta_comment(ACL_XML2 *xml, const char *data)
{
int ch;
if (xml->curr_node->text == xml->addr)
if (xml->curr_node->text == xml->dummy)
SKIP_SPACE(data);
if (*data == 0)
return data;
if (xml->curr_node->text == xml->addr)
xml->curr_node->text = xml->ptr;
if (xml->curr_node->text == xml->dummy)
xml->curr_node->text = END(xml);
while ((ch = *data) != 0) {
if (xml->curr_node->quote) {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
if (ch == xml->curr_node->quote)
xml->curr_node->quote = 0;
else {
xml->len--;
*xml->ptr++ = ch;
}
else
ADD(xml, ch);
} else if (IS_QUOTE(ch)) {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
if (xml->curr_node->quote == 0)
xml->curr_node->quote = ch;
else {
xml->len--;
*xml->ptr++ = ch;
}
else
ADD(xml, ch);
} else if (ch == '<') {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
xml->curr_node->nlt++;
xml->len--;
*xml->ptr++ = ch;
ADD(xml, ch);
} else if (ch == '>') {
if (xml->curr_node->nlt == 0
&& xml->curr_node->meta[0] == '-'
&& xml->curr_node->meta[1] == '-')
{
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
data++;
xml->len--;
xml->curr_node->text_size = xml->ptr -
xml->curr_node->text;
*xml->ptr++ = 0;
xml->curr_node->text_size =
END(xml) - xml->curr_node->text;
ADD(xml, '\0');
xml->curr_node->status = ACL_XML2_S_MEND;
break;
}
xml->curr_node->nlt--;
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
xml->len--;
*xml->ptr++ = ch;
ADD(xml, ch);
} else if (xml->curr_node->nlt > 0) {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
xml->len--;
*xml->ptr++ = ch;
ADD(xml, ch);
} else if (ch == '-') {
if (xml->curr_node->meta[0] != '-')
xml->curr_node->meta[0] = '-';
@ -598,24 +503,21 @@ static const char *xml_parse_meta_comment(ACL_XML2 *xml, const char *data)
xml->curr_node->meta[1] = '-';
} else {
if (xml->curr_node->meta[0] == '-') {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
xml->len--;
*xml->ptr++ = '-';
ADD(xml, '-');
xml->curr_node->meta[0] = 0;
}
if (xml->curr_node->meta[1] == '-') {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
xml->len--;
*xml->ptr++ = '-';
ADD(xml, '-');
xml->curr_node->meta[1] = 0;
}
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
xml->len--;
*xml->ptr++ = ch;
ADD(xml, ch);
}
data++;
@ -624,14 +526,14 @@ static const char *xml_parse_meta_comment(ACL_XML2 *xml, const char *data)
if (xml->curr_node->status == ACL_XML2_S_MEND
&& (xml->flag & ACL_XML2_FLAG_XML_DECODE)
&& xml->curr_node->text_size > 0
&& xml->len > 0)
&& !NO_SPACE(xml))
{
const char *txt = xml->curr_node->text;
xml->curr_node->text = xml->ptr;
(void) acl_xml_decode2(txt, &xml->ptr, &xml->len);
xml->curr_node->text_size = xml->ptr
- xml->curr_node->text - 1;
xml->curr_node->text = END(xml);
(void) acl_xml_decode(txt, xml->vbuf);
xml->curr_node->text_size = END(xml) - xml->curr_node->text;
ADD(xml, '\0'); /* skip one byte */
}
return data;
@ -648,55 +550,55 @@ static const char *xml_parse_left_tag(ACL_XML2 *xml, const char *data)
{
int ch;
if (xml->curr_node->ltag == xml->addr)
if (xml->curr_node->ltag == xml->dummy)
SKIP_SPACE(data);
if (*data == 0)
return data;
if (xml->curr_node->ltag == xml->addr)
xml->curr_node->ltag = xml->ptr;
if (xml->curr_node->ltag == xml->dummy)
xml->curr_node->ltag = END(xml);
while ((ch = *data) != 0) {
if (ch == '>') {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
xml->curr_node->ltag_size =
END(xml) - xml->curr_node->ltag;
ADD(xml, '\0');
data++;
xml->len--;
xml->curr_node->ltag_size = xml->ptr -
xml->curr_node->ltag;
*xml->ptr++ = 0;
xml_parse_check_self_closed(xml);
if ((xml->curr_node->flag & ACL_XML2_F_SELF_CL)
&& xml->curr_node->last_ch == '/')
{
size_t n = xml->curr_node->ltag_size;
if (n >= 2)
xml->curr_node->ltag[n - 2] = 0;
xml->curr_node->status = ACL_XML2_S_RGT;
if (xml->curr_node->ltag_size > 0) {
size_t n;
xml->curr_node->ltag_size--;
n = xml->curr_node->ltag_size;
xml->curr_node->ltag[n] = 0;
}
xml->curr_node->status = ACL_XML2_S_RGT;
} else
xml->curr_node->status = ACL_XML2_S_LGT;
break;
} else if (IS_SPACE(ch)) {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
data++;
xml->len--;
xml->curr_node->ltag_size = xml->ptr -
xml->curr_node->ltag;
*xml->ptr++ = 0;
xml->curr_node->ltag_size =
END(xml) - xml->curr_node->ltag;
ADD(xml, '\0');
xml->curr_node->status = ACL_XML2_S_ATTR;
xml->curr_node->last_ch = ch;
break;
} else {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
data++;
xml->len--;
*xml->ptr++ = ch;
ADD(xml, ch);
xml->curr_node->last_ch = ch;
}
}
@ -709,7 +611,7 @@ static const char *xml_parse_attr(ACL_XML2 *xml, const char *data)
int ch;
ACL_XML2_ATTR *attr = xml->curr_node->curr_attr;
if (attr == NULL || attr->name == xml->addr) {
if (attr == NULL || attr->name == xml->dummy) {
SKIP_SPACE(data);
SKIP_WHILE(*data == '=', data);
}
@ -728,11 +630,10 @@ static const char *xml_parse_attr(ACL_XML2 *xml, const char *data)
xml->curr_node->status = ACL_XML2_S_LGT;
xml->curr_node->curr_attr = NULL;
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
data++;
xml->len--;
*xml->ptr++ = 0;
ADD(xml, '\0');
return data;
}
@ -751,26 +652,24 @@ static const char *xml_parse_attr(ACL_XML2 *xml, const char *data)
if (attr == NULL) {
attr = acl_xml2_attr_alloc(xml->curr_node);
xml->curr_node->curr_attr = attr;
attr->name = xml->ptr;
attr->name = END(xml);
}
while ((ch = *data) != 0) {
xml->curr_node->last_ch = ch;
if (ch == '=') {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
data++;
xml->len--;
attr->name_size = xml->ptr - attr->name;
*xml->ptr++ = 0;
attr->name_size = END(xml) - attr->name;
ADD(xml, '\0');
xml->curr_node->status = ACL_XML2_S_AVAL;
break;
}
if (!IS_SPACE(ch)) {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
xml->len--;
*xml->ptr++ = ch;
ADD(xml, ch);
}
data++;
@ -784,7 +683,7 @@ static const char *xml_parse_attr_val(ACL_XML2 *xml, const char *data)
int ch;
ACL_XML2_ATTR *attr = xml->curr_node->curr_attr;
if (attr->value == xml->addr && !attr->quote) {
if (attr->value == xml->dummy && !attr->quote) {
SKIP_SPACE(data);
if (IS_QUOTE(*data))
attr->quote = *data++;
@ -793,62 +692,57 @@ static const char *xml_parse_attr_val(ACL_XML2 *xml, const char *data)
if (*data == 0)
return data;
if (attr->value == xml->addr)
attr->value = xml->ptr;
if (attr->value == xml->dummy)
attr->value = END(xml);
while ((ch = *data) != 0) {
if (attr->quote) {
if (ch == attr->quote) {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
data++;
xml->len--;
attr->value_size = xml->ptr - attr->value;
*xml->ptr++ = 0;
attr->value_size = END(xml) - attr->value;
ADD(xml, '\0');
xml->curr_node->status = ACL_XML2_S_ATTR;
xml->curr_node->last_ch = ch;
break;
}
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
xml->len--;
*xml->ptr++ = ch;
ADD(xml, ch);
xml->curr_node->last_ch = ch;
} else if (ch == '>') {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
data++;
xml->len--;
attr->value_size = xml->ptr - attr->value;
*xml->ptr++ = 0;
attr->value_size = END(xml) - attr->value;
ADD(xml, '\0');
xml_parse_check_self_closed(xml);
if ((xml->curr_node->flag & ACL_XML2_F_SELF_CL)
&& xml->curr_node->last_ch == '/')
{
if (attr->value_size >= 2)
attr->value[attr->value_size - 2] = 0;
if (--attr->value_size >= 0)
attr->value[attr->value_size] = 0;
xml->curr_node->status = ACL_XML2_S_RGT;
} else
xml->curr_node->status = ACL_XML2_S_LGT;
break;
} else if (IS_SPACE(ch)) {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
data++;
xml->len--;
attr->value_size = xml->ptr - attr->value;
*xml->ptr++ = 0;
attr->value_size = END(xml) - attr->value;
ADD(xml, '\0');
xml->curr_node->status = ACL_XML2_S_ATTR;
xml->curr_node->last_ch = ch;
break;
} else {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
xml->len--;
*xml->ptr++ = ch;
ADD(xml, ch);
xml->curr_node->last_ch = ch;
}
@ -861,14 +755,13 @@ static const char *xml_parse_attr_val(ACL_XML2 *xml, const char *data)
/* 当状态发生改变时,则说明属性值已经完毕 */
if ((xml->flag & ACL_XML2_FLAG_XML_DECODE) && attr->value_size > 1
&& xml->len > 0)
{
if ((xml->flag & ACL_XML2_FLAG_XML_DECODE) && attr->value_size > 1) {
const char *val = attr->value;
attr->value = xml->ptr;
(void) acl_xml_decode2(val, &xml->ptr, &xml->len);
attr->value_size = xml->ptr - attr->value - 1;
attr->value = END(xml);
(void) acl_xml_decode(val, xml->vbuf);
attr->value_size = END(xml) - attr->value;
ADD(xml, '\0'); /* skip one byte */
}
/* 将该标签ID号映射至哈希表中以便于快速查询 */
@ -904,59 +797,53 @@ static const char *xml_parse_text(ACL_XML2 *xml, const char *data)
{
int ch;
if (xml->curr_node->text == xml->addr)
if (xml->curr_node->text == xml->dummy)
SKIP_SPACE(data);
if (*data == 0)
return data;
if (xml->curr_node->text == xml->addr)
xml->curr_node->text = xml->ptr;
if (xml->curr_node->text == xml->dummy)
xml->curr_node->text = END(xml);
while ((ch = *data) != 0) {
if (ch == '<') {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
data++;
xml->len--;
xml->curr_node->text_size = xml->ptr
- xml->curr_node->text;
*xml->ptr++ = 0;
xml->curr_node->text_size =
END(xml) - xml->curr_node->text;
ADD(xml, '\0');
xml->curr_node->status = ACL_XML2_S_RLT;
break;
}
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
data++;
xml->len--;
*xml->ptr++ = ch;
ADD(xml, ch);
}
if (xml->curr_node->status == ACL_XML2_S_RLT
&& (xml->flag & ACL_XML2_FLAG_XML_DECODE)
&& xml->curr_node->text_size > 1
&& xml->len > 0)
&& !NO_SPACE(xml))
{
char *txt = xml->curr_node->text;
xml->curr_node->text = xml->ptr;
(void) acl_xml_decode2(txt, &xml->ptr, &xml->len);
xml->curr_node->text_size = xml->ptr
- xml->curr_node->text - 1;
/* xml->ptr pointer to the position after '\0', but we
* want to get the position before '\0', so subtract 2.
*/
txt = xml->ptr - 2;
xml->curr_node->text = END(xml);
(void) acl_xml_decode(txt, xml->vbuf);
xml->curr_node->text_size = END(xml) - xml->curr_node->text;
txt = END(xml) - 1;
while (txt >= xml->curr_node->text && IS_SPACE(*txt)) {
*txt-- = 0;
xml->curr_node->text_size--;
}
ADD(xml, '\0');
}
return data;
@ -977,12 +864,13 @@ static const char *xml_parse_right_lt(ACL_XML2 *xml, const char *data)
return data;
} else if ((xml->curr_node->flag & ACL_XML2_F_LEAF)) {
/* XXX: some error ? */
if (xml->len < MIN_LEN * 2)
if (NO_SPACE(xml))
return data;
xml->len--;
*xml->ptr++ = '<';
xml->len--;
*xml->ptr++ = *data++;
ADD(xml, '<');
if (NO_SPACE(xml))
return data;
ADD(xml, *data);
data++;
xml->curr_node->status = ACL_XML2_S_TXT;
return data;
@ -1021,13 +909,6 @@ static void update_children_depth(ACL_XML2_NODE *parent)
}
}
static void string_copy(char *to, const char *from)
{
while (*from)
*to++ = *from++;
*to = 0;
}
/* 查找与右标签相同的父节点 */
static int search_match_node(ACL_XML2 *xml)
{
@ -1041,8 +922,8 @@ static int search_match_node(ACL_XML2 *xml)
while (parent != xml->root) {
if (acl_strcasecmp(xml->curr_node->rtag, parent->ltag) == 0) {
parent->rtag = xml->ptr;
string_copy(xml->ptr, xml->curr_node->rtag);
parent->rtag = END(xml);
APPEND(xml, xml->curr_node->rtag);
parent->status = ACL_XML2_S_RGT;
xml->curr_node = parent;
break;
@ -1079,33 +960,32 @@ static const char *xml_parse_right_tag(ACL_XML2 *xml, const char *data)
/* after: "</" */
if (curr_node->rtag == xml->addr)
if (curr_node->rtag == xml->dummy)
SKIP_SPACE(data);
if (*data == 0)
return data;
if (curr_node->rtag == xml->addr)
curr_node->rtag = xml->ptr;
if (curr_node->rtag == xml->dummy)
curr_node->rtag = END(xml);
while ((ch = *data) != 0) {
if (ch == '>') {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
data++;
xml->len--;
curr_node->rtag_size = xml->ptr - curr_node->rtag;
*xml->ptr++ = 0;
curr_node->rtag_size = END(xml) - curr_node->rtag;
ADD(xml, '\0');
curr_node->status = ACL_XML2_S_RGT;
break;
}
if (!IS_SPACE(ch)) {
if (xml->len < MIN_LEN)
if (NO_SPACE(xml))
return data;
xml->len--;
*xml->ptr++ = ch;
ADD(xml, ch);
}
data++;
}
@ -1124,8 +1004,8 @@ static const char *xml_parse_right_tag(ACL_XML2 *xml, const char *data)
/* 如果节点标签名与开始标签名不匹配,
*
*/
curr_node->text = xml->ptr;
string_copy(xml->ptr, curr_node->rtag);
curr_node->text = END(xml);
APPEND(xml, curr_node->rtag);
/* 重新设置当前节点状态,以便于其可以找到 "</" */
curr_node->status = ACL_XML2_S_TXT;
@ -1203,7 +1083,7 @@ const char *acl_xml2_update(ACL_XML2 *xml, const char *data)
data = status_tab[xml->curr_node->status].callback(xml, data);
if (xml->len < MIN_LEN && acl_xml2_mmap_extend(xml) == 0) {
if (NO_SPACE(xml)) {
acl_msg_warn("%s(%d), %s: space not enougth!",
__FILE__, __LINE__, myname);
break;

View File

@ -272,38 +272,23 @@ int acl_xml2_removeElementAttr(ACL_XML2_NODE *node, const char *name)
/***************************************************************************/
#define MIN 1
static const char *string_copy(const char *in, ACL_XML2 *xml)
{
if (xml->len < MIN && acl_xml2_mmap_extend(xml) < MIN)
return in;
while (*in != 0 && xml->len > MIN) {
*xml->ptr++ = *in++;
xml->len--;
if (xml->len < MIN && acl_xml2_mmap_extend(xml) < MIN)
return in;
}
if (xml->len > MIN || acl_xml2_mmap_extend(xml) > MIN) {
*xml->ptr++ = 0;
xml->len--;
}
return in;
}
#define STR acl_vstring_str
#define LEN ACL_VSTRING_LEN
#define END(x) acl_vstring_end((x)->vbuf)
#define ADD(x, ch) ACL_VSTRING_ADDCH((x)->vbuf, (ch))
#define APPEND(x, y) acl_vstring_strcat((x)->vbuf, (y))
#define TERM(x) ACL_VSTRING_TERMINATE((x)->vbuf)
#define NO_SPACE(x) acl_vbuf_eof(&((x)->vbuf->vbuf))
void acl_xml2_node_set_text(ACL_XML2_NODE *node, const char *text)
{
if (text == NULL || *text == 0)
return;
node->text = node->xml->ptr;
string_copy(text, node->xml);
node->text_size = node->xml->ptr - node->text ;
if (node->text_size > 0)
node->text_size--;
node->text = END(node->xml);
APPEND(node->xml, text);
node->text_size = END(node->xml) - node->text;
ADD(node->xml, '\0');
}
ACL_XML2_NODE *acl_xml2_create_node(ACL_XML2 *xml, const char* tag,
@ -313,18 +298,16 @@ ACL_XML2_NODE *acl_xml2_create_node(ACL_XML2 *xml, const char* tag,
acl_assert(tag && *tag);
node->ltag = xml->ptr;
string_copy(tag, xml);
node->ltag_size = xml->ptr - node->ltag;
if (node->ltag_size > 0)
node->ltag_size--;
node->ltag = END(xml);
APPEND(xml, tag);
node->ltag_size = END(xml) - node->ltag;
ADD(xml, '\0');
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--;
node->text = END(xml);
APPEND(xml, text);
node->text_size = END(xml) - node->text;
ADD(xml, '\0');
}
return node;
@ -336,18 +319,17 @@ ACL_XML2_ATTR *acl_xml2_node_add_attr(ACL_XML2_NODE *node, const char *name,
ACL_XML2_ATTR *attr = acl_xml2_attr_alloc(node);
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--;
attr->name = END(node->xml);
APPEND(node->xml, name);
attr->name_size = END(node->xml) - attr->name;
ADD(node->xml, '\0');
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--;
attr->value = END(node->xml);
APPEND(node->xml, value);
attr->value_size = END(node->xml) - attr->value;
ADD(node->xml, '\0');
}
return attr;
@ -373,26 +355,23 @@ ACL_XML2_ATTR *acl_xml2_addElementAttr(ACL_XML2_NODE *node,
ACL_XML2_ATTR *attr = acl_xml2_getElementAttr(node, name);
if (attr) {
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--;
attr->value = END(node->xml);
APPEND(node->xml, value);
attr->value_size = END(node->xml) - attr->value;
ADD(node->xml, '\0');
return attr;
}
attr = acl_xml2_attr_alloc(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->name = END(node->xml);
APPEND(node->xml, name);
attr->name_size = END(node->xml) - attr->name;
ADD(node->xml, '\0');
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--;
attr->value = END(node->xml);
APPEND(node->xml, value);
attr->value_size = END(node->xml) - attr->value;
ADD(node->xml, '\0');
acl_array_append(node->attr_list, attr);
@ -401,56 +380,18 @@ ACL_XML2_ATTR *acl_xml2_addElementAttr(ACL_XML2_NODE *node,
/***************************************************************************/
static const char *escape_append(ACL_XML2 *xml, const char *in, int quoted)
static void escape_append(ACL_XML2 *xml, const char *in, int quoted)
{
const char *next = in, *last = in;
size_t len = strlen(in);
if (quoted)
ADD(xml, '"');
if (xml->len < MIN && acl_xml2_mmap_extend(xml) < MIN)
return next;
if (in && *in)
(void) acl_xml_encode(in, xml->vbuf);
if (quoted) {
*xml->ptr++ = '"';
xml->len--;
}
if (quoted)
ADD(xml, '"');
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 < MIN && acl_xml2_mmap_extend(xml) < MIN)
return next;
if (quoted) {
*xml->ptr++ = '"';
xml->len--;
}
if (xml->len >= MIN)
*xml->ptr = 0;
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;
TERM(xml);
}
const char *acl_xml2_build(ACL_XML2 *xml)
@ -458,154 +399,89 @@ const char *acl_xml2_build(ACL_XML2 *xml)
ACL_XML2_ATTR *attr;
ACL_XML2_NODE *node;
ACL_ITER iter1, iter2;
char *res = xml->ptr;
if (xml->len < MIN)
return xml->addr;
/* reserve one space for the last '\0 */
xml->len--;
char *res = END(xml);
acl_foreach(iter1, xml) {
CHECK_SPACE(xml);
if (NO_SPACE(xml))
break;
node = (ACL_XML2_NODE*) iter1.data;
if (ACL_XML2_IS_CDATA(node)) {
mem_copy(xml, "<![CDATA[");
CHECK_SPACE(xml);
if (node->text_size > 0) {
mem_copy(xml, node->text);
CHECK_SPACE(xml);
}
APPEND(xml, "<![CDATA[");
if (node->text_size > 0)
APPEND(xml, node->text);
} else if (ACL_XML2_IS_COMMENT(node)) {
mem_copy(xml, "<!--");
CHECK_SPACE(xml);
mem_copy(xml, node->text);
CHECK_SPACE(xml);
APPEND(xml, "<!--");
if (node->text_size > 0)
APPEND(xml, node->text);
} else if ((node->flag & ACL_XML2_F_META_QM)) {
mem_copy(xml, "<?");
CHECK_SPACE(xml);
mem_copy(xml, node->ltag);
CHECK_SPACE(xml);
APPEND(xml, "<?");
if (node->ltag_size > 0)
APPEND(xml, node->ltag);
} else if ((node->flag & ACL_XML2_F_META_EM)) {
mem_copy(xml, "<!");
CHECK_SPACE(xml);
APPEND(xml, "<!");
if (node->ltag_size > 0)
APPEND(xml, node->ltag);
mem_copy(xml, node->ltag);
CHECK_SPACE(xml);
ADD(xml, ' ');
*xml->ptr++ = ' ';
xml->len--;
CHECK_SPACE(xml);
if (node->text_size > 0) {
mem_copy(xml, node->text);
CHECK_SPACE(xml);
}
if (node->text_size > 0)
APPEND(xml, node->text);
} else {
*xml->ptr++ = '<';
xml->len--;
CHECK_SPACE(xml);
mem_copy(xml, node->ltag);
CHECK_SPACE(xml);
ADD(xml, '<');
if (node->ltag_size > 0)
APPEND(xml, node->ltag);
}
acl_foreach(iter2, node->attr_list) {
attr = (ACL_XML2_ATTR*) iter2.data;
*xml->ptr++ = ' ';
xml->len--;
CHECK_SPACE(xml);
mem_copy(xml, attr->name);
CHECK_SPACE(xml);
*xml->ptr++ = '=';
xml->len--;
CHECK_SPACE(xml);
ADD(xml, ' ');
APPEND(xml, attr->name);
ADD(xml, '=');
escape_append(xml, attr->value, 1);
CHECK_SPACE(xml);
}
if (acl_ring_size(&node->children) > 0) {
*xml->ptr++ = '>';
xml->len--;
CHECK_SPACE(xml);
ADD(xml, '>');
if (node->text_size > 0) {
if (node->text_size > 0)
escape_append(xml, node->text, 0);
CHECK_SPACE(xml);
}
continue;
}
if (ACL_XML2_IS_CDATA(node)) {
mem_copy(xml, "]]>");
CHECK_SPACE(xml);
APPEND(xml, "]]>");
} else if (ACL_XML2_IS_COMMENT(node)) {
mem_copy(xml, "-->");
CHECK_SPACE(xml);
APPEND(xml, "-->");
} else if (node->flag & ACL_XML2_F_META_QM) {
mem_copy(xml, "?>");
CHECK_SPACE(xml);
APPEND(xml, "?>");
} else if (node->flag & ACL_XML2_F_META_EM) {
*xml->ptr++ = '>';
xml->len--;
CHECK_SPACE(xml);
ADD(xml, '>');
} else if (node->text_size == 0) {
mem_copy(xml, "></");
CHECK_SPACE(xml);
APPEND(xml, "></");
escape_append(xml, node->ltag, 0);
CHECK_SPACE(xml);
*xml->ptr++ = '>';
xml->len--;
CHECK_SPACE(xml);
ADD(xml, '>');
} else {
*xml->ptr++ = '>';
xml->len--;
CHECK_SPACE(xml);
ADD(xml, '>');
escape_append(xml, node->text, 0);
CHECK_SPACE(xml);
mem_copy(xml, "</");
CHECK_SPACE(xml);
APPEND(xml, "</");
escape_append(xml, node->ltag, 0);
CHECK_SPACE(xml);
*xml->ptr++ = '>';
xml->len--;
CHECK_SPACE(xml);
ADD(xml, '>');
}
while (node->parent != node->xml->root
&& acl_xml2_node_next(node) == NULL)
{
mem_copy(xml, "</");
CHECK_SPACE(xml);
APPEND(xml, "</");
escape_append(xml, node->parent->ltag, 0);
CHECK_SPACE(xml);
*xml->ptr++ = '>';
xml->len--;
CHECK_SPACE(xml);
ADD(xml, '>');
node = node->parent;
}
}
*xml->ptr = 0;
TERM(xml);
return res;
}

View File

@ -1,6 +1,23 @@
修改历史列表:
-----------------------------------------------------------------------
403) 2016.1.31
403.1) feature: string 类支持内存映射文件方式管理内存,从而可以支持更多的内存空间
403.2) samples: string/string5, 用于测试内存映射文件
403.3) feature: xml/xml1/xml2 支持使用 dbuf_guard 会话内存池来创建临时对象,
从而提升了内存使用效率
402) 2016.1.27
402.1) bugfix: charset_conv 类中的方法 update当 m_addInvalid 为 false应该
过滤掉无效的字符
402.2) performance: mime_state_parse.cpp 中的 mime_bound_body 函数优化了处理
大邮件的性能
401) 2016.1.22
401.1) feature: HttpServlet 类增加了请求/响应成员函数(req_/res_),以便于将
读取 HTTP 请求数据体分离
401.2) bugfix: connect_manager 类少两个设置函数 set_check_inter/set_idle_ttl
400) 2016.1.15
400.1) feature: redis 库增加了出错日志输出,便于运行时进行信息调试

View File

@ -1,16 +1,15 @@
#pragma once
#include "acl_cpp/acl_cpp_define.hpp"
#include <list>
#include "acl_cpp/stdlib/dbuf_pool.hpp"
#include "acl_cpp/http/http_type.hpp"
namespace acl {
class dbuf_pool;
/**
* http cookie
*/
class ACL_CPP_API HttpCookie
class ACL_CPP_API HttpCookie : public dbuf_obj
{
public:
/**
@ -18,23 +17,23 @@ public:
* @param name {const char*} cookie > 0
* @param value {const char*} cookie 0
*
* @param dbuf {dbuf_pool*}
* @param dbuf {dbuf_guard*}
*/
HttpCookie(const char* name, const char* value, dbuf_pool* dbuf = NULL);
HttpCookie(const char* name, const char* value, dbuf_guard* dbuf = NULL);
/**
* 使使 setCookie cookie
* @param dbuf {dbuf_pool*}
* @param dbuf {dbuf_guard*}
*/
HttpCookie(dbuf_pool* dbuf = NULL);
HttpCookie(dbuf_guard* dbuf = NULL);
/**
*
* @param cookie {const HttpCookie*} NULL
*
* @param dbuf {dbuf_pool*}
* @param cookie {const HttpCookie*} NULL
* @param dbuf {dbuf_guard*}
*/
HttpCookie(const HttpCookie* cookie, dbuf_pool* dbuf = NULL);
HttpCookie(const HttpCookie* cookie, dbuf_guard* dbuf = NULL);
/**
*
*/
@ -155,14 +154,18 @@ public:
const std::list<HTTP_PARAM*>& getParams(void) const;
private:
dbuf_pool* dbuf_internal_;
dbuf_pool* dbuf_;
dbuf_guard* dbuf_internal_;
dbuf_guard* dbuf_;
char dummy_[1];
char* name_;
char* value_;
std::list<HTTP_PARAM*> params_;
bool splitNameValue(char* data, HTTP_PARAM* param);
protected:
// HttpCookie(HttpCookie&) {}
// HttpCookie(const HttpCookie&) {}
};
} // namespace acl end

View File

@ -5,9 +5,8 @@
namespace acl {
class dbuf_pool;
class socket_stream;
class session;
class socket_stream;
class HttpServletRequest;
class HttpServletResponse;
@ -85,10 +84,21 @@ public:
* @return {HttpServlet&}
*/
HttpServlet& setParseBodyLimit(int length);
/**
* HttpServlet HTTP doXXX
* @return {bool} false
* true /
*
*/
bool start(void);
/**
* HttpServlet HTTP doXXX
* @return {bool}
* HttpServlet HTTP doXXX
* start start /
*
* @return {bool} false
*
*/
bool doRun();
@ -224,11 +234,13 @@ public:
return false;
}
protected:
HttpServletRequest* req_;
HttpServletResponse* res_;
private:
dbuf_pool* dbuf_;
session* session_;
session* session_ptr_;
size_t reserve_size_;
socket_stream* stream_;
bool first_;
char local_charset_[32];
@ -237,7 +249,6 @@ private:
int parse_body_limit_;
void init();
bool doRun(dbuf_pool* dbuf);
};
} // namespace acl

View File

@ -8,7 +8,7 @@
namespace acl {
class dbuf_pool;
class dbuf_guard;
class istream;
class ostream;
class socket_stream;
@ -46,12 +46,10 @@ public:
* @param body_limit {int} POST
* MIME
* on false
* @param dbuf {dbuf_pool*}
*/
HttpServletRequest(HttpServletResponse& res, session& store,
socket_stream& stream, const char* charset = NULL,
bool body_parse = true, int body_limit = 102400,
dbuf_pool* dbuf = NULL);
bool body_parse = true, int body_limit = 102400);
~HttpServletRequest(void);
/**
@ -330,8 +328,8 @@ public:
void sprint_header(string& out, const char* prompt);
private:
dbuf_pool* dbuf_internal_;
dbuf_pool* dbuf_;
dbuf_guard* dbuf_internal_;
dbuf_guard* dbuf_;
http_request_error_t req_error_;
char cookie_name_[64];
HttpServletResponse& res_;

View File

@ -3,14 +3,13 @@
namespace acl {
class dbuf_pool;
class dbuf_guard;
class string;
class ostream;
class socket_stream;
class http_header;
class http_client;
class HttpCookie;
class HttpServlet;
class HttpServletRequest;
/**
@ -23,9 +22,8 @@ public:
/**
*
* @param stream {socket_stream&}
* @param dbuf {dbuf_pool*}
*/
HttpServletResponse(socket_stream& stream, dbuf_pool* dbuf = NULL);
HttpServletResponse(socket_stream& stream);
~HttpServletResponse(void);
/**
@ -245,8 +243,8 @@ public:
}
private:
dbuf_pool* dbuf_internal_;
dbuf_pool* dbuf_;
dbuf_guard* dbuf_internal_;
dbuf_guard* dbuf_;
socket_stream& stream_; // 客户端连接流
HttpServletRequest* request_; // http 请求对象
http_client* client_; // http 响应流对象

View File

@ -1,5 +1,6 @@
#pragma once
#include "acl_cpp/acl_cpp_define.hpp"
#include "acl_cpp/stdlib//dbuf_pool.hpp"
#include <map>
namespace acl {
@ -9,7 +10,7 @@ class session;
/**
* HttpSession memcached
*/
class ACL_CPP_API HttpSession
class ACL_CPP_API HttpSession : public dbuf_obj
{
public:
/**

View File

@ -1,6 +1,7 @@
#pragma once
#include "acl_cpp/acl_cpp_define.hpp"
#include <list>
#include "acl_cpp/stdlib/dbuf_pool.hpp"
#include "acl_cpp/http/http_type.hpp"
struct HTTP_HDR_RES;
@ -8,21 +9,20 @@ struct HTTP_HDR_ENTRY;
namespace acl {
class dbuf_pool;
class string;
class HttpCookie;
/**
* HTTP
*/
class ACL_CPP_API http_header
class ACL_CPP_API http_header : public dbuf_obj
{
public:
/**
*
* @param dbuf {dbuf_pool*}
* @param dbuf {dbuf_guard*}
*/
http_header(dbuf_pool* dbuf = NULL);
http_header(dbuf_guard* dbuf = NULL);
/**
* HTTP
@ -37,16 +37,16 @@ public:
* add_param
*
* add_param
* @param dbuf {dbuf_pool*}
* @param dbuf {dbuf_guard*}
*/
http_header(const char* url, dbuf_pool* dbuf = NULL);
http_header(const char* url, dbuf_guard* dbuf = NULL);
/**
* HTTP
* @param status {int} 1xx, 2xx, 3xx, 4xx, 5xx
* @param dbuf {dbuf_pool*}
* @param dbuf {dbuf_guard*}
*/
http_header(int status, dbuf_pool* dbuf = NULL);
http_header(int status, dbuf_guard* dbuf = NULL);
virtual ~http_header(void);
@ -386,8 +386,8 @@ public:
}
private:
dbuf_pool* dbuf_internal_;
dbuf_pool* dbuf_;
dbuf_guard* dbuf_internal_;
dbuf_guard* dbuf_;
//char* domain_; // HTTP 服务器域名
//unsigned short port_; // HTTP 服务器端口
char* url_; // HTTP 请求的 URL

View File

@ -2,6 +2,7 @@
#include "acl_cpp/acl_cpp_define.hpp"
#include <vector>
#include <list>
#include "acl_cpp/stdlib/dbuf_pool.hpp"
#include "acl_cpp/stdlib/string.hpp"
#include "acl_cpp/mime/mime_attach.hpp"
#include "acl_cpp/http/http_type.hpp"
@ -50,7 +51,9 @@ public:
* @return {const char*} NULL
*/
const char* get_value(void) const;
protected:
private:
http_mime_t mime_type_;
char* param_value_;
@ -64,7 +67,7 @@ private:
* http mime 使
* update true
*/
class ACL_CPP_API http_mime
class ACL_CPP_API http_mime : public dbuf_obj
{
public:
/**
@ -112,10 +115,10 @@ public:
*
*/
const http_mime_node* get_node(const char* name) const;
protected:
private:
char* boundary_;
char* save_path_;
string boundary_;
string save_path_;
off_t off_;
MIME_STATE* mime_state_;
std::list<http_mime_node*> mime_nodes_;

View File

@ -1,6 +1,7 @@
#pragma once
#include "acl_cpp/acl_cpp_define.hpp"
#include <map>
#include "acl_cpp/stdlib/dbuf_pool.hpp"
#include "acl_cpp/stdlib/string.hpp"
namespace acl {
@ -30,7 +31,7 @@ public:
/**
* session 使 memcached session
*/
class ACL_CPP_API session
class ACL_CPP_API session : public dbuf_obj
{
public:
/**

View File

@ -1,5 +1,6 @@
#pragma once
#include "acl_cpp/acl_cpp_define.hpp"
#include "acl_cpp/stdlib/noncopyable.hpp"
#include <vector>
struct ACL_DBUF_POOL;
@ -206,7 +207,7 @@ private:
* dbuf_pool
* dbuf_pool
*/
class ACL_CPP_API dbuf_guard
class ACL_CPP_API dbuf_guard : public noncopyable
{
public:
/**
@ -499,9 +500,6 @@ private:
// 扩充 objs_ 数组对象的空间
void extend_objs();
// 禁止引用拷贝
dbuf_guard(dbuf_guard&) {}
};
/**

View File

@ -2,6 +2,7 @@
#include "acl_cpp/acl_cpp_define.hpp"
#include <list>
#include <vector>
#include "acl_cpp/stdlib/dbuf_pool.hpp"
#include "acl_cpp/stdlib/pipe_stream.hpp"
struct ACL_JSON_NODE;
@ -23,7 +24,7 @@ class json;
/**
* json json.create_node()
*/
class ACL_CPP_API json_node
class ACL_CPP_API json_node : public dbuf_obj
{
public:
/**
@ -367,7 +368,7 @@ private:
void prepare_iter(void);
};
class ACL_CPP_API json : public pipe_stream
class ACL_CPP_API json : public pipe_stream, public dbuf_obj
{
public:
/**

View File

@ -48,6 +48,17 @@ public:
* @param n {size_t} s
*/
string(const void* s, size_t n);
#if !defined(_WIN32) && !defined(_WIN64)
/**
*
* @param fd {int}
* @param max {size_t}
* @param n {size_t}
*/
string(int fd, size_t max, size_t n);
#endif
virtual ~string(void);
/**

View File

@ -2,6 +2,7 @@
#include "acl_cpp/acl_cpp_define.hpp"
#include <vector>
#include <list>
#include "acl_cpp/stdlib/dbuf_pool.hpp"
#include "acl_cpp/stdlib/string.hpp"
#include "acl_cpp/stdlib/pipe_stream.hpp"
@ -20,7 +21,7 @@ namespace acl {
class xml;
class xml_node;
class ACL_CPP_API xml_attr
class ACL_CPP_API xml_attr : public dbuf_obj
{
public:
/**
@ -46,7 +47,7 @@ protected:
xml_node* node_;
};
class ACL_CPP_API xml_node
class ACL_CPP_API xml_node : public dbuf_obj
{
public:
/**
@ -269,6 +270,7 @@ public:
protected:
friend class xml;
friend class dbuf_guard;
/**
* xml
@ -289,7 +291,7 @@ protected:
class string;
class ACL_CPP_API xml : public pipe_stream
class ACL_CPP_API xml : public pipe_stream, public dbuf_obj
{
public:
xml(void);
@ -475,12 +477,13 @@ public:
virtual void clear(void);
protected:
dbuf_guard dbuf_;
std::vector<xml_node*> elements_;
string* buf_;
//bool dummyRootAdded_;
ACL_TOKEN* m_pTokenTree;
std::list<xml_node*> nodes_tmp_;
//std::list<xml_node*> nodes_tmp_;
};
} // namespace acl

View File

@ -175,6 +175,7 @@ public:
protected:
friend class xml1;
friend class dbuf_guard;
/**
* xml

View File

@ -131,6 +131,7 @@ public:
protected:
friend class xml2;
friend class dbuf_guard;
xml2_node(xml* xml_ptr, ACL_XML2_NODE* node);
~xml2_node(void);
@ -149,56 +150,44 @@ class fstream;
class ACL_CPP_API xml2 : public xml
{
public:
/**
* 使 xml
* @param addr {char*}
*
* @param size {size_t} addr
*
* @param data {const char*}
*/
xml2(char* addr, size_t size, const char* data = NULL);
/**
* 使 xml
* @param filepath {const char*}
* @param size {size_t}
* @param max_len {size_t}
*
* @param data {const char*}
* @param block {size_t}
* @param keep_open {bool}
*
* @param init_len {size_t}
*/
xml2(const char* filepath, size_t size, const char* data = NULL,
size_t block = 8192, bool keep_open = true);
xml2(const char* filepath, size_t max_len, const char* data = NULL,
size_t init_len = 8192);
/**
* 使 xml
* @param fp {fstream&} xml
* fp xml
* @param size {size_t}
* @param max_len {size_t}
*
* @param data {const char*}
* @param block {size_t}
* @param init_len {size_t}
*/
xml2(fstream& fp, size_t size, const char* data = NULL,
size_t block = 8192);
xml2(fstream& fp, size_t max_len, const char* data = NULL,
size_t init_len = 8192);
/**
* 使 xml
* @param fd {ACL_FILE_HANDLE} xml
* fp xml
* @param size {size_t}
* @param max_len {size_t}
*
* @param data {const char*}
* @param block {size_t}
* @param init_len {size_t}
*/
#if defined(_WIN32) || defined(_WIN64)
xml2(void* fd, size_t size, const char* data = NULL,
size_t block = 8192);
xml2(void* fd, size_t max_len, const char* data = NULL,
size_t init_len = 8192);
#else
xml2(int fd, size_t size, const char* data = NULL,
size_t block = 8192);
xml2(int fd, size_t max_len, const char* data = NULL,
size_t init_len = 8192);
#endif
~xml2(void);

View File

@ -250,7 +250,10 @@ static void mime_test1(acl::mime& mime, const char* path, bool htmlFirst)
for (; cit != attaches.end(); cit++)
{
buf = "./var/";
buf << (*cit)->get_filename();
const char* filename = (*cit)->get_filename();
if (filename == NULL)
continue;
buf << filename;
acl::string attach_name;
acl::rfc2047 rfc2047;
@ -448,6 +451,7 @@ int main(int argc, char* argv[])
bool htmlFirst = false;
acl::string path("test.eml");
acl::string cmd("test1");
acl::log::stdout_open(true);
while ((ch = (char) getopt(argc, argv, "hst:f:")) > 0)
{

View File

@ -0,0 +1,124 @@
#!/bin/sh
./mime -s -t test1 -f test1.eml
diff test1.eml var/test1.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test2.eml
diff test2.eml var/test2.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test3.eml
diff test3.eml var/test3.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test4.eml
diff test4.eml var/test4.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test5.eml
diff test5.eml var/test5.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test6.eml
diff test6.eml var/test6.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test7.eml
diff test7.eml var/test7.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test8.eml
diff test8.eml var/test8.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test9.eml
diff test8.eml var/test8.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test10.eml
diff test10.eml var/test10.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test11.eml
diff test11.eml var/test11.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test12.eml
diff test12.eml var/test12.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test13.eml
diff test13.eml var/test13.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test14.eml
diff test14.eml var/test14.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test15.eml
diff test15.eml var/test15.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test16.eml
diff test16.eml var/test16.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test17.eml
diff test17.eml var/test17.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test18.eml
diff test18.eml var/test18.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test19.eml
diff test19.eml var/test19.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test21.eml
diff test21.eml var/test21.eml
echo ""
echo "Enter any key to continue ..."
read tmp
./mime -s -t test1 -f test22.eml
diff test22.eml var/test22.eml

View File

@ -379,6 +379,9 @@ int main(int argc, char* argv[])
rfc2047_test(rfc2047, s10);
/////////////////////////////////////////////////////////////////////
const char* s11 = "=?utf-8?B?57rnur/kuIrmg4XlhrXnu5/orqE=?=";
rfc2047_test(rfc2047, s11);
getchar();
return (0);

View File

@ -4,8 +4,12 @@ all:
@(cd string1; make)
@(cd string2; make)
@(cd string3; make)
@(cd string4; make)
@(cd string5; make)
clean:
@(cd string1; make clean)
@(cd string2; make clean)
@(cd string3; make clean)
@(cd string4; make clean)
@(cd string5; make clean)

View File

@ -0,0 +1,3 @@
base_path = ../../..
PROG = string
include ../../Makefile.in

View File

@ -0,0 +1,120 @@
#include "lib_acl.h"
#include "acl_cpp/lib_acl.hpp"
#include <stdio.h>
#include <string>
static void test(acl::string& buf)
{
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
buf += "hello world!";
}
static void test_mmap(int max)
{
const char* filename = "local.map";
acl::fstream fp;
if (fp.open(filename, O_RDWR | O_CREAT | O_TRUNC, 0600) == false)
{
printf("open %s error %s\r\n", filename, acl::last_serror());
return;
}
size_t max_len = 1024 * 1024 * 500, init_len = 4096;
acl::string buf(fp.file_handle(), max_len, init_len);
ACL_METER_TIME(">> begin acl::string");
for (int i = 0; i < max; i++)
{
test(buf);
}
ACL_METER_TIME(">> end acl::string");
}
static void test_mem(int max)
{
size_t max_len = 1024 * 1024 * 500, init_len = 4096;
acl::string buf(init_len);
buf.set_max(max_len);
ACL_METER_TIME(">> begin acl::string");
for (int i = 0; i < max; i++)
{
test(buf);
}
ACL_METER_TIME(">> end acl::string");
}
static void usage(const char* procname)
{
printf("usage: %s -h [help] -m [use_mmap] -n max_count\r\n", procname);
}
int main(int argc, char* argv[])
{
bool use_mmap = false;
int ch, max = 100000;
while ((ch = getopt(argc, argv, "hmn:")) > 0)
{
switch (ch)
{
case 'h':
usage(argv[0]);
return 0;
case 'm':
use_mmap = true;
break;
case 'n':
max = atoi(optarg);
break;
default:
break;
}
}
if (use_mmap)
test_mmap(max);
else
test_mem(max);
return (0);
}

View File

@ -0,0 +1,3 @@
#!/bin/sh
valgrind --tool=memcheck --leak-check=yes --show-reachable=yes -v ./string -m

View File

@ -14,6 +14,8 @@ connect_manager::connect_manager()
, service_idx_(0)
, stat_inter_(1)
, retry_inter_(1)
, idle_ttl_(-1)
, check_inter_(-1)
, monitor_(NULL)
{
}
@ -79,6 +81,16 @@ void connect_manager::set_retry_inter(int n)
lock_.unlock();
}
void connect_manager::set_check_inter(int n)
{
check_inter_ = n;
}
void connect_manager::set_idle_ttl(time_t ttl)
{
idle_ttl_ = ttl;
}
void connect_manager::init(const char* default_addr, const char* addr_list,
size_t count, int conn_timeout /* = 30 */, int rw_timeout /* = 30 */)
{

View File

@ -8,7 +8,7 @@ namespace acl
{
HttpCookie::HttpCookie(const char* name, const char* value,
dbuf_pool* dbuf /* = NULL */)
dbuf_guard* dbuf /* = NULL */)
{
if (dbuf != NULL)
{
@ -17,7 +17,7 @@ HttpCookie::HttpCookie(const char* name, const char* value,
}
else
{
dbuf_internal_ = new dbuf_pool;
dbuf_internal_ = new dbuf_guard;
dbuf_ = dbuf_internal_;
}
@ -27,7 +27,7 @@ HttpCookie::HttpCookie(const char* name, const char* value,
dummy_[0] = 0;
}
HttpCookie::HttpCookie(dbuf_pool* dbuf /* = NULL */)
HttpCookie::HttpCookie(dbuf_guard* dbuf /* = NULL */)
{
if (dbuf != NULL)
{
@ -36,7 +36,7 @@ HttpCookie::HttpCookie(dbuf_pool* dbuf /* = NULL */)
}
else
{
dbuf_internal_ = new dbuf_pool;
dbuf_internal_ = new dbuf_guard;
dbuf_ = dbuf_internal_;
}
@ -45,7 +45,7 @@ HttpCookie::HttpCookie(dbuf_pool* dbuf /* = NULL */)
dummy_[0] = 0;
}
HttpCookie::HttpCookie(const HttpCookie* cookie, dbuf_pool* dbuf /* = NULL */)
HttpCookie::HttpCookie(const HttpCookie* cookie, dbuf_guard* dbuf /* = NULL */)
{
if (dbuf != NULL)
{
@ -54,11 +54,14 @@ HttpCookie::HttpCookie(const HttpCookie* cookie, dbuf_pool* dbuf /* = NULL */)
}
else
{
dbuf_internal_ = new dbuf_pool;
dbuf_internal_ = new dbuf_guard;
dbuf_ = dbuf_internal_;
}
dummy_[0] = 0;
acl_assert(cookie);
if (cookie->name_)
name_ = dbuf_->dbuf_strdup(cookie->name_);
else
@ -81,8 +84,7 @@ HttpCookie::HttpCookie(const HttpCookie* cookie, dbuf_pool* dbuf /* = NULL */)
HttpCookie::~HttpCookie(void)
{
if (dbuf_internal_)
dbuf_internal_->destroy();
delete dbuf_internal_;
}
void HttpCookie::destroy(void)

View File

@ -1,7 +1,6 @@
#include "acl_stdafx.hpp"
#include "acl_cpp/stdlib/dbuf_pool.hpp"
#include "acl_cpp/stdlib/snprintf.hpp"
#include "acl_cpp/stdlib/log.hpp"
#include "acl_cpp/stdlib/snprintf.hpp"
#include "acl_cpp/stream/socket_stream.hpp"
#include "acl_cpp/session/memcache_session.hpp"
#include "acl_cpp/http/http_header.hpp"
@ -14,50 +13,45 @@ namespace acl
{
HttpServlet::HttpServlet(socket_stream* stream, session* session)
: stream_(stream)
: req_(NULL)
, res_(NULL)
, stream_(stream)
{
dbuf_ = new dbuf_pool;
init();
if (session == NULL)
{
session_ = new (dbuf_->dbuf_alloc(sizeof(memcache_session)))
memcache_session("127.0.0.1");
session_ = NEW memcache_session("127.0.0.1");
session_ptr_ = session_;
reserve_size_ = sizeof(memcache_session);
}
else
{
session_ = session;
session_ptr_ = NULL;
reserve_size_ = 0;
}
}
HttpServlet::HttpServlet(socket_stream* stream,
const char* memcache_addr /* = "127.0.0.1:11211" */)
: stream_(stream)
: req_(NULL)
, res_(NULL)
, stream_(stream)
{
dbuf_ = new dbuf_pool;
init();
session_ = new (dbuf_->dbuf_alloc(sizeof(memcache_session)))
memcache_session(memcache_addr);
session_ = NEW memcache_session(memcache_addr);
session_ptr_ = session_;
reserve_size_ = sizeof(memcache_session);
}
HttpServlet::HttpServlet()
{
dbuf_ = new dbuf_pool;
init();
req_ = NULL;
res_ = NULL;
stream_ = NULL;
session_ = NULL;
session_ptr_ = NULL;
reserve_size_ = 0;
}
void HttpServlet::init()
@ -71,9 +65,8 @@ void HttpServlet::init()
HttpServlet::~HttpServlet(void)
{
if (session_ptr_)
session_ptr_->~session();
dbuf_->destroy();
delete req_;
delete res_;
}
#define COPY(x, y) ACL_SAFE_STRNCPY((x), (y), sizeof((x)))
@ -106,7 +99,7 @@ HttpServlet& HttpServlet::setParseBodyLimit(int length)
return *this;
}
bool HttpServlet::doRun(dbuf_pool* dbuf)
bool HttpServlet::start()
{
socket_stream* in;
socket_stream* out;
@ -133,67 +126,69 @@ bool HttpServlet::doRun(dbuf_pool* dbuf)
cgi_mode = false;
}
// req/res 采用栈变量,减少内存分配次数
// 在 HTTP 长连接重复请求情况下,以防万一,需要首先删除请求/响应对象
delete req_;
delete res_;
HttpServletResponse res(*out, dbuf);
HttpServletRequest req(res, *session_, *in, local_charset_,
parse_body_enable_, parse_body_limit_, dbuf);
res_ = NEW HttpServletResponse(*out);
req_ = NEW HttpServletRequest(*res_, *session_, *in, local_charset_,
parse_body_enable_, parse_body_limit_);
// 设置 HttpServletRequest 对象
res.setHttpServletRequest(&req);
res_->setHttpServletRequest(req_);
if (rw_timeout_ >= 0)
req.setRwTimeout(rw_timeout_);
req_->setRwTimeout(rw_timeout_);
res.setCgiMode(cgi_mode);
res_->setCgiMode(cgi_mode);
string method_s(32);
http_method_t method = req.getMethod(&method_s);
http_method_t method = req_->getMethod(&method_s);
// 根据请求的值自动设定是否需要保持长连接
if (!cgi_mode)
res.setKeepAlive(req.isKeepAlive());
res_->setKeepAlive(req_->isKeepAlive());
bool ret;
switch (method)
{
case HTTP_METHOD_GET:
ret = doGet(req, res);
ret = doGet(*req_, *res_);
break;
case HTTP_METHOD_POST:
ret = doPost(req, res);
ret = doPost(*req_, *res_);
break;
case HTTP_METHOD_PUT:
ret = doPut(req, res);
ret = doPut(*req_, *res_);
break;
case HTTP_METHOD_CONNECT:
ret = doConnect(req, res);
ret = doConnect(*req_, *res_);
break;
case HTTP_METHOD_PURGE:
ret = doPurge(req, res);
ret = doPurge(*req_, *res_);
break;
case HTTP_METHOD_DELETE:
ret = doDelete(req, res);
ret = doDelete(*req_, *res_);
break;
case HTTP_METHOD_HEAD:
ret = doHead(req, res);
ret = doHead(*req_, *res_);
break;
case HTTP_METHOD_OPTION:
ret = doOptions(req, res);
ret = doOptions(*req_, *res_);
break;
case HTTP_METHOD_PROPFIND:
ret = doPropfind(req, res);
ret = doPropfind(*req_, *res_);
break;
case HTTP_METHOD_OTHER:
ret = doOther(req, res, method_s.c_str());
ret = doOther(*req_, *res_, method_s.c_str());
break;
default:
ret = false; // 有可能是IO失败或未知方法
if (req.getLastError() == HTTP_REQ_ERR_METHOD)
doUnknown(req, res);
if (req_->getLastError() == HTTP_REQ_ERR_METHOD)
doUnknown(*req_, *res_);
else if (first)
doError(req, res);
doError(*req_, *res_);
break;
}
@ -208,18 +203,18 @@ bool HttpServlet::doRun(dbuf_pool* dbuf)
delete out;
}
// 返回给上层调用者true 表示继续保持长连接,否则表示需断开连接
return ret && req.isKeepAlive()
&& res.getHttpHeader().get_keep_alive();
return ret;
}
bool HttpServlet::doRun()
{
bool ret = doRun(dbuf_);
bool ret = start();
if (req_ == NULL || res_ == NULL)
return ret;
// 重置内存池状态
dbuf_->dbuf_reset(reserve_size_);
return ret;
// 返回给上层调用者true 表示继续保持长连接,否则表示需断开连接
return ret && req_->isKeepAlive()
&& res_->getHttpHeader().get_keep_alive();
}
bool HttpServlet::doRun(session& session, socket_stream* stream /* = NULL */)

View File

@ -1,5 +1,5 @@
#include "acl_stdafx.hpp"
#include "acl_cpp/stdlib//dbuf_pool.hpp"
#include "acl_cpp/stdlib/dbuf_pool.hpp"
#include "acl_cpp/stdlib/snprintf.hpp"
#include "acl_cpp/stdlib/log.hpp"
#include "acl_cpp/stdlib/string.hpp"
@ -28,7 +28,7 @@ namespace acl
HttpServletRequest::HttpServletRequest(HttpServletResponse& res,
session& store, socket_stream& stream,
const char* charset /* = NULL */, bool body_parse /* = true */,
int body_limit /* = 102400 */, dbuf_pool* dbuf /* = NULL */)
int body_limit /* = 102400 */)
: req_error_(HTTP_REQ_OK)
, res_(res)
, store_(store)
@ -45,16 +45,8 @@ HttpServletRequest::HttpServletRequest(HttpServletResponse& res,
, xml_(NULL)
, readHeaderCalled_(false)
{
if (dbuf != NULL)
{
dbuf_ = dbuf;
dbuf_internal_ = NULL;
}
else
{
dbuf_internal_ = new dbuf_pool;
dbuf_ = dbuf_internal_;
}
dbuf_internal_ = new dbuf_guard;
dbuf_ = dbuf_internal_;
COPY(cookie_name_, "ACL_SESSION_ID");
ACL_VSTREAM* in = stream.get_vstream();
@ -73,23 +65,9 @@ HttpServletRequest::HttpServletRequest(HttpServletResponse& res,
HttpServletRequest::~HttpServletRequest(void)
{
std::vector<HttpCookie*>::iterator it = cookies_.begin();
for (; it != cookies_.end(); ++it)
(*it)->~HttpCookie();
if (http_session_)
http_session_->~HttpSession();
if (client_)
client_->~http_client();
if (mime_)
mime_->~http_mime();
if (json_)
json_->~json();
if (xml_)
xml_->~xml();
if (dbuf_internal_)
dbuf_internal_->destroy();
delete dbuf_internal_;
}
http_method_t HttpServletRequest::getMethod(string* method_s /* = NULL */) const
@ -121,17 +99,15 @@ void HttpServletRequest::add_cookie(char* data)
char* end = ptr + strlen(ptr) - 1;
while (end > ptr && (*end == ' ' || *end == '\t'))
*end-- = 0;
HttpCookie* cookie = new (dbuf_->dbuf_alloc(sizeof(HttpCookie)))
HttpCookie(data, ptr, dbuf_);
cookies_.push_back(cookie);
setCookie(data, ptr);
}
void HttpServletRequest::setCookie(const char* name, const char* value)
{
if (name == NULL || *name == 0 || value == NULL)
return;
HttpCookie* cookie = new (dbuf_->dbuf_alloc(sizeof(HttpCookie)))
HttpCookie(name, value, dbuf_);
HttpCookie* cookie = dbuf_->create<HttpCookie, const char*,
const char*, dbuf_guard*> (name, value, dbuf_);
cookies_.push_back(cookie);
}
@ -167,23 +143,21 @@ const std::vector<HttpCookie*>& HttpServletRequest::getCookies(void) const
if (req->cookies_table == NULL)
return cookies_;
const char* name, *value;
HttpCookie* cookie;
ACL_HTABLE_ITER iter;
// 遍历 HTTP 请求头中的 cookie 项
acl_htable_foreach(iter, req->cookies_table)
{
name = acl_htable_iter_key(iter);
value = (char*) acl_htable_iter_value(iter);
const char* name = acl_htable_iter_key(iter);
const char* value = (char*) acl_htable_iter_value(iter);
if (name == NULL || *name == 0
|| value == NULL || *value == 0)
{
continue;
}
// 创建 cookie 对象并将之加入数组中
cookie = new (dbuf_->dbuf_alloc(sizeof(HttpCookie)))
HttpCookie(name, value, dbuf_);
HttpCookie* cookie = dbuf_->create<HttpCookie, const char*,
const char*, dbuf_guard*>(name, value, dbuf_);
const_cast<HttpServletRequest*>
(this)->cookies_.push_back(cookie);
}
@ -255,8 +229,7 @@ HttpSession& HttpServletRequest::getSession(bool create /* = true */,
if (http_session_ != NULL)
return *http_session_;
http_session_ = new (dbuf_->dbuf_alloc(sizeof(HttpSession)))
HttpSession(store_);
http_session_ = dbuf_->create<HttpSession, session&>(store_);
const char* sid;
if ((sid = getCookieValue(cookie_name_)) != NULL)
@ -266,8 +239,8 @@ HttpSession& HttpServletRequest::getSession(bool create /* = true */,
// 获得唯一 ID 标识符
sid = store_.get_sid();
// 生成 cookie 对象,并分别向请求对象和响应对象添加 cookie
HttpCookie* cookie = new (dbuf_->dbuf_alloc(sizeof(HttpCookie)))
HttpCookie(cookie_name_, sid, dbuf_);
HttpCookie* cookie = dbuf_->create<HttpCookie, const char*,
const char*, dbuf_guard*>(cookie_name_, sid, dbuf_);
res_.addCookie(cookie);
setCookie(cookie_name_, sid);
}
@ -275,8 +248,8 @@ HttpSession& HttpServletRequest::getSession(bool create /* = true */,
{
store_.set_sid(sid_in);
// 生成 cookie 对象,并分别向请求对象和响应对象添加 cookie
HttpCookie* cookie = new (dbuf_->dbuf_alloc(sizeof(HttpCookie)))
HttpCookie(cookie_name_, sid_in, dbuf_);
HttpCookie* cookie = dbuf_->create<HttpCookie, const char*,
const char*, dbuf_guard*>(cookie_name_, sid_in, dbuf_);
res_.addCookie(cookie);
setCookie(cookie_name_, sid_in);
}
@ -556,7 +529,6 @@ bool HttpServletRequest::readHeader(string* method_s)
{
client_ = new (dbuf_->dbuf_alloc(sizeof(http_client)))
http_client(&stream_, rw_timeout_);
if (client_->read_head() == false)
{
req_error_ = HTTP_REQ_ERR_IO;
@ -638,8 +610,8 @@ bool HttpServletRequest::readHeader(string* method_s)
else
{
request_type_ = HTTP_REQUEST_MULTIPART_FORM;
mime_ = new (dbuf_->dbuf_alloc(sizeof(http_mime)))
http_mime(bound, localCharset_);
mime_ = dbuf_->create<http_mime, const char*,
const char*>(bound, localCharset_);
}
return true;
@ -677,12 +649,17 @@ bool HttpServletRequest::readHeader(string* method_s)
return ret == -1 ? false : true;
}
if (!EQ(ctype, "text"))
{
request_type_ = HTTP_REQUEST_OTHER;
return true;
}
// 当数据类型为 text/json 格式时:
if (EQ(ctype, "text") && EQ(stype, "json"))
else if (EQ(stype, "json"))
{
request_type_ = HTTP_REQUEST_TEXT_JSON;
json_ = new (dbuf_->dbuf_alloc(sizeof(json))) json();
json_ = dbuf_->create<json>();
ssize_t dlen = (ssize_t) len, n;
char buf[8192];
istream& in = getInputStream();
@ -702,10 +679,10 @@ bool HttpServletRequest::readHeader(string* method_s)
}
// 当数据类型为 text/xml 格式时:
if (EQ(ctype, "text") && EQ(stype, "xml"))
else if (EQ(stype, "xml"))
{
request_type_ = HTTP_REQUEST_TEXT_XML;
xml_ = new (dbuf_->dbuf_alloc(sizeof(xml1))) xml1();
xml_ = dbuf_->create<xml1>();
ssize_t dlen = (ssize_t) len, n;
char buf[8192];
istream& in = getInputStream();
@ -723,9 +700,11 @@ bool HttpServletRequest::readHeader(string* method_s)
}
return true;
}
request_type_ = HTTP_REQUEST_OTHER;
return true;
else
{
request_type_ = HTTP_REQUEST_OTHER;
return true;
}
}
const char* HttpServletRequest::getRequestReferer(void) const

View File

@ -6,33 +6,22 @@
#include "acl_cpp/stream/socket_stream.hpp"
#include "acl_cpp/http/http_header.hpp"
#include "acl_cpp/http/http_client.hpp"
#include "acl_cpp/http/HttpServlet.hpp"
#include "acl_cpp/http/HttpServletRequest.hpp"
#include "acl_cpp/http/HttpServletResponse.hpp"
namespace acl
{
HttpServletResponse::HttpServletResponse(socket_stream& stream,
dbuf_pool* dbuf /* = NULL */)
HttpServletResponse::HttpServletResponse(socket_stream& stream)
: stream_(stream)
, request_(NULL)
{
if (dbuf != NULL)
{
dbuf_ = dbuf;
dbuf_internal_ = NULL;
}
else
{
dbuf_internal_ = new dbuf_pool;
dbuf_ = dbuf_internal_;
}
dbuf_internal_ = new dbuf_guard;
dbuf_ = dbuf_internal_;
client_ = new (dbuf_->dbuf_alloc(sizeof(http_client)))
http_client(&stream_, stream_.get_rw_timeout());
header_ = new (dbuf_->dbuf_alloc(sizeof(http_header)))
http_header(dbuf_);
header_ = dbuf_->create<http_header, dbuf_guard*>(dbuf_);
header_->set_request_mode(false);
charset_[0] = 0;
@ -43,10 +32,7 @@ HttpServletResponse::HttpServletResponse(socket_stream& stream,
HttpServletResponse::~HttpServletResponse(void)
{
client_->~http_client();
header_->~http_header();
if (dbuf_internal_)
dbuf_internal_->destroy();
delete dbuf_internal_;
}
HttpServletResponse& HttpServletResponse::setRedirect(

View File

@ -13,7 +13,7 @@ namespace acl
#define CP(x, y) ACL_SAFE_STRNCPY(x, y, sizeof(x))
http_header::http_header(dbuf_pool* dbuf /* = NULL */)
http_header::http_header(dbuf_guard* dbuf /* = NULL */)
{
if (dbuf != NULL)
{
@ -22,13 +22,13 @@ http_header::http_header(dbuf_pool* dbuf /* = NULL */)
}
else
{
dbuf_internal_ = new dbuf_pool;
dbuf_internal_ = new dbuf_guard;
dbuf_ = dbuf_internal_;
}
init();
}
http_header::http_header(const char* url, dbuf_pool* dbuf /* = NULL */)
http_header::http_header(const char* url, dbuf_guard* dbuf /* = NULL */)
{
if (dbuf != NULL)
{
@ -37,7 +37,7 @@ http_header::http_header(const char* url, dbuf_pool* dbuf /* = NULL */)
}
else
{
dbuf_internal_ = new dbuf_pool;
dbuf_internal_ = new dbuf_guard;
dbuf_ = dbuf_internal_;
}
init();
@ -45,7 +45,7 @@ http_header::http_header(const char* url, dbuf_pool* dbuf /* = NULL */)
set_url(url);
}
http_header::http_header(int status, dbuf_pool* dbuf /* = NULL */)
http_header::http_header(int status, dbuf_guard* dbuf /* = NULL */)
{
if (dbuf != NULL)
{
@ -54,7 +54,7 @@ http_header::http_header(int status, dbuf_pool* dbuf /* = NULL */)
}
else
{
dbuf_internal_ = new dbuf_pool;
dbuf_internal_ = new dbuf_guard;
dbuf_ = dbuf_internal_;
}
init();
@ -64,8 +64,7 @@ http_header::http_header(int status, dbuf_pool* dbuf /* = NULL */)
http_header::~http_header(void)
{
clear();
if (dbuf_internal_)
dbuf_internal_->destroy();
delete dbuf_internal_;
}
void http_header::init()
@ -90,9 +89,6 @@ void http_header::init()
void http_header::clear()
{
std::list<HttpCookie*>::iterator it = cookies_.begin();
for (; it != cookies_.end(); ++it)
(*it)->~HttpCookie();
cookies_.clear();
entries_.clear();
params_.clear();
@ -170,8 +166,8 @@ http_header& http_header::add_cookie(const char* name, const char* value,
if (name == NULL || *name == 0 || value == NULL)
return *this;
HttpCookie* cookie = new (dbuf_->dbuf_alloc((sizeof(HttpCookie))))
HttpCookie(name, value, dbuf_);
HttpCookie* cookie = dbuf_->create<HttpCookie, const char*,
const char*, dbuf_guard*>(name, value, dbuf_);
if (domain && *domain)
cookie->setDomain(domain);
@ -188,8 +184,8 @@ http_header& http_header::add_cookie(const HttpCookie* in)
if (in == NULL)
return *this;
HttpCookie* cookie = new (dbuf_->dbuf_alloc(sizeof(HttpCookie)))
HttpCookie(in);
HttpCookie* cookie = dbuf_->create<HttpCookie, const HttpCookie*,
dbuf_guard*> (in, dbuf_);
cookies_.push_back(cookie);
return *this;
}

View File

@ -135,9 +135,7 @@ http_mime::http_mime(const char* boundary,
if (boundary == NULL || strlen(boundary) < 2)
{
logger_error("boundary invalid");
boundary = NULL;
mime_state_ = NULL;
save_path_ = NULL;
return;
}
// HTTP 的 MIME 格式与 邮件的 MIME 的分隔符有所不同,
@ -149,7 +147,7 @@ http_mime::http_mime(const char* boundary,
boundary++;
if (*boundary == '-')
boundary++;
boundary_ = acl_mystrdup(boundary);
boundary_ = boundary;
if (local_charset && *local_charset)
safe_snprintf(local_charset_, sizeof(local_charset_),
@ -159,7 +157,7 @@ http_mime::http_mime(const char* boundary,
decode_on_ = true;
save_path_ = NULL;
save_path_.clear();
mime_state_ = mime_state_alloc();
// 为了使用邮件的 mime 解析器,需要模拟出一个头部字段
@ -177,10 +175,6 @@ http_mime::http_mime(const char* boundary,
http_mime::~http_mime()
{
if (boundary_)
acl_myfree(boundary_);
if (save_path_)
acl_myfree(save_path_);
if (mime_state_)
mime_state_free(mime_state_);
std::list<http_mime_node*>::iterator it = mime_nodes_.begin();
@ -191,7 +185,7 @@ http_mime::~http_mime()
void http_mime::set_saved_path(const char* path)
{
if (path && *path)
save_path_ = acl_mystrdup(path);
save_path_ = path;
}
bool http_mime::update(const char* data, size_t len)

View File

@ -159,8 +159,10 @@ static void mime_node_free(MIME_NODE *node)
acl_vstring_free(node->buffer);
if (node->boundary)
acl_vstring_free(node->boundary);
#ifdef SAVE_BODY
if (node->body)
acl_vstring_free(node->body);
#endif
acl_myfree(node);
}
@ -498,3 +500,16 @@ const char *mime_stype_name(size_t stype)
return (OTHER_NAME);
return (mime_stype_map[stype - MIME_STYPE_MIN].name);
}
const char *mime_head_value(MIME_NODE* node, const char* name)
{
ACL_ITER iter;
acl_foreach(iter, node->header_list)
{
HEADER_NV* hdr = (HEADER_NV*) iter.data;
if (strcasecmp(hdr->name, name) == 0 && *hdr->value)
return (hdr->value);
}
return NULL;
}

View File

@ -15,6 +15,8 @@ struct MAIL_ADDR
char *comment;
};
//#define SAVE_BODY
struct MIME_NODE
{
ACL_RING children; /**< 子结点集合 */
@ -59,7 +61,9 @@ struct MIME_NODE
char bound_term[3];
ACL_VSTRING *buffer; /**< headers, quoted-printable body */
#ifdef SAVE_BODY
ACL_VSTRING *body;
#endif
ACL_RING node; /**< 当前结点 */
off_t header_begin; /**< 结点头开始位置 */
@ -131,5 +135,6 @@ int mime_node_delete(MIME_NODE *node);
void mime_node_add_child(MIME_NODE *parent, MIME_NODE *child);
const char *mime_ctype_name(size_t ctype);
const char *mime_stype_name(size_t stype);
const char *mime_head_value(MIME_NODE *node, const char *name);
#endif

View File

@ -607,14 +607,113 @@ static int mime_state_head(MIME_STATE *state, const char *s, int n)
return n;
}
#if 1
// 分析 multipart 部分体, 当匹配到一个完整的分隔符后则表明该部分数据体分析完毕
static int mime_bound_body(MIME_STATE *state, const char * const boundary,
MIME_NODE *node, const char *s, int n, int *finish)
{
const unsigned char *cp = (const unsigned char*) s;
const unsigned char *end = (const unsigned char*) s + n;
size_t bound_len = strlen(boundary);
off_t curr_off = state->curr_off;
off_t last_cr_pos = node->last_cr_pos;
off_t last_lf_pos = node->last_lf_pos;
const char *bound_ptr = node->bound_ptr;
unsigned char ch;
#ifdef SAVE_BODY
const unsigned char *startn = NULL;
#endif
for (; cp < end; cp++) {
ch = *cp;
// 记录下 \r\n 的位置
if (ch == '\r')
last_cr_pos = curr_off;
else if (ch == '\n')
last_lf_pos = curr_off;
curr_off++;
if (bound_ptr == NULL) {
if (ch != *boundary) {
#ifdef SAVE_BODY
ADDCH(node->body, ch);
#endif
continue;
}
#ifdef SAVE_BODY
startn = cp;
#endif
bound_ptr = boundary;
}
if (ch != *bound_ptr) {
#ifdef SAVE_BODY
// 说明之前的匹配失效,需要重新匹配,
// 但必须将之前匹配的字符拷贝
if (bound_ptr > boundary) {
APPEND(node->body, boundary,
bound_ptr - boundary);
}
#endif
bound_ptr = NULL;
} else if (*++bound_ptr == 0) {
/* 说明完全匹配 */
*finish = 1;
node->body_end = curr_off - bound_len;
node->body_data_end = node->body_end;
// 因为 body_end 记录的是某个结点最后的位置,
// 其中会包含, 根据协议附加的 \r\n所以真实
// 数据的结束位置 body_data_end 是去掉这些数据
// 后的位置
if (last_lf_pos + (off_t) bound_len == curr_off - 1)
{
node->body_data_end--;
if (last_cr_pos + 1 == last_lf_pos)
node->body_data_end--;
}
#ifdef SAVE_BODY
if (startn > (const unsigned char *) s) {
/* 将匹配之前的数据拷贝 */
APPEND(node->body, (const char*) s,
(const char*) startn - s);
}
#endif
bound_ptr = NULL;
cp++;
break;
}
}
node->bound_ptr = bound_ptr;
node->last_cr_pos = last_cr_pos;
node->last_lf_pos = last_lf_pos;
state->curr_off = curr_off;
return (int) (n - ((const char*) cp - s));
}
#else
// 分析 multipart 部分体, 当匹配到一个完整的分隔符后则表明该部分数据体分析完毕
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, *end = (const unsigned char*) s + n;
#ifdef SAVE_BODY
const unsigned char *startn = NULL;
#endif
size_t bound_len = strlen(boundary);
// printf(">>>size: %ld\r\n", (long) ACL_VSTRING_SIZE(node->body));
for (cp = (const unsigned char *) s; cp < end; cp++) {
// 记录下 \r\n 的位置
if (*cp == '\r')
@ -626,12 +725,14 @@ static int mime_bound_body(MIME_STATE *state, const char *boundary,
if (node->bound_ptr != NULL) {
if (*cp != *node->bound_ptr) {
#ifdef SAVE_BODY
// 说明之前的匹配失效,需要重新匹配,
// 但必须将之前匹配的字符拷贝
if (node->bound_ptr > boundary) {
APPEND(node->body, boundary,
node->bound_ptr - boundary);
}
#endif
node->bound_ptr = NULL;
} else if (*++node->bound_ptr == 0) {
@ -654,11 +755,13 @@ static int mime_bound_body(MIME_STATE *state, const char *boundary,
node->body_data_end--;
}
#ifdef SAVE_BODY
if (startn > (const unsigned char *) s) {
/* 将匹配之前的数据拷贝 */
APPEND(node->body, (const char*) s,
(const char*) startn - s);
}
#endif
node->bound_ptr = NULL;
cp++;
break;
@ -669,7 +772,9 @@ static int mime_bound_body(MIME_STATE *state, const char *boundary,
// --> node->bound_ptr == NULL
if (*cp != *boundary) {
#ifdef SAVE_BODY
ADDCH(node->body, *cp);
#endif
continue;
}
@ -698,25 +803,33 @@ static int mime_bound_body(MIME_STATE *state, const char *boundary,
break;
}
#ifdef SAVE_BODY
startn = cp;
#endif
}
return (int) (n - ((const char*) cp - s));
}
#endif
// 分析邮件体或 multipart 部分体
static int mime_state_body(MIME_STATE *state, const char *s, int n)
{
int finish = 0;
#ifdef SAVE_BODY
if (state->curr_node->body == NULL)
state->curr_node->body = acl_vstring_alloc(1024);
#endif
if (state->curr_bound == NULL) {
/* 如果没有分隔符,则说明是文本类型,即只有正文内容 */
#ifdef SAVE_BODY
APPEND(state->curr_node->body, s, n);
#endif
state->curr_off += n;
/* 因为 curr_off 指向下一个偏移位置,所以

View File

@ -611,6 +611,11 @@ const std::list<mime_node*>& mime::get_mime_nodes(bool enableDecode /* = true */
return (*m_pNodes);
}
static bool has_content_id(MIME_NODE* node)
{
return mime_head_value(node, "Content-ID") == NULL ? false : true;
}
const std::list<mime_attach*>& mime::get_attachments(bool enableDecode /* = true */,
const char* toCharset /* = "gb2312" */, off_t off /* = 0 */)
{
@ -628,11 +633,12 @@ const std::list<mime_attach*>& mime::get_attachments(bool enableDecode /* = true
acl_foreach(iter, m_pMimeState)
{
node = (MIME_NODE*) iter.data;
if (node->header_filename == NULL)
continue;
attach = NEW mime_attach(m_pFilePath, node,
enableDecode, toCharset, off);
m_pAttaches->push_back(attach);
if (node->header_filename != NULL || has_content_id(node))
{
attach = NEW mime_attach(m_pFilePath, node,
enableDecode, toCharset, off);
m_pAttaches->push_back(attach);
}
}
return (*m_pAttaches);
}

View File

@ -356,7 +356,6 @@ bool charset_conv::update(const char* in, size_t len, acl::string* out)
ret = __iconv(m_iconv, &pIn, &nIn, &pOut, &nOut);
#endif
if (ret != (size_t) -1)
{
if ((ret = SIZE(m_pOutBuf) - nOut) > 0)
@ -411,8 +410,9 @@ bool charset_conv::update(const char* in, size_t len, acl::string* out)
acl_assert(pIn >= STR(m_pInBuf));
// 跳过无效字节
(*out) += (char)(*pIn); // 直接拷贝无效字节
// 是否跳过无效字节?
if (m_addInvalid)
(*out) += (char)(*pIn); // 直接拷贝无效字节
nIn--;
pIn++;
if (nIn > 0)

View File

@ -63,6 +63,24 @@ string::string(const void* s, size_t n) : use_bin_(false)
TERM(vbf_);
}
#if !defined(_WIN32) && !defined(_WIN64)
string::string(int fd, size_t max, size_t n)
{
if (n < 1)
n = 1;
if (fd >= 0)
vbf_ = acl_vstring_mmap_alloc(fd, max, n);
else
vbf_ = ALLOC(n);
list_tmp_ = NULL;
vector_tmp_ = NULL;
pair_tmp_ = NULL;
scan_ptr_ = NULL;
line_state_ = NULL;
line_state_offset_ = 0;
}
#endif
string::~string()
{
FREE(vbf_);

View File

@ -124,15 +124,17 @@ void xml::clear(void)
if (buf_)
buf_->clear();
std::vector<acl::xml_node*>::iterator it = elements_.begin();
for (; it != elements_.end(); ++it)
delete (*it);
//std::vector<acl::xml_node*>::iterator it = elements_.begin();
//for (; it != elements_.end(); ++it)
// delete (*it);
elements_.clear();
std::list<xml_node*>::iterator it1 = nodes_tmp_.begin();
for (; it1 != nodes_tmp_.end(); ++it1)
delete (*it1);
nodes_tmp_.clear();
//std::list<xml_node*>::iterator it1 = nodes_tmp_.begin();
//for (; it1 != nodes_tmp_.end(); ++it1)
// delete (*it1);
//nodes_tmp_.clear();
dbuf_.dbuf_reset();
}
const acl::string& xml::getText()

View File

@ -264,7 +264,10 @@ const std::vector<xml_node*>& xml1::getElementsByTagName(const char* tag) const
acl_foreach(iter, a)
{
ACL_XML_NODE *tmp = (ACL_XML_NODE*) iter.data;
xml1_node* node = NEW xml1_node(const_cast<xml1*>(this), tmp);
// xml1_node* node = NEW xml1_node(const_cast<xml1*>(this), tmp);
xml1_node* node = const_cast<dbuf_guard&>(dbuf_)
.create<xml1_node, xml1*, ACL_XML_NODE*>
(const_cast<xml1*>(this), tmp);
const_cast<xml1*>(this)->elements_.push_back(node);
}
@ -278,8 +281,11 @@ xml_node* xml1::getFirstElementByTag(const char* tag) const
if (node == NULL)
return NULL;
xml1_node* n = NEW xml1_node(const_cast<xml1*>(this), node);
const_cast<xml1*>(this)->nodes_tmp_.push_back(n);
// xml1_node* n = NEW xml1_node(const_cast<xml1*>(this), node);
// const_cast<xml1*>(this)->nodes_tmp_.push_back(n);
xml1_node* n = const_cast<dbuf_guard&>(dbuf_)
.create<xml1_node, xml1*, ACL_XML_NODE*>
(const_cast<xml1*>(this), node);
return n;
}
@ -295,7 +301,10 @@ const std::vector<xml_node*>& xml1::getElementsByTags(const char* tags) const
acl_foreach(iter, a)
{
ACL_XML_NODE *tmp = (ACL_XML_NODE*) iter.data;
xml1_node* node = NEW xml1_node(const_cast<xml1*>(this), tmp);
// xml1_node* node = NEW xml1_node(const_cast<xml1*>(this), tmp);
xml1_node* node = const_cast<dbuf_guard&>(dbuf_)
.create<xml1_node, xml1*, ACL_XML_NODE*>
(const_cast<xml1*>(this), tmp);
const_cast<xml1*>(this)->elements_.push_back(node);
}
@ -312,8 +321,11 @@ xml_node* xml1::getFirstElementByTags(const char* tags) const
ACL_XML_NODE* node = (ACL_XML_NODE*) acl_array_index(a, 0);
acl_assert(node);
xml1_node* n = NEW xml1_node(const_cast<xml1*>(this), node);
const_cast<xml1*>(this)->nodes_tmp_.push_back(n);
// xml1_node* n = NEW xml1_node(const_cast<xml1*>(this), node);
// const_cast<xml1*>(this)->nodes_tmp_.push_back(n);
xml1_node* n = const_cast<dbuf_guard&>(dbuf_)
.create<xml1_node, xml1*, ACL_XML_NODE*>
(const_cast<xml1*>(this), node);
acl_xml_free_array(a);
return n;
@ -330,7 +342,10 @@ const std::vector<xml_node*>& xml1::getElementsByName(const char* value) const
acl_foreach(iter, a)
{
ACL_XML_NODE *tmp = (ACL_XML_NODE*) iter.data;
xml1_node* node = NEW xml1_node(const_cast<xml1*>(this), tmp);
// xml1_node* node = NEW xml1_node(const_cast<xml1*>(this), tmp);
xml1_node* node = const_cast<dbuf_guard&>(dbuf_)
.create<xml1_node, xml1*, ACL_XML_NODE*>
(const_cast<xml1*>(this), tmp);
const_cast<xml1*>(this)->elements_.push_back(node);
}
@ -350,7 +365,10 @@ const std::vector<xml_node*>& xml1::getElementsByAttr(
acl_foreach(iter, a)
{
ACL_XML_NODE *tmp = (ACL_XML_NODE*) iter.data;
xml1_node* node = NEW xml1_node(const_cast<xml1*>(this), tmp);
// xml1_node* node = NEW xml1_node(const_cast<xml1*>(this), tmp);
xml1_node* node = const_cast<dbuf_guard&>(dbuf_)
.create<xml1_node, xml1*, ACL_XML_NODE*>
(const_cast<xml1*>(this), tmp);
const_cast<xml1*>(this)->elements_.push_back(node);
}
@ -364,8 +382,11 @@ xml_node* xml1::getElementById(const char* id) const
if (node == NULL)
return NULL;
xml1_node* n = NEW xml1_node(const_cast<xml1*>(this), node);
const_cast<xml1*>(this)->nodes_tmp_.push_back(n);
// xml1_node* n = NEW xml1_node(const_cast<xml1*>(this), node);
// const_cast<xml1*>(this)->nodes_tmp_.push_back(n);
xml1_node* n = const_cast<dbuf_guard&>(dbuf_)
.create<xml1_node, xml1*, ACL_XML_NODE*>
(const_cast<xml1*>(this), node);
return n;
}
@ -462,8 +483,10 @@ const acl::string& xml1::getText()
xml_node& xml1::create_node(const char* tag, const char* text /* = NULL */)
{
ACL_XML_NODE* node = acl_xml_create_node(xml_, tag, text);
xml1_node* n = NEW xml1_node(this, node);
nodes_tmp_.push_back(n);
// xml1_node* n = NEW xml1_node(this, node);
// nodes_tmp_.push_back(n);
xml1_node* n = dbuf_.create<xml1_node, xml1*, ACL_XML_NODE*>
(this, node);
return *n;
}
@ -484,8 +507,10 @@ xml_node* xml1::first_node(void)
if (node == NULL)
return NULL;
xml1_node* n = NEW xml1_node(this, node);
nodes_tmp_.push_back(n);
// xml1_node* n = NEW xml1_node(this, node);
// nodes_tmp_.push_back(n);
xml1_node* n = dbuf_.create<xml1_node, xml1*, ACL_XML_NODE*>
(this, node);
return n;
}
@ -497,8 +522,10 @@ xml_node* xml1::next_node(void)
if (node == NULL)
return NULL;
xml1_node* n = NEW xml1_node(this, node);
nodes_tmp_.push_back(n);
// xml1_node* n = NEW xml1_node(this, node);
// nodes_tmp_.push_back(n);
xml1_node* n = dbuf_.create<xml1_node, xml1*, ACL_XML_NODE*>
(this, node);
return n;
}

View File

@ -206,66 +206,52 @@ int xml2_node::children_count(void) const
//////////////////////////////////////////////////////////////////////
xml2::xml2(char* addr, size_t size, const char* data /* = NULL */)
xml2::xml2(const char* filepath, size_t max_len, const char* data /* = NULL */,
size_t init_len /* = 8192 */)
{
acl_assert(addr && size > 0);
acl_assert(filepath && max_len > 0 && init_len > 0);
if (max_len < init_len)
max_len = init_len;
iter_ = NULL;
root_ = NULL;
xml_ = acl_xml2_alloc(addr, size);
if (data && *data)
update(data);
}
xml2::xml2(const char* filepath, size_t size, const char* data /* = NULL */,
size_t block /* = 8192 */, bool keep_open /* = true */)
{
acl_assert(filepath && size > 0 && block > 0);
if (block > size)
block = size;
iter_ = NULL;
root_ = NULL;
xml_ = acl_xml2_mmap_file(filepath, size, block,
keep_open ? 1 : 0, NULL);
xml_ = acl_xml2_mmap_file(filepath, max_len, init_len, NULL);
if (data && *data)
update(data);
}
xml2::xml2(fstream& fp, size_t size, const char* data /* = NULL */,
size_t block /* = 8192 */)
xml2::xml2(fstream& fp, size_t max_len, const char* data /* = NULL */,
size_t init_len /* = 8192 */)
{
acl_assert(size > 0 && block > 0);
acl_assert(max_len > 0 && init_len > 0);
if (block > size)
block = size;
if (max_len < init_len)
max_len = init_len;
iter_ = NULL;
root_ = NULL;
xml_ = acl_xml2_mmap_fd((ACL_FILE_HANDLE) fp.file_handle(),
size, block, NULL);
xml_ = acl_xml2_mmap_fd(fp.file_handle(),
max_len, init_len, NULL);
if (data && *data)
update(data);
}
xml2::xml2(ACL_FILE_HANDLE fd, size_t size, const char* data /* = NULL */,
size_t block /* = 8192 */)
xml2::xml2(ACL_FILE_HANDLE fd, size_t max_len, const char* data /* = NULL */,
size_t init_len /* = 8192 */)
{
acl_assert(fd != ACL_FILE_INVALID);
acl_assert(size > 0);
acl_assert(max_len > 0);
if (block > size)
block = size;
if (init_len > max_len)
max_len = init_len;
xml_ = acl_xml2_mmap_fd(fd, size, block, NULL);
xml_ = acl_xml2_mmap_fd(fd, max_len, init_len, NULL);
if (data && *data)
update(data);
@ -308,7 +294,10 @@ const std::vector<xml_node*>& xml2::getElementsByTagName(const char* tag) const
acl_foreach(iter, a)
{
ACL_XML2_NODE *tmp = (ACL_XML2_NODE*) iter.data;
xml2_node* node = NEW xml2_node(const_cast<xml2*>(this), tmp);
// xml2_node* node = NEW xml2_node(const_cast<xml2*>(this), tmp);
xml2_node* node = const_cast<dbuf_guard&>(dbuf_)
.create<xml2_node, xml2*, ACL_XML2_NODE*>
(const_cast<xml2*>(this), tmp);
const_cast<xml2*>(this)->elements_.push_back(node);
}
@ -322,8 +311,11 @@ xml_node* xml2::getFirstElementByTag(const char* tag) const
if (node == NULL)
return NULL;
xml2_node* n = NEW xml2_node(const_cast<xml2*>(this), node);
const_cast<xml2*>(this)->nodes_tmp_.push_back(n);
// xml2_node* n = NEW xml2_node(const_cast<xml2*>(this), node);
// const_cast<xml2*>(this)->nodes_tmp_.push_back(n);
xml2_node* n = const_cast<dbuf_guard&>(dbuf_)
.create<xml2_node, xml2*, ACL_XML2_NODE*>
(const_cast<xml2*>(this), node);
return n;
}
@ -339,7 +331,10 @@ const std::vector<xml_node*>& xml2::getElementsByTags(const char* tags) const
acl_foreach(iter, a)
{
ACL_XML2_NODE *tmp = (ACL_XML2_NODE*) iter.data;
xml2_node* node = NEW xml2_node(const_cast<xml2*>(this), tmp);
// xml2_node* node = NEW xml2_node(const_cast<xml2*>(this), tmp);
xml2_node* node = const_cast<dbuf_guard&>(dbuf_)
.create<xml2_node, xml2*, ACL_XML2_NODE*>
(const_cast<xml2*>(this), tmp);
const_cast<xml2*>(this)->elements_.push_back(node);
}
@ -356,8 +351,11 @@ xml_node* xml2::getFirstElementByTags(const char* tags) const
ACL_XML2_NODE* node = (ACL_XML2_NODE*) acl_array_index(a, 0);
acl_assert(node);
xml2_node* n = NEW xml2_node(const_cast<xml2*>(this), node);
const_cast<xml2*>(this)->nodes_tmp_.push_back(n);
// xml2_node* n = NEW xml2_node(const_cast<xml2*>(this), node);
// const_cast<xml2*>(this)->nodes_tmp_.push_back(n);
xml2_node* n = const_cast<dbuf_guard&>(dbuf_)
.create<xml2_node, xml2*, ACL_XML2_NODE*>
(const_cast<xml2*>(this), node);
acl_xml_free_array(a);
return n;
@ -374,7 +372,10 @@ const std::vector<xml_node*>& xml2::getElementsByName(const char* value) const
acl_foreach(iter, a)
{
ACL_XML2_NODE *tmp = (ACL_XML2_NODE*) iter.data;
xml2_node* node = NEW xml2_node(const_cast<xml2*>(this), tmp);
// xml2_node* node = NEW xml2_node(const_cast<xml2*>(this), tmp);
xml2_node* node = const_cast<dbuf_guard&>(dbuf_)
.create<xml2_node, xml2*, ACL_XML2_NODE*>
(const_cast<xml2*>(this), tmp);
const_cast<xml2*>(this)->elements_.push_back(node);
}
@ -394,7 +395,10 @@ const std::vector<xml_node*>& xml2::getElementsByAttr(
acl_foreach(iter, a)
{
ACL_XML2_NODE *tmp = (ACL_XML2_NODE*) iter.data;
xml2_node* node = NEW xml2_node(const_cast<xml2*>(this), tmp);
// xml2_node* node = NEW xml2_node(const_cast<xml2*>(this), tmp);
xml2_node* node = const_cast<dbuf_guard&>(dbuf_)
.create<xml2_node, xml2*, ACL_XML2_NODE*>
(const_cast<xml2*>(this), tmp);
const_cast<xml2*>(this)->elements_.push_back(node);
}
@ -408,8 +412,11 @@ xml_node* xml2::getElementById(const char* id) const
if (node == NULL)
return (NULL);
xml2_node* n = NEW xml2_node(const_cast<xml2*>(this), node);
const_cast<xml2*>(this)->nodes_tmp_.push_back(n);
// xml2_node* n = NEW xml2_node(const_cast<xml2*>(this), node);
// const_cast<xml2*>(this)->nodes_tmp_.push_back(n);
xml2_node* n = const_cast<dbuf_guard&>(dbuf_)
.create<xml2_node, xml2*, ACL_XML2_NODE*>
(const_cast<xml2*>(this), node);
return n;
}
@ -427,8 +434,10 @@ const acl::string& xml2::getText()
xml_node& xml2::create_node(const char* tag, const char* text /* = NULL */)
{
ACL_XML2_NODE* node = acl_xml2_create_node(xml_, tag, text);
xml2_node* n = NEW xml2_node(this, node);
nodes_tmp_.push_back(n);
// xml2_node* n = NEW xml2_node(this, node);
// nodes_tmp_.push_back(n);
xml2_node* n = dbuf_.create<xml2_node, xml2*, ACL_XML2_NODE*>
(this, node);
return *n;
}
@ -449,8 +458,10 @@ xml_node* xml2::first_node(void)
if (node == NULL)
return NULL;
xml2_node* n = NEW xml2_node(this, node);
nodes_tmp_.push_back(n);
// xml2_node* n = NEW xml2_node(this, node);
// nodes_tmp_.push_back(n);
xml2_node* n = dbuf_.create<xml2_node, xml2*, ACL_XML2_NODE*>
(this, node);
return n;
}
@ -462,8 +473,10 @@ xml_node* xml2::next_node(void)
if (node == NULL)
return NULL;
xml2_node* n = NEW xml2_node(this, node);
nodes_tmp_.push_back(n);
// xml2_node* n = NEW xml2_node(this, node);
// nodes_tmp_.push_back(n);
xml2_node* n = dbuf_.create<xml2_node, xml2*, ACL_XML2_NODE*>
(this, node);
return n;
}
@ -478,7 +491,7 @@ void xml2::build_xml(string& out) const
const char* xml2::to_string(size_t* len /* = NULL */) const
{
const char* dat = acl_xml2_build(xml_);
if (dat <= xml_->addr)
if (dat >= acl_vstring_end(xml_->vbuf))
{
if (len)
*len = 0;
@ -486,7 +499,7 @@ const char* xml2::to_string(size_t* len /* = NULL */) const
}
if (len)
*len = xml_->ptr - dat;
*len = acl_vstring_end(xml_->vbuf) - dat;
return dat;
}

View File

@ -256,7 +256,8 @@ bool istream::read_peek(string& buf, bool clear /* = false */)
if (clear)
buf.clear();
if (acl_vstream_read_peek(stream_, buf.vstring()) == ACL_VSTREAM_EOF)
int n = acl_vstream_read_peek(stream_, buf.vstring());
if (n == ACL_VSTREAM_EOF)
{
#if ACL_EWOULDBLOCK == ACL_EAGAIN
if (stream_->errnum != ACL_EWOULDBLOCK)
@ -269,6 +270,8 @@ bool istream::read_peek(string& buf, bool clear /* = false */)
}
return false;
}
else if (n == 0)
return false;
else
return true;
}