From 9a500bdc2a9914dbe96f9b65b4990030c85b357b Mon Sep 17 00:00:00 2001 From: jarodruan Date: Sat, 22 Feb 2020 21:20:30 +0800 Subject: [PATCH] merge taf, and update auth crypo to des3 --- examples/SSLDemo/Client/config.conf | 24 +- examples/SSLDemo/Server/config.conf | 24 +- servant/libservant/AdapterProxy.cpp | 101 +- servant/libservant/AdminServant.cpp | 15 +- servant/libservant/AppProtocol.cpp | 2 + servant/libservant/Application.cpp | 59 +- servant/libservant/AsyncProcThread.cpp | 46 - servant/libservant/AuthLogic.cpp | 25 +- servant/libservant/Communicator.cpp | 306 +- servant/libservant/CommunicatorEpoll.cpp | 87 +- servant/libservant/CoroutineScheduler.cpp | 9 +- servant/libservant/EndpointInfo.cpp | 106 +- servant/libservant/EndpointManager.cpp | 181 +- servant/libservant/ObjectProxy.cpp | 67 +- servant/libservant/ObjectProxyFactory.cpp | 1 + servant/libservant/Servant.cpp | 33 +- servant/libservant/ServantHandle.cpp | 76 +- servant/libservant/ServantProxy.cpp | 166 +- servant/libservant/StatReport.cpp | 16 +- servant/libservant/Transceiver.cpp | 154 +- servant/protocol | 2 +- servant/servant/AdapterProxy.h | 8 +- servant/servant/AppProtocol.h | 105 +- servant/servant/Application.h | 66 +- servant/servant/AsyncProcThread.h | 2 + servant/servant/AuthLogic.h | 2 +- servant/servant/Communicator.h | 31 +- servant/servant/CommunicatorEpoll.h | 2 +- servant/servant/CoroutineScheduler.h | 27 +- servant/servant/EndpointInfo.h | 70 +- servant/servant/EndpointManager.h | 22 +- servant/servant/Global.h | 11 +- servant/servant/Message.h | 15 +- servant/servant/NetworkUtil.h | 48 - servant/servant/ObjectProxy.h | 6 +- servant/servant/PropertyReport.h | 13 +- servant/servant/Servant.h | 20 +- servant/servant/ServantHandle.h | 17 +- servant/servant/ServantHelper.h | 3 +- servant/servant/ServantProxy.h | 77 +- servant/servant/ServantProxyFactory.h | 2 +- servant/servant/Transceiver.h | 16 +- tools/tarsparse/tars.lex.cpp | 2218 -------------- tools/tarsparse/tars.tab.cpp | 3080 -------------------- tools/tarsparse/tars.tab.hpp | 7 +- util/include/util/tc_base64.h | 15 +- util/include/util/tc_cas_queue.h | 3 +- util/include/util/tc_clientsocket.h | 47 +- util/include/util/tc_common.h | 31 +- util/include/util/tc_config.h | 23 +- util/include/util/tc_consistent_hash_new.h | 6 +- util/include/util/tc_cron.h | 259 ++ util/include/util/tc_des.h | 147 + util/include/util/tc_epoll_server.h | 226 +- util/include/util/tc_ex.h | 3 + util/include/util/tc_gzip.h | 10 + util/include/util/tc_hashmap.h | 8 +- util/include/util/tc_hashmap_compact.h | 9 +- util/include/util/tc_http.h | 58 +- util/include/util/tc_http_async.h | 3 +- util/include/util/tc_json.h | 371 +-- util/include/util/tc_lock.h | 103 +- util/include/util/tc_loop_queue.h | 32 +- util/include/util/tc_malloc_chunk.h | 2 - util/include/util/tc_md5.h | 17 +- util/include/util/tc_mem_chunk.h | 3 - util/include/util/tc_mem_queue.h | 10 +- util/include/util/tc_mem_vector.h | 12 +- util/include/util/tc_multi_hashmap.h | 44 +- util/include/util/tc_mysql.h | 135 +- util/include/util/tc_option.h | 8 + util/include/util/tc_pack.h | 12 +- util/include/util/tc_platform.h | 2 + util/include/util/tc_rbtree.h | 11 +- util/include/util/tc_sem_mutex.h | 70 +- util/include/util/tc_sha.h | 2 +- util/include/util/tc_singleton.h | 38 +- util/include/util/tc_socket.h | 68 +- util/include/util/tc_spin_lock.h | 2 - util/include/util/tc_squeue.h | 391 ++- util/include/util/tc_thread_cond.h | 1 - util/include/util/tc_thread_pool.h | 1 - util/include/util/tc_thread_rwlock.h | 13 +- util/include/util/tc_timeout_queue_map.h | 4 +- util/include/util/tc_timeout_queue_new.h | 30 +- util/include/util/tc_timer.h | 217 ++ util/src/tc_base64.cpp | 36 +- util/src/tc_clientsocket.cpp | 45 +- util/src/tc_common.cpp | 370 +-- util/src/tc_config.cpp | 290 +- util/src/tc_consistent_hash_new.cpp | 21 +- util/src/tc_cron.cpp | 386 +++ util/src/tc_des.cpp | 581 ++++ util/src/tc_epoll_server.cpp | 293 +- util/src/tc_gzip.cpp | 58 +- util/src/tc_hashmap.cpp | 649 +++-- util/src/tc_hashmap_compact.cpp | 24 +- util/src/tc_http.cpp | 437 +-- util/src/tc_json.cpp | 1295 ++++---- util/src/tc_malloc_chunk.cpp | 4 +- util/src/tc_md5.cpp | 44 +- util/src/tc_mysql.cpp | 295 +- util/src/tc_option.cpp | 18 + util/src/tc_sem_mutex.cpp | 241 +- util/src/tc_socket.cpp | 65 +- util/src/tc_thread.cpp | 1 + util/src/tc_thread_cond.cpp | 73 - util/src/tc_thread_mutex.cpp | 197 +- util/src/tc_thread_rwlock.cpp | 99 - util/src/tc_timeprovider.cpp | 122 - util/src/tc_timer.cpp | 150 + 111 files changed, 6089 insertions(+), 9520 deletions(-) delete mode 100644 tools/tarsparse/tars.lex.cpp delete mode 100644 tools/tarsparse/tars.tab.cpp create mode 100644 util/include/util/tc_cron.h create mode 100644 util/include/util/tc_des.h create mode 100644 util/include/util/tc_timer.h create mode 100644 util/src/tc_cron.cpp create mode 100644 util/src/tc_des.cpp create mode 100644 util/src/tc_timer.cpp diff --git a/examples/SSLDemo/Client/config.conf b/examples/SSLDemo/Client/config.conf index 7c1ad85..a8b4505 100755 --- a/examples/SSLDemo/Client/config.conf +++ b/examples/SSLDemo/Client/config.conf @@ -23,28 +23,28 @@ #module name modulename = TestApp.SSLClient #server crt - ca = ../examples/SSLDemo/certs/server.crt + ca = ./examples/SSLDemo/certs/server.crt #can be empty - cert = ../examples/SSLDemo/certs/client.crt + cert = ./examples/SSLDemo/certs/client.crt #can be empty - key = ../examples/SSLDemo/certs/client.key + key = ./examples/SSLDemo/certs/client.key #server crt - ca = ../examples/SSLDemo/certs/server1.crt + ca = ./examples/SSLDemo/certs/server1.crt #can be empty - # cert = ../examples/SSLDemo/certs/client1.crt + # cert = ./examples/SSLDemo/certs/client1.crt #can be empty - # key = ../examples/SSLDemo/certs/client1.key + # key = ./examples/SSLDemo/certs/client1.key #server crt - ca = ../examples/SSLDemo/certs/server1.crt + ca = ./examples/SSLDemo/certs/server1.crt #can be empty - cert = ../examples/SSLDemo/certs/client1.crt + cert = ./examples/SSLDemo/certs/client1.crt #can be empty - key = ../examples/SSLDemo/certs/client1.key + key = ./examples/SSLDemo/certs/client1.key @@ -53,11 +53,11 @@ #auth secret key secretkey = 123456 #server crt - ca = ../examples/SSLDemo/certs/server1.crt + ca = ./examples/SSLDemo/certs/server1.crt #can be empty - cert = ../examples/SSLDemo/certs/client1.crt + cert = ./examples/SSLDemo/certs/client1.crt #can be empty - key = ../examples/SSLDemo/certs/client1.key + key = ./examples/SSLDemo/certs/client1.key diff --git a/examples/SSLDemo/Server/config.conf b/examples/SSLDemo/Server/config.conf index 6570aeb..4c56ef0 100755 --- a/examples/SSLDemo/Server/config.conf +++ b/examples/SSLDemo/Server/config.conf @@ -52,9 +52,9 @@ # log = tars.tarslog.LogObj #client crt, it can be empty when verifyclient is 0 - ca = ../examples/SSLDemo/certs/client.crt - cert = ../examples/SSLDemo/certs/server.crt - key = ../examples/SSLDemo/certs/server.key + ca = ./examples/SSLDemo/certs/client.crt + cert = ./examples/SSLDemo/certs/server.crt + key = ./examples/SSLDemo/certs/server.key #default is 0 verifyclient = 1 @@ -90,9 +90,9 @@ queuecap = 1000000 #tars protocol protocol = tars - # ca = ../examples/SSLDemo/certs/client1.crt - cert = ../examples/SSLDemo/certs/server1.crt - key = ../examples/SSLDemo/certs/server1.key + # ca = ./examples/SSLDemo/certs/client1.crt + cert = ./examples/SSLDemo/certs/server1.crt + key = ./examples/SSLDemo/certs/server1.key #default is 0 verifyclient = 0 @@ -112,9 +112,9 @@ queuecap = 1000000 #tars protocol protocol = tars - ca = ../examples/SSLDemo/certs/client1.crt - cert = ../examples/SSLDemo/certs/server1.crt - key = ../examples/SSLDemo/certs/server1.key + ca = ./examples/SSLDemo/certs/client1.crt + cert = ./examples/SSLDemo/certs/server1.crt + key = ./examples/SSLDemo/certs/server1.key #default is 0 verifyclient = 1 @@ -138,9 +138,9 @@ accesskey = tars-test-user #auth secret key secretkey = 123456 - ca = ../examples/SSLDemo/certs/client1.crt - cert = ../examples/SSLDemo/certs/server1.crt - key = ../examples/SSLDemo/certs/server1.key + ca = ./examples/SSLDemo/certs/client1.crt + cert = ./examples/SSLDemo/certs/server1.crt + key = ./examples/SSLDemo/certs/server1.key #default is 0 verifyclient = 1 diff --git a/servant/libservant/AdapterProxy.cpp b/servant/libservant/AdapterProxy.cpp index c1dd16d..68fb9e8 100755 --- a/servant/libservant/AdapterProxy.cpp +++ b/servant/libservant/AdapterProxy.cpp @@ -69,13 +69,13 @@ AdapterProxy::AdapterProxy(ObjectProxy * pObjectProxy,const EndpointInfo &ep,Com _timeoutLogFlag = _communicator->getTimeoutLogFlag(); } - if (ep.type() == EndpointInfo::UDP) + if (ep.isTcp()) { - _trans.reset(new UdpTransceiver(this, ep)); + _trans.reset(new TcpTransceiver(this, ep)); } else { - _trans.reset(new TcpTransceiver(this, ep)); + _trans.reset(new UdpTransceiver(this, ep)); } //初始化stat的head信息 @@ -176,7 +176,7 @@ int AdapterProxy::invoke(ReqMessage * msg) //链表是空的, 则直接发送当前这条数据, 如果链表非空或者发送失败了, 则放到队列中, 等待下次发送 if(_timeoutQueue->sendListEmpty() && _trans->sendRequest(msg->sReqData) != Transceiver::eRetError) { - TLOGTARS("[TARS][AdapterProxy::invoke push (send) objname:" << _objectProxy->name() << ",desc:" << _endpoint.desc() << ",id:" << msg->request.iRequestId << endl); + TLOGTARS("[TARS][AdapterProxy::invoke push (send) obj:" << _objectProxy->name() << ",desc:" << _endpoint.desc() << ",id:" << msg->request.iRequestId << endl); //请求发送成功了,单向调用直接返回 if(msg->eType == ReqMessage::ONE_WAY) @@ -198,7 +198,7 @@ int AdapterProxy::invoke(ReqMessage * msg) msg->eStatus = ReqMessage::REQ_EXC; finishInvoke(msg); - return 0; + } } @@ -215,7 +215,6 @@ int AdapterProxy::invoke(ReqMessage * msg) msg->eStatus = ReqMessage::REQ_EXC; finishInvoke(msg); - return 0; } } @@ -268,7 +267,7 @@ void AdapterProxy::doInvoke() void AdapterProxy::finishInvoke(bool bFail) { - TLOGTARS("[TARS][AdapterProxy::finishInvoke(bool) objname:" << _objectProxy->name() << ",desc:" << _endpoint.desc() << ",bFail:" << bFail << endl); + TLOGTARS("[TARS][AdapterProxy::finishInvoke(bool) obj:" << _objectProxy->name() << ",desc:" << _endpoint.desc() << ",bFail:" << bFail << endl); time_t now = TNOW; @@ -369,8 +368,12 @@ void AdapterProxy::finishInvoke(bool bFail) } } +int AdapterProxy::getConTimeout() +{ + return _objectProxy->getConTimeout(); +} -bool AdapterProxy::checkActive(bool bForceConnect) +bool AdapterProxy::checkActive(bool bForceConnect, bool onlyCheck) { time_t now = TNOW; @@ -466,11 +469,6 @@ void AdapterProxy::setConTimeout(bool bConTimeout) } } -int AdapterProxy::getConTimeout() -{ - return _objectProxy->getConTimeout(); -} - //屏蔽结点 void AdapterProxy::setInactive() { @@ -485,32 +483,8 @@ void AdapterProxy::setInactive() void AdapterProxy::finishInvoke(shared_ptr & rsp) { - TLOGTARS("[TARS][AdapterProxy::finishInvoke(ResponsePacket) objname:" << _objectProxy->name() << ",desc:" << _endpoint.desc() - << ",id:" << rsp->iRequestId << endl); - -// if (_trans->getAuthState() != AUTH_SUCC) -// { -// std::string ret(rsp->sBuffer.begin(), rsp->sBuffer.end()); -// tars::AUTH_STATE tmp = AUTH_SUCC; -// tars::stoe(ret, tmp); -// int newstate = tmp; -// -// TLOGTARS("[TARS]AdapterProxy::finishInvoke from state " << _trans->getAuthState() << " to " << newstate << endl); -// _trans->setAuthState(newstate); -// -// if (newstate == AUTH_SUCC) -// { -// // flush old buffered msg when auth is not complete -// doInvoke(); -// } -// else -// { -// TLOGERROR("newstate is " << newstate << ", error close!\n"); -// _trans->close(); -// } -// -// return; -// } +// TLOGTARS("[TARS][AdapterProxy::finishInvoke(ResponsePacket) obj:" << _objectProxy->name() << ", desc:" << _endpoint.desc() +// << ", id:" << rsp->iRequestId << endl); ReqMessage * msg = NULL; @@ -544,7 +518,7 @@ void AdapterProxy::finishInvoke(shared_ptr & rsp) { if(_timeoutLogFlag) { - TLOGERROR("[TARS][AdapterProxy::finishInvoke(ResponsePacket) objname:"<< _objectProxy->name() << ",get req-ptr NULL,may be timeout,id:" << rsp->iRequestId + TLOGERROR("[TARS][AdapterProxy::finishInvoke(ResponsePacket) obj:"<< _objectProxy->name() << ",get req-ptr NULL,may be timeout,id:" << rsp->iRequestId << ",desc:" << _endpoint.desc() << endl); } return ; @@ -564,14 +538,18 @@ void AdapterProxy::finishInvoke(ReqMessage * msg) { assert(msg->eStatus != ReqMessage::REQ_REQ); - TLOGTARS("[TARS][AdapterProxy::finishInvoke(ReqMessage) objname:" << _objectProxy->name() << ",desc:" << _endpoint.desc() << " ,id:" << msg->response->iRequestId << endl); + TLOGTARS("[TARS][AdapterProxy::finishInvoke(ReqMessage) obj:" << _objectProxy->name() << ", desc:" << _endpoint.desc() + << " ,id:" << msg->response->iRequestId + << ", status:" << msg->eStatus + << ", ret: " << msg->response->iRet << endl); + +#ifdef _USE_OPENTRACKING + finishTrack(msg); +#endif //单向调用 if(msg->eType == ReqMessage::ONE_WAY) { - #ifdef _USE_OPENTRACKING - finishTrack(msg); - #endif delete msg; msg = NULL; return ; @@ -579,9 +557,7 @@ void AdapterProxy::finishInvoke(ReqMessage * msg) //stat 上报调用统计 stat(msg); -#ifdef _USE_OPENTRACKING - finishTrack(msg); -#endif + //超时屏蔽统计,异常不算超时统计 if(msg->eStatus != ReqMessage::REQ_EXC && !msg->bPush) { @@ -596,8 +572,8 @@ void AdapterProxy::finishInvoke(ReqMessage * msg) assert(msg->pMonitor); TC_ThreadLock::Lock sync(*(msg->pMonitor)); + msg->bMonitorFin = true; msg->pMonitor->notify(); - msg->bMonitorFin = true; } else { @@ -621,13 +597,15 @@ void AdapterProxy::finishInvoke(ReqMessage * msg) { msg->callback->onDispatch(msgPtr); } - catch(exception & e) + catch (exception & e) { - TLOGERROR("[TARS][AdapterProxy::finishInvoke(ReqMessage) ex:" << e.what() << ",line:" << __LINE__ << endl); + //FDLOG("taferror")<<"[TAF]AdapterProxy::finishInvoke(ReqMessage) exp:"<callback->getCoroParallelBasePtr(); - if(ptr) + if (ptr) { ptr->insert(msg); - if(ptr->checkAllReqReturn()) + if (ptr->checkAllReqReturn()) { msg->sched->put(msg->iCoroId); } @@ -663,13 +641,17 @@ void AdapterProxy::finishInvoke(ReqMessage * msg) return; } +//ObjectProxy * AdapterProxy::getObjProxy() +//{ +// return _objectProxy; +//} void AdapterProxy::doTimeout() { ReqMessage * msg; while(_timeoutQueue->timeout(msg)) { - TLOGTARS("[TARS][AdapterProxy::doTimeout objname:" << _objectProxy->name() << ",desc:" << _endpoint.desc() << ",id " << msg->request.iRequestId << endl); + TLOGTARS("[TARS][AdapterProxy::doTimeout obj:" << _objectProxy->name() << ",desc:" << _endpoint.desc() << ",id " << msg->request.iRequestId << endl); assert(msg->eStatus == ReqMessage::REQ_REQ); @@ -763,12 +745,11 @@ void AdapterProxy::finishTrack(ReqMessage * msg) void AdapterProxy::stat(ReqMessage * msg) { - TLOGTARS("[TARS][AdapterProxy::stat(ReqMessage) objname:" << _objectProxy->name() << ",desc:" << _endpoint.desc() << ",id:" << msg->response->iRequestId << endl); - - if(msg->bPush) + if (msg->bPush) { return ; } + TLOGTARS("[TARS]AdapterProxy::stat(ReqMessage) " << _objectProxy->name() << ", " << _endpoint.desc() << " ,id:" << msg->response->iRequestId << endl); StatMicMsgBody body; int64_t sptime = 0; @@ -837,7 +818,7 @@ void AdapterProxy::merge(const StatMicMsgBody& inBody,StatMicMsgBody& outBody/*o void AdapterProxy::mergeStat(map & mStatMicMsg) { - TLOGTARS("[TARS][AdapterProxy::doStat objname:" << _objectProxy->name() << ",desc:" << _endpoint.desc() << endl); + TLOGTARS("[TARS][AdapterProxy::doStat obj:" << _objectProxy->name() << ",desc:" << _endpoint.desc() << endl); for (const auto& kv : _statBody) { @@ -883,7 +864,7 @@ void AdapterProxy::addConnExc(bool bExc) TLOGERROR("[TARS][AdapterProxy::addConnExc desc:"<< _endpoint.desc() << ",connect exception status is false!(connect ok)"< ProxyProtocol::tarsRequest(RequestPacket& request, Transceiver *) { TarsOutputStream os; diff --git a/servant/libservant/Application.cpp b/servant/libservant/Application.cpp index 16eed0c..c09408b 100644 --- a/servant/libservant/Application.cpp +++ b/servant/libservant/Application.cpp @@ -36,9 +36,6 @@ #endif -// #include -// #include - #if TARS_SSL #include "util/tc_openssl.h" #endif @@ -76,11 +73,11 @@ std::string ServerConfig::Notify; //信息通知中心 std::string ServerConfig::LogPath; //logpath int ServerConfig::LogSize; //log大小(字节) int ServerConfig::LogNum; //log个数() -std::string ServerConfig::LogLevel; //log日志级别 +std::string ServerConfig::LogLevel; //log日志级别 std::string ServerConfig::ConfigFile; //框架配置文件路径 -int ServerConfig::ReportFlow; //是否服务端上报所有接口stat流量 0不上报 1上报 (用于非tars协议服务流量统计) -int ServerConfig::IsCheckSet; //是否对按照set规则调用进行合法性检查 0,不检查,1检查 -bool ServerConfig::OpenCoroutine; //是否启用协程处理方式 +int ServerConfig::ReportFlow = 1; //是否服务端上报所有接口stat流量 0不上报 1上报 (用于非taf协议服务流量统计) +int ServerConfig::IsCheckSet = 1; //是否对按照set规则调用进行合法性检查 0,不检查,1检查 +bool ServerConfig::OpenCoroutine = false; //是否启用协程处理方式 size_t ServerConfig::CoroutineMemSize; //协程占用内存空间的最大大小 uint32_t ServerConfig::CoroutineStackSize; //每个协程的栈大小(默认128k) bool ServerConfig::ManualListen = false; //手工启动监听端口 @@ -108,7 +105,6 @@ PropertyReportPtr g_pReportRspQueue; /**上报服务端发送队列大小的间隔时间**/ #define REPORT_SEND_QUEUE_INTERVAL 10 - /////////////////////////////////////////////////////////////////////////////////////////// Application::Application() { @@ -126,6 +122,11 @@ Application::~Application() #endif } +string Application::getTarsVersion() +{ + return TARS_VERSION; +} + TC_Config& Application::getConfig() { return _conf; @@ -175,6 +176,16 @@ void heartBeatFunc(const string& adapterName) TARS_KEEPALIVE(adapterName); } +void Application::manualListen() +{ + vector v = getEpollServer()->getBindAdapters(); + + for(auto &b : v) + { + b->manualListen(); + } +} + void Application::waitForShutdown() { _epollServer->setCallbackFunctor(reportRspQueue); @@ -712,8 +723,8 @@ void Application::main(const TC_Option &option) //设置服务的core limit TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_CLOSE_CORE, Application::cmdCloseCoreDump); - //重新加载locator信息 - TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_RELOAD_LOCATOR, Application::cmdReloadLocator); + //设置是否标准输出 + TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_CLOSE_COUT, Application::cmdCloseCout); //上报版本 TARS_REPORTVERSION(TARS_VERSION); @@ -855,6 +866,7 @@ string Application::toDefault(const string &s, const string &sDefault) } return s; } + string Application::setDivision() { bool bEnableSet = TC_Common::lower(_conf.get("/tars/application", "n"))=="y"?true:false;; @@ -939,6 +951,9 @@ void Application::initializeServer() exe = _conf.get("/tars/application/server"); } + ServerConfig::ServerName = toDefault(_conf.get("/tars/application/server"), exe); + + #if TARGET_PLATFORM_WINDOWS ServerConfig::BasePath = TC_File::simplifyDirectory(_conf.get("/tars/application/server")) + FILE_SEP; if (ServerConfig::BasePath == FILE_SEP) @@ -964,7 +979,6 @@ void Application::initializeServer() #endif ServerConfig::TarsPath = TC_File::simplifyDirectory(ServerConfig::LogPath + FILE_SEP + ".." + FILE_SEP) + FILE_SEP; - ServerConfig::ServerName = toDefault(_conf.get("/tars/application/server"), exe); ServerConfig::LogSize = TC_Common::toSize(toDefault(_conf.get("/tars/application/server"), "52428800"), 52428800); ServerConfig::LogNum = TC_Common::strto(toDefault(_conf.get("/tars/application/server"), "10")); @@ -976,9 +990,9 @@ void Application::initializeServer() ServerConfig::Notify = _conf.get("/tars/application/server"); ServerConfig::ReportFlow = _conf.get("/tars/application/server")=="0"?0:1; ServerConfig::IsCheckSet = _conf.get("/tars/application/server","1")=="0"?0:1; - ServerConfig::OpenCoroutine = TC_Common::strto(toDefault(_conf.get("/tars/application/server"), "0")); - ServerConfig::CoroutineMemSize = TC_Common::toSize(toDefault(_conf.get("/tars/application/server"), "1073741824"), 1073741824); - ServerConfig::CoroutineStackSize = TC_Common::toSize(toDefault(_conf.get("/tars/application/server"), "131072"), 131072); + ServerConfig::OpenCoroutine = TC_Common::strto(toDefault(_conf.get("/tars/application/server"), "0")); + ServerConfig::CoroutineMemSize = TC_Common::toSize(toDefault(_conf.get("/tars/application/server"), "1073741824"), 1073741824); + ServerConfig::CoroutineStackSize= (uint32_t)TC_Common::toSize(toDefault(_conf.get("/tars/application/server"), "131072"), 131072); ServerConfig::ManualListen = _conf.get("/tars/application/server", "0") == "0" ? false : true; ServerConfig::MergeNetImp = _conf.get("/tars/application/server", "0") == "0" ? false : true; ServerConfig::NetThread = TC_Common::strto(toDefault(_conf.get("/tars/application/server"), "1")); @@ -1021,23 +1035,20 @@ void Application::initializeServer() //输出信息 outServer(cout); - string sNetThread = _conf.get("/tars/application/server", "1"); - unsigned int iNetThreadNum = TC_Common::strto(sNetThread); - - if(iNetThreadNum < 1) + if(ServerConfig::NetThread < 1) { - iNetThreadNum = 1; + ServerConfig::NetThread = 1; cout << OUT_LINE << "\nwarning:netThreadNum < 1." << endl; } //网络线程的配置数目不能15个 - if(iNetThreadNum > 15) + if(ServerConfig::NetThread > 15) { - iNetThreadNum = 15; + ServerConfig::NetThread = 15; cout << OUT_LINE << "\nwarning:netThreadNum > 15." << endl; } - _epollServer = new TC_EpollServer(iNetThreadNum); + _epollServer = new TC_EpollServer(ServerConfig::NetThread); //初始化服务是否对空链接进行超时检查 bool bEnable = (_conf.get("/tars/application/server","0")=="1")?true:false; @@ -1108,8 +1119,6 @@ void Application::initializeServer() setAdapter(lsPtr, "AdminAdapter"); -// lsPtr->setName("AdminAdapter"); - lsPtr->setEndpoint(ServerConfig::Local); lsPtr->setMaxConns(TC_EpollServer::BindAdapter::DEFAULT_MAX_CONN); @@ -1279,6 +1288,7 @@ void Application::checkServantNameValid(const string& servant, const string& sPr cout << os.str() << endl; + exit(-1); } } @@ -1297,7 +1307,6 @@ void Application::outAdapter(ostream &os, const string &v, TC_EpollServer::BindA // os << outfill("queuesize") << lsPtr->getRecvBufferSize() << endl; os << TC_Common::outfill("connections") << lsPtr->getNowConnection() << endl; os << TC_Common::outfill("protocol") << lsPtr->getProtocolName() << endl; - // os << TC_Common::outfill("handlegroup") << lsPtr->getHandleGroupName() << endl; os << TC_Common::outfill("handlethread") << lsPtr->getHandleNum() << endl; } ////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/servant/libservant/AsyncProcThread.cpp b/servant/libservant/AsyncProcThread.cpp index 06620c1..c64781c 100644 --- a/servant/libservant/AsyncProcThread.cpp +++ b/servant/libservant/AsyncProcThread.cpp @@ -128,51 +128,5 @@ void AsyncProcThread::callback(ReqMessage * msg) TLOGERROR("[TARS][AsyncProcThread exception.]" << endl); } } - -// void AsyncProcThread::run() -// { -// while (!_terminate) -// { -// ReqMessage * msg = NULL; - -// //异步请求回来的响应包处理 -// if(_msgQueue->empty()) -// { -// TC_ThreadLock::Lock lock(*this); -// timedWait(1000); -// } - -// if (_msgQueue->pop_front(msg)) -// { -// //从回调对象把线程私有数据传递到回调线程中 -// ServantProxyThreadData * pServantProxyThreadData = ServantProxyThreadData::getData(); -// assert(pServantProxyThreadData != NULL); - -// //把染色的消息设置在线程私有数据里面 -// pServantProxyThreadData->_dyeing = msg->bDyeing; -// pServantProxyThreadData->_dyeingKey = msg->sDyeingKey; - -// if(msg->adapter) -// { -// // snprintf(pServantProxyThreadData->_szHost, sizeof(pServantProxyThreadData->_szHost), "%s", msg->adapter->endpoint().desc().c_str()); -// pServantProxyThreadData->_szHost = msg->adapter->endpoint().desc(); -// } - -// try -// { -// ReqMessagePtr msgPtr = msg; -// msg->callback->onDispatch(msgPtr); -// } -// catch (exception& e) -// { -// TLOGERROR("[TARS][AsyncProcThread exception]:" << e.what() << endl); -// } -// catch (...) -// { -// TLOGERROR("[TARS][AsyncProcThread exception.]" << endl); -// } -// } -// } -// } ///////////////////////////////////////////////////////////////////////// } diff --git a/servant/libservant/AuthLogic.cpp b/servant/libservant/AuthLogic.cpp index e5b669b..fb1d300 100644 --- a/servant/libservant/AuthLogic.cpp +++ b/servant/libservant/AuthLogic.cpp @@ -15,7 +15,7 @@ */ #include "util/tc_epoll_server.h" -#include "util/tc_tea.h" +#include "util/tc_des.h" #include "util/tc_sha.h" #include "util/tc_md5.h" #include "servant/Application.h" @@ -169,18 +169,18 @@ int processAuthReqHelper(const BasicAuthPackage& pkg, const BasicAuthInfo& info) tmp[i] |= pt[i]; } - tmpKey = TC_MD5::md5bin(tmp); + tmpKey = TC_MD5::md5str(tmp); } string secret1; { - vector dec; +// vector dec; try { - TC_Tea::decrypt(tmpKey.data(), pkg.sSignature.data(), pkg.sSignature.size(), dec); - secret1.assign(dec.begin(), dec.end()); + secret1 = TC_Des::decrypt3(tmpKey.data(), pkg.sSignature.data(), pkg.sSignature.size()); +// secret1.assign(dec.begin(), dec.end()); } - catch (const TC_Tea_Exception& ) + catch (const TC_DES_Exception& ) { return AUTH_DEC_FAIL; } @@ -248,7 +248,7 @@ string defaultCreateAuthReq(const BasicAuthInfo& info /*, const string& hashMeth string secret2 = TC_SHA::sha1str(secret1.data(), secret1.size()); // create tmpKey - string tmpKey; + string tmpKey; { string tmp = secret2; const char* pt = (const char* )&pkg.iTime; @@ -256,16 +256,17 @@ string defaultCreateAuthReq(const BasicAuthInfo& info /*, const string& hashMeth { tmp[i] |= pt[i]; } - // 保证key是16字节 - tmpKey = TC_MD5::md5bin(tmp); + // 只用了前面24字节 + tmpKey = TC_MD5::md5str(tmp); } // then use tmpKey to enc secret1, show server that I know secret1, ie, I know secret. - vector secret1Enc; +// vector secret1Enc; - TC_Tea::encrypt(tmpKey.data(), secret1.data(), secret1.size(), secret1Enc); +// TC_Tea::encrypt(tmpKey.data(), secret1.data(), secret1.size(), secret1Enc); + pkg.sSignature = TC_Des::encrypt3(tmpKey.data(), secret1.data(), secret1.size()); - pkg.sSignature.assign(secret1Enc.begin(), secret1Enc.end()); +// pkg.sSignature.assign(secret1Enc.begin(), secret1Enc.end()); pkg.writeTo(os); return os.getByteBuffer(); diff --git a/servant/libservant/Communicator.cpp b/servant/libservant/Communicator.cpp index d94c489..7744a49 100644 --- a/servant/libservant/Communicator.cpp +++ b/servant/libservant/Communicator.cpp @@ -50,6 +50,10 @@ Communicator::Communicator() , _traceManager(NULL) #endif { +#if TARGET_PLATFORM_WINDOWS + WSADATA wsadata; + WSAStartup(MAKEWORD(2, 2), &wsadata); +#endif memset(_communicatorEpoll,0,sizeof(_communicatorEpoll)); } @@ -67,6 +71,10 @@ Communicator::Communicator(TC_Config& conf, const string& domain/* = CONFIG_ROOT Communicator::~Communicator() { terminate(); + +#if TARGET_PLATFORM_WINDOWS + WSACleanup(); +#endif } bool Communicator::isTerminating() @@ -170,12 +178,20 @@ void Communicator::setProperty(TC_Config& conf, const string& domain/* = CONFIG_ } } - initClientConfig(); +// initClientConfig(); } -void Communicator::initClientConfig() +void Communicator::initialize() { - ClientConfig::SetOpen = TC_Common::lower(getProperty("enableset", "n"))=="y"?true:false; + TC_LockT lock(*this); + + if (_initialized) return; + + _initialized = true; + + ClientConfig::TarsVersion = TARS_VERSION; + + ClientConfig::SetOpen = TC_Common::lower(getProperty("enableset", "n")) == "y" ? true : false; if (ClientConfig::SetOpen) { @@ -185,9 +201,7 @@ void Communicator::initClientConfig() string sWildCard = "*"; - if (vtSetDivisions.size()!=3 - || vtSetDivisions[0]==sWildCard - || vtSetDivisions[1]==sWildCard) + if (vtSetDivisions.size()!=3 || vtSetDivisions[0]==sWildCard || vtSetDivisions[1]==sWildCard) { //set分组名不对时默认没有打开set分组 ClientConfig::SetOpen = false; @@ -223,10 +237,116 @@ void Communicator::initClientConfig() //取失败则使用ip代替进程名 exe = ClientConfig::LocalIp; } + ClientConfig::ModuleName = getProperty("modulename", exe); + +#if TARS_SSL + + string ca = getProperty("ca"); + string cert = getProperty("cert"); + string key = getProperty("key"); + + if(!ca.empty()) { + _ctx = TC_OpenSSL::newCtx(ca, cert, key, false); + + if(!_ctx) + { + TLOGERROR("[TARS]load client ssl error, ca:" << ca << endl); + exit(-1); + } + } +#endif + + _servantProxyFactory = new ServantProxyFactory(this); + + _clientThreadNum = TC_Common::strto(getProperty("netthread","1")); + + if(0 == _clientThreadNum) + { + _clientThreadNum = 1; + } + else if(MAX_CLIENT_THREAD_NUM < _clientThreadNum) + { + _clientThreadNum = MAX_CLIENT_THREAD_NUM; + } + + //异步线程数 + _asyncThreadNum = TC_Common::strto(getProperty("asyncthread", "3")); + + if(_asyncThreadNum == 0) + { + _asyncThreadNum = 3; + } + + if(_asyncThreadNum > MAX_CLIENT_ASYNCTHREAD_NUM) + { + _asyncThreadNum = MAX_CLIENT_ASYNCTHREAD_NUM; + } + + bool merge = TC_Common::strto(getProperty("mergenetasync", "0")); + + //异步队列的大小 + size_t iAsyncQueueCap = TC_Common::strto(getProperty("asyncqueuecap", "100000")); + if(iAsyncQueueCap < 10000) + { + iAsyncQueueCap = 10000; + } + + //第一个通信器才去启动回调线程 + for (size_t i = 0; i < _asyncThreadNum; ++i) { + _asyncThread.push_back(new AsyncProcThread(iAsyncQueueCap, merge)); + } + + //stat总是有对象, 保证getStat返回的对象总是有效 + _statReport = new StatReport(_clientThreadNum); + + for(size_t i = 0; i < _clientThreadNum; ++i) + { + _communicatorEpoll[i] = new CommunicatorEpoll(this, i); + _communicatorEpoll[i]->start(); + } + + //异步队列数目上报 + _reportAsyncQueue= getStatReport()->createPropertyReport(ClientConfig::ModuleName + ".asyncqueue", PropertyReport::avg()); + + //初始化统计上报接口 + string statObj = getProperty("stat", ""); + + string propertyObj = getProperty("property", ""); + + int iReportInterval = TC_Common::strto(getProperty("report-interval", "60000")); + + int iReportTimeout = TC_Common::strto(getProperty("report-timeout", "5000")); + + int iSampleRate = TC_Common::strto(getProperty("sample-rate", "1000")); + + int iMaxSampleCount = TC_Common::strto(getProperty("max-sample-count", "100")); + + int iMaxReportSize = TC_Common::strto(getProperty("max-report-size", "1400")); + + _timeoutLogFlag = TC_Common::strto(getProperty("timeout-log-flag", "1")); + + _minTimeout = TC_Common::strto(getProperty("min-timeout", "100")); + if(_minTimeout < 1) + _minTimeout = 1; + + StatFPrx statPrx = NULL; + if (!statObj.empty()) + { + statPrx = stringToProxy(statObj); + } + + //上报Property信息的代理 + PropertyFPrx propertyPrx = NULL; + if (!propertyObj.empty()) + { + propertyPrx = stringToProxy(propertyObj); + } + + string sSetDivision = ClientConfig::SetOpen?ClientConfig::SetDivision:""; + _statReport->setReportInfo(statPrx, propertyPrx, ClientConfig::ModuleName, ClientConfig::LocalIp, sSetDivision, iReportInterval, iSampleRate, iMaxSampleCount, iMaxReportSize, iReportTimeout); - ClientConfig::ModuleName = getProperty("modulename", exe); #if _USE_OPENTRACKING - string collector_host = getProperty("collector_host", ""); + string collector_host = getProperty("collector_host", ""); string collector_port = getProperty("collector_port", ""); if(!collector_host.empty() && !collector_port.empty()) { @@ -234,7 +354,7 @@ void Communicator::initClientConfig() zipkin::ZipkinOtTracerOptions options; options.service_name = ClientConfig::ModuleName; options.service_address = {zipkin::IpVersion::v4, ClientConfig::LocalIp}; - + options.sample_rate = strtod(getProperty("sample_rate", "1.0").c_str(), NULL); options.collector_host = collector_host; options.collector_port = atoi(collector_port.c_str()); @@ -245,13 +365,12 @@ void Communicator::initClientConfig() } + void Communicator::setProperty(const map& properties) { TC_LockT lock(*this); _properties = properties; - - initClientConfig(); } void Communicator::setProperty(const string& name, const string& value) @@ -259,8 +378,6 @@ void Communicator::setProperty(const string& name, const string& value) TC_LockT lock(*this); _properties[name] = value; - - initClientConfig(); } string Communicator::getProperty(const string& name, const string& dft/* = ""*/) @@ -333,127 +450,6 @@ int Communicator::reloadProperty(string & sResult) return 0; } -void Communicator::initialize() -{ - TC_LockT lock(*this); - - if (_initialized) - return; - - _initialized = true; - -#if TARS_SSL - - string ca = getProperty("ca"); - string cert = getProperty("cert"); - string key = getProperty("key"); - - if(!ca.empty()) { - _ctx = TC_OpenSSL::newCtx(ca, cert, key, false); - - if(!_ctx) - { - TLOGERROR("[TARS]load client ssl error, ca:" << ca << endl); - exit(-1); - } - } -#endif - - _servantProxyFactory = new ServantProxyFactory(this); - - _clientThreadNum = TC_Common::strto(getProperty("netthread","1")); - - if(0 == _clientThreadNum) - { - _clientThreadNum = 1; - } - else if(MAX_CLIENT_THREAD_NUM < _clientThreadNum) - { - _clientThreadNum = MAX_CLIENT_THREAD_NUM; - } - - //异步线程数 - _asyncThreadNum = TC_Common::strto(getProperty("asyncthread", "3")); - - if(_asyncThreadNum == 0) - { - _asyncThreadNum = 3; - } - - if(_asyncThreadNum > MAX_CLIENT_ASYNCTHREAD_NUM) - { - _asyncThreadNum = MAX_CLIENT_ASYNCTHREAD_NUM; - } - - bool merge = TC_Common::strto(getProperty("mergenetasync", "0")); - - //异步队列的大小 - size_t iAsyncQueueCap = TC_Common::strto(getProperty("asyncqueuecap", "100000")); - if(iAsyncQueueCap < 10000) - { - iAsyncQueueCap = 10000; - } - - //第一个通信器才去启动回调线程 - for (size_t i = 0; i < _asyncThreadNum; ++i) { - _asyncThread.push_back(new AsyncProcThread(iAsyncQueueCap, merge)); - } - - //stat总是有对象, 保证getStat返回的对象总是有效 - _statReport = new StatReport(_clientThreadNum); - - for(size_t i = 0; i < _clientThreadNum; ++i) - { - _communicatorEpoll[i] = new CommunicatorEpoll(this, i); - _communicatorEpoll[i]->start(); - } - - //异步队列数目上报 - string moduleName = getProperty("modulename", ""); - if(!moduleName.empty()) - { - _reportAsyncQueue= getStatReport()->createPropertyReport(moduleName + ".asyncqueue", PropertyReport::avg()); - } - - //初始化统计上报接口 - string statObj = getProperty("stat", ""); - - string propertyObj = getProperty("property", ""); - - int iReportInterval = TC_Common::strto(getProperty("report-interval", "60000")); - - int iReportTimeout = TC_Common::strto(getProperty("report-timeout", "5000")); - - int iSampleRate = TC_Common::strto(getProperty("sample-rate", "1000")); - - int iMaxSampleCount = TC_Common::strto(getProperty("max-sample-count", "100")); - - int iMaxReportSize = TC_Common::strto(getProperty("max-report-size", "1400")); - - _timeoutLogFlag = TC_Common::strto(getProperty("timeout-log-flag", "1")); - - _minTimeout = TC_Common::strto(getProperty("min-timeout", "100")); - if(_minTimeout < 1) - _minTimeout = 1; - - StatFPrx statPrx = NULL; - if (!statObj.empty()) - { - statPrx = stringToProxy(statObj); - } - - //上报Property信息的代理 - PropertyFPrx propertyPrx = NULL; - if (!propertyObj.empty()) - { - propertyPrx = stringToProxy(propertyObj); - } - - string sSetDivision = ClientConfig::SetOpen?ClientConfig::SetDivision:""; - _statReport->setReportInfo(statPrx, propertyPrx, ClientConfig::ModuleName, ClientConfig::LocalIp, sSetDivision, iReportInterval, iSampleRate, iMaxSampleCount, iMaxReportSize, iReportTimeout); -} - - vector Communicator::getEndpoint(const string & objName) { ServantProxy * pServantProxy = getServantProxy(objName); @@ -466,26 +462,6 @@ vector Communicator::getEndpoint4All(const string & objName) return pServantProxy->getEndpoint4All(); } -void Communicator::doStat() -{ - if(_reportAsyncQueue) - { - size_t n = 0; - for(size_t i = 0;i < _asyncThreadNum; ++i) - { - n = n + _asyncThread[i]->getSize(); - } - _reportAsyncQueue->report(n); - } - -} - -void Communicator::pushAsyncThreadQueue(ReqMessage * msg) -{ - //先不考虑每个线程队列数目不一致的情况 - _asyncThread[(++_asyncSeq)%_asyncThreadNum]->push_back(msg); -} - void Communicator::terminate() { { @@ -526,6 +502,8 @@ void Communicator::terminate() } } + //把锁释放掉, 再来等待线程停止, 避免死锁 + //因为通信器线程运行过程中, 有可能加上上面那把锁 if (_initialized) { for (size_t i = 0; i < _clientThreadNum; ++i) @@ -548,7 +526,25 @@ void Communicator::terminate() _servantProxyFactory = NULL; } } - +} + + +void Communicator::pushAsyncThreadQueue(ReqMessage * msg) +{ + //先不考虑每个线程队列数目不一致的情况 + _asyncThread[(_asyncSeq++)%_asyncThreadNum]->push_back(msg); +} + +void Communicator::doStat() +{ + //队列长度上报 + if (_reportAsyncQueue) { + size_t n = 0; + for (size_t i = 0; i < _asyncThreadNum; ++i) { + n = n + _asyncThread[i]->getSize(); + } + _reportAsyncQueue->report((int) n); + } } ServantProxy * Communicator::getServantProxy(const string& objectName,const string& setName) diff --git a/servant/libservant/CommunicatorEpoll.cpp b/servant/libservant/CommunicatorEpoll.cpp index 7b125ee..35057d1 100755 --- a/servant/libservant/CommunicatorEpoll.cpp +++ b/servant/libservant/CommunicatorEpoll.cpp @@ -30,10 +30,7 @@ CommunicatorEpoll::CommunicatorEpoll(Communicator * pCommunicator,size_t netThre , _nextTime(0) , _nextStatTime(0) , _objectProxyFactory(NULL) -// , _asyncThreadNum(3) -// , _asyncSeq(0) , _netThreadSeq(netThreadSeq) -// , _reportAsyncQueue(NULL) , _noSendQueueLimit(1000) , _timeoutCheckInterval(100) { @@ -53,12 +50,6 @@ CommunicatorEpoll::CommunicatorEpoll(Communicator * pCommunicator,size_t netThre _noSendQueueLimit = 1000; } - // //epollwait的超时时间 - // _waitTimeout = TC_Common::strto(pCommunicator->getProperty("epollwaittimeout", "100")); - // if(_waitTimeout < 1) - // { - // _waitTimeout = 1; - // } //检查超时请求的时间间隔,单位:ms _timeoutCheckInterval = TC_Common::strto(pCommunicator->getProperty("timeoutcheckinterval", "100")); @@ -72,55 +63,10 @@ CommunicatorEpoll::CommunicatorEpoll(Communicator * pCommunicator,size_t netThre _notify[i] = NULL; } - // if(isFirstNetThread()) { - - // //异步线程数 - // _asyncThreadNum = TC_Common::strto(pCommunicator->getProperty("asyncthread", "3")); - - // if(_asyncThreadNum == 0) - // { - // _asyncThreadNum = 3; - // } - - // if(_asyncThreadNum > MAX_CLIENT_ASYNCTHREAD_NUM) - // { - // _asyncThreadNum = MAX_CLIENT_ASYNCTHREAD_NUM; - // } - - // //第一个通信器才去启动回调线程 - // for (size_t i = 0; i < _asyncThreadNum; ++i) { - // _asyncThread.push_back(new AsyncProcThread(iAsyncQueueCap, merge)); - // } - - // //异步队列数目上报 - // string moduleName = pCommunicator->getProperty("modulename", ""); - // if(!moduleName.empty()) - // { - // PropertyReportPtr asyncQueuePtr = pCommunicator->getStatReport()->createPropertyReport(moduleName + ".asyncqueue", PropertyReport::avg()); - // _reportAsyncQueue = asyncQueuePtr.get(); - // } - // } } CommunicatorEpoll::~CommunicatorEpoll() { - // if(isFirstNetThread()) { - // for(size_t i = 0;i < _asyncThreadNum; ++i) - // { - // if(_asyncThread[i]) - // { - // if (_asyncThread[i]->isAlive()) - // { - // _asyncThread[i]->terminate(); - // _asyncThread[i]->getThreadControl().join(); - // } - - // delete _asyncThread[i]; - // _asyncThread[i] = NULL; - // } - // } - // } - for(size_t i = 0;i < MAX_CLIENT_NOTIFYEVENT_NUM;++i) { if(_notify[i]) @@ -413,16 +359,7 @@ void CommunicatorEpoll::doStat() if(isFirstNetThread()) { _communicator->doStat(); - // //异步队列长度上报 - // if(_reportAsyncQueue) - // { - // size_t n = 0; - // for(size_t i = 0;i < _asyncThreadNum; ++i) - // { - // n = n + _asyncThread[i]->getSize(); - // } - // _reportAsyncQueue->report(n); - // } + } StatReport::MapStatMicMsg mStatMicMsg; @@ -443,14 +380,7 @@ void CommunicatorEpoll::doStat() void CommunicatorEpoll::pushAsyncThreadQueue(ReqMessage * msg) { _communicator->pushAsyncThreadQueue(msg); - // //先不考虑每个线程队列数目不一致的情况 - // _asyncThread[_asyncSeq]->push_back(msg); - // _asyncSeq ++; - // if(_asyncSeq == _asyncThreadNum) - // { - // _asyncSeq = 0; - // } } void CommunicatorEpoll::run() @@ -465,14 +395,10 @@ void CommunicatorEpoll::run() { try { - // int iTimeout = ((_waitTimeout < _timeoutCheckInterval) ? _waitTimeout : _timeoutCheckInterval); - + //考虑到检测超时等的情况 这里就wait100ms吧 int num = _ep.wait(100); + if (_terminate) break; - if(_terminate) - { - break; - } //先处理epoll的网络事件 for (int i = 0; i < num; ++i) @@ -481,10 +407,9 @@ void CommunicatorEpoll::run() uint64_t data = TC_Epoller::getU64(ev); - if(data == 0) - { - continue; //data非指针, 退出循环 - } + if(data == 0) continue; //data非指针, 退出循环 + +// int64_t ms = TNOWMS; handle((FDInfo*)data, ev); } diff --git a/servant/libservant/CoroutineScheduler.cpp b/servant/libservant/CoroutineScheduler.cpp index a81cf00..633d90c 100644 --- a/servant/libservant/CoroutineScheduler.cpp +++ b/servant/libservant/CoroutineScheduler.cpp @@ -756,11 +756,14 @@ void CoroutineScheduler::terminate() uint32_t CoroutineScheduler::generateId() { - while (++_uniqId < 1); + uint32_t i = ++_uniqId; + if(i == 0) { + i = ++_uniqId; + } - assert(_uniqId <= _poolSize); + assert(i <= _poolSize); - return _uniqId; + return i; } // void CoroutineScheduler::switchCoro(CoroutineInfo *from, CoroutineInfo *to) diff --git a/servant/libservant/EndpointInfo.cpp b/servant/libservant/EndpointInfo.cpp index 3fe6e32..2d48fff 100755 --- a/servant/libservant/EndpointInfo.cpp +++ b/servant/libservant/EndpointInfo.cpp @@ -22,46 +22,22 @@ namespace tars { EndpointInfo::EndpointInfo() -: _port(0) -, _grid(0) -, _qos(0) -, _type(TCP) -, _weight(-1) -, _weighttype(0) -, _authType(AUTH_TYPENONE) -, _isIPv6(false) -, _addressSucc(false) { _setDivision.clear(); - memset(&_addr,0,sizeof(_addr)); +// memset(&_addr,0,sizeof(struct sockaddr_in)); + memset(&_addr,0,sizeof(_addr)); + //7暂时写死 修改默认值一定要修改这个7 +// memcpy(_host,"0.0.0.0",7); + //snprintf(_host, sizeof(_host), "%s", "0.0.0.0"); } -EndpointInfo::EndpointInfo(const string& host, uint16_t port, EndpointInfo::EType type, int32_t grid, const string & setDivision, int qos, int weight, unsigned int weighttype, int authType) -: _host(host) -, _port(port) -, _grid(grid) -, _qos(qos) -, _type(type) + +EndpointInfo::EndpointInfo(const string& host, uint16_t port, TC_Endpoint::EType type, int32_t grid, const string & setDivision, int qos, int weight, unsigned int weighttype, int authType) +: _ep(host, port, 60000, type, grid, qos, weight, weighttype, authType) , _setDivision(setDivision) -, _weight(weight) -, _weighttype(weighttype) -, _authType((AUTH_TYPE)authType) , _addressSucc(false) { - _isIPv6 = TC_Socket::addressIsIPv6(host); - if(_weighttype == 0) - { - _weight = -1; - } - else - { - if(_weight == -1) - { - _weight = 100; - } - _weight = (_weight > 100 ? 100 : _weight); - } _cmpDesc = createCompareDesc(); @@ -72,13 +48,13 @@ void EndpointInfo::parseAddress() { // try // { - if (_isIPv6) + if (isIPv6()) { - TC_Socket::parseAddrWithPort(_host, _port, _addr.in6); + TC_Socket::parseAddrWithPort(_ep.getHost(), _ep.getPort(), _addr.in6); } else { - TC_Socket::parseAddrWithPort(_host, _port, _addr.in); + TC_Socket::parseAddrWithPort(_ep.getHost(), _ep.getPort(), _addr.in); } // } // catch (...) @@ -89,43 +65,13 @@ void EndpointInfo::parseAddress() string EndpointInfo::createCompareDesc() { - ostringstream os; - if (_type == EndpointInfo::UDP) { os << "udp:"; } - if (_type == EndpointInfo::TCP) { os << "tcp:"; } - if (_type == EndpointInfo::SSL) { os << "ssl:"; } - os << _grid << ":" << _host << ":" << _port - << ":" << _setDivision << ":" << _qos << ":" << _weight << ":" << _weighttype << ":" << _authType; + return _ep.toString(); - return os.str(); } string EndpointInfo::createDesc() const { - ostringstream os; - - if (_type == EndpointInfo::TCP) - os << "tcp"; - else if (_type == EndpointInfo::UDP) - os << "udp"; - else - os << "ssl"; - - os << " -h " << host(); - os << " -p " << port(); - if(0 != _grid) - os << " -g " << _grid; - - if (!_setDivision.empty()) - { - os << " -s " << _setDivision; - } - - if(0 != _qos) - os << " -q " << _qos; - if(0 != _authType) - os << " -e " << _authType; - - return os.str(); + return _ep.toString(); } bool EndpointInfo::operator == (const EndpointInfo& r) const @@ -138,19 +84,25 @@ bool EndpointInfo::operator < (const EndpointInfo& r) const return (_cmpDesc < r._cmpDesc); } -string EndpointInfo::host() const +const string &EndpointInfo::host() const { - return string(_host); + return _ep.getHost(); } int32_t EndpointInfo::grid() const { - return _grid; + return _ep.getGrid(); } + uint16_t EndpointInfo::port() const { - return _port; + return _ep.getPort(); +} + +bool EndpointInfo::isTcp() const +{ + return _ep.isTcp(); } const struct sockaddr_in& EndpointInfo::addr() const @@ -160,13 +112,13 @@ const struct sockaddr_in& EndpointInfo::addr() const const struct sockaddr * EndpointInfo::addrPtr() const { - return _isIPv6 ? (struct sockaddr *)&_addr.in6 : (struct sockaddr *)&_addr.in; -} - -EndpointInfo::EType EndpointInfo::type() const -{ - return _type; + return _ep.isIPv6() ? (struct sockaddr *)&_addr.in6 : (struct sockaddr *)&_addr.in; } +// +//EndpointInfo::EType EndpointInfo::type() const +//{ +// return _type; +//} const string& EndpointInfo::setDivision() const { diff --git a/servant/libservant/EndpointManager.cpp b/servant/libservant/EndpointManager.cpp index 266c09c..fbbf2ae 100644 --- a/servant/libservant/EndpointManager.cpp +++ b/servant/libservant/EndpointManager.cpp @@ -13,7 +13,7 @@ * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ - +#include "util/tc_port.h" #include "servant/EndpointManager.h" #include "servant/ObjectProxy.h" #include "servant/TarsLogger.h" @@ -48,7 +48,7 @@ QueryEpBase::QueryEpBase(Communicator * pComm, bool bFirstNetThread,bool bInterf setNoDelete(true); } -void QueryEpBase::callback_findObjectById4All(tars::Int32 ret, const vector& activeEp, const vector& inactiveEp) +void QueryEpBase::callback_findObjectById4All(Int32 ret, const vector& activeEp, const vector& inactiveEp) { TLOGTARS("[TARS][callback_findObjectById4All _objName:" << _objName << "|ret:" << ret << ",active:" << activeEp.size() @@ -57,14 +57,14 @@ void QueryEpBase::callback_findObjectById4All(tars::Int32 ret, const vector& activeEp, const vector& inactiveEp) +void QueryEpBase::callback_findObjectById4Any(Int32 ret, const vector& activeEp, const vector& inactiveEp) { TLOGTARS("[TARS][callback_findObjectById4Any _objName:" << _objName << "|ret:" << ret << ",active:" << activeEp.size() @@ -73,14 +73,14 @@ void QueryEpBase::callback_findObjectById4Any(tars::Int32 ret, const vector& activeEp, const vector& inactiveEp) +void QueryEpBase::callback_findObjectByIdInSameGroup(Int32 ret, const vector& activeEp, const vector& inactiveEp) { TLOGTARS("[TARS][callback_findObjectByIdInSameGroup _objName:" << _objName << "|ret:"< &activeEp, const vector & inactiveEp) +void QueryEpBase::callback_findObjectByIdInSameSet( Int32 ret, const vector &activeEp, const vector & inactiveEp) { TLOGTARS("[TARS][callback_findObjectByIdInSameSet _objName:" << _objName << "|ret:" << ret << ",active:" << activeEp.size() @@ -112,7 +112,7 @@ void QueryEpBase::callback_findObjectByIdInSameSet_exception( Int32 ret) doEndpointsExp(ret); } -void QueryEpBase::callback_findObjectByIdInSameStation( Int32 ret, const vector &activeEp, const vector &inactiveEp) +void QueryEpBase::callback_findObjectByIdInSameStation( Int32 ret, const vector &activeEp, const vector &inactiveEp) { TLOGTARS("[TARS][callback_findObjectByIdInSameStation _objName:" << _objName << "|ret:" << ret << ",active:" << activeEp.size() @@ -150,11 +150,11 @@ bool QueryEpBase::init(const string & sObjName,const string & sLocator,const str void QueryEpBase::setObjName(const string & sObjName) { - string sEndpoints(""); - string sInactiveEndpoints(""); - string::size_type pos = sObjName.find_first_of('@'); + string sEndpoints; + string sInactiveEndpoints; + if (pos != string::npos) { //[直接连接]指定服务的IP和端口列表 @@ -280,17 +280,18 @@ void QueryEpBase::setEndpoints(const string & sEndpoints, set & se { TC_Endpoint ep(vEndpoints[i]); - EndpointInfo::EType type; - if (ep.isSSL()) - type = EndpointInfo::SSL; - else if (ep.isTcp()) - type = EndpointInfo::TCP; - else - type = EndpointInfo::UDP; +// TC_Endpoint::EType type = ep.getType(); +// if (ep.isSSL()) +// type = TC_Endpoint::SSL; +// else if (ep.isTcp()) +// type = TC_Endpoint::TCP; +// else +// type = TC_Endpoint::UDP; string sSetDivision; //解析set分组信息 + if (!_direct) { string sep = " -s "; size_t pos = vEndpoints[i].rfind(sep); @@ -320,7 +321,7 @@ void QueryEpBase::setEndpoints(const string & sEndpoints, set & se } } - EndpointInfo epi(ep.getHost(), ep.getPort(), type, ep.getGrid(), sSetDivision, ep.getQos(), ep.getWeight(), ep.getWeightType(), ep.getAuthType()); + EndpointInfo epi(ep.getHost(), ep.getPort(), ep.getType(), ep.getGrid(), sSetDivision, ep.getQos(), ep.getWeight(), ep.getWeightType(), ep.getAuthType()); setEndpoints.insert(epi); } @@ -381,8 +382,8 @@ void QueryEpBase::refreshReg(GetEndpointType type, const string & sName) { if(bSync) { - vector activeEp; - vector inactiveEp; + vector activeEp; + vector inactiveEp; int iRet = 0; switch(type) { @@ -468,7 +469,7 @@ void QueryEpBase::refreshReg(GetEndpointType type, const string & sName) } } -void QueryEpBase::doEndpoints(const vector& activeEp, const vector& inactiveEp, int iRet, bool bSync) +void QueryEpBase::doEndpoints(const vector& activeEp, const vector& inactiveEp, int iRet, bool bSync) { if(iRet != 0) { @@ -525,8 +526,8 @@ void QueryEpBase::doEndpoints(const vector& activeEp, const vec // tars istcp意思和这里枚举值对应 - EndpointInfo::EType type = EndpointInfo::EType(activeEp[i].istcp); - EndpointInfo ep(activeEp[i].host, activeEp[i].port, type, activeEp[i].grid, activeEp[i].setId, activeEp[i].qos, activeEp[i].weight, activeEp[i].weightType, activeEp[i].authType); +// EndpointInfo::EType type = EndpointInfo::EType(activeEp[i].istcp); + EndpointInfo ep(activeEp[i].host, activeEp[i].port, (TC_Endpoint::EType)activeEp[i].istcp, activeEp[i].grid, activeEp[i].setId, activeEp[i].qos, activeEp[i].weight, activeEp[i].weightType, activeEp[i].authType); activeEps.insert(ep); } @@ -535,8 +536,8 @@ void QueryEpBase::doEndpoints(const vector& activeEp, const vec for (uint32_t i = 0; i < inactiveEp.size(); ++i) { // tars istcp意思和这里枚举值对应 - EndpointInfo::EType type = EndpointInfo::EType(inactiveEp[i].istcp); - EndpointInfo ep(inactiveEp[i].host, inactiveEp[i].port, type, inactiveEp[i].grid, inactiveEp[i].setId, inactiveEp[i].qos, inactiveEp[i].weight, inactiveEp[i].weightType, inactiveEp[i].authType); +// EndpointInfo::EType type = EndpointInfo::EType(inactiveEp[i].istcp); + EndpointInfo ep(inactiveEp[i].host, inactiveEp[i].port, (TC_Endpoint::EType)activeEp[i].istcp, inactiveEp[i].grid, inactiveEp[i].setId, inactiveEp[i].qos, inactiveEp[i].weight, inactiveEp[i].weightType, inactiveEp[i].authType); inactiveEps.insert(ep); } @@ -792,23 +793,27 @@ void EndpointManager::doNotify() _objectProxy->doInvoke(); } -bool EndpointManager::selectAdapterProxy(ReqMessage * msg,AdapterProxy * & pAdapterProxy) +bool EndpointManager::selectAdapterProxy(ReqMessage * msg,AdapterProxy * & pAdapterProxy, bool onlyCheck) { pAdapterProxy = NULL; - //刷新主控 - refreshReg(E_DEFAULT,""); - //无效的数据 返回true - if(!_valid) - { - return true; - } + if(!onlyCheck) + { + //刷新主控 + refreshReg(E_DEFAULT,""); + + //无效的数据 返回true + if(!_valid) + { + return true; + } + } //如果有hash,则先使用hash策略 if (msg->bHash) { - pAdapterProxy = getHashProxy(msg->iHashCode, msg->bConHash); + pAdapterProxy = getHashProxy(msg->iHashCode, msg->bConHash, onlyCheck); return false; } @@ -820,18 +825,18 @@ bool EndpointManager::selectAdapterProxy(ReqMessage * msg,AdapterProxy * & pAdap if(_weightType == E_STATIC_WEIGHT || msg->eType == ReqMessage::ONE_WAY) bStaticWeighted = true; - pAdapterProxy = getWeightedProxy(bStaticWeighted); + pAdapterProxy = getWeightedProxy(bStaticWeighted, onlyCheck); } else { //普通轮询模式 - pAdapterProxy = getNextValidProxy(); + pAdapterProxy = getNextValidProxy(onlyCheck); } return false; } -AdapterProxy * EndpointManager::getNextValidProxy() +AdapterProxy * EndpointManager::getNextValidProxy(bool onlyCheck) { if (_activeProxys.empty()) { @@ -847,7 +852,7 @@ AdapterProxy * EndpointManager::getNextValidProxy() if(_lastRoundPosition >= _activeProxys.size()) _lastRoundPosition = 0; - if(_activeProxys[_lastRoundPosition]->checkActive()) + if(_activeProxys[_lastRoundPosition]->checkActive(false, onlyCheck)) { return _activeProxys[_lastRoundPosition]; } @@ -857,52 +862,54 @@ AdapterProxy * EndpointManager::getNextValidProxy() conn.push_back(_activeProxys[_lastRoundPosition]); } - if(conn.size() > 0) - { - //都有问题, 随机选择一个没有connect超时或者链接异常的发送 - AdapterProxy * adapterProxy = conn[((uint32_t)rand() % conn.size())]; + if(!onlyCheck) { + if(conn.size() > 0) + { + //都有问题, 随机选择一个没有connect超时或者链接异常的发送 + AdapterProxy * adapterProxy = conn[((uint32_t)rand() % conn.size())]; - //该proxy可能已经被屏蔽,需重新连一次 - adapterProxy->checkActive(true); - return adapterProxy; - } + //该proxy可能已经被屏蔽,需重新连一次 + adapterProxy->checkActive(true, false); + return adapterProxy; + } - //所有adapter都有问题 选不到结点,随机找一个重试 - AdapterProxy * adapterProxy = _activeProxys[((uint32_t)rand() % _activeProxys.size())]; + //所有adapter都有问题 选不到结点,随机找一个重试 + AdapterProxy * adapterProxy = _activeProxys[((uint32_t)rand() % _activeProxys.size())]; - //该proxy可能已经被屏蔽,需重新连一次 - adapterProxy->checkActive(true); + //该proxy可能已经被屏蔽,需重新连一次 + adapterProxy->checkActive(true, false); + } return NULL; } -AdapterProxy* EndpointManager::getHashProxy(int64_t hashCode, bool bConsistentHash) +AdapterProxy* EndpointManager::getHashProxy(int64_t hashCode, bool bConsistentHash, bool onlyCheck) { if(_weightType == E_STATIC_WEIGHT) { if(bConsistentHash) { - return getConHashProxyForWeight(hashCode, true); + return getConHashProxyForWeight(hashCode, true, onlyCheck); } else { - return getHashProxyForWeight(hashCode, true, _hashStaticRouterCache); + return getHashProxyForWeight(hashCode, true, _hashStaticRouterCache, onlyCheck); } } else { if(bConsistentHash) { - return getConHashProxyForNormal(hashCode); + return getConHashProxyForNormal(hashCode, onlyCheck); } else { - return getHashProxyForNormal(hashCode); + return getHashProxyForNormal(hashCode, onlyCheck); } } } -AdapterProxy* EndpointManager::getHashProxyForWeight(int64_t hashCode, bool bStatic, vector &vRouterCache) +AdapterProxy* EndpointManager::getHashProxyForWeight(int64_t hashCode, bool bStatic, vector &vRouterCache, bool onlyCheck) { if(_vRegProxys.empty()) { @@ -965,7 +972,7 @@ AdapterProxy* EndpointManager::getHashProxyForWeight(int64_t hashCode, bool bSta hash = hash % thisHash.size(); } - if (thisHash[hash]->checkActive()) + if (thisHash[hash]->checkActive(false, onlyCheck)) { return thisHash[hash]; } @@ -978,38 +985,40 @@ AdapterProxy* EndpointManager::getHashProxyForWeight(int64_t hashCode, bool bSta } while(!thisHash.empty()); - if(conn.size() > 0) - { - hash = ((int64_t)hashCode) % conn.size(); + if(!onlyCheck) { + if(conn.size() > 0) + { + hash = ((int64_t)hashCode) % conn.size(); - //这里做判断的原因是:32位系统下,如果hashCode为负值,hash经过上面的计算会是一个超大值,导致越界 - if(hash >= conn.size()) - { - hash = hash % conn.size(); - } + //这里做判断的原因是:32位系统下,如果hashCode为负值,hash经过上面的计算会是一个超大值,导致越界 + if(hash >= conn.size()) + { + hash = hash % conn.size(); + } - //都有问题, 随机选择一个没有connect超时或者链接异常的发送 - AdapterProxy *adapterProxy = conn[hash]; + //都有问题, 随机选择一个没有connect超时或者链接异常的发送 + AdapterProxy *adapterProxy = conn[hash]; - //该proxy可能已经被屏蔽,需重新连一次 - adapterProxy->checkActive(true); - return adapterProxy; - } + //该proxy可能已经被屏蔽,需重新连一次 + adapterProxy->checkActive(true, false); + return adapterProxy; + } - //所有adapter都有问题 选不到结点,随机找一个重试 - AdapterProxy * adapterProxy = _activeProxys[((uint32_t)rand() % _activeProxys.size())]; - //该proxy可能已经被屏蔽,需重新连一次 - adapterProxy->checkActive(true); + //所有adapter都有问题 选不到结点,随机找一个重试 + AdapterProxy * adapterProxy = _activeProxys[((uint32_t)rand() % _activeProxys.size())]; + //该proxy可能已经被屏蔽,需重新连一次 + adapterProxy->checkActive(true, false); + } return NULL; } } - return getHashProxyForNormal(hashCode); + return getHashProxyForNormal(hashCode, onlyCheck); } -AdapterProxy* EndpointManager::getConHashProxyForWeight(int64_t hashCode, bool bStatic) +AdapterProxy* EndpointManager::getConHashProxyForWeight(int64_t hashCode, bool bStatic, bool onlyCheck) { if(_vRegProxys.empty()) { @@ -1107,7 +1116,7 @@ AdapterProxy* EndpointManager::getConHashProxyForWeight(int64_t hashCode, bool b } } - return getHashProxyForNormal(hashCode); + return getHashProxyForNormal(hashCode, onlyCheck); } bool EndpointManager::checkHashStaticWeightChange(bool bStatic) @@ -1312,7 +1321,7 @@ void EndpointManager::updateConHashProxyWeighted(bool bStatic, vector& ObjectProxy::getSocketOpt() { return _socketOpts; } - -void ObjectProxy::setPushCallbacks(const ServantProxyCallbackPtr& cb) -{ - _pushCallback = cb; -} - -ServantProxyCallbackPtr ObjectProxy::getPushCallback() -{ - return _pushCallback; -} +// +//bool ObjectProxy::invoke_sync(ReqMessage * msg) +//{ +// TLOGTAF("[TAF][ObjectProxy::invoke_sync, " << _name << ", begin]" << endl); +// +// //选择一个远程服务的Adapter来调用 +// AdapterProxy * pAdapterProxy = NULL; +// //选一个活的 +// _endpointManger->selectAdapterProxy(msg, pAdapterProxy, true); +// +// if(!pAdapterProxy) +// { +// return false; +// } +// +// msg->adapter = pAdapterProxy; +// return pAdapterProxy->invoke_sync(msg); +//} void ObjectProxy::invoke(ReqMessage * msg) { @@ -141,7 +176,7 @@ void ObjectProxy::invoke(ReqMessage * msg) //选择一个远程服务的Adapter来调用 AdapterProxy * pAdapterProxy = NULL; - bool bFirst = _endpointManger->selectAdapterProxy(msg, pAdapterProxy); + bool bFirst = _endpointManger->selectAdapterProxy(msg, pAdapterProxy, false); if(bFirst) { @@ -167,8 +202,6 @@ void ObjectProxy::invoke(ReqMessage * msg) return ; } -// pAdapterProxy = pAdapterProxy->clone(); - msg->adapter = pAdapterProxy; pAdapterProxy->invoke(msg); } @@ -188,7 +221,7 @@ void ObjectProxy::doInvoke() //选择一个远程服务的Adapter来调用 AdapterProxy * pAdapterProxy = NULL; - _endpointManger->selectAdapterProxy(msg,pAdapterProxy); + _endpointManger->selectAdapterProxy(msg,pAdapterProxy, false); if(!pAdapterProxy) { @@ -202,8 +235,6 @@ void ObjectProxy::doInvoke() return; } -// pAdapterProxy = pAdapterProxy->clone(); - msg->adapter = pAdapterProxy; pAdapterProxy->invoke(msg); @@ -293,7 +324,7 @@ void ObjectProxy::doInvokeException(ReqMessage * msg) void ObjectProxy::doTimeout() { -// TLOGTARS("[TARS][ObjectProxy::doInvokeException, objname:" << _name << "]" << endl); + const vector & vAdapterProxy = _endpointManger->getAdapters(); for(size_t iAdapter=0; iAdapter< vAdapterProxy.size();++iAdapter) { diff --git a/servant/libservant/ObjectProxyFactory.cpp b/servant/libservant/ObjectProxyFactory.cpp index fb2bffd..4241d1e 100644 --- a/servant/libservant/ObjectProxyFactory.cpp +++ b/servant/libservant/ObjectProxyFactory.cpp @@ -23,6 +23,7 @@ ObjectProxyFactory::ObjectProxyFactory(CommunicatorEpoll * pCommunicatorEpoll) : _communicatorEpoll(pCommunicatorEpoll) , _objNum(0) { +// memset(_vpObjectProxys,0,sizeof(_vpObjectProxys)); } ObjectProxyFactory::~ObjectProxyFactory() diff --git a/servant/libservant/Servant.cpp b/servant/libservant/Servant.cpp index ca4b5d9..ef986b7 100644 --- a/servant/libservant/Servant.cpp +++ b/servant/libservant/Servant.cpp @@ -26,8 +26,6 @@ namespace tars { thread_local shared_ptr CallbackThreadData::g_sp; -// TC_ThreadMutex CallbackThreadData::_mutex; -// pthread_key_t CallbackThreadData::_key = 0; Servant::Servant():_handle(NULL) { @@ -92,7 +90,7 @@ int Servant::dispatch(TarsCurrentPtr current, vector &buffer) return ret; } -TC_ThreadQueue& Servant::getResponseQueue() +TC_CasQueue& Servant::getResponseQueue() { return _asyncResponseQueue; } @@ -143,35 +141,6 @@ CallbackThreadData * CallbackThreadData::getData() g_sp.reset(new CallbackThreadData()); } return g_sp.get(); - - // if(_key == 0) - // { - // TC_LockT lock(_mutex); - // if(_key == 0) - // { - // int iRet = ::pthread_key_create(&_key, CallbackThreadData::destructor); - - // if (iRet != 0) - // { - // TLOGERROR("[TARS][CallbackThreadData pthread_key_create fail:" << errno << ":" << strerror(errno) << "]" << endl); - // return NULL; - // } - // } - // } - - // CallbackThreadData * pCbtd = (CallbackThreadData*)pthread_getspecific(_key); - - // if(!pCbtd) - // { - // TC_LockT lock(_mutex); - - // pCbtd = new CallbackThreadData(); - - // int iRet = pthread_setspecific(_key, (void *)pCbtd); - - // assert(iRet == 0); - // } - // return pCbtd; } diff --git a/servant/libservant/ServantHandle.cpp b/servant/libservant/ServantHandle.cpp index a5b5bb2..b07f3ec 100644 --- a/servant/libservant/ServantHandle.cpp +++ b/servant/libservant/ServantHandle.cpp @@ -39,7 +39,7 @@ ServantHandle::ServantHandle() ServantHandle::~ServantHandle() { - map::iterator it = _servants.begin(); + auto it = _servants.begin(); while(it != _servants.end()) { @@ -71,17 +71,19 @@ void ServantHandle::run() { initialize(); - if (!ServerConfig::OpenCoroutine) { - handleImp(); - } - else { - unsigned int iThreadNum = getEpollServer()->getLogicThreadNum(); + if (!ServerConfig::OpenCoroutine) + { + handleImp(); + } + else + { + //by goodenpei, 判断是否启用顺序模式 + _bindAdapter->initThreadRecvQueue(getHandleIndex()); + + size_t iThreadNum = getEpollServer()->getLogicThreadNum(); - size_t iCoroutineNum = - (ServerConfig::CoroutineMemSize > ServerConfig::CoroutineStackSize) ? (ServerConfig::CoroutineMemSize - / (ServerConfig::CoroutineStackSize * iThreadNum)) : 1; - if (iCoroutineNum < 1) - iCoroutineNum = 1; + size_t iCoroutineNum = (ServerConfig::CoroutineMemSize > ServerConfig::CoroutineStackSize) ? (ServerConfig::CoroutineMemSize / (ServerConfig::CoroutineStackSize * iThreadNum)) : 1; + if (iCoroutineNum < 1) iCoroutineNum = 1; startHandle(); @@ -97,7 +99,8 @@ void ServantHandle::run() pSptd->_sched = _coroSched; - while (!getEpollServer()->isTerminate()) { + while (!getEpollServer()->isTerminate()) + { _coroSched->tars_run(); } @@ -215,7 +218,6 @@ void ServantHandle::handleRequest() } } -// void ServantHandle::handleRecvData(TC_EpollServer::tagRecvData *stRecvData) void ServantHandle::handleRecvData(const shared_ptr &data) { try @@ -250,11 +252,11 @@ void ServantHandle::handleAsyncResponse() { ReqMessagePtr resp; - map::iterator it = _servants.begin(); + auto it = _servants.begin(); while (it != _servants.end()) { - while (it->second->getResponseQueue().pop_front(resp, 0)) + while (it->second->getResponseQueue().pop_front(resp)) { try { @@ -302,7 +304,7 @@ void ServantHandle::handleAsyncResponse() void ServantHandle::handleCustomMessage(bool bExpectIdle) { - for (map::iterator it = _servants.begin(); it != _servants.end(); it++) + for (auto it = _servants.begin(); it != _servants.end(); it++) { //业务处理附加的自有消息 try @@ -323,7 +325,7 @@ void ServantHandle::handleCustomMessage(bool bExpectIdle) bool ServantHandle::allFilterIsEmpty() { - map::iterator it = _servants.begin(); + auto it = _servants.begin(); while (it != _servants.end()) { @@ -351,7 +353,7 @@ void ServantHandle::initialize() exit(-1); } - map::iterator it = _servants.begin(); + auto it = _servants.begin(); if(it == _servants.end()) { @@ -392,38 +394,6 @@ void ServantHandle::initialize() } } -// void ServantHandle::heartbeat() -// { -// time_t fcur = TNOW; - -// map::iterator it; - -// map& adapters = _handleGroup->adapters; - -// for (it = adapters.begin(); it != adapters.end(); ++it) -// { -// if (abs(fcur - it->second->getHeartBeatTime()) > HEART_BEAT_INTERVAL) -// { -// it->second->setHeartBeatTime(fcur); - -// TARS_KEEPALIVE(it->second->getName()); - -// //上报连接数 比率 -// if (it->second->_pReportConRate) -// { -// it->second->_pReportConRate->report(it->second->getNowConnection()*1000/it->second->getMaxConns()); -// } - -// //有队列, 且队列长度>0才上报 -// if (it->second->_pReportQueue) -// { -// it->second->_pReportQueue->report(it->second->getRecvBufferSize()); -// } -// } -// } -// } - - void ServantHandle::heartbeat() { time_t fcur = TNOW; @@ -509,7 +479,7 @@ void ServantHandle::handleClose(const shared_ptr &d TarsCurrentPtr current = createCloseCurrent(data); - map::iterator sit = _servants.find(current->getServantName()); + auto sit = _servants.find(current->getServantName()); if (sit == _servants.end()) { @@ -830,7 +800,7 @@ void ServantHandle::handleTarsProtocol(const TarsCurrentPtr ¤t) //处理tracking信息 processTracking(current); #endif - map::iterator sit = _servants.find(current->getServantName()); + auto sit = _servants.find(current->getServantName()); if (sit == _servants.end()) { @@ -901,7 +871,7 @@ void ServantHandle::handleNoTarsProtocol(const TarsCurrentPtr ¤t) << current->getPort() << "|" << current->getServantName() << endl); - map::iterator sit = _servants.find(current->getServantName()); + auto sit = _servants.find(current->getServantName()); assert(sit != _servants.end()); diff --git a/servant/libservant/ServantProxy.cpp b/servant/libservant/ServantProxy.cpp index 0f2a11a..2da75ac 100644 --- a/servant/libservant/ServantProxy.cpp +++ b/servant/libservant/ServantProxy.cpp @@ -233,6 +233,7 @@ string ServantProxy::TARS_MASTER_KEY = "TARS_MASTER_KEY"; string ServantProxy::STATUS_TRACK_KEY = "STATUS_TRACK_KEY"; +//////////////////////////////////// ServantProxy::ServantProxy(Communicator * pCommunicator, ObjectProxy ** ppObjectProxy, size_t iClientThreadNum) : _communicator(pCommunicator) , _objectProxy(ppObjectProxy) @@ -256,34 +257,17 @@ ServantProxy::ServantProxy(Communicator * pCommunicator, ObjectProxy ** ppObject { _minTimeout = 1; } - // get AK/SK -// const TC_Config& conf = Application::getConfig(); -// vector adapterNames; -// -// cout << "accessKey:" << conf.get("/tars/application/client/TestApp.AuthServer.AuthObj") << ", obj:" << tars_name() << endl; -// -// if (conf.getDomainVector("/tars/application/client", adapterNames)) -// { -// cout << TC_Common::tostr(adapterNames.begin(), adapterNames.end()) << ", " << tars_name() << endl; -// auto it = std::find(adapterNames.begin(), adapterNames.end(), tars_name()); -// if (it != adapterNames.end()) -// { -// string accessKey = conf.get("/tars/application/client/" + *it + ""); -// string secretKey = conf.get("/tars/application/client/" + *it + ""); -// -// cout << "accessKey:" << accessKey << ", secretKey:" << secretKey << endl; -// for(size_t i = 0;i < _objectProxyNum; ++i) -// { -// _objectProxy[i]->setAccessKey(pCommunicator->getServantProperty(tars_name(), "accesskey")); -// _objectProxy[i]->setSecretKey(pCommunicator->getServantProperty(tars_name(), "secretkey")); -// } -// } -// } } ServantProxy::~ServantProxy() { +// if (_endpointInfo) +// { +// delete _endpointInfo; +// _endpointInfo = NULL; +// } + if(_objectProxy) { //set _objectProxy to NULL @@ -374,7 +358,7 @@ void ServantProxy::tars_set_protocol(const ProxyProtocol& protocol) } -void ServantProxy::tars_set_sockopt(int level, int optname, const void * optval, socklen_t optlen) +void ServantProxy::tars_set_sockopt(int level, int optname, const void * optval, SOCKET_LEN_TYPE optlen) { TC_LockT lock(*this); @@ -450,6 +434,14 @@ ServantProxy* ServantProxy::tars_hash(int64_t key) return this; } +//ServantProxy* ServantProxy::tars_direct() +//{ +// ServantProxyThreadData *pSptd = ServantProxyThreadData::getData(); +// +// pSptd->_direct = true; +// return this; +//} + ServantProxy* ServantProxy::tars_consistent_hash(int64_t key) { ServantProxyThreadData * pSptd = ServantProxyThreadData::getData(); @@ -496,6 +488,55 @@ void ServantProxy::tars_set_push_callback(const ServantProxyCallbackPtr & cb) } } +// +//void ServantProxy::invoke_async(ReqMessage *msg, ServantProxyThreadData *pSptd, ReqInfoQueue *pReqQ, bool bCoroAsync) +//{ +//// assert(ReqMessage::ASYNC_CALL == msg->eType); +// +// if (bCoroAsync) +// { +// if (pSptd->_sched) +// { +// CoroParallelBasePtr coroPtr = msg->callback->getCoroParallelBasePtr(); +// if (coroPtr) +// { +// coroPtr->incReqCount(); +// +// msg->bCoroFlag = true; +// msg->sched = pSptd->_sched; +// msg->iCoroId = pSptd->_sched->getCoroutineId(); +// } +// else +// { +// TLOGERROR("[TAF][ServantProxy::invoke_async use coroutine's callback not set CoroParallelBasePtr]" << endl); +// delete msg; +// msg = NULL; +// throw TarsUseCoroException("ServantProxy::invoke_async use coroutine's callback not set CoroParallelBasePtr"); +// } +// } +// else +// { +// TLOGERROR("[TAF][ServantProxy::invoke coroutine mode invoke not open]" << endl); +// delete msg; +// msg = NULL; +// throw TarsUseCoroException("coroutine mode invoke not open"); +// } +// } +// +// //通知网络线程 +// bool bEmpty; +// if (!pReqQ->push_back(msg, bEmpty)) +// { +// TLOGERROR("[TAF][ServantProxy::invoke_async msgQueue push_back error num:" << pSptd->_netSeq << "]" << endl); +// msg->pObjectProxy->getCommunicatorEpoll()->notify(pSptd->_reqQNo, pReqQ); +// delete msg; +// throw TarsClientQueueException("client queue full"); +// } +// +// msg->pObjectProxy->getCommunicatorEpoll()->notify(pSptd->_reqQNo, pReqQ); +// +//} + void ServantProxy::invoke(ReqMessage * msg, bool bCoroAsync) { msg->proxy = this; @@ -673,10 +714,7 @@ void ServantProxy::invoke(ReqMessage * msg, bool bCoroAsync) os << ",servant:" << msg->pObjectProxy->name() << ",func:" << msg->request.sFuncName; - if(msg->adapter) - { - os << ",adapter:" << msg->adapter->endpoint().desc(); - } + if (msg->adapter) os << ",adapter:" << msg->adapter->endpoint().desc(); os << ",reqid:" << msg->request.iRequestId << "]"; @@ -699,16 +737,7 @@ void ServantProxy::invoke(ReqMessage * msg, bool bCoroAsync) } } -//同步调用返回,唤醒等待的业务线程 -void ServantProxy::finished(ReqMessage * msg) -{ - if(msg->pMonitor) - { - TC_ThreadLock::Lock sync(*(msg->pMonitor)); - msg->pMonitor->notify(); - msg->bMonitorFin = true; - } -} + ////////////////////////////////////////////////////////////////// void ServantProxy::tars_invoke_async(char cPacketType, @@ -721,16 +750,16 @@ void ServantProxy::tars_invoke_async(char cPacketType, { ReqMessage * msg = new ReqMessage(); - msg->init(callback?ReqMessage::ASYNC_CALL:ReqMessage::ONE_WAY,NULL,sFuncName); + msg->init(callback?ReqMessage::ASYNC_CALL:ReqMessage::ONE_WAY); msg->callback = callback; msg->request.iVersion = TARSVERSION; msg->request.cPacketType = (callback ? cPacketType : TARSONEWAY); - + msg->request.sFuncName = sFuncName; msg->request.sServantName = (*_objectProxy)->name(); - msg->request.sFuncName = sFuncName; + buf.swap(msg->request.sBuffer); - // msg->request.sBuffer = buf; + msg->request.context = context; msg->request.status = status; msg->request.iTimeout = _asyncTimeout; @@ -755,15 +784,14 @@ shared_ptr ServantProxy::tars_invoke(char cPacketType, { ReqMessage * msg = new ReqMessage(); - msg->init(ReqMessage::SYNC_CALL,NULL,sFuncName); + msg->init(ReqMessage::SYNC_CALL); msg->request.iVersion = TARSVERSION; msg->request.cPacketType = cPacketType; - + msg->request.sFuncName = sFuncName; msg->request.sServantName = (*_objectProxy)->name(); - msg->request.sFuncName = sFuncName; + buf.swap(msg->request.sBuffer); - // msg->request.sBuffer = buf; msg->request.context = context; msg->request.status = status; msg->request.iTimeout = _syncTimeout; @@ -798,11 +826,12 @@ void ServantProxy::rpc_call(uint32_t iRequestId, { ReqMessage * msg = new ReqMessage(); - msg->init(ReqMessage::SYNC_CALL,NULL,sFuncName); + msg->init(ReqMessage::SYNC_CALL); msg->bFromRpc = true; + msg->request.sFuncName = sFuncName; msg->request.iRequestId = iRequestId; - msg->request.sFuncName = sFuncName; + msg->request.sBuffer.assign(buff, buff + len); invoke(msg); @@ -822,48 +851,17 @@ void ServantProxy::rpc_call_async(uint32_t iRequestId, { ReqMessage * msg = new ReqMessage(); - msg->init(callback?ReqMessage::ASYNC_CALL:ReqMessage::ONE_WAY,NULL,sFuncName); - + msg->init(callback?ReqMessage::ASYNC_CALL:ReqMessage::ONE_WAY); + msg->request.sFuncName = sFuncName; msg->bFromRpc = true; msg->callback = callback; msg->request.iRequestId = iRequestId; - msg->request.sFuncName = sFuncName; + msg->request.sBuffer.assign(buff, buff + len); invoke(msg, bCoro); } -// -// -//void ServantProxy::http1_call(const std::string& method, -// const std::string& uri, -// const std::map& headers, -// const std::string& body, -// std::map& rheaders, -// std::string& rbody) -//{ -// ReqMessage* msg = new ReqMessage(); -// -// msg->init(ReqMessage::SYNC_CALL, NULL, ""); -// -// msg->bFromRpc = true; -// msg->request.sServantName = uri; -// msg->request.sFuncName = method; -// msg->request.iRequestId = this->tars_gen_requestid(); -// -// // 使用下面两个字段保存头部和包体 -// msg->request.context = headers; -// -// msg->request.sBuffer.assign(body.begin(), body.end()); -// -// invoke(msg); -// -// rheaders.swap(msg->response->status); -// rbody.assign(msg->response->sBuffer.begin(), msg->response->sBuffer.end()); -// -// delete msg; -// msg = NULL; -//} void ServantProxy::http_call(const std::string& method, const std::string& uri, @@ -874,7 +872,7 @@ void ServantProxy::http_call(const std::string& method, { ReqMessage* msg = new ReqMessage(); - msg->init(ReqMessage::SYNC_CALL, NULL, ""); + msg->init(ReqMessage::SYNC_CALL); msg->bFromRpc = true; msg->request.sServantName = uri; @@ -901,7 +899,7 @@ void ServantProxy::http_call_async(const std::string& method, { ReqMessage * msg = new ReqMessage(); - msg->init(ReqMessage::ASYNC_CALL, NULL, ""); + msg->init(ReqMessage::ASYNC_CALL); msg->bFromRpc = true; msg->request.sServantName = uri; diff --git a/servant/libservant/StatReport.cpp b/servant/libservant/StatReport.cpp index 8bcefe8..e67ff40 100755 --- a/servant/libservant/StatReport.cpp +++ b/servant/libservant/StatReport.cpp @@ -439,8 +439,7 @@ void StatReport::doSample(const string& strSlaveName, int StatReport::reportMicMsg(MapStatMicMsg& msg,bool bFromClient) { - if(msg.empty()) - return 0; + if (msg.empty()) return 0; try { int iLen = 0; @@ -759,6 +758,16 @@ void StatReport::run() { while(!_terminate) { + { + Lock lock(*this); + + if (_terminate) + return; + + timedWait(1000); + + } + try { time_t tNow = TNOW; @@ -804,9 +813,6 @@ void StatReport::run() _time = tNow; } - Lock lock(*this); - - timedWait(1000); } catch ( exception& e ) { diff --git a/servant/libservant/Transceiver.cpp b/servant/libservant/Transceiver.cpp index 76e6b8b..9ce715a 100755 --- a/servant/libservant/Transceiver.cpp +++ b/servant/libservant/Transceiver.cpp @@ -48,6 +48,8 @@ Transceiver::Transceiver(AdapterProxy * pAdapterProxy,const EndpointInfo &ep) Transceiver::~Transceiver() { close(); + + } void Transceiver::checkTimeout() @@ -63,7 +65,7 @@ void Transceiver::checkTimeout() bool Transceiver::isSSL() const { - return _adapterProxy->endpoint().type() == EndpointInfo::SSL; + return _adapterProxy->endpoint().type() == TC_Endpoint::SSL; } void Transceiver::reconnect() @@ -90,7 +92,7 @@ void Transceiver::connect() //每次连接前都重新解析一下地址, 避免dns变了! _ep.parseAddress(); - if (_ep.type() == EndpointInfo::UDP) + if (_ep.type() == TC_Endpoint::UDP) { fd = NetworkUtil::createSocket(true, false, _ep.isIPv6()); _connStatus = eConnected; @@ -202,7 +204,7 @@ void Transceiver::doAuthReq() { ObjectProxy* obj = _adapterProxy->getObjProxy(); - TLOGTARS("[TARS][Transceiver::doAuthReq obj:" << obj->name() << ", auth type:" << etos(_adapterProxy->endpoint().authType()) << endl); + TLOGTARS("[TARS][Transceiver::doAuthReq obj:" << obj->name() << ", auth type:" << etos((AUTH_TYPE)_adapterProxy->endpoint().authType()) << endl); if (_adapterProxy->endpoint().authType() == AUTH_TYPENONE) { @@ -220,6 +222,102 @@ void Transceiver::doAuthReq() } } +// +//void Transceiver::sendRecv(ReqMessage *msg)//const shared_ptr &sbuff, BasePacket &rsp, int timeout) +//{ +// if(_syncSock == NULL) +// { +// if(_ep.isTcp()) +// { +// _syncSock = new TC_TCPClient(_ep.host(), _ep.port(), msg->request.iTimeout); +// } +// else +// { +// _syncSock = new TC_UDPClient(_ep.host(), _ep.port(), msg->request.iTimeout); +// } +// } +// +// int iRet = _syncSock->send(msg->sReqData->buffer(), (uint32_t) msg->sReqData->length()); +// if (iRet < 0) +// { +// msg->eStatus = ReqMessage::REQ_NET; +// msg->response->sResultDesc = "send failed ret:" + TC_Common::tostr(iRet); +// return; +// } +// +//// cout << _syncSock->getSocket()->getSendBufferSize() << ", " << _syncSock->getSocket()->getRecvBufferSize() << endl; +// +// TC_NetWorkBuffer recvBuffer(NULL); +// +// do +// { +// try +// { +// size_t iHeaderLen = BUFFER_SIZE; +// // char rbuff[BUFFER_SIZE] = {0x00}; +// vector rbuff(iHeaderLen); +// +// iRet = _syncSock->recv(rbuff.data(), iHeaderLen); +// if(iRet < 0) +// { +// if (iRet == TC_ClientSocket::EM_TIMEOUT) +// { +// msg->eStatus = ReqMessage::REQ_TIME; +// msg->response->sResultDesc = "recv info timeout, ret:" + TC_Common::tostr(iRet); +// } +// else +// { +// msg->eStatus = ReqMessage::REQ_NET; +// msg->response->sResultDesc = "recv body failed, ret:" + TC_Common::tostr(iRet); +// } +// break; +// } +// +// // recvBuffer.addBuffer(rbuff, iHeaderLen); +// rbuff.resize(iHeaderLen); +// recvBuffer.addSwapBuffer(rbuff); +// +// TC_NetWorkBuffer::PACKET_TYPE ret = _pAdapterProxy->getObjProxy()->getProxyProtocol().responseFunc(recvBuffer, *msg->response.get()); +// +// if (ret == TC_NetWorkBuffer::PACKET_ERR) +// { +// TLOGERROR("[TAF][tcp doResponse," << _pAdapterProxy->getObjProxy()->name() << ",fd:" << _iFd << "," << _ep.desc() << ",tcp recv decode error" << endl); +// msg->eStatus = ReqMessage::REQ_NET; +// msg->response->sResultDesc = "recv packet decode failed"; +// +// } +// else if (ret == TC_NetWorkBuffer::PACKET_FULL) { +// msg->eStatus = ReqMessage::REQ_RSP; +// } +// else { +// continue; +// } +// } +// catch (exception & ex) { +// TLOGERROR( +// "[TAF][tcp doResponse," << _pAdapterProxy->getObjProxy()->name() << ",fd:" << _iFd << "," << _ep.desc() << ",tcp recv decode error:" << ex.what() << endl); +// msg->eStatus = ReqMessage::REQ_NET; +// msg->response->sResultDesc = "recv packet decode failed"; +// +// assert(msg->request.iRequestId == msg->response->iRequestId); +// } +// catch (...) { +// TLOGERROR( +// "[TAF][tcp doResponse," << _pAdapterProxy->getObjProxy()->name() << ",fd:" << _iFd << "," << _ep.desc() << ",tcp recv decode error." << endl); +// msg->eStatus = ReqMessage::REQ_NET; +// msg->response->sResultDesc = "recv packet decode failed"; +// } +// +// break; +// }while(true); +// +// if(msg->eStatus != ReqMessage::REQ_RSP) +// { +// _syncSock->close(); +// } +//} + + void Transceiver::finishInvoke(shared_ptr &rsp) { if (_authState != AUTH_SUCC) @@ -303,7 +401,10 @@ bool Transceiver::sendAuthData(const BasicAuthInfo& info) void Transceiver::close() { if(!isValid()) return; - +// if(_adapterProxy->getObjProxy()->getPushCallback()) +// { +// _adapterProxy->getObjProxy()->getPushCallback()->onClose(); +// } #if TARS_SSL if (_openssl) { @@ -442,11 +543,6 @@ int Transceiver::sendRequest(const shared_ptr &buff) return eRetError; } - static std::atomic totalSend{0}; - totalSend += iRet; - -// cout << "totalSend:" << totalSend << endl; - //没有全部发送完,写buffer 返回成功 if(iRet < (int)buff->length()) { @@ -456,34 +552,6 @@ int Transceiver::sendRequest(const shared_ptr &buff) } return eRetOk; - -// #if TARS_SSL -// // 握手数据已加密,直接发送,会话数据需加密 -// std::string out; -// if (isSSL() && _openssl->isHandshaked()) -// { -// out = _openssl->Write(pData, iSize); -// pData = out.data(); -// iSize = out.size(); -// } -// #endif - - // int iRet = this->send(pData,iSize,0); - - // //失败,直接返回 - // if(iRet < 0) - // { - // return eRetError; - // } - - // //没有全部发送完,写buffer 返回成功 - // if(iRet < (int)iSize) - // { - // _sendBuffer.PushData(pData+iRet,iSize-iRet); - // return eRetFull; - // } - - // return eRetOk; } ////////////////////////////////////////////////////////// @@ -500,18 +568,12 @@ int TcpTransceiver::doResponse() int iRet = 0; int recvCount = 0; - - static std::atomic totalRecv{0}; - do { char buff[BUFFER_SIZE] = {0x00}; if ((iRet = this->recv(buff, BUFFER_SIZE, 0)) > 0) { - totalRecv += iRet; - -// cout << "totalRecv:" << totalRecv << endl; TC_NetWorkBuffer *rbuf = &_recvBuffer; #if TARS_SSL @@ -571,7 +633,9 @@ int TcpTransceiver::doResponse() else { break; } - }while(true); + + } + while (ret == TC_NetWorkBuffer::PACKET_FULL); //接收的数据小于buffer大小, 内核会再次通知你 if(iRet < BUFFER_SIZE) @@ -601,7 +665,7 @@ int TcpTransceiver::doResponse() } while (iRet>0); - TLOGTARS("[TARS][tcp doResponse, " << _adapterProxy->getObjProxy()->name() << ",fd:" << _fd << ", all recvbuf:" << _recvBuffer.getBufferLength() << "]" << endl); +// TLOGTARS("[TARS][tcp doResponse, " << _adapterProxy->getObjProxy()->name() << ",fd:" << _fd << ", all recvbuf:" << _recvBuffer.getBufferLength() << "]" << endl); return 0; } diff --git a/servant/protocol b/servant/protocol index 5f8fc7a..7c22d46 160000 --- a/servant/protocol +++ b/servant/protocol @@ -1 +1 @@ -Subproject commit 5f8fc7a0ed15dd784c0d41cf89a465656d7a23e0 +Subproject commit 7c22d46777d76c8c08c2161f7cb4d9f0f45991d7 diff --git a/servant/servant/AdapterProxy.h b/servant/servant/AdapterProxy.h index e8c891b..a2d11c5 100644 --- a/servant/servant/AdapterProxy.h +++ b/servant/servant/AdapterProxy.h @@ -50,12 +50,6 @@ public: */ ~AdapterProxy(); - /** - * clone - * @return - */ -// AdapterProxy *clone(); - /** * 调用server端对象方法 */ @@ -78,7 +72,7 @@ public: * @onlyCheck: 只判断是否已经连接上 * @return bool */ - bool checkActive(bool bForceConnect = false); + bool checkActive(bool bForceConnect = false, bool onlyCheck = false); /** * 记录连接是否异常 diff --git a/servant/servant/AppProtocol.h b/servant/servant/AppProtocol.h index 9b51aa9..c9a73ed 100644 --- a/servant/servant/AppProtocol.h +++ b/servant/servant/AppProtocol.h @@ -24,7 +24,6 @@ #include "tup/RequestF.h" #include "tup/tup.h" #include "servant/BaseF.h" -#include "util/tc_epoll_server.h" #include "util/tc_network_buffer.h" using namespace std; @@ -50,6 +49,9 @@ T net2host(T len) assert(true); return 0; } + +class Transceiver; + ////////////////////////////////////////////////////////////////////// /** * 协议解析 @@ -347,7 +349,108 @@ public: return TC_NetWorkBuffer::PACKET_FULL; } + /** + * wup响应包(wup的响应会放在ResponsePacket的buffer中) + * @param request + * @param buff + */ + static TC_NetWorkBuffer::PACKET_TYPE jsonResponse(TC_NetWorkBuffer &in, ResponsePacket& done) + { + return jsonResponseLen(in, done); + } + template + static TC_NetWorkBuffer::PACKET_TYPE jsonResponseLen(TC_NetWorkBuffer &in, ResponsePacket& rsp) + { + uint32_t len = (uint32_t)in.getBufferLength(); + + //收到的字节数太少, 还需要继续接收 + if (len < sizeof(uint32_t)) + return TC_NetWorkBuffer::PACKET_LESS; + + //获取包总体长度 + uint32_t iHeaderLen = in.getValueOf4(); + + //做一下保护,长度大于10M + if (iHeaderLen < iMinLength || iHeaderLen > iMaxLength) + { + throw TarsDecodeException("packet length too long or too short,len:" + TC_Common::tostr(iHeaderLen)); + } + + //包没有接收全 + if (len < iHeaderLen) + { + //看看包头是否正确 + static const uint32_t head = 20; + + if (len >= head) + { + string buffer; + in.getHeader(head, buffer); + + TarsInputStream is; + is.setBuffer(buffer.c_str() + sizeof(tars::Int32), head); + + is.read(rsp.iVersion, 1, false); + + if (rsp.iVersion != JSONVERSION) + { + throw TarsDecodeException("json version not correct, version:" + TC_Common::tostr(rsp.iVersion)); + } + + is.read(rsp.cPacketType, 2, false); + + if (rsp.cPacketType != TARSNORMAL) + { + throw TarsDecodeException("packettype not correct, packettype:" + TC_Common::tostr((int)rsp.cPacketType)); + } + + is.read(rsp.iMessageType, 3, false); + is.read(rsp.iRequestId, 4, false); + is.read(rsp.iRet, 5, false); + + if (rsp.iRet < TARSSERVERUNKNOWNERR) + { + throw TarsDecodeException("response value not correct, value:" + TC_Common::tostr(rsp.iRet)); + } + } + + return TC_NetWorkBuffer::PACKET_LESS; + } + else + { + vector buffer; + bool ret = in.parseBufferOf4(buffer, iMinLength, iMaxLength); + if (!ret) + { + throw TarsDecodeException("parse buffer exception"); + } + + TarsInputStream is; + is.setBuffer(buffer.data(), buffer.size()); + + rsp.readFrom(is); + + if (rsp.iVersion != JSONVERSION) + { + throw TarsDecodeException("json version not correct, version:" + TC_Common::tostr(rsp.iVersion)); + } + + if (rsp.cPacketType != TARSNORMAL) + { + throw TarsDecodeException("packettype not correct, packettype:" + TC_Common::tostr((int)rsp.cPacketType)); + } + + if (rsp.iRet < TARSSERVERUNKNOWNERR) + { + throw TarsDecodeException("response value not correct, value:" + TC_Common::tostr(rsp.iRet)); + } + + } + + return TC_NetWorkBuffer::PACKET_FULL; + } + public: /** * tars请求包 diff --git a/servant/servant/Application.h b/servant/servant/Application.h index 1c48e1f..00cf529 100644 --- a/servant/servant/Application.h +++ b/servant/servant/Application.h @@ -23,8 +23,8 @@ #include "util/tc_autoptr.h" #include "util/tc_config.h" -#include "util/tc_epoll_server.h" #include "util/tc_option.h" +#include "util/tc_epoll_server.h" #include "servant/BaseNotify.h" #include "servant/ServantHelper.h" #include "servant/ServantHandle.h" @@ -143,13 +143,6 @@ class PropertyReport; */ class Application : public BaseNotify { -public: - - enum - { - REPORT_SEND_QUEUE_INTERVAL = 10, /**上报服务端发送队列大小的间隔时间**/ - }; - public: /** * 应用构造 @@ -200,6 +193,11 @@ public: */ static void terminate(); + /** + * 获取tarsservant框架的版本 + */ + static string getTarsVersion(); + /** * 添加Config * @param filename @@ -217,6 +215,25 @@ public: */ void manualListen(); + /** + * 添加Servant + * @param T + * @param id + */ + template + void addServant(const string &id) + { + ServantHelperManager::getInstance()->addServant(id, this, true); + + } + + /** + * 非taf协议server,设置Servant的协议解析器 + * @param protocol + * @param servant + */ + void addServantProtocol(const string &servant, const TC_NetWorkBuffer::protocol_functor &protocol); + protected: /** * 初始化, 只会进程调用一次 @@ -355,24 +372,13 @@ protected: protected: /** - * 添加Servant - * @param T - * @param id - */ - template void addServant(const string &id) - { - ServantHelperManager::getInstance()->addServant(id, this, true); - } - - /** - * 非tars协议server,设置Servant的协议解析器 - * @param protocol - * @param servant - */ - void addServantProtocol(const string& servant, const TC_NetWorkBuffer::protocol_functor& protocol); - - /** - *设置Servant的连接断开回调 + * + * + * @param command + * @param params + * @param result + * + * @return bool */ void addServantOnClose(const string& servant, const TC_EpollServer::close_functor& f); @@ -424,13 +430,9 @@ protected: /** * bind server adapter */ - void bindAdapter(vector& adapters); + void bindAdapter(vector &adapters); - /** - * set adapter - * @param adapter - */ - void setAdapter(TC_EpollServer::BindAdapterPtr& adapter, const string &name); + void setAdapter(TC_EpollServer::BindAdapterPtr& adapter, const string &name); /** * @param servant diff --git a/servant/servant/AsyncProcThread.h b/servant/servant/AsyncProcThread.h index 6f69dd8..1109d79 100644 --- a/servant/servant/AsyncProcThread.h +++ b/servant/servant/AsyncProcThread.h @@ -19,6 +19,8 @@ #include "servant/Message.h" #include "servant/Global.h" +#include "util/tc_cas_queue.h" +#include "util/tc_thread_queue.h" namespace tars { diff --git a/servant/servant/AuthLogic.h b/servant/servant/AuthLogic.h index 42aff17..7fe2142 100644 --- a/servant/servant/AuthLogic.h +++ b/servant/servant/AuthLogic.h @@ -1,4 +1,4 @@ -#include "servant/Auth.h" +#include "servant/AuthF.h" #include "util/tc_epoll_server.h" namespace tars diff --git a/servant/servant/Communicator.h b/servant/servant/Communicator.h index 9206e72..026f148 100644 --- a/servant/servant/Communicator.h +++ b/servant/servant/Communicator.h @@ -99,16 +99,17 @@ public: */ ~Communicator(); - /** - * 生成代理 - * @param T - * @param objectName - * @param setName 指定set调用的setid - * @return T - */ - template T stringToProxy(const string& objectName,const string& setName="") - { - T prx = NULL; +public: + /** + * 生成代理 + * @param T + * @param objectName + * @param setName 指定set调用的setid + * @return T + */ + template T stringToProxy(const string& objectName, const string& setName = "") + { + T prx = NULL; stringToProxy(objectName, prx,setName); @@ -251,11 +252,6 @@ protected: */ bool isTerminating(); - /** - * 由Property初始化客户端配置 - */ - void initClientConfig(); - /** * 获取对象代理生成器 * @return ServantProxyFactoryPtr @@ -392,11 +388,8 @@ protected: /* * 分发给异步线程的索引seq */ - size_t _asyncSeq; + size_t _asyncSeq = 0; -//#if TARS_SSL -// shared_ptr _ctx; -//#endif #ifdef _USE_OPENTRACKING public: struct TraceManager:public TC_HandleBase{ diff --git a/servant/servant/CommunicatorEpoll.h b/servant/servant/CommunicatorEpoll.h index bb7da28..d79d94c 100644 --- a/servant/servant/CommunicatorEpoll.h +++ b/servant/servant/CommunicatorEpoll.h @@ -41,9 +41,9 @@ struct FDInfo { enum { - ET_C_TERMINATE = 0, ET_C_NOTIFY = 1, ET_C_NET = 2, + ET_C_TERMINATE = 3, }; /** diff --git a/servant/servant/CoroutineScheduler.h b/servant/servant/CoroutineScheduler.h index 671a82c..ae6cabe 100644 --- a/servant/servant/CoroutineScheduler.h +++ b/servant/servant/CoroutineScheduler.h @@ -24,7 +24,7 @@ #include #include "util/tc_platform.h" #include "util/tc_fcontext.h" -#include "util/tc_thread_queue.h" +#include "util/tc_cas_queue.h" #include "util/tc_monitor.h" #include #include "util/tc_thread.h" @@ -210,17 +210,6 @@ protected: //在协程里执行实际逻辑的入口函数 static void corotineProc(void * args, transfer_t t); - - // /** - // * 协程的入口函数 - // */ - // static void corotineEntry(intptr_t q); - - // /** - // * 在协程里执行实际逻辑的入口函数 - // */ - // static void corotineProc(void * args); - public: /** * 构造函数 @@ -285,7 +274,6 @@ public: /** * 获取协程所处的上下文 */ - // inline fcontext_t* getCtx() { return (!_main ? _ctx_to : &_ctx_from); } inline fcontext_t getCtx() { return _ctx; } inline void setCtx(fcontext_t ctx) { _ctx = ctx; } public: @@ -325,12 +313,6 @@ private: * 创建协程后,协程所在的上下文 */ fcontext_t _ctx; - // fcontext_t* _ctx_to; - - /* - * 创建协程前的上下文 - */ - // fcontext_t _ctx_from; /* * 协程初始化函数入口函数 @@ -601,15 +583,10 @@ private: */ CoroutineInfo _free; - /* - * 协程栈空间的内存分配器 - */ - // standard_stack_allocator _alloc; - /* * 需要激活的协程队列,其他线程使用,用来激活等待结果的协程 */ - TC_ThreadQueue > _activeCoroQueue; + TC_CasQueue > _activeCoroQueue; /* * 锁通知 diff --git a/servant/servant/EndpointInfo.h b/servant/servant/EndpointInfo.h index ba785d0..e03380a 100755 --- a/servant/servant/EndpointInfo.h +++ b/servant/servant/EndpointInfo.h @@ -19,7 +19,11 @@ #include "servant/Global.h" #include "util/tc_socket.h" -#include "Auth.h" +#include "AuthF.h" + +#if TARGET_PLATFORM_WINDOWS +#include +#endif using namespace std; @@ -34,7 +38,7 @@ namespace tars class EndpointInfo { public: - enum EType { UDP = 0, TCP = 1, SSL = 2}; +// enum EType { UDP = TC_ClientSocket::, TCP = 1, SSL = 2}; /** * 构造函数 @@ -47,7 +51,7 @@ public: * @param port * @param type */ - EndpointInfo(const string& host, uint16_t port, EndpointInfo::EType type, int32_t grid, const string & setDivision, int qos, int weight = -1, unsigned int weighttype = 0, int authType = 0); + EndpointInfo(const string& host, uint16_t port, TC_Endpoint::EType type, int32_t grid, const string & setDivision, int qos, int weight = -1, unsigned int weighttype = 0, int authType = 0); /** * 地址的字符串描述,不带set信息 @@ -81,14 +85,14 @@ public: * * @return string */ - const string& fulldesc() const; + bool isTcp() const; /** * 获取主机名 * * @return const string& */ - string host() const; + const string &host() const; /** * 获取端口号 @@ -106,17 +110,17 @@ public: /* * 获取qos的descp值 */ - int32_t qos() const {return _qos;} + int32_t qos() const {return _ep.getQos();} /* * 获取节点的静态权重值 */ - int weight() const {return _weight;} + int weight() const {return _ep.getWeight();} /** * @brief 获取节点的权重使用方式 */ - unsigned int getWeightType() const { return _weighttype; } + unsigned int getWeightType() const { return _ep.getWeightType(); } /** * 解析域名 @@ -142,7 +146,7 @@ public: * * @return EndpointInfo::EType */ - EndpointInfo::EType type() const; + TC_Endpoint::EType type() const { return _ep.getType(); } /** *设置set分组信息 @@ -161,13 +165,13 @@ public: /* * 获取认证类型 */ - AUTH_TYPE authType() const { return _authType; } + int authType() const { return _ep.getAuthType(); } /** * @brief is ipv6 socket or not * @return true if is ipv6 */ - bool isIPv6() const { return _isIPv6; } + bool isIPv6() const { return _ep.isIPv6(); } /** * 等于 @@ -210,46 +214,13 @@ protected: string createCompareDesc(); private: - /** - * 地址IP - */ - string _host; - - /** - * 端口号 - */ - uint16_t _port; - - /** - * 路由状态 - */ - int32_t _grid; - - /* - * qos的dscp值 - */ - - int32_t _qos; - - /** - * 类型 - */ - EndpointInfo::EType _type; + TC_Endpoint _ep; /** *set分组信息 */ string _setDivision; - /** - * 节点的静态权重值 - */ - int _weight; - - /** - * 节点的权重使用方式 - */ - unsigned int _weighttype; /** * 地址 @@ -270,15 +241,6 @@ private: */ string _desc; - /** - * 认证类型 - */ - tars::AUTH_TYPE _authType; - - /** - * _host is IPv6 or not - */ - bool _isIPv6; /** * 解析域名成功 diff --git a/servant/servant/EndpointManager.h b/servant/servant/EndpointManager.h index 8c2d64c..f4ff397 100644 --- a/servant/servant/EndpointManager.h +++ b/servant/servant/EndpointManager.h @@ -17,12 +17,12 @@ #ifndef __TARS_ENDPOINT_MANAGER_H_ #define __TARS_ENDPOINT_MANAGER_H_ -#include "util/tc_spin_lock.h" -#include "util/tc_consistent_hash_new.h" #include "servant/EndpointInfo.h" #include "servant/EndpointF.h" #include "servant/QueryF.h" #include "servant/AppProtocol.h" +#include "util/tc_spin_lock.h" +#include "util/tc_consistent_hash_new.h" namespace tars { @@ -343,7 +343,7 @@ public: /** * 根据请求策略从可用的服务列表选择一个服务节点 */ - bool selectAdapterProxy(ReqMessage * msg, AdapterProxy * & pAdapterProxy); + bool selectAdapterProxy(ReqMessage * msg, AdapterProxy * & pAdapterProxy, bool onlyCheck); /** * 获取所有的服务节点 @@ -358,33 +358,33 @@ private: /* * 轮询选取一个结点 */ - AdapterProxy * getNextValidProxy(); + AdapterProxy * getNextValidProxy(bool onlyCheck); /* * 根据hash值选取一个结点 */ - AdapterProxy* getHashProxy(int64_t hashCode, bool bConsistentHash = false); + AdapterProxy* getHashProxy(int64_t hashCode, bool bConsistentHash = false, bool onlyCheck = false); /* * 根据hash值按取模方式,从正常节点中选取一个结点 */ - AdapterProxy* getHashProxyForNormal(int64_t hashCode); + AdapterProxy* getHashProxyForNormal(int64_t hashCode, bool onlyCheck); /* * 根据hash值按一致性hash方式,从正常节点中选取一个结点 */ - AdapterProxy* getConHashProxyForNormal(int64_t hashCode); + AdapterProxy* getConHashProxyForNormal(int64_t hashCode, bool onlyCheck); /* * 根据hash值按取模方式,从静态权重节点中选取一个结点 */ - AdapterProxy* getHashProxyForWeight(int64_t hashCode, bool bStatic, vector &vRouterCache); + AdapterProxy* getHashProxyForWeight(int64_t hashCode, bool bStatic, vector &vRouterCache, bool onlyCheck); /* * 根据hash值按一致性hash方式,从静态权重节点中选取一个结点 */ - AdapterProxy* getConHashProxyForWeight(int64_t hashCode, bool bStatic); + AdapterProxy* getConHashProxyForWeight(int64_t hashCode, bool bStatic, bool onlyCheck); /* * 判断静态权重节点是否有变化 @@ -409,12 +409,12 @@ private: /* * 根据后端服务的权重值选取一个结点 */ - AdapterProxy* getWeightedProxy(bool bStaticWeighted); + AdapterProxy* getWeightedProxy(bool bStaticWeighted, bool onlyCheck); /* * 根据后端服务的权重值选取一个结点 */ - AdapterProxy* getWeightedForNormal(bool bStaticWeighted); + AdapterProxy* getWeightedForNormal(bool bStaticWeighted, bool onlyCheck); /* * 根据各个节点的权重值,建立各个节点的调用数 diff --git a/servant/servant/Global.h b/servant/servant/Global.h index b27deec..89073b2 100755 --- a/servant/servant/Global.h +++ b/servant/servant/Global.h @@ -25,14 +25,7 @@ #include #include #include -#include -#include -//#include -#include -#include -#include -#include - +#include "util/tc_platform.h" #include "util/tc_clientsocket.h" #include "util/tc_autoptr.h" #include "util/tc_common.h" @@ -75,7 +68,7 @@ typedef TC_AutoPtr StatFPrx; typedef TC_AutoPtr StatReportPtr; typedef TC_AutoPtr FDReactorPtr; // typedef TC_AutoPtr ServantProxyFactoryPtr; -typedef TC_AutoPtr ObjectProxyFactoryPtr; +//typedef TC_AutoPtr ObjectProxyFactoryPtr; typedef TC_AutoPtr AsyncProcThreadPtr; ////////////////////////////////////////////////////////////// diff --git a/servant/servant/Message.h b/servant/servant/Message.h index 1603bfc..8760e39 100644 --- a/servant/servant/Message.h +++ b/servant/servant/Message.h @@ -17,17 +17,17 @@ #ifndef __TARS_MESSAGE_H_ #define __TARS_MESSAGE_H_ -#include "servant/Global.h" +#include #include "util/tc_autoptr.h" #include "util/tc_monitor.h" #include "util/tc_loop_queue.h" -#include #include "servant/CoroutineScheduler.h" +#include "servant/Global.h" namespace tars { -///////////////////////////////////////////////////////////////////////// +class CoroutineScheduler; /** * 超时一定比率后进行节点屏蔽 * 设置超时检查参数 @@ -221,7 +221,7 @@ struct ReqMessage : public TC_HandleBase /* * 初始化 */ - void init(CallType eCallType, ObjectProxy * pObj, const string & sFuncName) + void init(CallType eCallType) { eStatus = ReqMessage::REQ_REQ; eType = eCallType; @@ -229,10 +229,9 @@ struct ReqMessage : public TC_HandleBase callback = NULL; proxy = NULL; - pObjectProxy = pObj; + pObjectProxy = NULL; response = std::make_shared(); - // sReqData.clear(); sReqData = std::make_shared(); pMonitor = NULL; bMonitorFin = false; @@ -269,7 +268,7 @@ struct ReqMessage : public TC_HandleBase shared_ptr sReqData; //请求消息体 ReqMonitor * pMonitor; //用于同步的monitor - bool bMonitorFin; //同步请求timewait是否结束 + volatile bool bMonitorFin; //同步请求timewait是否结束 int64_t iBeginTime; //请求时间 int64_t iEndTime; //完成时间 @@ -296,7 +295,7 @@ struct ReqMessage : public TC_HandleBase }; typedef TC_AutoPtr ReqMessagePtr; -typedef TC_LoopQueue ReqInfoQueue; +typedef TC_LoopQueue ReqInfoQueue; #define HTTP2 "http2" diff --git a/servant/servant/NetworkUtil.h b/servant/servant/NetworkUtil.h index 65e6b0f..23898cd 100644 --- a/servant/servant/NetworkUtil.h +++ b/servant/servant/NetworkUtil.h @@ -17,23 +17,6 @@ #ifndef __TARS_NETWORK_UTIL_H_ #define __TARS_NETWORK_UTIL_H_ -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include - - #include "util/tc_socket.h" #if TARGET_PLATFORM_WINDOWS #include @@ -51,36 +34,5 @@ struct NetworkUtil static std::string errorToString(int); }; - -// struct NetworkUtil -// { -// static const int INVALID_SOCKET = -1; -// static const int SOCKET_ERROR = -1; - -// static int createSocket(bool, bool isLocal = false, bool isIpv6 = false); - -// static void closeSocketNoThrow(int); - -// static void setBlock(int, bool); - -// static void setTcpNoDelay(int); - -// static void setKeepAlive(int); - -// static void doBind(int, struct sockaddr_in&); - -// static void doBind(int, const struct sockaddr *, socklen_t); - -// static bool doConnect(int, const struct sockaddr_in&); - -// static bool doConnect(int, const struct sockaddr *, socklen_t); - -// static void getAddress(const std::string&, int, struct sockaddr_in&); - -// static void getAddress(const std::string&, int, struct sockaddr_in6&); - -// static std::string errorToString(int); -// }; - } #endif diff --git a/servant/servant/ObjectProxy.h b/servant/servant/ObjectProxy.h index 7a939f7..5aa7738 100644 --- a/servant/servant/ObjectProxy.h +++ b/servant/servant/ObjectProxy.h @@ -100,9 +100,9 @@ public: ProxyProtocol& getProxyProtocol(); /** - * 设置套接口选项 - */ - void setSocketOpt(int level, int optname, const void *optval, socklen_t optlen); + *设置套接口选项 + */ + void setSocketOpt(int level, int optname, const void *optval, SOCKET_LEN_TYPE optlen); /** * 获取套接字选项 diff --git a/servant/servant/PropertyReport.h b/servant/servant/PropertyReport.h index b1c04fa..6705ebd 100755 --- a/servant/servant/PropertyReport.h +++ b/servant/servant/PropertyReport.h @@ -17,9 +17,10 @@ #ifndef __TARS_PROPERTY_REPORT_H_ #define __TARS_PROPERTY_REPORT_H_ + #include "util/tc_lock.h" #include "util/tc_autoptr.h" -#include "util/tc_thread_mutex.h" - +//#include "util/tc_thread_mutex.h" +#include "util/tc_spin_lock.h" #include #include #include @@ -48,7 +49,7 @@ public: /** * 获取该属性的服务名称 */ - std::string getMasterName() { return _sMasterName; } + const std::string &getMasterName() const { return _sMasterName; } public: @@ -169,7 +170,7 @@ typedef TC_AutoPtr PropertyReportPtr; */ template -class PropertyReportImp : public PropertyReport, public TC_ThreadMutex +class PropertyReportImp : public PropertyReport, public TC_SpinLock { public: using PropertyReportData = std::tuple; @@ -194,7 +195,7 @@ public: */ void report(int iValue) override { - TC_LockT lock(*this); + TC_LockT lock(*this); Helper::value>::Report(*this, iValue); } @@ -206,7 +207,7 @@ public: */ vector > get() override { - TC_LockT lock(*this); + TC_LockT lock(*this); return Helper::value>::Get(*this); } diff --git a/servant/servant/Servant.h b/servant/servant/Servant.h index 95fc3f5..91cb1ab 100644 --- a/servant/servant/Servant.h +++ b/servant/servant/Servant.h @@ -19,6 +19,8 @@ #include "util/tc_autoptr.h" #include "util/tc_epoll_server.h" +#include "util/tc_thread_pool.h" +#include "util/tc_cas_queue.h" #include "servant/ServantProxy.h" #include "servant/TarsCurrent.h" #include "servant/BaseNotify.h" @@ -171,7 +173,7 @@ public: * 获得响应的数据队列 * @return TC_ThreadQueue& */ - TC_ThreadQueue& getResponseQueue(); + TC_CasQueue& getResponseQueue(); protected: /** @@ -190,9 +192,11 @@ protected: TC_EpollServer::Handle* _handle; /** - * 异步响应队列 + * 异步响应队列, 每个Servant一个队列, 这个用于在ServantImp中, 再异步发请求给其他服务 + * 回调Callback使用ServantCallback时, 能保证响应包在Servant::doResponse中响应, 且和发送ServantImp是同一个线程 + * 缺点就是Servant::onDispatch, 通知ServantImp时, 需要把所有线程都唤醒 */ - TC_ThreadQueue _asyncResponseQueue; + TC_CasQueue _asyncResponseQueue; }; typedef TC_AutoPtr ServantPtr; @@ -219,6 +223,14 @@ public: */ virtual int onDispatch(ReqMessagePtr msg); + /** + * 连接关闭 + * @param msg + * @return int + */ + virtual void onClose() + { + } /** * 获得生成时所属的servant * @return const ServantPtr& @@ -250,8 +262,6 @@ class CallbackThreadData //: public TC_ThreadPool::ThreadData { public: static thread_local shared_ptr g_sp; - // static TC_ThreadMutex _mutex; //全局的互斥锁 - // static pthread_key_t _key; //私有线程数据key /** * 构造函数 diff --git a/servant/servant/ServantHandle.h b/servant/servant/ServantHandle.h index cf9735d..5e9b69e 100644 --- a/servant/servant/ServantHandle.h +++ b/servant/servant/ServantHandle.h @@ -21,11 +21,11 @@ #include #include #include +#include "util/tc_platform.h" #include "util/tc_monitor.h" #include "util/tc_epoll_server.h" #include "servant/Servant.h" #include "servant/StatReport.h" -// #include #include "servant/CoroutineScheduler.h" #ifdef _USE_OPENTRACKING #include "opentracing/span.h" @@ -110,10 +110,11 @@ protected: */ virtual void handleClose(const shared_ptr &data); - /** - * handleFilter拆分的第一部分,处理异步调用队列 - */ - virtual void handleAsyncResponse(); + + /** + * handleFilter拆分的第一部分,处理异步调用队列 + */ + virtual void handleAsyncResponse(); /** * handleFilter拆分的第二部分,处理用户自有数据 @@ -197,12 +198,8 @@ protected: /** * 处理对象 */ - map _servants; + unordered_map _servants; - /** - * 消息到达通知 - */ - // TC_ThreadLock _monitor; /** * 协程调度器 diff --git a/servant/servant/ServantHelper.h b/servant/servant/ServantHelper.h index f81ef86..eae8c24 100644 --- a/servant/servant/ServantHelper.h +++ b/servant/servant/ServantHelper.h @@ -22,6 +22,7 @@ #include #include "util/tc_autoptr.h" #include "util/tc_singleton.h" +#include "util/tc_spin_lock.h" #include "servant/Servant.h" namespace tars @@ -157,7 +158,7 @@ public: /** * 是否是已经被染色 */ - bool isDyeing() {return _isDyeing;} + bool isDyeing() const {return _isDyeing;} protected: diff --git a/servant/servant/ServantProxy.h b/servant/servant/ServantProxy.h index 3ced586..800c941 100644 --- a/servant/servant/ServantProxy.h +++ b/servant/servant/ServantProxy.h @@ -198,6 +198,7 @@ public: { TC_LockT lock(_mutex); vRet.swap(_vReqMessage); + _vReqMessage.clear(); } return vRet; @@ -278,7 +279,7 @@ public: /** * 获取coro并行请求的共享智能指针 */ - virtual const tars::CoroParallelBasePtr& getCoroParallelBasePtr() { return _pPtr; } + virtual const CoroParallelBasePtr& getCoroParallelBasePtr() { return _pPtr; } /** * 异步请求是否在网络线程处理 @@ -519,7 +520,7 @@ public: /** *设置套接字选项 */ - void tars_set_sockopt(int level, int optname, const void *optval, socklen_t optlen); + void tars_set_sockopt(int level, int optname, const void *optval, SOCKET_LEN_TYPE optlen); /** * 设置超时检查参数 @@ -545,7 +546,13 @@ public: */ virtual ServantProxy* tars_consistent_hash(int64_t key); - /** +// /** +// * 直接同步调用 +// * @return +// */ +// virtual ServantProxy* taf_direct(); + + /** * 清除当前的Hash数据 * 空函数 为了兼容以前的 * @param key @@ -587,25 +594,6 @@ public: */ virtual void tars_set_push_callback(const ServantProxyCallbackPtr& cb); - /** - * TARS协议同步方法调用 - */ - virtual shared_ptr tars_invoke(char cPacketType, - const string& sFuncName, - tars::TarsOutputStream& buf, - const map& context, - const map& status); - - /** - * TARS协议异步方法调用 - */ - virtual void tars_invoke_async(char cPacketType, - const string& sFuncName, - tars::TarsOutputStream &buf, - const map& context, - const map& status, - const ServantProxyCallbackPtr& callback, - bool bCoro = false); /** * 普通协议同步远程调用 @@ -655,6 +643,25 @@ public: */ virtual void tars_setMasterFlag(bool bMasterFlag) {_masterFlag = bMasterFlag;} + /** + * TARS协议同步方法调用 + */ + virtual shared_ptr tars_invoke(char cPacketType, + const string& sFuncName, + tars::TarsOutputStream& buf, + const map& context, + const map& status); + + /** + * TARS协议异步方法调用 + */ + virtual void tars_invoke_async(char cPacketType, + const string& sFuncName, + tars::TarsOutputStream &buf, + const map& context, + const map& status, + const ServantProxyCallbackPtr& callback, + bool bCoro = false); private: /** @@ -662,16 +669,26 @@ private: * @param req * @return int */ - void invoke(ReqMessage * msg, bool bCoroAsync = false); + void invoke(ReqMessage *msg, bool bCoroAsync = false); - /** - * 远程方法调用返回 - * @param req - * @return int - */ - void finished(ReqMessage * msg); +// /** +// * invoke 异步 +// * @param msg +// * @param pSptd +// * @param pReqQ +// * @param bCoroAsync +// */ +// void invoke_async(ReqMessage *msg, ServantProxyThreadData *pSptd, ReqInfoQueue *pReqQ, bool bCoroAsync); - /** +// /** +// * invoke 同步 +// * @param msg +// * @param pSptd +// * @param pReqQ +// */ +// void invoke_sync(ReqMessage *msg, ServantProxyThreadData *pSptd, ReqInfoQueue *pReqQ); + + /** * 选取一个网络线程对应的信息 * @param pSptd * @return void diff --git a/servant/servant/ServantProxyFactory.h b/servant/servant/ServantProxyFactory.h index 34cc2f0..0ff4436 100644 --- a/servant/servant/ServantProxyFactory.h +++ b/servant/servant/ServantProxyFactory.h @@ -27,7 +27,7 @@ namespace tars /** * 创建ServantProxy对象,每个object在进程空间只有一个ServantProxy实例 */ -class ServantProxyFactory : public TC_HandleBase, public TC_ThreadRecMutex +class ServantProxyFactory : public TC_ThreadRecMutex { public: /** diff --git a/servant/servant/Transceiver.h b/servant/servant/Transceiver.h index feb63ab..1c5dd17 100755 --- a/servant/servant/Transceiver.h +++ b/servant/servant/Transceiver.h @@ -22,6 +22,7 @@ #include "servant/CommunicatorEpoll.h" #include "servant/AuthLogic.h" #include +#include using namespace std; @@ -56,8 +57,11 @@ public: enum ReturnStatus { eRetError = -1, - eRetOk = 0, - eRetFull = 1, + eRetOk =0, + eRetFull=1, + eRetTimeout=2, + eRetPacket=3, + }; /* @@ -283,7 +287,9 @@ protected: #if TARS_SSL std::shared_ptr _openssl; #endif - + //同步调用的fd +// TC_ClientSocket *_syncSock = NULL; + /* * 发送buffer */ @@ -374,7 +380,6 @@ public: * @param flag * @return int */ - virtual int send(const void* buf, uint32_t len, uint32_t flag); /** @@ -391,8 +396,7 @@ public: * @param done * @return int */ - // virtual int doResponse(list& done); - virtual int doResponse(); + virtual int doResponse(); private: /* diff --git a/tools/tarsparse/tars.lex.cpp b/tools/tarsparse/tars.lex.cpp deleted file mode 100644 index 1e5dbb2..0000000 --- a/tools/tarsparse/tars.lex.cpp +++ /dev/null @@ -1,2218 +0,0 @@ -#line 2 "tars.lex.cpp" - -#line 4 "tars.lex.cpp" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 37 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN (yy_start) = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START (((yy_start) - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart(yyin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -extern yy_size_t yyleng; - -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires - * access to the local variable yy_act. Since yyless() is a macro, it would break - * existing scanners that call yyless() from OUTSIDE yylex. - * One obvious solution it to make yy_act a global. I tried that, and saw - * a 5% performance hit in a non-yylineno scanner, because yy_act is - * normally declared as a register variable-- so it is not worth it. - */ - #define YY_LESS_LINENO(n) \ - do { \ - int yyl;\ - for ( yyl = n; yyl < yyleng; ++yyl )\ - if ( yytext[yyl] == '\n' )\ - --yylineno;\ - }while(0) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = (yy_hold_char); \ - YY_RESTORE_YY_MORE_OFFSET \ - (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, (yytext_ptr) ) - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - yy_size_t yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* Stack of input buffers. */ -static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ -static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ -static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ - ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; -static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ -yy_size_t yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 0; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart (FILE *input_file ); -void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); -YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); -void yy_delete_buffer (YY_BUFFER_STATE b ); -void yy_flush_buffer (YY_BUFFER_STATE b ); -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); -void yypop_buffer_state (void ); - -static void yyensure_buffer_stack (void ); -static void yy_load_buffer_state (void ); -static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); - -#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) - -YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); -YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); - -void *yyalloc (yy_size_t ); -void *yyrealloc (void *,yy_size_t ); -void yyfree (void * ); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -typedef unsigned char YY_CHAR; - -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; - -typedef int yy_state_type; - -extern int yylineno; - -int yylineno = 1; - -extern char *yytext; -#define yytext_ptr yytext - -static yy_state_type yy_get_previous_state (void ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); -static int yy_get_next_buffer (void ); -static void yy_fatal_error (yyconst char msg[] ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - (yytext_ptr) = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ - (yy_hold_char) = *yy_cp; \ - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - -#define YY_NUM_RULES 13 -#define YY_END_OF_BUFFER 14 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[52] = - { 0, - 0, 0, 0, 0, 14, 12, 11, 11, 8, 12, - 12, 12, 12, 9, 9, 12, 6, 13, 13, 0, - 0, 9, 9, 10, 5, 4, 10, 9, 0, 0, - 3, 0, 7, 6, 0, 2, 0, 0, 10, 0, - 10, 9, 0, 0, 10, 0, 0, 0, 1, 1, - 0 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 5, 6, 1, 1, 1, 1, 7, - 1, 8, 9, 1, 10, 11, 12, 13, 14, 14, - 14, 14, 14, 14, 14, 15, 15, 16, 1, 1, - 1, 1, 1, 1, 17, 17, 17, 17, 18, 19, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 1, 1, 1, 1, 20, 1, 17, 17, 21, 22, - - 23, 19, 20, 20, 24, 20, 20, 25, 20, 26, - 20, 20, 20, 20, 20, 20, 27, 20, 20, 28, - 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[29] = - { 0, - 1, 2, 3, 2, 1, 1, 2, 1, 4, 4, - 1, 1, 5, 5, 5, 1, 6, 6, 6, 2, - 6, 6, 6, 2, 2, 2, 2, 2 - } ; - -static yyconst flex_int16_t yy_base[58] = - { 0, - 0, 0, 119, 118, 122, 125, 125, 125, 125, 97, - 18, 21, 29, 31, 25, 104, 48, 125, 114, 83, - 43, 0, 0, 47, 125, 125, 0, 76, 38, 0, - 125, 65, 125, 71, 89, 88, 71, 54, 125, 66, - 69, 0, 52, 72, 76, 49, 49, 20, 38, 28, - 125, 95, 100, 106, 109, 110, 113 - } ; - -static yyconst flex_int16_t yy_def[58] = - { 0, - 51, 1, 52, 52, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 14, 51, 53, 51, 54, 51, - 51, 14, 15, 51, 51, 51, 24, 14, 55, 56, - 51, 51, 51, 53, 54, 54, 51, 57, 51, 51, - 51, 56, 51, 51, 51, 51, 51, 51, 51, 51, - 0, 51, 51, 51, 51, 51, 51 - } ; - -static yyconst flex_int16_t yy_nxt[154] = - { 0, - 6, 7, 8, 7, 9, 10, 6, 6, 11, 11, - 12, 13, 14, 15, 15, 16, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 21, 50, - 22, 23, 23, 24, 24, 24, 25, 23, 23, 50, - 26, 27, 49, 28, 28, 23, 40, 40, 29, 32, - 32, 32, 51, 29, 33, 24, 24, 24, 30, 24, - 24, 24, 44, 44, 38, 39, 32, 32, 32, 38, - 48, 33, 32, 32, 32, 47, 46, 33, 41, 41, - 41, 41, 41, 41, 45, 45, 45, 39, 45, 45, - 45, 43, 36, 36, 39, 18, 18, 18, 18, 18, - - 18, 34, 34, 51, 34, 34, 35, 35, 37, 35, - 35, 35, 41, 41, 42, 42, 45, 45, 36, 31, - 20, 51, 19, 19, 5, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51 - } ; - -static yyconst flex_int16_t yy_chk[154] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 11, 50, - 11, 11, 11, 12, 12, 12, 13, 15, 15, 49, - 13, 14, 48, 14, 14, 14, 29, 29, 14, 17, - 17, 17, 15, 14, 17, 21, 21, 21, 14, 24, - 24, 24, 38, 38, 24, 24, 32, 32, 32, 24, - 47, 32, 34, 34, 34, 46, 43, 34, 40, 40, - 40, 41, 41, 41, 44, 44, 44, 41, 45, 45, - 45, 37, 36, 35, 45, 52, 52, 52, 52, 52, - - 52, 53, 53, 28, 53, 53, 54, 54, 20, 54, - 54, 54, 55, 55, 56, 56, 57, 57, 19, 16, - 10, 5, 4, 3, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51 - } ; - -/* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[14] = - { 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, }; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -extern int yy_flex_debug; -int yy_flex_debug = 0; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -/** - * Tencent is pleased to support the open source community by making Tars available. - * - * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -#line 20 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -#include -#include -#include -#include -#include -#include -#define YYSTYPE GrammarBasePtr - -#include "parse.h" -#include "tars.tab.hpp" - -using namespace std; - -extern "C" -{ - int yywrap() - { - return 1; - } -} - -struct include_file_state -{ - YY_BUFFER_STATE state; - string file; -}; - -#define MAX_INCLUDE_DEPTH 200 -include_file_state include_file_stack[MAX_INCLUDE_DEPTH]; -int include_file_stack_ptr = 0; - -int isatty(int) -{ - return 0; -} - - -#line 571 "tars.lex.cpp" - -#define INITIAL 0 -#define INCL 1 - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -static int yy_init_globals (void ); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy (void ); - -int yyget_debug (void ); - -void yyset_debug (int debug_flag ); - -YY_EXTRA_TYPE yyget_extra (void ); - -void yyset_extra (YY_EXTRA_TYPE user_defined ); - -FILE *yyget_in (void ); - -void yyset_in (FILE * in_str ); - -FILE *yyget_out (void ); - -void yyset_out (FILE * out_str ); - -yy_size_t yyget_leng (void ); - -char *yyget_text (void ); - -int yyget_lineno (void ); - -void yyset_lineno (int line_number ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap (void ); -#else -extern int yywrap (void ); -#endif -#endif - - static void yyunput (int c,char *buf_ptr ); - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (void ); -#else -static int input (void ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - size_t n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex (void); - -#define YY_DECL int yylex (void) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - -#line 67 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" - - -#line 749 "tars.lex.cpp" - - if ( !(yy_init) ) - { - (yy_init) = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! (yy_start) ) - (yy_start) = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ); - } - - yy_load_buffer_state( ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); - - /* Support of yytext. */ - *yy_cp = (yy_hold_char); - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = (yy_start); -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 52 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 125 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - - if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) - { - yy_size_t yyl; - for ( yyl = 0; yyl < yyleng; ++yyl ) - if ( yytext[yyl] == '\n' ) - - yylineno++; -; - } - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = (yy_hold_char); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 69 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -{ BEGIN(INCL); } - YY_BREAK -case 2: -YY_RULE_SETUP -#line 71 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -{ - if ( include_file_stack_ptr >= MAX_INCLUDE_DEPTH ) - { - g_parse->error("Includes nested too deeply" ); - } - - string file; - bool b = g_parse->getFilePath( yytext, file); - g_parse->currentContextPtr()->addInclude(file); - - //该文件没解析过 - if(b) - { - include_file_stack[include_file_stack_ptr].state = YY_CURRENT_BUFFER; - include_file_stack[include_file_stack_ptr].file = file; - include_file_stack_ptr++; - - yyin = fopen( file.c_str(), "r" ); - if ( !yyin ) - { - g_parse->error("can't open file:" + file); - } - - yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE ) ); - - g_parse->pushFile(file); - } - BEGIN(INITIAL); -} - YY_BREAK -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(INCL): -#line 101 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -{ - --include_file_stack_ptr; - if ( include_file_stack_ptr < 0 ) - { - include_file_stack_ptr = 0; - yyterminate(); - } - else - { - yy_delete_buffer(YY_CURRENT_BUFFER ); - fclose(yyin); - yy_switch_to_buffer(include_file_stack[include_file_stack_ptr].state ); - g_parse->popFile(); - } -} - YY_BREAK -case 3: -YY_RULE_SETUP -#line 117 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -{ - return TARS_SCOPE_DELIMITER; -} - YY_BREAK -case 4: -YY_RULE_SETUP -#line 121 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -{ - // C++ comment - bool e = false; - while(!e) - { - int input = yyinput(); - if(input == '\n') - { - g_parse->nextLine(); - } - - if(input == '\n' || input == EOF) - { - e = true; - } - } -} - YY_BREAK -case 5: -YY_RULE_SETUP -#line 139 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -{ - // C comment - bool e = false; - string comment = yytext + 2; - while(!e) - { - int input = yyinput(); - switch(input) - { - case '*': - { - int nextInput = yyinput(); - if(nextInput == '/') - { - e = true; - } - else - { - comment += static_cast(input); - unput(nextInput); - } - break; - } - case '\n': - { - comment += static_cast(input); - g_parse->nextLine(); - break; - } - case EOF: - { - g_parse->error("EOF in comment"); - e = true; - break; - } - default: - { - comment += static_cast(input); - break; - } - } - } - if(comment[0] == '*') - { - //todo - } -} - YY_BREAK -case 6: -YY_RULE_SETUP -#line 187 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -{ - StringGrammarPtr ident = new StringGrammar; - ident->v = yytext; - yylval = ident; - return g_parse->checkKeyword(ident->v); -} - YY_BREAK -case 7: -/* rule 7 can match eol */ -YY_RULE_SETUP -#line 194 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -{ - StringGrammarPtr ident = new StringGrammar; - ident->v = yytext; - ident->v.erase(ident->v.find_first_of(" \t\v\n\r\f(")); - - yylval = ident; - - return TARS_OP; -} - YY_BREAK -case 8: -YY_RULE_SETUP -#line 204 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -{ - StringGrammarPtr str = new StringGrammar; - bool e = false; - while(!e) - { - int input = yyinput(); - switch(input) - { - case '"': - { - e = true; - break; - } - case '\n': - { - g_parse->error("newline in string"); - break; - } - case EOF: - { - g_parse->error("EOF in string"); - break; - } - case '\\': - { - static string specialChars = "nrtvfab?"; - static string octalChars = "0123"; - - char nextInput = static_cast(yyinput()); - if(nextInput == '\\' || nextInput == '"' || nextInput == '\'') - { - str->v += nextInput; - } - else if(specialChars.find(nextInput) != string::npos) - { - str->v += '\\'; - str->v += nextInput; - } - else if(octalChars.find(nextInput) != string::npos) - { - static string octalDigits = "01234567"; - - unsigned short us = nextInput - '0'; - if(octalDigits.find_first_of(nextInput = static_cast(yyinput())) != string::npos) - { - us = us * 8 + nextInput - '0'; - if(octalDigits.find_first_of(nextInput = static_cast(yyinput())) != string::npos) - { - us = us * 8 + nextInput - '0'; - } - else - { - unput(nextInput); - } - } - else - { - unput(nextInput); - } - - if(us == 0) - { - g_parse->error("illegal NUL character in string constant"); - } - str->v += static_cast(us); - } - else if(nextInput == 'x') - { - long long ull = 0; - while(isxdigit(nextInput = static_cast(yyinput()))) - { - ull *= 16; - if(isdigit(nextInput)) - { - ull += nextInput - '0'; - } - else if(islower(nextInput)) - { - ull += nextInput - 'a' + 10; - } - else - { - ull += nextInput - 'A' + 10; - } - } - - unput(nextInput); - - if(ull == 0) - { - g_parse->error("illegal NUL character in string constant"); - } - str->v += static_cast(ull); - } - else - { - str->v += static_cast(input); - } - - break; - } - default: - { - str->v += static_cast(input); - break; - } - } - } - yylval = str; - return TARS_STRING_LITERAL; -} - YY_BREAK -case 9: -YY_RULE_SETUP -#line 316 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -{ - errno = 0; - IntergerGrammarPtr ptr = new IntergerGrammar; - yylval = ptr; - - string value = yytext; - const char* beg = value.c_str(); - char* e = 0; - - ptr->v = strtoll(beg, &e, 0); - if(!(errno == 0 && beg != e)) - { - assert(ptr->v != 0); - string err = "integer constant `"; - err += value; - err += "' out of range"; - g_parse->error(err); - } - - return TARS_CONST_INTEGER; -} - YY_BREAK -case 10: -YY_RULE_SETUP -#line 338 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -{ - errno = 0; - FloatGrammarPtr ptr = new FloatGrammar; - yylval = ptr; - - string value(yytext); - - char lastChar = value[value.size() - 1]; - if(lastChar == 'f' || lastChar == 'F') - { - value = value.substr(0, value.size() - 1); - } - - ptr->v = strtod(value.c_str(), 0); - if((errno == ERANGE) && (ptr->v == HUGE_VAL || ptr->v == -HUGE_VAL)) - { - string err = "float point constant `"; - err += value; - err += "' too large (overflow)"; - g_parse->error(err); - } - else if(errno == ERANGE && ptr->v == 0) - { - string err = "float point constant `"; - err += value; - err += "' too small (underflow)"; - g_parse->error(err); - } - return TARS_CONST_FLOAT; -} - YY_BREAK -case 11: -/* rule 11 can match eol */ -YY_RULE_SETUP -#line 369 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -{ - if(yytext[0] == '\n') - { - g_parse->nextLine(); - } -} - YY_BREAK -case 12: -YY_RULE_SETUP -#line 376 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -{ - if(yytext[0] < 32 || yytext[0] > 126) - { - stringstream s; - s << "illegal input character: '\\"; - s.width(3); - s.fill('0'); - s << oct << static_cast(static_cast(yytext[0])); - s << "'"; - - g_parse->error(s.str()); - return BAD_CHAR; - } - return yytext[0]; -} - YY_BREAK -case 13: -YY_RULE_SETUP -#line 392 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" -ECHO; - YY_BREAK -#line 1211 "tars.lex.cpp" - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = (yy_hold_char); - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++(yy_c_buf_p); - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = (yy_c_buf_p); - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_END_OF_FILE: - { - (yy_did_buffer_switch_on_eof) = 0; - - if ( yywrap( ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = - (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - (yy_c_buf_p) = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of yylex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (void) -{ - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = (yytext_ptr); - register int number_to_move, i; - int ret_val; - - if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; - - else - { - yy_size_t num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; - - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - yy_size_t new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - if ( (yy_n_chars) == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart(yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - (yy_n_chars) += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; - - (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (void) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = (yy_start); - - for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 52 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) -{ - register int yy_is_jam; - register char *yy_cp = (yy_c_buf_p); - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 52 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 51); - - return yy_is_jam ? 0 : yy_current_state; -} - - static void yyunput (int c, register char * yy_bp ) -{ - register char *yy_cp; - - yy_cp = (yy_c_buf_p); - - /* undo effects of setting up yytext */ - *yy_cp = (yy_hold_char); - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register yy_size_t number_to_move = (yy_n_chars) + 2; - register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - register char *source = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - - while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - if ( c == '\n' ){ - --yylineno; - } - - (yytext_ptr) = yy_bp; - (yy_hold_char) = *yy_cp; - (yy_c_buf_p) = yy_cp; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (void) -#else - static int input (void) -#endif - -{ - int c; - - *(yy_c_buf_p) = (yy_hold_char); - - if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - /* This was really a NUL. */ - *(yy_c_buf_p) = '\0'; - - else - { /* need more input */ - yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart(yyin ); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap( ) ) - return EOF; - - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = (yytext_ptr) + offset; - break; - } - } - } - - c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ - *(yy_c_buf_p) = '\0'; /* preserve yytext */ - (yy_hold_char) = *++(yy_c_buf_p); - - if ( c == '\n' ) - - yylineno++; -; - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * - * @note This function does not reset the start condition to @c INITIAL . - */ - void yyrestart (FILE * input_file ) -{ - - if ( ! YY_CURRENT_BUFFER ){ - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ); - } - - yy_init_buffer(YY_CURRENT_BUFFER,input_file ); - yy_load_buffer_state( ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * - */ - void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) -{ - - /* TODO. We should be able to replace this entire function body - * with - * yypop_buffer_state(); - * yypush_buffer_state(new_buffer); - */ - yyensure_buffer_stack (); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - yy_load_buffer_state( ); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - (yy_did_buffer_switch_on_eof) = 1; -} - -static void yy_load_buffer_state (void) -{ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - (yy_hold_char) = *(yy_c_buf_p); -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * - * @return the allocated buffer state. - */ - YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer(b,file ); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with yy_create_buffer() - * - */ - void yy_delete_buffer (YY_BUFFER_STATE b ) -{ - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yyfree((void *) b->yy_ch_buf ); - - yyfree((void *) b ); -} - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a yyrestart() or at EOF. - */ - static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) - -{ - int oerrno = errno; - - yy_flush_buffer(b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then yy_init_buffer was _probably_ - * called from yyrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * - */ - void yy_flush_buffer (YY_BUFFER_STATE b ) -{ - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - yy_load_buffer_state( ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * - */ -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) -{ - if (new_buffer == NULL) - return; - - yyensure_buffer_stack(); - - /* This block is copied from yy_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - (yy_buffer_stack_top)++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from yy_switch_to_buffer. */ - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * - */ -void yypop_buffer_state (void) -{ - if (!YY_CURRENT_BUFFER) - return; - - yy_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - if ((yy_buffer_stack_top) > 0) - --(yy_buffer_stack_top); - - if (YY_CURRENT_BUFFER) { - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void yyensure_buffer_stack (void) -{ - yy_size_t num_to_alloc; - - if (!(yy_buffer_stack)) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - (yy_buffer_stack_max) = num_to_alloc; - (yy_buffer_stack_top) = 0; - return; - } - - if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = (yy_buffer_stack_max) + grow_size; - (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc - ((yy_buffer_stack), - num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); - (yy_buffer_stack_max) = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer(b ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to yylex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * yy_scan_bytes() instead. - */ -YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) -{ - - return yy_scan_bytes(yystr,strlen(yystr) ); -} - -/** Setup the input buffer state to scan the given bytes. The next call to yylex() will - * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - yy_size_t i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) yyalloc(n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer(buf,n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg ) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = (yy_hold_char); \ - (yy_c_buf_p) = yytext + yyless_macro_arg; \ - (yy_hold_char) = *(yy_c_buf_p); \ - *(yy_c_buf_p) = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the current line number. - * - */ -int yyget_lineno (void) -{ - - return yylineno; -} - -/** Get the input stream. - * - */ -FILE *yyget_in (void) -{ - return yyin; -} - -/** Get the output stream. - * - */ -FILE *yyget_out (void) -{ - return yyout; -} - -/** Get the length of the current token. - * - */ -yy_size_t yyget_leng (void) -{ - return yyleng; -} - -/** Get the current token. - * - */ - -char *yyget_text (void) -{ - return yytext; -} - -/** Set the current line number. - * @param line_number - * - */ -void yyset_lineno (int line_number ) -{ - - yylineno = line_number; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * - * @see yy_switch_to_buffer - */ -void yyset_in (FILE * in_str ) -{ - yyin = in_str ; -} - -void yyset_out (FILE * out_str ) -{ - yyout = out_str ; -} - -int yyget_debug (void) -{ - return yy_flex_debug; -} - -void yyset_debug (int bdebug ) -{ - yy_flex_debug = bdebug ; -} - -static int yy_init_globals (void) -{ - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from yylex_destroy(), so don't allocate here. - */ - - /* We do not touch yylineno unless the option is enabled. */ - yylineno = 1; - - (yy_buffer_stack) = 0; - (yy_buffer_stack_top) = 0; - (yy_buffer_stack_max) = 0; - (yy_c_buf_p) = (char *) 0; - (yy_init) = 0; - (yy_start) = 0; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * yylex_init() - */ - return 0; -} - -/* yylex_destroy is for both reentrant and non-reentrant scanners. */ -int yylex_destroy (void) -{ - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - yy_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - yypop_buffer_state(); - } - - /* Destroy the stack itself. */ - yyfree((yy_buffer_stack) ); - (yy_buffer_stack) = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * yylex() is called, initialization will occur. */ - yy_init_globals( ); - - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s ) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *yyalloc (yy_size_t size ) -{ - return (void *) malloc( size ); -} - -void *yyrealloc (void * ptr, yy_size_t size ) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void yyfree (void * ptr ) -{ - free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 392 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.l" - - - - diff --git a/tools/tarsparse/tars.tab.cpp b/tools/tarsparse/tars.tab.cpp deleted file mode 100644 index cae5f76..0000000 --- a/tools/tarsparse/tars.tab.cpp +++ /dev/null @@ -1,3080 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "3.0.4" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - - - - -/* Copy the first part of user declarations. */ -#line 17 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:339 */ - -#include -#include -#include - -using namespace std; - -#define YYSTYPE GrammarBasePtr - -#include "parse.h" -#define YYDEBUG 1 -#define YYINITDEPTH 10000 - -#line 80 "tars.tab.cpp" /* yacc.c:339 */ - -# ifndef YY_NULLPTR -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr -# else -# define YY_NULLPTR 0 -# endif -# endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* In a future release of Bison, this section will be replaced - by #include "tars.tab.hpp". */ -#ifndef YY_YY_TARS_TAB_HPP_INCLUDED -# define YY_YY_TARS_TAB_HPP_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 1 -#endif -#if YYDEBUG -extern int yydebug; -#endif - -/* Token type. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - TARS_VOID = 258, - TARS_STRUCT = 259, - TARS_BOOL = 260, - TARS_BYTE = 261, - TARS_SHORT = 262, - TARS_INT = 263, - TARS_DOUBLE = 264, - TARS_FLOAT = 265, - TARS_LONG = 266, - TARS_STRING = 267, - TARS_VECTOR = 268, - TARS_MAP = 269, - TARS_NAMESPACE = 270, - TARS_INTERFACE = 271, - TARS_IDENTIFIER = 272, - TARS_OUT = 273, - TARS_OP = 274, - TARS_KEY = 275, - TARS_ROUTE_KEY = 276, - TARS_REQUIRE = 277, - TARS_OPTIONAL = 278, - TARS_CONST_INTEGER = 279, - TARS_CONST_FLOAT = 280, - TARS_FALSE = 281, - TARS_TRUE = 282, - TARS_STRING_LITERAL = 283, - TARS_SCOPE_DELIMITER = 284, - TARS_CONST = 285, - TARS_ENUM = 286, - TARS_UNSIGNED = 287, - BAD_CHAR = 288 - }; -#endif - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef int YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - - -extern YYSTYPE yylval; - -int yyparse (void); - -#endif /* !YY_YY_TARS_TAB_HPP_INCLUDED */ - -/* Copy the second part of user declarations. */ - -#line 165 "tars.tab.cpp" /* yacc.c:358 */ - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#else -typedef signed char yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - -#ifndef YY_ATTRIBUTE -# if (defined __GNUC__ \ - && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ - || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -# define YY_ATTRIBUTE(Spec) __attribute__(Spec) -# else -# define YY_ATTRIBUTE(Spec) /* empty */ -# endif -#endif - -#ifndef YY_ATTRIBUTE_PURE -# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -#endif - -#ifndef YY_ATTRIBUTE_UNUSED -# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) -#endif - -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) -#else -# define YYUSE(E) /* empty */ -#endif - -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -# define YY_INITIAL_VALUE(Value) Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS -# include /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's 'empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (0) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 75 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 565 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 46 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 42 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 137 -/* YYNSTATES -- Number of states. */ -#define YYNSTATES 199 - -/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 288 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 41, 42, 2, 37, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 43, 34, - 44, 38, 45, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 39, 2, 40, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 35, 2, 36, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33 -}; - -#if YYDEBUG - /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 68, 68, 75, 74, 79, 78, 83, 88, 95, - 99, 103, 107, 110, 114, 124, 123, 146, 159, 170, - 174, 182, 193, 198, 212, 220, 219, 253, 252, 271, - 284, 304, 303, 337, 341, 352, 355, 358, 363, 370, - 376, 393, 422, 423, 434, 436, 447, 458, 470, 482, - 494, 506, 510, 519, 530, 542, 541, 583, 587, 593, - 602, 606, 611, 620, 629, 647, 669, 691, 708, 712, - 716, 720, 729, 739, 749, 757, 765, 773, 786, 806, - 824, 833, 843, 853, 862, 867, 871, 880, 889, 893, - 902, 906, 910, 914, 918, 922, 926, 930, 934, 938, - 942, 946, 950, 954, 972, 976, 980, 984, 993, 997, - 1006, 1009, 1015, 1028, 1031, 1034, 1037, 1040, 1043, 1046, - 1049, 1052, 1055, 1058, 1061, 1064, 1067, 1070, 1073, 1076, - 1079, 1082, 1085, 1088, 1091, 1094, 1097, 1100 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || 0 -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "TARS_VOID", "TARS_STRUCT", "TARS_BOOL", - "TARS_BYTE", "TARS_SHORT", "TARS_INT", "TARS_DOUBLE", "TARS_FLOAT", - "TARS_LONG", "TARS_STRING", "TARS_VECTOR", "TARS_MAP", "TARS_NAMESPACE", - "TARS_INTERFACE", "TARS_IDENTIFIER", "TARS_OUT", "TARS_OP", "TARS_KEY", - "TARS_ROUTE_KEY", "TARS_REQUIRE", "TARS_OPTIONAL", "TARS_CONST_INTEGER", - "TARS_CONST_FLOAT", "TARS_FALSE", "TARS_TRUE", "TARS_STRING_LITERAL", - "TARS_SCOPE_DELIMITER", "TARS_CONST", "TARS_ENUM", "TARS_UNSIGNED", - "BAD_CHAR", "';'", "'{'", "'}'", "','", "'='", "'['", "']'", "')'", - "'*'", "':'", "'<'", "'>'", "$accept", "start", "definitions", "$@1", - "$@2", "definition", "enum_def", "@3", "enum_id", "enumerator_list", - "enumerator", "namespace_def", "@4", "key_def", "$@5", "key_members", - "interface_def", "@6", "interface_id", "interface_exports", - "interface_export", "operation", "operation_preamble", "return_type", - "parameters", "routekey_qualifier", "out_qualifier", "struct_def", "@7", - "struct_id", "struct_exports", "data_member", "struct_type_id", - "const_initializer", "const_def", "type_id", "type", "type_no", "vector", - "map", "scoped_name", "keyword", YY_NULLPTR -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[NUM] -- (External) token number corresponding to the - (internal) symbol number NUM (which must be that of a token). */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 59, 123, 125, 44, 61, 91, - 93, 41, 42, 58, 60, 62 -}; -# endif - -#define YYPACT_NINF -146 - -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-146))) - -#define YYTABLE_NINF -113 - -#define yytable_value_is_error(Yytable_value) \ - 0 - - /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -static const yytype_int16 yypact[] = -{ - 145, -22, 286, 20, 445, 16, 372, 475, 42, -146, - 26, -146, -146, -146, -146, -146, -146, -146, -146, -146, - -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, - -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, - -146, -146, -146, -146, -146, -146, -146, -146, -146, -146, - -146, -146, 11, -146, -146, -146, -146, -146, -146, -146, - -146, -146, 7, 2, -146, 37, 51, 23, 182, 19, - -146, -146, 35, -146, -146, -146, 31, 32, 33, 49, - 102, 66, -2, -146, 386, 415, -146, -146, -146, -146, - 153, -5, 69, -146, 8, 87, 102, 505, 252, 220, - -146, 120, -146, -146, 5, -146, 29, 78, -146, -146, - -146, -146, -146, -146, 79, 86, 88, -146, -146, -146, - -146, -146, 75, 80, 83, -146, 81, -146, 90, 93, - -146, 12, 112, -146, 372, 372, 314, 98, 103, -146, - -146, 107, 122, -146, -146, 533, 127, 108, -146, 153, - -146, 505, 252, -146, 252, -146, -146, 15, 68, 82, - -146, -146, -146, -146, 372, 372, -146, -146, 220, -146, - -146, -26, 109, 118, -146, -146, -146, -146, -146, 343, - -146, -146, -146, 117, 119, -146, 146, -146, -146, 372, - 372, -146, 153, 153, -146, -146, -146, -146, -146 -}; - - /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 7, 13, 15, 9, 12, 10, 31, 11, 55, 14, - 5, 59, 114, 113, 115, 116, 117, 118, 120, 119, - 121, 122, 124, 125, 126, 57, 127, 123, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 58, 25, - 33, 34, 0, 86, 90, 91, 93, 95, 99, 98, - 97, 100, 0, 0, 110, 0, 0, 0, 85, 88, - 101, 102, 103, 17, 18, 1, 0, 0, 0, 0, - 0, 0, 0, 107, 0, 0, 111, 92, 94, 96, - 0, 80, 0, 84, 0, 0, 0, 24, 0, 0, - 6, 0, 27, 105, 0, 109, 0, 77, 72, 73, - 75, 76, 74, 79, 0, 0, 0, 82, 89, 87, - 112, 4, 21, 0, 20, 22, 0, 43, 0, 37, - 39, 0, 0, 42, 0, 0, 0, 0, 61, 63, - 71, 0, 0, 106, 104, 0, 0, 0, 83, 0, - 16, 24, 0, 32, 0, 54, 53, 0, 0, 0, - 45, 41, 68, 69, 0, 0, 70, 56, 0, 26, - 29, 0, 0, 78, 81, 23, 19, 36, 35, 0, - 40, 49, 47, 64, 67, 60, 0, 28, 108, 0, - 0, 46, 0, 0, 30, 50, 48, 65, 66 -}; - - /* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -146, -146, -65, -146, -146, -146, -146, -146, -146, 13, - -146, -146, -146, -146, -146, -146, -146, -146, -146, -109, - -146, -146, -146, -146, -146, -17, -13, -146, -146, -146, - -1, -146, -146, -145, -146, -6, -82, -146, -146, -146, - -51, 3 -}; - - /* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 8, 9, 76, 80, 10, 11, 77, 12, 123, - 124, 13, 81, 14, 142, 171, 15, 78, 16, 128, - 129, 130, 131, 132, 157, 158, 159, 17, 79, 18, - 137, 138, 139, 113, 19, 140, 68, 69, 70, 71, - 72, 125 -}; - - /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ -static const yytype_int16 yytable[] = -{ - 67, 82, 104, 106, 175, 48, 143, 51, 83, 118, - 74, 186, 20, 53, 187, 100, 133, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 95, 64, 64, - 155, 121, 119, 156, 115, 102, 141, 49, 116, 114, - 65, 65, 75, 177, 66, 178, 85, 197, 198, -44, - 144, 84, 179, -44, 86, 52, 180, 87, 88, 89, - -3, 90, 94, 172, 95, 96, 145, 97, 98, 53, - 133, 93, 133, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 53, 99, 64, 117, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 65, 114, 64, - 66, 101, -8, 1, 120, -52, 2, -110, 146, -52, - 147, 65, 148, 149, 66, 152, 150, 3, 4, -51, - 151, 1, 5, -51, 2, 160, 153, 154, 162, 163, - 166, 161, 6, 7, 167, 3, 4, 168, -8, 170, - 5, 114, 114, 169, 173, -8, 1, -112, 174, 2, - 6, 7, 181, 182, 188, 192, -8, 193, 183, 184, - 3, 4, 189, 194, 176, 5, 190, 185, 0, 0, - 107, 0, 0, 191, 0, 6, 7, 108, 109, 110, - 111, 112, 65, 195, 196, 22, 23, 24, 25, 26, - 27, 28, 29, 0, 30, 31, 32, 33, 34, 91, - 36, 0, 37, 0, 38, 39, 40, 41, 42, 43, - 44, 0, 45, 46, 47, 0, 0, 0, 0, 0, - 0, 53, 0, 0, 92, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 0, 0, 64, 0, 0, - 0, 0, 134, 135, 136, 0, 0, 0, 0, 65, - 0, 0, 66, 126, 0, 127, -62, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 0, 0, 64, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 65, 0, 0, 66, 0, 0, 21, -38, 22, - 23, 24, 25, 26, 27, 28, 29, 0, 30, 31, - 32, 33, 34, 35, 36, 0, 37, 0, 38, 39, - 40, 41, 42, 43, 44, 53, 45, 46, 47, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, - 0, 64, 0, 0, 0, 0, 164, 165, 0, 0, - 0, 0, 0, 65, 53, 0, 66, 0, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, - 64, 155, 0, 0, 156, 0, 0, 0, 0, 0, - 0, 0, 65, 53, 0, 66, 0, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 103, 0, 64, - 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 65, 0, 64, 66, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 65, 105, 0, 66, 0, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 65, 0, 0, 66, 22, 23, - 24, 25, 26, 27, 28, 29, 0, 30, 31, 32, - 33, 34, 50, 36, 0, 37, 0, 38, 39, 40, - 41, 42, 43, 44, 0, 45, 46, 47, 22, 23, - 24, 25, 26, 27, 28, 29, 0, 30, 31, 32, - 33, 34, 73, 36, 0, 37, 0, 38, 39, 40, - 41, 42, 43, 44, 0, 45, 46, 47, 22, 23, - 24, 25, 26, 27, 28, 29, 0, 30, 31, 32, - 33, 34, 122, 36, 0, 37, 0, 38, 39, 40, - 41, 42, 43, 44, 0, 45, 46, 47, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, - 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 65, 0, 0, 66 -}; - -static const yytype_int16 yycheck[] = -{ - 6, 52, 84, 85, 149, 2, 1, 4, 1, 1, - 7, 37, 34, 1, 40, 80, 98, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 29, 17, 17, - 18, 96, 24, 21, 39, 37, 101, 17, 43, 90, - 29, 29, 0, 152, 32, 154, 44, 192, 193, 37, - 45, 44, 37, 41, 17, 39, 41, 6, 7, 8, - 34, 38, 43, 145, 29, 34, 37, 35, 35, 1, - 152, 68, 154, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 1, 35, 17, 17, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 29, 149, 17, - 32, 35, 0, 1, 17, 37, 4, 29, 29, 41, - 24, 29, 24, 38, 32, 34, 36, 15, 16, 37, - 37, 1, 20, 41, 4, 131, 36, 34, 134, 135, - 136, 19, 30, 31, 36, 15, 16, 34, 36, 17, - 20, 192, 193, 36, 17, 0, 1, 29, 40, 4, - 30, 31, 158, 159, 45, 38, 36, 38, 164, 165, - 15, 16, 179, 17, 151, 20, 179, 168, -1, -1, - 17, -1, -1, 179, -1, 30, 31, 24, 25, 26, - 27, 28, 29, 189, 190, 3, 4, 5, 6, 7, - 8, 9, 10, -1, 12, 13, 14, 15, 16, 17, - 18, -1, 20, -1, 22, 23, 24, 25, 26, 27, - 28, -1, 30, 31, 32, -1, -1, -1, -1, -1, - -1, 1, -1, -1, 42, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, -1, -1, 17, -1, -1, - -1, -1, 22, 23, 24, -1, -1, -1, -1, 29, - -1, -1, 32, 1, -1, 3, 36, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, -1, -1, 17, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 29, -1, -1, 32, -1, -1, 1, 36, 3, - 4, 5, 6, 7, 8, 9, 10, -1, 12, 13, - 14, 15, 16, 17, 18, -1, 20, -1, 22, 23, - 24, 25, 26, 27, 28, 1, 30, 31, 32, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, - -1, 17, -1, -1, -1, -1, 22, 23, -1, -1, - -1, -1, -1, 29, 1, -1, 32, -1, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, -1, -1, - 17, 18, -1, -1, 21, -1, -1, -1, -1, -1, - -1, -1, 29, 1, -1, 32, -1, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 1, -1, 17, - -1, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 29, -1, 17, 32, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 29, 1, -1, 32, -1, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 29, -1, -1, 32, 3, 4, - 5, 6, 7, 8, 9, 10, -1, 12, 13, 14, - 15, 16, 17, 18, -1, 20, -1, 22, 23, 24, - 25, 26, 27, 28, -1, 30, 31, 32, 3, 4, - 5, 6, 7, 8, 9, 10, -1, 12, 13, 14, - 15, 16, 17, 18, -1, 20, -1, 22, 23, 24, - 25, 26, 27, 28, -1, 30, 31, 32, 3, 4, - 5, 6, 7, 8, 9, 10, -1, 12, 13, 14, - 15, 16, 17, 18, -1, 20, -1, 22, 23, 24, - 25, 26, 27, 28, -1, 30, 31, 32, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, -1, -1, - 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 29, -1, -1, 32 -}; - - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 1, 4, 15, 16, 20, 30, 31, 47, 48, - 51, 52, 54, 57, 59, 62, 64, 73, 75, 80, - 34, 1, 3, 4, 5, 6, 7, 8, 9, 10, - 12, 13, 14, 15, 16, 17, 18, 20, 22, 23, - 24, 25, 26, 27, 28, 30, 31, 32, 87, 17, - 17, 87, 39, 1, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 17, 29, 32, 81, 82, 83, - 84, 85, 86, 17, 87, 0, 49, 53, 63, 74, - 50, 58, 86, 1, 44, 44, 17, 6, 7, 8, - 38, 17, 42, 87, 43, 29, 34, 35, 35, 35, - 48, 35, 37, 1, 82, 1, 82, 17, 24, 25, - 26, 27, 28, 79, 86, 39, 43, 17, 1, 24, - 17, 48, 17, 55, 56, 87, 1, 3, 65, 66, - 67, 68, 69, 82, 22, 23, 24, 76, 77, 78, - 81, 48, 60, 1, 45, 37, 29, 24, 24, 38, - 36, 37, 34, 36, 34, 18, 21, 70, 71, 72, - 81, 19, 81, 81, 22, 23, 81, 36, 34, 36, - 17, 61, 82, 17, 40, 79, 55, 65, 65, 37, - 41, 81, 81, 81, 81, 76, 37, 40, 45, 71, - 72, 81, 38, 38, 17, 81, 81, 79, 79 -}; - - /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 46, 47, 49, 48, 50, 48, 48, 48, 51, - 51, 51, 51, 51, 51, 53, 52, 54, 54, 55, - 55, 56, 56, 56, 56, 58, 57, 60, 59, 61, - 61, 63, 62, 64, 64, 65, 65, 65, 65, 66, - 67, 68, 69, 69, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 71, 72, 74, 73, 75, 75, 75, - 76, 76, 76, 77, 78, 78, 78, 78, 78, 78, - 78, 78, 79, 79, 79, 79, 79, 79, 79, 80, - 81, 81, 81, 81, 81, 81, 81, 82, 82, 82, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 84, 84, 84, 84, 85, 85, - 86, 86, 86, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87 -}; - - /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 0, 4, 0, 4, 1, 0, 1, - 1, 1, 1, 1, 1, 0, 5, 2, 2, 3, - 1, 1, 1, 3, 0, 0, 6, 0, 7, 1, - 3, 0, 5, 2, 2, 3, 3, 1, 0, 1, - 3, 2, 1, 1, 0, 1, 3, 2, 4, 2, - 4, 1, 1, 1, 1, 0, 5, 2, 2, 2, - 3, 1, 0, 1, 3, 5, 5, 3, 2, 2, - 2, 1, 1, 1, 1, 1, 1, 1, 3, 4, - 2, 5, 3, 4, 2, 1, 1, 3, 1, 3, - 1, 1, 2, 1, 2, 1, 2, 1, 1, 1, - 1, 1, 1, 1, 4, 3, 4, 2, 6, 3, - 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1 -}; - - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) - -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 - - - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - -/* This macro is provided for backward compatibility. */ -#ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -#endif - - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - - -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ - -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -{ - FILE *yyo = yyoutput; - YYUSE (yyo); - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - YYUSE (yytype); -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -{ - YYFPRINTF (yyoutput, "%s %s (", - yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); - - yy_symbol_value_print (yyoutput, yytype, yyvaluep); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -static void -yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) -{ - unsigned long int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, - yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyssp, yyvsp, Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -yystrlen (const char *yystr) -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -yystpcpy (char *yydest, const char *yysrc) -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) -{ - YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; - - /* There are many possibilities here to consider: - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) - { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } - } - - switch (yycount) - { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ - } - - { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; - } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; -} -#endif /* YYERROR_VERBOSE */ - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -{ - YYUSE (yyvaluep); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yytype); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - - - -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; -/* Number of syntax errors so far. */ -int yynerrs; - - -/*----------. -| yyparse. | -`----------*/ - -int -yyparse (void) -{ - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - 'yyss': related to states. - 'yyvs': related to semantic values. - - Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = yylex (); - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 3: -#line 75 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 1469 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 5: -#line 79 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - yyerrok; -} -#line 1477 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 7: -#line 84 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("`;' missing after definition"); -} -#line 1485 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 8: -#line 88 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 1492 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 9: -#line 96 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - assert((yyvsp[0]) == 0 || NamespacePtr::dynamicCast((yyvsp[0]))); -} -#line 1500 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 10: -#line 100 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - assert((yyvsp[0]) == 0 || InterfacePtr::dynamicCast((yyvsp[0]))); -} -#line 1508 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 11: -#line 104 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - assert((yyvsp[0]) == 0 || StructPtr::dynamicCast((yyvsp[0]))); -} -#line 1516 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 12: -#line 108 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 1523 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 13: -#line 111 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - assert((yyvsp[0]) == 0 || EnumPtr::dynamicCast((yyvsp[0]))); -} -#line 1531 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 14: -#line 115 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - assert((yyvsp[0]) == 0 || ConstPtr::dynamicCast((yyvsp[0]))); -} -#line 1539 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 15: -#line 124 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = (yyvsp[0]); -} -#line 1547 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 16: -#line 128 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - if((yyvsp[-2])) - { - g_parse->popContainer(); - (yyval) = (yyvsp[-2]); - } - else - { - (yyval) = 0; - } - - (yyval) = (yyvsp[-3]); -} -#line 1565 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 17: -#line 147 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - NamespacePtr c = NamespacePtr::dynamicCast(g_parse->currentContainer()); - if(!c) - { - g_parse->error("enum must define in namespace"); - } - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - EnumPtr e = c->createEnum(ident->v); - g_parse->pushContainer(e); - - (yyval) = e; -} -#line 1582 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 18: -#line 160 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - g_parse->error("keyword `" + ident->v + "' cannot be used as enumeration name"); - (yyval) = (yyvsp[0]); -} -#line 1592 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 19: -#line 171 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = (yyvsp[-1]); -} -#line 1600 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 20: -#line 175 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 1607 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 21: -#line 183 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - TypePtr type = TypePtr::dynamicCast(g_parse->createBuiltin(Builtin::KindLong)); - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - TypeIdPtr tPtr = new TypeId(type, ident->v); - tPtr->disableDefault(); - EnumPtr e = EnumPtr::dynamicCast(g_parse->currentContainer()); - assert(e); - e->addMember(tPtr); - (yyval) = e; -} -#line 1622 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 22: -#line 194 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - g_parse->error("keyword `" + ident->v + "' cannot be used as enumerator"); -} -#line 1631 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 23: -#line 199 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - TypePtr type = TypePtr::dynamicCast(g_parse->createBuiltin(Builtin::KindLong)); - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[-2])); - TypeIdPtr tPtr = new TypeId(type, ident->v); - ConstGrammarPtr sPtr = ConstGrammarPtr::dynamicCast((yyvsp[0])); - g_parse->checkConstValue(tPtr, sPtr->t); - tPtr->setDefault(sPtr->v); - EnumPtr e = EnumPtr::dynamicCast(g_parse->currentContainer()); - assert(e); - e->addMember(tPtr); - (yyval) = e; -} -#line 1648 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 24: -#line 212 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 1655 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 25: -#line 220 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - ContainerPtr c = g_parse->currentContainer(); - NamespacePtr n = c->createNamespace(ident->v); - if(n) - { - g_parse->pushContainer(n); - (yyval) = GrammarBasePtr::dynamicCast(n); - } - else - { - (yyval) = 0; - } -} -#line 1674 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 26: -#line 235 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - if((yyvsp[-3])) - { - g_parse->popContainer(); - (yyval) = (yyvsp[-3]); - } - else - { - (yyval) = 0; - } -} -#line 1690 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 27: -#line 253 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[-1])); - StructPtr sp = StructPtr::dynamicCast(g_parse->findUserType(ident->v)); - if(!sp) - { - g_parse->error("struct '" + ident->v + "' undefined!"); - } - - g_parse->setKeyStruct(sp); -} -#line 1705 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 28: -#line 264 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 1712 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 29: -#line 272 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - StructPtr np = g_parse->getKeyStruct(); - if(np) - { - np->addKey(ident->v); - } - else - { - (yyval) = 0; - } -} -#line 1729 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 30: -#line 285 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - StructPtr np = g_parse->getKeyStruct(); - if(np) - { - np->addKey(ident->v); - } - else - { - (yyval) = 0; - } -} -#line 1746 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 31: -#line 304 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - - NamespacePtr c = NamespacePtr::dynamicCast(g_parse->currentContainer()); - - InterfacePtr cl = c->createInterface(ident->v); - if(cl) - { - g_parse->pushContainer(cl); - (yyval) = GrammarBasePtr::dynamicCast(cl); - } - else - { - (yyval) = 0; - } -} -#line 1767 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 32: -#line 321 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - if((yyvsp[-3])) - { - g_parse->popContainer(); - (yyval) = GrammarBasePtr::dynamicCast((yyvsp[-3])); - } - else - { - (yyval) = 0; - } -} -#line 1783 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 33: -#line 338 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = (yyvsp[0]); -} -#line 1791 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 34: -#line 342 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - g_parse->error("keyword `" + ident->v + "' cannot be used as interface name"); - (yyval) = (yyvsp[0]); -} -#line 1801 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 35: -#line 353 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 1808 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 36: -#line 356 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 1815 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 37: -#line 359 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("`;' missing after definition"); -} -#line 1823 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 38: -#line 363 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 1830 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 40: -#line 377 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - if((yyvsp[-2])) - { - g_parse->popContainer(); - (yyval) = GrammarBasePtr::dynamicCast((yyvsp[-2])); - } - else - { - (yyval) = 0; - } -} -#line 1846 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 41: -#line 394 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - TypePtr returnType = TypePtr::dynamicCast((yyvsp[-1])); - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - string name = ident->v; - InterfacePtr cl = InterfacePtr::dynamicCast(g_parse->currentContainer()); - if(cl) - { - OperationPtr op = cl->createOperation(name, returnType); - if(op) - { - g_parse->pushContainer(op); - (yyval) = GrammarBasePtr::dynamicCast(op); - } - else - { - (yyval) = 0; - } - } - else - { - (yyval) = 0; - } -} -#line 1874 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 43: -#line 424 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = 0; -} -#line 1882 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 44: -#line 434 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 1889 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 45: -#line 437 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - TypeIdPtr tsp = TypeIdPtr::dynamicCast((yyvsp[0])); - - OperationPtr op = OperationPtr::dynamicCast(g_parse->currentContainer()); - assert(op); - if(op) - { - op->createParamDecl(tsp, false, false); - } -} -#line 1904 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 46: -#line 448 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - TypeIdPtr tsp = TypeIdPtr::dynamicCast((yyvsp[0])); - - OperationPtr op = OperationPtr::dynamicCast(g_parse->currentContainer()); - assert(op); - if(op) - { - op->createParamDecl(tsp, false, false); - } -} -#line 1919 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 47: -#line 459 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - BoolGrammarPtr isOutParam = BoolGrammarPtr::dynamicCast((yyvsp[-1])); - TypeIdPtr tsp = TypeIdPtr::dynamicCast((yyvsp[0])); - - OperationPtr op = OperationPtr::dynamicCast(g_parse->currentContainer()); - assert(op); - if(op) - { - op->createParamDecl(tsp, isOutParam->v, false); - } -} -#line 1935 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 48: -#line 471 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - BoolGrammarPtr isOutParam = BoolGrammarPtr::dynamicCast((yyvsp[-1])); - TypeIdPtr tsp = TypeIdPtr::dynamicCast((yyvsp[0])); - - OperationPtr op = OperationPtr::dynamicCast(g_parse->currentContainer()); - assert(op); - if(op) - { - op->createParamDecl(tsp, isOutParam->v, false); - } -} -#line 1951 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 49: -#line 483 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - BoolGrammarPtr isRouteKeyParam = BoolGrammarPtr::dynamicCast((yyvsp[-1])); - TypeIdPtr tsp = TypeIdPtr::dynamicCast((yyvsp[0])); - - OperationPtr op = OperationPtr::dynamicCast(g_parse->currentContainer()); - assert(op); - if(op) - { - op->createParamDecl(tsp, false, isRouteKeyParam->v); - } -} -#line 1967 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 50: -#line 495 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - BoolGrammarPtr isRouteKeyParam = BoolGrammarPtr::dynamicCast((yyvsp[-1])); - TypeIdPtr tsp = TypeIdPtr::dynamicCast((yyvsp[0])); - - OperationPtr op = OperationPtr::dynamicCast(g_parse->currentContainer()); - assert(op); - if(op) - { - op->createParamDecl(tsp, false, isRouteKeyParam->v); - } -} -#line 1983 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 51: -#line 507 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("'out' must be defined with a type"); -} -#line 1991 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 52: -#line 511 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("'routekey' must be defined with a type"); -} -#line 1999 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 53: -#line 520 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - BoolGrammarPtr routekey = new BoolGrammar; - routekey->v = true; - (yyval) = GrammarBasePtr::dynamicCast(routekey); -} -#line 2009 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 54: -#line 531 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - BoolGrammarPtr out = new BoolGrammar; - out->v = true; - (yyval) = GrammarBasePtr::dynamicCast(out); -} -#line 2019 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 55: -#line 542 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - NamespacePtr np = NamespacePtr::dynamicCast(g_parse->currentContainer()); - if(np) - { - StructPtr sp = np->createStruct(ident->v); - if(sp) - { - g_parse->pushContainer(sp); - (yyval) = GrammarBasePtr::dynamicCast(sp); - } - else - { - (yyval) = 0; - } - } - else - { - g_parse->error("struct '" + ident->v + "' must definition in namespace"); - } -} -#line 2045 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 56: -#line 564 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - if((yyvsp[-3])) - { - g_parse->popContainer(); - } - (yyval) = (yyvsp[-3]); - - StructPtr st = StructPtr::dynamicCast((yyval)); - assert(st); - if(st->getAllMemberPtr().size() == 0) - { - g_parse->error("struct `" + st->getSid() + "' must have at least one member"); - } -} -#line 2064 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 57: -#line 584 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = (yyvsp[0]); -} -#line 2072 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 58: -#line 588 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - - g_parse->error("keyword `" + ident->v + "' cannot be used as struct name"); -} -#line 2082 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 59: -#line 594 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("abstract declarator '' used as declaration"); -} -#line 2090 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 60: -#line 603 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - -} -#line 2098 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 61: -#line 607 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("';' missing after definition"); -} -#line 2106 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 62: -#line 611 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2113 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 63: -#line 621 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = GrammarBasePtr::dynamicCast((yyvsp[0])); -} -#line 2121 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 64: -#line 630 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StructPtr np = StructPtr::dynamicCast(g_parse->currentContainer()); - if(np) - { - IntergerGrammarPtr iPtr = IntergerGrammarPtr::dynamicCast((yyvsp[-2])); - g_parse->checkTag(iPtr->v); - - TypeIdPtr tPtr = TypeIdPtr::dynamicCast((yyvsp[0])); - tPtr->setRequire(iPtr->v); - np->addTypeId(tPtr); - (yyval) = GrammarBasePtr::dynamicCast((yyvsp[0])); - } - else - { - (yyval) = 0; - } -} -#line 2143 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 65: -#line 648 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StructPtr np = StructPtr::dynamicCast(g_parse->currentContainer()); - if(np) - { - IntergerGrammarPtr iPtr = IntergerGrammarPtr::dynamicCast((yyvsp[-4])); - g_parse->checkTag(iPtr->v); - - TypeIdPtr tPtr = TypeIdPtr::dynamicCast((yyvsp[-2])); - ConstGrammarPtr sPtr = ConstGrammarPtr::dynamicCast((yyvsp[0])); - g_parse->checkConstValue(tPtr, sPtr->t); - - tPtr->setRequire(iPtr->v); - tPtr->setDefault(sPtr->v); - np->addTypeId(tPtr); - (yyval) = GrammarBasePtr::dynamicCast((yyvsp[-2])); - } - else - { - (yyval) = 0; - } -} -#line 2169 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 66: -#line 670 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StructPtr np = StructPtr::dynamicCast(g_parse->currentContainer()); - if(np) - { - IntergerGrammarPtr iPtr = IntergerGrammarPtr::dynamicCast((yyvsp[-4])); - g_parse->checkTag(iPtr->v); - - TypeIdPtr tPtr = TypeIdPtr::dynamicCast((yyvsp[-2])); - ConstGrammarPtr sPtr = ConstGrammarPtr::dynamicCast((yyvsp[0])); - g_parse->checkConstValue(tPtr, sPtr->t); - - tPtr->setOptional(iPtr->v); - tPtr->setDefault(sPtr->v); - np->addTypeId(tPtr); - (yyval) = GrammarBasePtr::dynamicCast((yyvsp[-2])); - } - else - { - (yyval) = 0; - } -} -#line 2195 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 67: -#line 692 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StructPtr np = StructPtr::dynamicCast(g_parse->currentContainer()); - if(np) - { - IntergerGrammarPtr iPtr = IntergerGrammarPtr::dynamicCast((yyvsp[-2])); - g_parse->checkTag(iPtr->v); - TypeIdPtr tPtr = TypeIdPtr::dynamicCast((yyvsp[0])); - tPtr->setOptional(iPtr->v); - np->addTypeId(tPtr); - (yyval) = GrammarBasePtr::dynamicCast((yyvsp[0])); - } - else - { - (yyval) = 0; - } -} -#line 2216 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 68: -#line 709 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("struct member need 'tag'"); -} -#line 2224 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 69: -#line 713 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("struct member need 'tag'"); -} -#line 2232 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 70: -#line 717 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("struct member need 'require' or 'optional'"); -} -#line 2240 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 71: -#line 721 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("struct member need 'tag' or 'require' or 'optional'"); -} -#line 2248 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 72: -#line 730 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - IntergerGrammarPtr intVal = IntergerGrammarPtr::dynamicCast((yyvsp[0])); - ostringstream sstr; - sstr << intVal->v; - ConstGrammarPtr c = new ConstGrammar(); - c->t = ConstGrammar::VALUE; - c->v = sstr.str(); - (yyval) = c; -} -#line 2262 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 73: -#line 740 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - FloatGrammarPtr floatVal = FloatGrammarPtr::dynamicCast((yyvsp[0])); - ostringstream sstr; - sstr << floatVal->v; - ConstGrammarPtr c = new ConstGrammar(); - c->t = ConstGrammar::VALUE; - c->v = sstr.str(); - (yyval) = c; -} -#line 2276 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 74: -#line 750 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - ConstGrammarPtr c = new ConstGrammar(); - c->t = ConstGrammar::STRING; - c->v = ident->v; - (yyval) = c; -} -#line 2288 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 75: -#line 758 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - ConstGrammarPtr c = new ConstGrammar(); - c->t = ConstGrammar::BOOL; - c->v = ident->v; - (yyval) = c; -} -#line 2300 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 76: -#line 766 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - ConstGrammarPtr c = new ConstGrammar(); - c->t = ConstGrammar::BOOL; - c->v = ident->v; - (yyval) = c; -} -#line 2312 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 77: -#line 774 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - - if (g_parse->checkEnum(ident->v) == false) - { - g_parse->error("error enum default value, not defined yet"); - } - ConstGrammarPtr c = new ConstGrammar(); - c->t = ConstGrammar::ENUM; - c->v = ident->v; - (yyval) = c; -} -#line 2329 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 78: -#line 787 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - - StringGrammarPtr scoped = StringGrammarPtr::dynamicCast((yyvsp[-2])); - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - - if (g_parse->checkEnum(ident->v) == false) - { - g_parse->error("error enum default value, not defined yet"); - } - ConstGrammarPtr c = new ConstGrammar(); - c->t = ConstGrammar::ENUM; - c->v = scoped->v + "::" + ident->v; - (yyval) = c; -} -#line 2348 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 79: -#line 807 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - NamespacePtr np = NamespacePtr::dynamicCast(g_parse->currentContainer()); - if(!np) - { - g_parse->error("const type must define in namespace"); - } - - TypeIdPtr t = TypeIdPtr::dynamicCast((yyvsp[-2])); - ConstGrammarPtr c = ConstGrammarPtr::dynamicCast((yyvsp[0])); - ConstPtr cPtr = np->createConst(t, c); - (yyval) = cPtr; -} -#line 2365 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 80: -#line 825 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - TypePtr type = TypePtr::dynamicCast((yyvsp[-1])); - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - - TypeIdPtr typeIdPtr = new TypeId(type, ident->v); - - (yyval) = GrammarBasePtr::dynamicCast(typeIdPtr); -} -#line 2378 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 81: -#line 834 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - TypePtr type = g_parse->createVector(TypePtr::dynamicCast((yyvsp[-4]))); - IntergerGrammarPtr iPtrSize = IntergerGrammarPtr::dynamicCast((yyvsp[-1])); - g_parse->checkArrayVaid(type,iPtrSize->v); - type->setArray(iPtrSize->v); - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[-3])); - TypeIdPtr typeIdPtr = new TypeId(type, ident->v); - (yyval) = GrammarBasePtr::dynamicCast(typeIdPtr); -} -#line 2392 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 82: -#line 844 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - TypePtr type = g_parse->createVector(TypePtr::dynamicCast((yyvsp[-2]))); - //IntergerGrammarPtr iPtrSize = IntergerGrammarPtr::dynamicCast($4); - g_parse->checkPointerVaid(type); - type->setPointer(true); - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - TypeIdPtr typeIdPtr = new TypeId(type, ident->v); - (yyval) = GrammarBasePtr::dynamicCast(typeIdPtr); -} -#line 2406 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 83: -#line 854 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - TypePtr type = TypePtr::dynamicCast((yyvsp[-3])); - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[-2])); - TypeIdPtr typeIdPtr = new TypeId(type, ident->v); - IntergerGrammarPtr iPtrSize = IntergerGrammarPtr::dynamicCast((yyvsp[-1])); - g_parse->checkArrayVaid(type,iPtrSize->v); - (yyval) = GrammarBasePtr::dynamicCast(typeIdPtr); -} -#line 2419 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 84: -#line 863 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - g_parse->error("keyword `" + ident->v + "' cannot be used as data member name"); -} -#line 2428 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 85: -#line 868 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("missing data member name"); -} -#line 2436 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 86: -#line 872 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("unkown type"); -} -#line 2444 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 87: -#line 881 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - - TypePtr type = TypePtr::dynamicCast((yyvsp[-2])); - IntergerGrammarPtr iPtrSize = IntergerGrammarPtr::dynamicCast((yyvsp[0])); - g_parse->checkArrayVaid(type,iPtrSize->v); - type->setArray(iPtrSize->v); - (yyval) = type; -} -#line 2457 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 88: -#line 890 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = (yyvsp[0]); -} -#line 2465 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 89: -#line 894 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("array missing size"); -} -#line 2473 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 90: -#line 903 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = g_parse->createBuiltin(Builtin::KindBool); -} -#line 2481 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 91: -#line 907 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = g_parse->createBuiltin(Builtin::KindByte); -} -#line 2489 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 92: -#line 911 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = g_parse->createBuiltin(Builtin::KindShort,true); -} -#line 2497 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 93: -#line 915 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = g_parse->createBuiltin(Builtin::KindShort); -} -#line 2505 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 94: -#line 919 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = g_parse->createBuiltin(Builtin::KindInt,true); -} -#line 2513 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 95: -#line 923 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = g_parse->createBuiltin(Builtin::KindInt); -} -#line 2521 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 96: -#line 927 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = g_parse->createBuiltin(Builtin::KindLong,true); -} -#line 2529 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 97: -#line 931 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = g_parse->createBuiltin(Builtin::KindLong); -} -#line 2537 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 98: -#line 935 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = g_parse->createBuiltin(Builtin::KindFloat); -} -#line 2545 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 99: -#line 939 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = g_parse->createBuiltin(Builtin::KindDouble); -} -#line 2553 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 100: -#line 943 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = g_parse->createBuiltin(Builtin::KindString); -} -#line 2561 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 101: -#line 947 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = GrammarBasePtr::dynamicCast((yyvsp[0])); -} -#line 2569 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 102: -#line 951 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = GrammarBasePtr::dynamicCast((yyvsp[0])); -} -#line 2577 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 103: -#line 955 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - TypePtr sp = g_parse->findUserType(ident->v); - if(sp) - { - (yyval) = GrammarBasePtr::dynamicCast(sp); - } - else - { - g_parse->error("'" + ident->v + "' undefined!"); - } -} -#line 2594 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 104: -#line 973 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = GrammarBasePtr::dynamicCast(g_parse->createVector(TypePtr::dynamicCast((yyvsp[-1])))); -} -#line 2602 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 105: -#line 977 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("vector error"); -} -#line 2610 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 106: -#line 981 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("vector missing '>'"); -} -#line 2618 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 107: -#line 985 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("vector missing type"); -} -#line 2626 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 108: -#line 994 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - (yyval) = GrammarBasePtr::dynamicCast(g_parse->createMap(TypePtr::dynamicCast((yyvsp[-3])), TypePtr::dynamicCast((yyvsp[-1])))); -} -#line 2634 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 109: -#line 998 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - g_parse->error("map error"); -} -#line 2642 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 110: -#line 1007 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2649 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 111: -#line 1010 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - ident->v = "::" + ident->v; - (yyval) = GrammarBasePtr::dynamicCast(ident); -} -#line 2659 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 112: -#line 1016 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { - StringGrammarPtr scoped = StringGrammarPtr::dynamicCast((yyvsp[-2])); - StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); - scoped->v += "::"; - scoped->v += ident->v; - (yyval) = GrammarBasePtr::dynamicCast(scoped); -} -#line 2671 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 113: -#line 1029 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2678 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 114: -#line 1032 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2685 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 115: -#line 1035 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2692 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 116: -#line 1038 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2699 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 117: -#line 1041 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2706 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 118: -#line 1044 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2713 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 119: -#line 1047 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2720 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 120: -#line 1050 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2727 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 121: -#line 1053 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2734 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 122: -#line 1056 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2741 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 123: -#line 1059 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2748 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 124: -#line 1062 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2755 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 125: -#line 1065 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2762 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 126: -#line 1068 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2769 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 127: -#line 1071 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2776 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 128: -#line 1074 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2783 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 129: -#line 1077 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2790 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 130: -#line 1080 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2797 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 131: -#line 1083 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2804 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 132: -#line 1086 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2811 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 133: -#line 1089 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2818 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 134: -#line 1092 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2825 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 135: -#line 1095 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2832 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 136: -#line 1098 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2839 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - case 137: -#line 1101 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ - { -} -#line 2846 "tars.tab.cpp" /* yacc.c:1646 */ - break; - - -#line 2850 "tars.tab.cpp" /* yacc.c:1646 */ - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*--------------------------------------. -| yyerrlab -- here on detecting error. | -`--------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) - { - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == 1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; - } - else - { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; - } - } - yyerror (yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; - } -# undef YYSYNTAX_ERROR -#endif - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - yystos[yystate], yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined yyoverflow || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - } - /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - return yyresult; -} -#line 1105 "/home/tarscpp/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1906 */ - - - diff --git a/tools/tarsparse/tars.tab.hpp b/tools/tarsparse/tars.tab.hpp index 547e017..f179ee1 100644 --- a/tools/tarsparse/tars.tab.hpp +++ b/tools/tarsparse/tars.tab.hpp @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.2.2. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,6 +30,9 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + #ifndef YY_YY_TARS_TAB_HPP_INCLUDED # define YY_YY_TARS_TAB_HPP_INCLUDED /* Debug traces. */ diff --git a/util/include/util/tc_base64.h b/util/include/util/tc_base64.h index f61b0f1..22e288e 100644 --- a/util/include/util/tc_base64.h +++ b/util/include/util/tc_base64.h @@ -55,6 +55,17 @@ public: */ static string decode(const string &data); + /** + * @brief 对字符串进行base64编码. + * + * @param buffer buffer指针 + * @param length 长度 + * @param bChangeLine 是否需要在最终编码数据加入换行符 , + * (RFC中建议每76个字符后加入回车换行,默认为不添加换行 + * @return string 编码后的数据 + */ + static string encode(const char *buffer, size_t length, bool bChangeLine = false); + /** * @brief 对字符串进行base64编码 . * @@ -65,7 +76,7 @@ public: * RFC中建议每76个字符后加入回车换行,默认为不添加换行 * @return 编码后的字符串的长度 */ - static int encode(const unsigned char* pSrc, int nSrcLen, char* pDst, bool bChangeLine = false); + static int encode(const unsigned char* pSrc, size_t nSrcLen, char* pDst, bool bChangeLine = false); /** * @brief 对字符串进行base64解码. @@ -75,7 +86,7 @@ public: * @param pDst 解码后的数据 * @return 解码后的字符串的长度 */ - static int decode(const char* pSrc, int nSrcLen, unsigned char* pDst); + static int decode(const char* pSrc, size_t nSrcLen, unsigned char* pDst); protected: diff --git a/util/include/util/tc_cas_queue.h b/util/include/util/tc_cas_queue.h index a04ed9b..6d6bc8b 100755 --- a/util/include/util/tc_cas_queue.h +++ b/util/include/util/tc_cas_queue.h @@ -15,9 +15,8 @@ namespace tars /** * @file tc_cas_queue.h * @brief 线程无锁 -#include 队列类. * - * @author jarodruan@upchina.com + * @author ruanshudong@qq.com */ ///////////////////////////////////////////////// diff --git a/util/include/util/tc_clientsocket.h b/util/include/util/tc_clientsocket.h index 9f67996..ff0225d 100644 --- a/util/include/util/tc_clientsocket.h +++ b/util/include/util/tc_clientsocket.h @@ -70,7 +70,7 @@ public: * @param timeout, 超时时间, 毫秒 * @param type, SOCK_STREAM或SOCK_DGRAM */ - TC_Endpoint(const string& host, int port, int timeout, int type = 1, int grid = 0, int qos = 0, int weight = -1, unsigned int weighttype = 0, int authType = 0) + TC_Endpoint(const string& host, int port, int timeout, EType type = TCP, int grid = 0, int qos = 0, int weight = -1, unsigned int weighttype = 0, int authType = 0) { init(host, port, timeout, type, grid, qos, weight, weighttype, authType); } @@ -133,7 +133,7 @@ public: * * @return bool */ - bool operator == (const TC_Endpoint& l) + bool operator == (const TC_Endpoint& l) const { return (_host == l._host && _port == l._port && _timeout == l._timeout && _type == l._type && _grid == l._grid && _qos == l._qos && _weight == l._weight && _weighttype == l._weighttype && @@ -144,14 +144,14 @@ public: * @brief 设置ip * @param str */ - void setHost(const string& host) { _host = host; } + void setHost(const string& host) { _host = host; _isIPv6 = TC_Socket::addressIsIPv6(_host); } /** * @brief 获取ip * * @return const string& */ - string getHost() const { return _host; } + const string &getHost() const { return _host; } /** * @brief 设置端口 @@ -185,6 +185,7 @@ public: * @return bool */ int isTcp() const { return _type == TCP || _type == SSL; } + /** * @brief 是否是SSL * @@ -196,17 +197,18 @@ public: * @brief 设置为TCP或UDP * @param bTcp */ - void setTcp(bool bTcp) { _type = bTcp; } + int isUdp() const { return _type == UDP; } +// void setTcp(bool bTcp) { _type = bTcp; } /** * @brief 设置为TCP/UDP/SSL * @param type */ - void setType(int type) { _type = type; } + void setType(EType type) { _type = type; } /** * @brief 获取协议类型 */ - int getType() const { return _type; } + EType getType() const { return _type; } /** * @brief 获取路由状态 * @param grid @@ -283,7 +285,7 @@ public: * * @return string */ - string toString() + string toString() const { ostringstream os; if (_type == TCP) @@ -323,7 +325,7 @@ public: void parse(const string &desc); private: - void init(const string& host, int port, int timeout, int istcp, int grid, int qos, int weight, unsigned int weighttype, int authType); + void init(const string& host, int port, int timeout, EType type, int grid, int qos, int weight, unsigned int weighttype, int authType); protected: /** @@ -344,7 +346,7 @@ protected: /** * 类型 */ - int _type; + EType _type; /** * 路由状态 @@ -427,10 +429,21 @@ public: */ virtual int recv(char *sRecvBuffer, size_t &iRecvLen) = 0; + /** + * 关闭连接 + */ + virtual void close(); + + /** + * 获取socket + * @return + */ + TC_Socket *getSocket() { return &_socket; } + /** * @brief 定义发送的错误 */ - enum + enum EM_CIENT_SOCKET_TYPE { EM_SUCCESS = 0, /** EM_SUCCESS:发送成功*/ EM_SEND = -1, /** EM_SEND:发送错误*/ @@ -465,10 +478,10 @@ protected: */ int _timeout; - /** - * _ip is ipv6 or not - */ - int _isIPv6; + /** + * 是否是IPv6 + */ + bool _isIPv6 = false; }; /** @@ -499,7 +512,7 @@ public: * @param iSendLen 发送buffer的长度 * @return int 0 成功,<0 失败 */ - int send(const char *sSendBuffer, size_t iSendLen); + virtual int send(const char *sSendBuffer, size_t iSendLen); /** * @brief 从服务器返回不超过iRecvLen的字节 @@ -507,7 +520,7 @@ public: * @param iRecvLen 指定接收多少个字符才返回,输出接收数据的长度 * @return int 0 成功,<0 失败 */ - int recv(char *sRecvBuffer, size_t &iRecvLen); + virtual int recv(char *sRecvBuffer, size_t &iRecvLen); /** * @brief 从服务器直到结束符(注意必须是服务器返回的结束符, diff --git a/util/include/util/tc_common.h b/util/include/util/tc_common.h index 3e1f32c..f7ba448 100644 --- a/util/include/util/tc_common.h +++ b/util/include/util/tc_common.h @@ -226,7 +226,6 @@ public: */ static string tm2str(const time_t &t, const string &sFormat = "%Y%m%d%H%M%S"); - /** * @brief 时间转换tm. * @@ -324,7 +323,6 @@ public: template static T strto(const string &sStr, const string &sDefault); - // typedef bool (*depthJudge)(const string& str1, const string& str2); /** * @brief 解析字符串,用分隔符号分隔,保存在vector里 * @@ -339,11 +337,10 @@ public: * @param sStr 输入字符串 * @param sSep 分隔字符串(每个字符都算为分隔符) * @param withEmpty true代表空的也算一个元素, false时空的过滤 - * @param depthJudge 对分割后的字符再次进行判断 * @return 解析后的字符vector */ template - static vector sepstr(const string &sStr, const string &sSep, bool withEmpty = false);//, depthJudge judge = nullptr); + static vector sepstr(const string &sStr, const string &sSep, bool withEmpty = false); /** * @brief T型转换成字符串,只要T能够使用ostream对象用<<重载,即可以被该函数支持 @@ -351,7 +348,12 @@ public: * @return 转换后的字符串 */ template - static string tostr(const T &t); + inline static string tostr(const T &t) + { + ostringstream sBuffer; + sBuffer << t; + return sBuffer.str(); + } /** * @brief vector转换成string. @@ -405,7 +407,7 @@ public: * @param sSep 两个元素之间的分隔符 * @return 转换后的字符串 */ - template + template static string tostr(InputIter iFirst, InputIter iLast, const string &sSep = "|"); /** @@ -466,7 +468,7 @@ public: * @param mSrcDest map<原字符串,目的字符串> * @return string 替换后的字符串 */ - static string replace(const string &sString, const map& mSrcDest); + static string replace(const string &sString, const map& mSrcDest); /** * @brief 匹配以.分隔的字符串,pat中*则代表通配符,代表非空的任何字符串 @@ -701,7 +703,7 @@ namespace p { if(!sStr.empty()) { - return atof(sStr.c_str()); + return (float) atof(sStr.c_str()); } return 0; } @@ -770,7 +772,6 @@ T TC_Common::strto(const string &sStr, const string &sDefault) return strto(s); } - template vector TC_Common::sepstr(const string &sStr, const string &sSep, bool withEmpty) { @@ -814,7 +815,6 @@ vector TC_Common::sepstr(const string &sStr, const string &sSep, bool withEmp return vt; } - template<> string TC_Common::tostr(const bool &t); @@ -857,14 +857,6 @@ string TC_Common::tostr(const long double &t); template<> string TC_Common::tostr(const std::string &t); -template -string TC_Common::tostr(const T &t) -{ - ostringstream sBuffer; - sBuffer << t; - return sBuffer.str(); -} - template string TC_Common::tostr(const vector &t) { @@ -939,7 +931,7 @@ string TC_Common::tostr(const pair &itPair) return sBuffer; } -template +template string TC_Common::tostr(InputIter iFirst, InputIter iLast, const string &sSep) { string sBuffer; @@ -963,7 +955,6 @@ string TC_Common::tostr(InputIter iFirst, InputIter iLast, const string &sSep) return sBuffer; } - template bool TC_Common::equal(const V& x, const V& y,E eps) { diff --git a/util/include/util/tc_config.h b/util/include/util/tc_config.h index ddbc284..5325701 100644 --- a/util/include/util/tc_config.h +++ b/util/include/util/tc_config.h @@ -63,7 +63,6 @@ struct TC_Config_Exception : public TC_Exception struct TC_ConfigNoParam_Exception : public TC_Exception { TC_ConfigNoParam_Exception(const string &buffer) : TC_Exception(buffer){}; - TC_ConfigNoParam_Exception(const string &buffer, int err) : TC_Exception(buffer, err){}; ~TC_ConfigNoParam_Exception() throw(){}; }; @@ -239,7 +238,6 @@ public: return new TC_ConfigDomain(*this); } -protected: /** * @brief 转义. * @@ -316,28 +314,17 @@ protected: * 例如: *
- * - * Name = Value - * - * - * Name = Value - * - *
* 获取参数:conf["/Main/Domain"] 获取域Map: - * getDomainMap("/Main/Domain", m); m得到Name/Value对 - - * 获取域Vector: getDomainVector("/Main", v); v得到Domain列表 - - 可以增加域或域下面的值对 + * 获取域Vector: getDomainVector("/Main", v); v得到Domain列表 可以增加域或域下面的值对 */ class TC_Config @@ -390,7 +377,7 @@ public: * @return 配置项对应的值 * @throws TC_Config_Exception */ - string operator[](const string &sName); + string operator[](const string &sName) const; /** * @brief 获取值, 注意如果没有不抛出异常,返回空字符串. @@ -400,6 +387,12 @@ public: */ string get(const string &sName, const string &sDefault="") const; + /** + * @brief 设置值. + * @param sName 参数名称, 例如: /Main/Domain + */ + void set(const string &sName, const string &value); + /** * @brief GetDomainParamMap获取域下面的参数值对. * diff --git a/util/include/util/tc_consistent_hash_new.h b/util/include/util/tc_consistent_hash_new.h index 95b71b6..5ca9a6c 100755 --- a/util/include/util/tc_consistent_hash_new.h +++ b/util/include/util/tc_consistent_hash_new.h @@ -38,7 +38,7 @@ enum TC_HashAlgorithmType class TC_HashAlgorithm : public TC_HandleBase { public: - virtual int32_t hash(const string & sKey) = 0; + virtual int32_t hash(const char *sKey, size_t length) = 0; virtual TC_HashAlgorithmType getHashType() = 0; protected: @@ -54,7 +54,7 @@ typedef TC_AutoPtr TC_HashAlgorithmPtr; class TC_KetamaHashAlg : public TC_HashAlgorithm { public: - virtual int32_t hash(const string & sKey); + virtual int32_t hash(const char *sKey, size_t length); virtual TC_HashAlgorithmType getHashType(); }; @@ -64,7 +64,7 @@ public: class TC_DefaultHashAlg : public TC_HashAlgorithm { public: - virtual int32_t hash(const string & sKey); + virtual int32_t hash(const char *sKey, size_t length); virtual TC_HashAlgorithmType getHashType(); }; diff --git a/util/include/util/tc_cron.h b/util/include/util/tc_cron.h new file mode 100644 index 0000000..580337f --- /dev/null +++ b/util/include/util/tc_cron.h @@ -0,0 +1,259 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include "util/tc_common.h" +#include "util/tc_ex.h" +#include + +namespace tars +{ + +struct TC_CronException : public TC_Exception +{ +public: + TC_CronException(const string& buffer) : TC_Exception(buffer) {}; +// TC_CronException(const string& buffer, bool err) : TC_Exception(buffer, err) {}; + ~TC_CronException() throw() {}; +}; + +typedef uint8_t cron_int; + +class TC_Cron +{ +public: + enum class CronField + { + second, + minute, + hour_of_day, + day_of_week, + day_of_month, + month, + year + }; + + static const std::time_t INVALID_TIME = static_cast(-1); + static const size_t INVALID_INDEX = static_cast(-1); + +public: + /** + * @brief 创建一个cron对象 + * @return cron 对象 + */ + // 字段分别为 + // 通配符以及含义 + // * all values selects all values within a field + // - range specify ranges + // , comma specify additional values + // / slash speficy increments + // DAYS = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" }; + // MONTHS = { "NIL", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" }; + // 各类例子 + // CRON Description + // * * * * * * Every second + // */5 * * * * * Every 5 seconds + // 0 */5 */2 * * * Every 5 minutes, every 2 hours + // 0 */2 */2 * */2 */2 Every 2 minutes, every 2 hours, every 2 days of the week, every 2 months + // 0 15 10 * * * * 10:15 AM every day + // 0 0/5 14 * * * Every 5 minutes starting at 2 PM and ending at 2:55 PM, every day + // 0 10,44 14 * 3 WED 2:10 PM and at 2:44 PM every Wednesday of March + // 0 15 10 * * MON-FRI 10:15 AM every Monday, Tuesday, Wednesday, Thursday and Friday + // 0 0 12 1/5 * * 12 PM every 5 days every month, starting on the first day of the month + // 0 11 11 11 11 * Every November 11th at 11:11 AM + static TC_Cron makecron(const string & expr); + + /** + * @brief 获取cron对象的下一个时间点 + * @param cron 对象 + * @return 如果返回 INVALID_TIME,则是错误时间,否则返回正确的时间戳 + */ + static std::time_t nextcron( const TC_Cron& cron, std::time_t timestamp); + + /** + * @brief 获取cron对象的下一个时间点 + * @param cron 对象 + * @return 如果返回 INVALID_TIME,则是错误时间,否则返回正确的时间戳 + */ + static std::time_t nextcron(const TC_Cron& cron); + +public: + std::bitset<60> seconds; + std::bitset<60> minutes; + std::bitset<24> hours; + std::bitset<7> days_of_week; + std::bitset<31> days_of_month; + std::bitset<12> months; + bool isset = false; + +public: + static const cron_int CRON_MIN_SECONDS = 0; + static const cron_int CRON_MAX_SECONDS = 59; + + static const cron_int CRON_MIN_MINUTES = 0; + static const cron_int CRON_MAX_MINUTES = 59; + + static const cron_int CRON_MIN_HOURS = 0; + static const cron_int CRON_MAX_HOURS = 23; + + static const cron_int CRON_MIN_DAYS_OF_WEEK = 0; + static const cron_int CRON_MAX_DAYS_OF_WEEK = 6; + + static const cron_int CRON_MIN_DAYS_OF_MONTH = 1; + static const cron_int CRON_MAX_DAYS_OF_MONTH = 31; + + static const cron_int CRON_MIN_MONTHS = 1; + static const cron_int CRON_MAX_MONTHS = 12; + + static const cron_int CRON_MAX_YEARS_DIFF = 4; + + static const std::vector DAYS; + static const std::vector MONTHS; + +protected: + /** + * @brief 判断是否包含字符 + * @return true 包含;false 不包含 + */ + static bool contains(const std::string &text, char ch) ; + + /** + * @brief 转换成crontab合法数字 + * @return cron_int + */ + static cron_int to_cron_int(const std::string& text); + + /** + * @brief 时间格式转换函数 + */ + static std::time_t tm_to_time(std::tm& tmt); + static std::tm* time_to_tm(std::time_t const* date, std::tm* const out); + + protected: + /** + * @brief 替换周/月的字符为下标 + */ + static std::string replaceOrdinals(std::string text, const std::vector & replacement); + + /** + * @brief 获取时间范围,用于计算通配符 + */ + static std::pair makeRange(std::string field, cron_int minval, cron_int maxval); + + /** + * @brief 设置crontab不同的位置标记 + */ + template + static void setCronField(std::string value, std::bitset& target, cron_int minval, cron_int maxval); + static void setCronDaysOfWeek(std::string value, std::bitset<7>& target); + static void setCronDaysOfMonth(std::string value, std::bitset<31>& target); + static void setCronMonth(std::string value, std::bitset<12>& target); + + /** + * @brief 计算下一个时间戳 + */ + template + static size_t findNext(const std::bitset & target, std::tm& tmt, unsigned int minimum, unsigned int maximum, unsigned int value, + CronField field, CronField next_field, const std::bitset<7> & marked_fields); + static bool findNext(const TC_Cron & cron, std::tm& tmt, size_t dot); + static size_t findNextDay(std::tm& tmt,std::bitset<31> const& days_of_month,size_t day_of_month,const std::bitset<7> & days_of_week,size_t day_of_week,const std::bitset<7> & marked_fields); + + /** + * @brief 位图控制函数 + */ + template + static size_t nextSetbit(const std::bitset & target, size_t minimum, size_t maximum, size_t offset); + static void addToField(std::tm& tmt, CronField field, int val); + static void setField(std::tm& tmt, CronField field, int val); + static void resetField(std::tm& tmt, CronField field); + static void resetAllFields(std::tm& tmt, const std::bitset<7> & marked_fields); + static void markField(std::bitset<7>& orders, CronField field); +}; + +template +void TC_Cron::setCronField(std::string value,std::bitset& target,cron_int minval,cron_int maxval) +{ + if (value.length() > 0 && value[value.length() - 1] == ',') + throw TC_CronException("[TC_Cron::setCronField] value cannot end with comma"); + + auto fields = TC_Common::sepstr(value, ","); + if (fields.empty()) + throw TC_CronException("[TC_Cron::setCronField] expression parsing error"); + + for (auto const& field : fields) + { + if (!contains(field, '/')) + { + auto item = makeRange(field, minval, maxval); + auto first = item.first; + auto last = item.second; + for (cron_int i = first - minval; i <= last - minval; ++i) + { + target.set(i); + } + } + else + { + auto parts = TC_Common::sepstr(field, "/"); + if (parts.size() != 2) + throw TC_CronException("[TC_Cron::setCronField] incrementer must have two fields"); + + auto item = makeRange(parts[0], minval, maxval); + auto first = item.first; + auto last = item.second; + + if (!contains(parts[0], '-')) + { + last = maxval; + } + + auto delta = to_cron_int(parts[1]); + if (delta <= 0) + throw TC_CronException("[TC_Cron::setCronField] incrementer must be a positive value"); + + for (cron_int i = first - minval; i <= last - minval; i += delta) + { + target.set(i); + } + } + } +} + +template +size_t TC_Cron::nextSetbit(const std::bitset & target,size_t minimum,size_t maximum,size_t offset) +{ + for (auto i = offset; i < N; ++i) + { + if (target.test(i)) return i; + } + + return INVALID_INDEX; +} + +template +size_t TC_Cron::findNext(const std::bitset & target, std::tm& tmt, unsigned int minimum, unsigned int maximum, unsigned int value, + CronField field, CronField next_field, const std::bitset<7> & marked_fields) +{ + auto next_value = nextSetbit(target, minimum, maximum, value); + if (INVALID_INDEX == next_value) + { + addToField(tmt, next_field, 1); + resetField(tmt, field); + next_value = nextSetbit(target, minimum, maximum, 0); + } + + if (INVALID_INDEX == next_value || next_value != value) + { + setField(tmt, field, static_cast(next_value)); + resetAllFields(tmt, marked_fields); + } + + return next_value; +} + +} + diff --git a/util/include/util/tc_des.h b/util/include/util/tc_des.h new file mode 100644 index 0000000..dbdd060 --- /dev/null +++ b/util/include/util/tc_des.h @@ -0,0 +1,147 @@ +#ifndef __TC_DES_H +#define __TC_DES_H + +#include +#include +#include "util/tc_ex.h" +using namespace std; + +namespace tars +{ + +///////////////////////////////////////////////// +/** + * @file tc_des.h + * @brief des加解密类(翻译至c代码) + * + * @author ruanshudong@qq.com + */ +///////////////////////////////////////////////// + + +/** + * @brief des异常. + */ +struct TC_DES_Exception : public TC_Exception +{ + TC_DES_Exception(const string &buffer) : TC_Exception(buffer){}; + ~TC_DES_Exception() throw(){}; +}; + + +/** + * @brief des/3des加密解密源码, 不依赖任何库. + * + * 在网上流行的d3des.h d3des.c修改完成. + * + * 对于des加密,8位密钥,不足8位的右补0x00,多余8位,只取左8位有效. + * + * 加密内容8位补齐,补齐方式为:少1位补一个0x01,少2位补两个0x02,... + * + * 本身已8位对齐的,后面补八个0x08. + * + * 对于3des加解密,如下:只支持3des-ecb加密方式; + * + * 24位密钥,不足24位的右补0x00,多余24位,只取左24位有效; + * + * 加密内容8位补齐,补齐方式为:少1位补一个0x01,少2位补两个0x02,... + * + * 本身已8位对齐的,后面补八个0x08. + * + * Key必须是null结束的字符串. + * + */ +class TC_Des +{ +public: + /** + * @brief des加密. + * + * @param key key, 8个字节 + * @param sIn 输入buffer + * @param iInLen 输入buffer长度 + * @return string 加密后的内容 + */ + static string encrypt(const char *key, const char *sIn, size_t iInlen); + + /** + * @brief des解密. + * + * @param key key, 8个字节 + * @param sIn 输入buffer + * @param iInlen 输入buffer长度 + * @return string 解码后的内容, 如果解密失败, 则为空 + */ + static string decrypt(const char *key, const char *sIn, size_t iInlen); + + /** + * @brief 3des加密. + * + * @param key key, 24个字节 + * @param sIn 输入buffer + * @param iInLen 输入buffer长度 + * @return string 加密后的内容 + */ + static string encrypt3(const char *key, const char *sIn, size_t iInlen); + + /** + * @brief 3des解密. + * @param key key, 24个字节 + * @param sIn 输入buffer + * @param iInlen 输入buffer长度 + * @return string解码后的内容, 如果解密失败, 则为空 + */ + static string decrypt3(const char *key, const char *sIn, size_t iInlen); + + /** + * @brief 定义加密/解密 . + */ + enum + { + EN0 = 0, /**加密*/ + DE1 = 1 /**解密*/ + }; + +protected: + /** + * @brief 获取key. + * + * @param key key值 + * @param mode 模式 :0代表加密, 1代表解密 + */ + static void deskey(const char *key, short mode, uint32_t *k); + + /** + * @brief des加密/解密. + * + * @param from 8个字节 + * @param to 加密解密只有的8个字节 + */ + static void des(const char *from, char *to, uint32_t *KnL); + + /** + * @brief 获取key. + * + * @param key key值 + * @param mode 模式,0代表加密, 1代表解密 + */ + static void des3key(const char *key, short mode, uint32_t *KnL, uint32_t *KnR, uint32_t *Kn3); + + /** + * @brief 3des. + * + * @param from 8个字节 + * @param into 加密解密只有的8个字节 + */ + static void des3(const char *from, char *into, uint32_t *KnL, uint32_t *KnR, uint32_t *Kn3); + +private: + static void cookey(register uint32_t *raw1, uint32_t *k); + static void scrunch(register const char *outof, register uint32_t *into); + static void unscrun(register uint32_t *outof, register char *into); + static void desfunc(register uint32_t *block, register uint32_t *keys); +}; + +} +#endif + diff --git a/util/include/util/tc_epoll_server.h b/util/include/util/tc_epoll_server.h index 2fcfb4e..4775bd4 100644 --- a/util/include/util/tc_epoll_server.h +++ b/util/include/util/tc_epoll_server.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -57,13 +58,10 @@ namespace tars class PropertyReport; -class TC_EpollServer : public TC_ThreadLock, public TC_HandleBase +class TC_EpollServer : public TC_HandleBase { public: - //////////////////////////////////////////////////////////////////////////// - /** - * 定义协议解析的返回值 - */ + enum EM_CLOSE_T { EM_CLIENT_CLOSE = 0, //客户端主动关闭 @@ -83,14 +81,11 @@ public: TCP_CONNECTION = 0, UDP_CONNECTION = 1, }; + /** * 定义协议解析接口的操作对象 * 注意必须是线程安全的或是可以重入的 */ - // using protocol_functor = std::function; - // using header_filter_functor = std::function; - // using conn_protocol_functor = std::function; - typedef std::function&)> header_filter_functor; class NetThread; @@ -102,6 +97,7 @@ public: typedef TC_AutoPtr HandlePtr; class RecvContext; + /** * 发送包的上下文 * 由RecvContext创建出来 @@ -159,8 +155,6 @@ public: shared_ptr createSendContext() { return std::make_shared(shared_from_this(), 's'); } shared_ptr createCloseContext() { return std::make_shared(shared_from_this(), 'c'); } -// int64_t _recvUS; - protected: uint32_t _uid; /**连接标示*/ string _ip; /**远程连接的ip*/ @@ -190,6 +184,7 @@ public: int timeout; int iLastRefreshTime; }; + //////////////////////////////////////////////////////////////////////////// /** * @brief 定义服务逻辑处理的接口 @@ -198,7 +193,7 @@ public: /** * 服务的逻辑处理代码 */ - class Handle : public TC_Thread, public TC_ThreadLock, public TC_HandleBase + class Handle : public TC_Thread, public TC_HandleBase { public: /** @@ -223,6 +218,12 @@ public: */ TC_EpollServer* getEpollServer(); + /** + * 获取adapter + * @return + */ + BindAdapter *getBindAdapter() const { return _bindAdapter; } + /** * 获取Handle的索引(0~handle个数-1) * @return @@ -276,7 +277,7 @@ public: virtual void initialize() {}; /** - * 唤醒HandleGroup中的handle线程 + * 唤醒handle对应的处理线程 */ virtual void notifyFilter(); @@ -320,14 +321,11 @@ public: */ virtual void handleOverload(const shared_ptr &data); - /** - * 处理Filter的消息 - */ - //virtual void handleFilter() {}; /** * 处理异步回调队列 */ virtual void handleAsyncResponse() {} + /** * handleFilter拆分的第二部分,处理用户自有数据 * 非游戏逻辑可忽略bExpectIdle参数 @@ -390,7 +388,6 @@ public: */ TC_EpollServer *_pEpollServer; - /** * handle对应的网路线程(网络线程和handle线程合并的情况下有效) */ @@ -411,10 +408,6 @@ public: */ uint32_t _handleIndex; - /** - * 所属handle组 - */ - // HandleGroupPtr _handleGroup; }; using close_functor = std::function; @@ -422,7 +415,7 @@ public: //////////////////////////////////////////////////////////////////////////// // 服务端口管理,监听socket信息 - class BindAdapter : public TC_ThreadLock, public TC_HandleBase + class BindAdapter : public TC_HandleBase { public: /** @@ -617,13 +610,13 @@ public: * 获取允许ip * @return vector: ip列表 */ - vector getAllow() const; + const vector &getAllow() const; /** * 获取禁止ip * @return vector: ip列表 */ - vector getDeny() const; + const vector &getDeny() const; /** * 获取allow deny次序 @@ -670,7 +663,7 @@ public: * 获取EpollServer * @return TC_EpollServer* */ - TC_EpollServer* getEpollServer(); + TC_EpollServer* getEpollServer() const { return _pEpollServer; } /** * 获取对应的网络线程 @@ -679,11 +672,6 @@ public: */ inline NetThread* getNetThreadOfFd(int fd) const { return _pEpollServer->getNetThreadOfFd(fd); } - /** - * 注册协议解析器 - * @param pp - */ - // void setProtocol(const protocol_functor& pf, int iHeaderLen = 0, const header_filter_functor& hf = echo_header_filter); /** * 注册协议解析器 * @param pp @@ -743,12 +731,6 @@ public: */ int getHeaderFilterLen(); - /** - * 设置ServantHandle数目 - * @param n - */ - void setHandleNum(int n); - /** * 所属handle组的handle数(每个handle一个对象) * @return int @@ -776,7 +758,7 @@ public: _iHandleNum = _pEpollServer->_netThreadNum; } - for (size_t i = 0; i < _iHandleNum ; ++i) + for (int32_t i = 0; i < _iHandleNum ; ++i) { HandlePtr handle = new T(); @@ -801,15 +783,15 @@ public: return _handles[index]; } - /** - * 设置服务端回包缓存的大小限制 - */ - void setBackPacketBuffLimit(size_t iLimitSize); + // /** + // * 设置服务端回包缓存的大小限制 + // */ + // void setBackPacketBuffLimit(size_t iLimitSize); - /** - * 获取服务端回包缓存的大小限制 - */ - size_t getBackPacketBuffLimit(); + // /** + // * 获取服务端回包缓存的大小限制 + // */ + // size_t getBackPacketBuffLimit(); /** @@ -874,23 +856,23 @@ public: public: //统计上报的对象 - PropertyReport * _pReportQueue = NULL; - PropertyReport * _pReportConRate = NULL; + PropertyReport * _pReportQueue = NULL; + PropertyReport * _pReportConRate = NULL; PropertyReport * _pReportTimeoutNum = NULL; protected: friend class TC_EpollServer; - /** - * 服务 - */ - TC_EpollServer *_pEpollServer; - /** * 加锁 */ mutable std::mutex _mutex; + /** + * 服务 + */ + TC_EpollServer *_pEpollServer = NULL; + /** * Adapter所用的HandleGroup */ @@ -910,6 +892,7 @@ public: * adapter的名字 */ string _name; + /** * 监听fd */ @@ -987,8 +970,8 @@ public: */ string _protocolName; - //回包缓存限制大小 - size_t _iBackPacketBuffLimit; + // 回包缓存限制大小 + // size_t _iBackPacketBuffLimit; //队列模式 bool _queueMode = false; @@ -1187,10 +1170,10 @@ public: * 接收Udp */ int recvUdp(); + /** * 解析协议 * @param o - * @return int: <0:协议错误, 0:没有一个完整的包, 1:收到至少一个包 */ int parseProtocol(TC_NetWorkBuffer &rbuf); @@ -1258,7 +1241,7 @@ public: /** * 接收数据buffer */ - TC_NetWorkBuffer _recvBuffer; + TC_NetWorkBuffer _recvBuffer; /** * 发送数据buffer @@ -1306,7 +1289,7 @@ public: /** * 带有时间链表的map */ - class ConnectionList : public TC_ThreadLock + class ConnectionList { public: /** @@ -1395,7 +1378,7 @@ public: /** * 服务 */ - NetThread *_pEpollServer; + NetThread *_pEpollServer; /** * 总计连接数 @@ -1432,6 +1415,7 @@ public: */ uint32_t _iConnectionMagic; }; + //////////////////////////////////////////////////////////////////////////// class NetThread : public TC_Thread, public TC_HandleBase { @@ -1455,12 +1439,6 @@ public: */ int getIndex() const { return _threadIndex; } - /** - * 绑定监听socket - * @param ls - */ - // int bind(BindAdapterPtr &lsPtr); - /** * 网络线程执行函数 */ @@ -1474,7 +1452,7 @@ public: /** * 生成epoll */ - void createEpoll(uint32_t iIndex = 0); + void createEpoll(uint32_t maxAllConn); /** * 初始化udp监听 @@ -1531,31 +1509,25 @@ public: * 记录日志 * @param s */ - void debug(const string &s); + void debug(const string &s) const; /** * INFO日志 * @param s */ - void info(const string &s); + void info(const string &s) const; /** * TARS日志 * @param s */ - void tars(const string &s); + void tars(const string &s) const; /** * 记录错误日志 * @param s */ - void error(const string &s); - - /** - * tars日志 - * @param s - */ - void tars(const string &s) const; + void error(const string &s) const; /** * 是否启用防止空链接攻击的机制 @@ -1609,7 +1581,7 @@ public: * @param bEraseList 是否是超时连接的删除 * @param closeType 关闭类型,0:表示客户端主动关闭;1:服务端主动关闭;2:连接超时服务端主动关闭 */ - void delConnection(Connection *cPtr, bool bEraseList = true,EM_CLOSE_T closeType=EM_CLIENT_CLOSE); + void delConnection(Connection *cPtr, bool bEraseList = true, EM_CLOSE_T closeType=EM_CLIENT_CLOSE); /** * 处理管道消息 @@ -1639,7 +1611,7 @@ public: /** * 服务 */ - TC_EpollServer *_epollServer; + TC_EpollServer *_epollServer; /** * net线程的id @@ -1661,11 +1633,6 @@ public: */ bool _bTerminate; - /** - * handle是否已经启动 - */ - bool _handleStarted; - /** * 通知epoll */ @@ -1686,6 +1653,7 @@ public: */ bool _bEmptyConnAttackCheck; + /** * 空连接超时时间,单位是毫秒,默认值2s, * 该时间必须小于等于adapter自身的超时时间 @@ -1725,11 +1693,6 @@ public: */ void setEmptyConnTimeout(int timeout); - /** - *设置NetThread的内存池信息 - */ - // void setNetThreadBufferPoolInfo(size_t minBlock, size_t maxBlock, size_t maxBytes); - /** * 设置本地日志 * @param plocalLogger @@ -1754,70 +1717,6 @@ public: */ inline bool isMergeHandleNetThread() const { return _mergeHandleNetThread; } - - // /** - // * 绑定到一个已经有的handle组上 - // * @param groupName - // * @param handleNum - // * @param adapter - // */ - // void setHandleGroup(const string& groupName, BindAdapterPtr adapter) - // { - // map::iterator it = _handleGroups.find(groupName); - - // if (it != _handleGroups.end()) - // { - // it->second->adapters[adapter->getName()] = adapter; - // adapter->_handleGroup = it->second; - // } - // } - - // /** - // * 创建一个handle对象组,如果已经存在则直接返回 - // * @param name - // * @return HandlePtr - // */ - // template void setHandleGroup(const string& groupName, int32_t handleNum, BindAdapterPtr adapter) - // { - // map::iterator it = _handleGroups.find(groupName); - - // if (it == _handleGroups.end()) - // { - // HandleGroupPtr hg = new HandleGroup(); - - // hg->name = groupName; - - // adapter->_handleGroup = hg; - - // for (int32_t i = 0; i < handleNum; ++i) - // { - // HandlePtr handle = new T(); - - // handle->setEpollServer(this); - - // handle->setHandleGroup(hg); - - // hg->handles.push_back(handle); - // } - - // _handleGroups[groupName] = hg; - - // it = _handleGroups.find(groupName); - // } - // it->second->adapters[adapter->getName()] = adapter; - - // adapter->_handleGroup = it->second; - // } - - // /** - // * 选择网络线程 - // * @param fd - // */ - // NetThread* getNetThreadOfFd(int fd) - // { - // return _netThreads[fd % _netThreads.size()]; - // } - /** * 绑定监听socket * @param ls @@ -1908,25 +1807,25 @@ public: * 记录日志 * @param s */ - void debug(const string &s); + void debug(const string &s) const; /** * INFO日志 * @param s */ - void info(const string &s); + void info(const string &s) const; /** * 记录错误日志 * @param s */ - void error(const string &s); + void error(const string &s) const; /** * tars日志 * @param s */ - void tars(const string &s); + void tars(const string &s) const; /** * 获取网络线程的数目 @@ -1987,16 +1886,11 @@ protected: void bind(const TC_Endpoint &ep, TC_Socket &s, bool manualListen); static void applicationCallback(TC_EpollServer *epollServer); -// public: - - //统计服务端相应队列大小的上报的对象 - // PropertyReport * _pReportRspQueue; - private: /** * 网络线程 */ - std::vector _netThreads; + std::vector _netThreads; /* * 网络线程数目 @@ -2027,12 +1921,12 @@ private: * 合并网络和业务线程 */ bool _mergeHandleNetThread = false; + /** * 本地循环日志 */ RollWrapperInterface *_pLocalLogger; - /** * */ @@ -2053,12 +1947,10 @@ private: */ heartbeat_callback_functor _heartFunc; - /** - * 处理handle对象 - */ - // map _handleGroups; }; + typedef TC_AutoPtr TC_EpollServerPtr; + } #endif diff --git a/util/include/util/tc_ex.h b/util/include/util/tc_ex.h index 1423567..075b84e 100644 --- a/util/include/util/tc_ex.h +++ b/util/include/util/tc_ex.h @@ -31,6 +31,9 @@ namespace tars */ ///////////////////////////////////////////////// +/** +* @brief 异常类. +*/ class TC_Exception : public exception { public: diff --git a/util/include/util/tc_gzip.h b/util/include/util/tc_gzip.h index af3dfab..a50c7ff 100755 --- a/util/include/util/tc_gzip.h +++ b/util/include/util/tc_gzip.h @@ -75,6 +75,16 @@ public: */ static bool compress(const char *src, size_t length, vector& buffer); + /** + * @brief 对数据进行压缩 + * + * @param src 需要压缩的数据 + * @param length 数据长度 + * @param buffer 输出buffer + * @return bool 成功失败 + */ + static bool compress(const char *src, size_t length, string& buffer); + /** * @brief 对数据进行解压 * diff --git a/util/include/util/tc_hashmap.h b/util/include/util/tc_hashmap.h index 4847a10..05d6c4d 100755 --- a/util/include/util/tc_hashmap.h +++ b/util/include/util/tc_hashmap.h @@ -42,7 +42,6 @@ namespace tars struct TC_HashMap_Exception : public TC_Exception { TC_HashMap_Exception(const string &buffer) : TC_Exception(buffer){}; - TC_HashMap_Exception(const string &buffer, int err) : TC_Exception(buffer, err){}; ~TC_HashMap_Exception() throw(){}; }; @@ -891,7 +890,7 @@ public: * * @return int */ - size_t getIndex() const { return _iIndex; } + int getIndex() const { return (int)_iIndex; } /** * @brief 下一个item @@ -1018,7 +1017,6 @@ public: * @brief map头 */ #pragma pack(1) - struct tagMapHead { char _cMaxVersion; /**大版本*/ @@ -1749,13 +1747,13 @@ protected: * @brief 某hash链表数据个数+1 * @param index */ - void incListCount(uint32_t index) { update(&item(index)->_iListCount, item(index)->_iListCount+1); } + void incListCount(uint32_t index) { update(&item(index)->_iListCount, (uint32_t)item(index)->_iListCount+1); } /** * @brief 某hash链表数据个数+1 * @param index */ - void delListCount(size_t index) { update(&item(index)->_iListCount, item(index)->_iListCount-1); } + void delListCount(size_t index) { update(&item(index)->_iListCount, (uint32_t)item(index)->_iListCount-1); } /** * @brief 相对地址换成绝对地址 diff --git a/util/include/util/tc_hashmap_compact.h b/util/include/util/tc_hashmap_compact.h index 7b4b1de..5f9a67b 100644 --- a/util/include/util/tc_hashmap_compact.h +++ b/util/include/util/tc_hashmap_compact.h @@ -44,7 +44,6 @@ namespace tars struct TC_HashMapCompact_Exception : public TC_Exception { TC_HashMapCompact_Exception(const string &buffer) : TC_Exception(buffer){}; - TC_HashMapCompact_Exception(const string &buffer, int err) : TC_Exception(buffer, err){}; ~TC_HashMapCompact_Exception() throw(){}; }; @@ -110,7 +109,7 @@ public: uint32_t _iGetPrev; /**Get链上的上一个Block*/ uint32_t _iSyncTime; /**上次缓写时间*/ uint32_t _iExpireTime; /** 数据过期的绝对时间,由设置或更新数据时提供,0表示不关心此时间*/ - uint8_t _iVersion; /** 数据版本,1为初始版本,0为保留*/ + uint8_t _iVersion; /** 数据版本,1为初始版本,0为保留*/ bool _bDirty; /**是否是脏数据*/ bool _bOnlyKey; /**是否只有key, 没有内容*/ bool _bNextChunk; /**是否有下一个chunk*/ @@ -1073,9 +1072,8 @@ public: uint32_t _iBackupTail; //热备指针 uint32_t _iSyncTail; //回写链表 uint32_t _iOnlyKeyCount; // OnlyKey个数 - bool _bInit; //是否已经完成初始化 + bool _bInit; //是否已经完成初始化 char _cReserve[15]; //保留 - //uint32_t _iReserve[4]; //保留 }; /** @@ -1107,7 +1105,6 @@ public: uint32_t _iListCount; /**链表个数*/ }; #pragma pack() - /** * @brief 64位操作系统用基数版本号, 32位操作系统用64位版本号 * */ @@ -1179,7 +1176,7 @@ public: /** * @brief 定义hash处理器 */ - using hash_functor = std::function; + typedef std::function hash_functor; ////////////////////////////////////////////////////////////////////////////////////////////// //map的接口定义 diff --git a/util/include/util/tc_http.h b/util/include/util/tc_http.h index 478f9a7..5adb562 100755 --- a/util/include/util/tc_http.h +++ b/util/include/util/tc_http.h @@ -76,7 +76,7 @@ struct TC_Http_Exception : public TC_Exception struct TC_HttpResponse_Exception : public TC_Http_Exception { TC_HttpResponse_Exception(const string &sBuffer) : TC_Http_Exception(sBuffer){}; - ~TC_HttpResponse_Exception() throw(){}; + ~TC_HttpResponse_Exception() {}; }; /** @@ -85,11 +85,10 @@ struct TC_HttpResponse_Exception : public TC_Http_Exception struct TC_HttpRequest_Exception : public TC_Http_Exception { TC_HttpRequest_Exception(const string &sBuffer) : TC_Http_Exception(sBuffer){}; - ~TC_HttpRequest_Exception() throw(){}; + ~TC_HttpRequest_Exception() {}; }; class TC_TCPClient; - class TC_HttpRequest; class TC_HttpResponse; @@ -293,14 +292,6 @@ protected: */ string toURL(); - /** - * @brief 获取段. - * - * @param frag - * @return string - */ - //string getFragment(const string& frag) const; - /** * @brief 类型到字符串的转换 * @@ -364,18 +355,7 @@ public: */ struct CmpCase { - bool operator()(const string &s1, const string &s2) const - { - //return TC_Common::upper(s1) < TC_Common::upper(s2); - if(TC_Port::strcasecmp(s1.c_str(), s2.c_str()) < 0) - { - return true; - } - else - { - return false; - } - } + bool operator()(const string &s1, const string &s2) const; }; typedef multimap http_header_type; @@ -467,21 +447,7 @@ public: * @param sHeadName header的名字 * @param sHeadValue header的值 */ - void setHeader(const string &sHeadName, const string &sHeadValue) - { - //Set-Cookie和Cookie可以有多个头 - const char * pStr1 = "SET-COOKIE"; - const char * pStr2 = "COOKIE";//原则上COOKIE只有一个,担心有兼容性问题,保留 - if((TC_Port::strcasecmp(sHeadName.c_str(), pStr1) != 0) && (TC_Port::strcasecmp(sHeadName.c_str(), pStr2) != 0)) - { - _headers.erase(sHeadName); - } - /* if(TC_Common::upper(sHeadName) != "SET-COOKIE" && TC_Common::upper(sHeadName) != "COOKIE") - { - _headers.erase(sHeadName); - }*/ - _headers.insert(multimap::value_type(sHeadName, sHeadValue)); - } + void setHeader(const string &sHeadName, const string &sHeadValue); /** * @brief 设置header,常用的值请使用已经有的get/set方法设 @@ -759,7 +725,7 @@ public: * * @return list& */ - list getAllCookie(); + const list& getAllCookie(); /** * @brief 删除过期的Cookie,仅仅存在与当前回话的Cookie不删除 @@ -990,6 +956,13 @@ public: */ void parseResponseHeader(const char* szBuffer); +protected: + /** + * 添加内容, 增量解析用到 + * @param sBuffer + */ + void addContent(const string &sBuffer); + protected: /** @@ -1016,6 +989,12 @@ protected: * 临时的content length */ size_t _iTmpContentLength; + + /** + * 接收到数据的长度 + */ + size_t _iRecvContentLength; + }; /********************* TC_HttpRequest ***********************/ @@ -1124,6 +1103,7 @@ public: * (注意, 是在encode的时候创建的) */ void setRequest(const string& method, const string &sUrl, const std::string& body = "", bool bNewCreateHost = false); + /** * @brief 设置Get请求包. * diff --git a/util/include/util/tc_http_async.h b/util/include/util/tc_http_async.h index bbd93a1..d6b5ce0 100644 --- a/util/include/util/tc_http_async.h +++ b/util/include/util/tc_http_async.h @@ -38,7 +38,7 @@ namespace tars * 1 背后会启动唯一的网络线程 * 2 目前只支持http短连接 * 3 RequestCallback回调里面, onSucc和onFailed是对应的, 每次异步请求, onSucc/onFailed其中之一会被唯一响应 -* @author jarodruan@tencent.com +* @author ruanshudong@qq.com */ ///////////////////////////////////////////////// @@ -434,6 +434,7 @@ protected: bool _bindAddrSet; }; + } #endif diff --git a/util/include/util/tc_json.h b/util/include/util/tc_json.h index 08894da..4f42550 100644 --- a/util/include/util/tc_json.h +++ b/util/include/util/tc_json.h @@ -1,30 +1,13 @@ -/** - * Tencent is pleased to support the open source community by making Tars available. - * - * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ + #ifndef __TC_JSON_H #define __TC_JSON_H #include #include -#include #include -#include #include #include -#include #include "util/tc_autoptr.h" @@ -38,110 +21,31 @@ namespace tars */ struct TC_Json_Exception : public TC_Exception { - TC_Json_Exception(const string &buffer) : TC_Exception(buffer){}; - ~TC_Json_Exception() throw(){}; + TC_Json_Exception(const string &buffer) : TC_Exception(buffer){}; + ~TC_Json_Exception() throw(){}; }; enum eJsonType { - eJsonTypeString, - eJsonTypeNum, - eJsonTypeObj, - eJsonTypeArray, - eJsonTypeBoolean, - eJsonTypeNull, + eJsonTypeString, + eJsonTypeNum, + eJsonTypeObj, + eJsonTypeArray, + eJsonTypeBoolean }; -/* - * 分析json字符串用到的 读字符的类 - */ -class BufferJsonReader -{ - const char * _buf; ///< 缓冲区 - size_t _buf_len; ///< 缓冲区长度 - size_t _cur; ///< 当前位置 - -public: - - BufferJsonReader () :_buf(NULL),_buf_len(0), _cur(0) {} - - void reset() { _cur = 0;} - - void setBuffer(const char * buf, size_t len) - { - _buf = buf; - _buf_len = len; - _cur = 0; - } - - void setBuffer(const std::vector &buf) - { - _buf = buf.data(); - _buf_len = buf.size(); - _cur = 0; - } - - const size_t &getCur() const { return _cur; } - - const char * getPoint() const { return _buf+_cur; } - - const char &read() { check(); _cur ++; return *(_buf+_cur-1); } - - const char &get() const { check(); return *(_buf+_cur); } - - const char &getBack() const { assert(_cur>0); return *(_buf+_cur-1); } - - void back() { assert(_cur>0); _cur--; } - - void check() const - { - if (_cur + 1 > _buf_len) - { - char s[64]; - snprintf(s, sizeof(s), "buffer overflow when peekBuf, over %u.", (uint32_t)_buf_len); - throw TC_Json_Exception(s); - } - } - - bool hasEnd() const { return _cur >= _buf_len; } -}; - -class JsonValue; -class JsonValueObj; -class JsonValueArray; -class JsonValueString; -class JsonValueBoolean; -class JsonValueNum; -class JsonValueNull; - -typedef TC_AutoPtr JsonValuePtr; -typedef TC_AutoPtr JsonValueObjPtr; -typedef TC_AutoPtr JsonValueNumPtr; -typedef TC_AutoPtr JsonValueArrayPtr; -typedef TC_AutoPtr JsonValueStringPtr; -typedef TC_AutoPtr JsonValueBooleanPtr; -typedef TC_AutoPtr JsonValueNullPtr; - /* * json类型的基类。没有任何意义 */ class JsonValue : public TC_HandleBase { public: - virtual eJsonType getType() const = 0; - virtual void write(ostream& ostr) const; - virtual void read(BufferJsonReader & reader, char c) = 0; - virtual ~JsonValue() { } - -public: - static JsonValuePtr createJsonValue(BufferJsonReader & reader); - static uint32_t getHex(BufferJsonReader & reader); - static bool isspace(char c); - static void writeString(const string &str, ostream& ostr); - -protected: - JsonValue(){}; + virtual eJsonType getType()=0; + virtual ~JsonValue() + { + } }; +typedef TC_AutoPtr JsonValuePtr; /* * json类型 string类型 例如"dd\ndfd" @@ -149,21 +53,24 @@ protected: class JsonValueString : public JsonValue { public: - JsonValueString(const string & s):value(s) - { - } - JsonValueString() - { - } + JsonValueString(const string & s):value(s) + { + } + JsonValueString() + { - eJsonType getType() const { return eJsonTypeString; } + } - virtual void write(ostream& ostr) const; - virtual void read(BufferJsonReader & reader, char c); - - virtual ~JsonValueString() { } - string value; + eJsonType getType() + { + return eJsonTypeString; + } + virtual ~JsonValueString() + { + } + string value; }; +typedef TC_AutoPtr JsonValueStringPtr; /* * json类型 number类型 例如 1.5e8 @@ -171,23 +78,24 @@ public: class JsonValueNum : public JsonValue { public: - JsonValueNum(double d,bool b=false):value(d),isInt(b) - { - } - JsonValueNum() - { - isInt=false; + JsonValueNum(double d,bool b=false):value(d),isInt(b) + { + } + JsonValueNum() + { + isInt=false; value=0.0f; - } - eJsonType getType() const { return eJsonTypeNum; } - virtual void write(ostream& ostr) const; - virtual void read(BufferJsonReader & reader, char c); - - virtual ~JsonValueNum(){} + } + eJsonType getType() + { + return eJsonTypeNum; + } + virtual ~JsonValueNum(){} public: - double value; - bool isInt; + double value; + bool isInt; }; +typedef TC_AutoPtr JsonValueNumPtr; /* * json类型 object类型 例如 {"aa","bb"} @@ -195,14 +103,15 @@ public: class JsonValueObj: public JsonValue { public: - eJsonType getType() const { return eJsonTypeObj; } - virtual void write(ostream& ostr) const; - virtual void read(BufferJsonReader & reader, char c); - const JsonValuePtr &get(const char *name); - virtual ~JsonValueObj(); + eJsonType getType() + { + return eJsonTypeObj; + } + virtual ~JsonValueObj(){} public: - unordered_map value; + unordered_map value; }; +typedef TC_AutoPtr JsonValueObjPtr; /* * json类型 array类型 例如 ["aa","bb"] @@ -210,14 +119,19 @@ public: class JsonValueArray: public JsonValue { public: - eJsonType getType() const { return eJsonTypeArray; } - void push_back(const JsonValuePtr & p) { value.push_back(p); } - virtual void write(ostream& ostr) const; - virtual void read(BufferJsonReader & reader, char c = 0); - virtual ~JsonValueArray(); + eJsonType getType() + { + return eJsonTypeArray; + } + void push_back(JsonValuePtr & p) + { + value.push_back(p); + } + virtual ~JsonValueArray(){} public: - vector value; + vector value; }; +typedef TC_AutoPtr JsonValueArrayPtr; /* * json类型 boolean类型 例如 true @@ -225,29 +139,98 @@ public: class JsonValueBoolean : public JsonValue { public: - eJsonType getType() const { return eJsonTypeBoolean; } - bool getValue() const { return value; } - virtual void write(ostream& ostr) const; - virtual void read(BufferJsonReader & reader,char c); - virtual ~JsonValueBoolean(){} + eJsonType getType() + { + return eJsonTypeBoolean; + } + bool getValue() + { + return value; + } + virtual ~JsonValueBoolean(){} public: - bool value; + bool value; }; +typedef TC_AutoPtr JsonValueBooleanPtr; /* - * json类型 null类型 例如"dd\ndfd" + * 分析json字符串用到的 读字符的类 */ -class JsonValueNull : public JsonValue +class BufferJsonReader { + const char * _buf; ///< 缓冲区 + size_t _buf_len; ///< 缓冲区长度 + size_t _cur; ///< 当前位置 + public: - JsonValueNull() { } - eJsonType getType() const { return eJsonTypeNull; } + BufferJsonReader () :_buf(NULL),_buf_len(0), _cur(0) {} - virtual void write(ostream& ostr) const; - virtual void read(BufferJsonReader & reader, char c); + void reset() { _cur = 0;} - virtual ~JsonValueNull() { } + void setBuffer(const char * buf, size_t len) + { + _buf = buf; + _buf_len = len; + _cur = 0; + } + + void setBuffer(const std::vector &buf) + { + _buf = buf.data(); + _buf_len = buf.size(); + _cur = 0; + } + + size_t getCur() + { + return _cur; + } + + const char * getPoint() + { + return _buf+_cur; + } + + char read() + { + check(); + _cur ++; + return *(_buf+_cur-1); + } + + char get() + { + check(); + return *(_buf+_cur); + } + + char getBack() + { + assert(_cur>0); + return *(_buf+_cur-1); + } + + void back() + { + assert(_cur>0); + _cur--; + } + + void check() + { + if (_cur + 1 > _buf_len) + { + char s[64]; + snprintf(s, sizeof(s), "buffer overflow when peekBuf, over %u.", (uint32_t)_buf_len); + throw TC_Json_Exception(s); + } + } + + bool hasEnd() + { + return _cur >= _buf_len; + } }; /* @@ -256,15 +239,71 @@ public: class TC_Json { public: - //json类型到字符串的转换 - static string writeValue(const JsonValuePtr &p); - - //解析成智能指针 - static JsonValuePtr getValue(const string & str); + //json类型到字符串的转换 + static string writeValue(const JsonValuePtr & p); + static void writeValue(const JsonValuePtr & p, string& ostr); + //json字符串到json结构的转换 + static JsonValuePtr getValue(const string & str); +private: + //string 类型到json字符串 + static void writeString(const JsonValueStringPtr & p, string& ostr); + static void writeString(const string & s, string& ostr); + + //num 类型到json字符串 + static void writeNum(const JsonValueNumPtr & p, string& ostr); + + //obj 类型到json字符串 + static void writeObj(const JsonValueObjPtr & p, string& ostr); + + //array 类型到json字符串 + static void writeArray(const JsonValueArrayPtr & p, string& ostr); + + //boolean 类型到json字符串 + static void writeBoolean(const JsonValueBooleanPtr & p, string& ostr); + + //读取json的value类型 也就是所有的json类型 如果不符合规范会抛异常 + static JsonValuePtr getValue(BufferJsonReader & reader); + //读取json的object 如果不符合规范会抛异常 + static JsonValueObjPtr getObj(BufferJsonReader & reader); + //读取json的array(数组) 如果不符合规范会抛异常 + static JsonValueArrayPtr getArray(BufferJsonReader & reader); + //读取json的string 如 "dfdf" 如果不符合规范会抛异常 + static JsonValueStringPtr getString(BufferJsonReader & reader,char head='\"'); + //读取json的数字 如 -213.56 如果不符合规范会抛异常 + static JsonValueNumPtr getNum(BufferJsonReader & reader,char head); + //读取json的boolean值 如 true false 如果不符合规范会抛异常 + static JsonValueBooleanPtr getBoolean(BufferJsonReader & reader,char c); + //读取json的 null 如果不符合规范会抛异常 + static JsonValuePtr getNull(BufferJsonReader & reader,char c); + //获取16进制形式的值 如\u003f 如果不符合规范会抛异常 + static uint32_t getHex(BufferJsonReader & reader); + //判断一个字符是否符合json定义的空白字符 + static bool isspace(char c); }; + +class TC_JsonWriteOstream +{ +public: + static void writeValue(const JsonValuePtr & p, ostream& ostr); +private: + //string 类型到json字符串 + static void writeString(const JsonValueStringPtr & p, ostream& ostr); + static void writeString(const string & s, ostream& ostr); + + //num 类型到json字符串 + static void writeNum(const JsonValueNumPtr & p, ostream& ostr); + + //obj 类型到json字符串 + static void writeObj(const JsonValueObjPtr & p, ostream& ostr); + + //array 类型到json字符串 + static void writeArray(const JsonValueArrayPtr & p, ostream& ostr); + + //boolean 类型到json字符串 + static void writeBoolean(const JsonValueBooleanPtr & p, ostream& ostr); +}; } #endif - diff --git a/util/include/util/tc_lock.h b/util/include/util/tc_lock.h index f8eec65..c128ab5 100644 --- a/util/include/util/tc_lock.h +++ b/util/include/util/tc_lock.h @@ -40,7 +40,6 @@ namespace tars struct TC_Lock_Exception : public TC_Exception { TC_Lock_Exception(const string &buffer) : TC_Exception(buffer){}; - TC_Lock_Exception(const string &buffer, int err) : TC_Exception(buffer, err){}; ~TC_Lock_Exception() throw() {}; }; @@ -125,9 +124,9 @@ public: protected: /** - * @brief 构造函数 - * 用于锁尝试操作,与TC_LockT相似 - * + * @brief 构造函数 + * 用于锁尝试操作,与TC_LockT相似 + * */ TC_LockT(const T& mutex, bool) : _mutex(mutex) { @@ -172,8 +171,8 @@ class TC_EmptyMutex { public: /** - * @brief 写锁. - * + * @brief 写锁. + * * @return int, 0 正确 */ int lock() const {return 0;} @@ -184,8 +183,8 @@ public: int unlock() const {return 0;} /** - * @brief 尝试解锁. - * + * @brief 尝试解锁. + * * @return int, 0 正确 */ bool trylock() const {return true;} @@ -201,40 +200,40 @@ class TC_RW_RLockT { public: /** - * @brief 构造函数,构造时枷锁 - * + * @brief 构造函数,构造时枷锁 + * * @param lock 锁对象 */ - TC_RW_RLockT(T& lock) - : _rwLock(lock),_acquired(false) - { - _rwLock.ReadLock(); - _acquired = true; - } + TC_RW_RLockT(T& lock) + : _rwLock(lock),_acquired(false) + { + _rwLock.readLock(); + _acquired = true; + } /** - * @brief 析构时解锁 + * @brief 析构时解锁 */ - ~TC_RW_RLockT() - { - if (_acquired) - { - _rwLock.Unlock(); - } - } + ~TC_RW_RLockT() + { + if (_acquired) + { + _rwLock.unReadLock(); + } + } private: - /** - *锁对象 - */ - const T& _rwLock; + /** + *锁对象 + */ + const T& _rwLock; /** * 是否已经上锁 */ mutable bool _acquired; - TC_RW_RLockT(const TC_RW_RLockT&); - TC_RW_RLockT& operator=(const TC_RW_RLockT&); + TC_RW_RLockT(const TC_RW_RLockT&); + TC_RW_RLockT& operator=(const TC_RW_RLockT&); }; template @@ -242,38 +241,38 @@ class TC_RW_WLockT { public: /** - * @brief 构造函数,构造时枷锁 - * + * @brief 构造函数,构造时枷锁 + * * @param lock 锁对象 */ - TC_RW_WLockT(T& lock) - : _rwLock(lock),_acquired(false) - { - _rwLock.WriteLock(); - _acquired = true; - } + TC_RW_WLockT(T& lock) + : _rwLock(lock),_acquired(false) + { + _rwLock.writeLock(); + _acquired = true; + } /** - * @brief 析构时解锁 + * @brief 析构时解锁 */ - ~TC_RW_WLockT() - { - if(_acquired) - { - _rwLock.Unlock(); - } - } + ~TC_RW_WLockT() + { + if(_acquired) + { + _rwLock.unWriteLock(); + } + } private: - /** - *锁对象 - */ - const T& _rwLock; + /** + *锁对象 + */ + const T& _rwLock; /** * 是否已经上锁 */ mutable bool _acquired; - TC_RW_WLockT(const TC_RW_WLockT&); - TC_RW_WLockT& operator=(const TC_RW_WLockT&); + TC_RW_WLockT(const TC_RW_WLockT&); + TC_RW_WLockT& operator=(const TC_RW_WLockT&); }; }; diff --git a/util/include/util/tc_loop_queue.h b/util/include/util/tc_loop_queue.h index a4c26e1..a20505e 100644 --- a/util/include/util/tc_loop_queue.h +++ b/util/include/util/tc_loop_queue.h @@ -33,16 +33,16 @@ namespace tars */ ///////////////////////////////////////////////// -template +template class TC_LoopQueue { public: typedef vector queue_type; - TC_LoopQueue(uint32_t iSize=Size) + TC_LoopQueue(size_t iSize) { //做个保护 最多不能超过 1000000 - assert(iSize<1000000); + // assert(iSize<1000000); _iBegin = 0; _iEnd = 0; _iCapacitySub = iSize; @@ -56,7 +56,7 @@ public: //delete _p; } - bool push_back(const T &t,bool & bEmpty,uint32_t & iBegin,uint32_t & iEnd) + bool push_back(const T &t,bool & bEmpty, size_t & iBegin, size_t & iEnd) { bEmpty = false; //uint32_t iEnd = _iEnd; @@ -90,7 +90,7 @@ public: bool push_back(const T &t,bool & bEmpty) { bEmpty = false; - uint32_t iEnd = _iEnd; + size_t iEnd = _iEnd; if((iEnd > _iBegin && iEnd - _iBegin < 2) || ( _iBegin > iEnd && _iBegin - iEnd > (_iCapacity-2) ) ) { @@ -128,7 +128,7 @@ public: bool push_back(const queue_type &vt) { - uint32_t iEnd=_iEnd; + size_t iEnd=_iEnd; if(vt.size()>(_iCapacity-1) || (iEnd>_iBegin && (iEnd-_iBegin)<(vt.size()+1)) || ( _iBegin>iEnd && (_iBegin-iEnd)>(_iCapacity-vt.size()-1) ) ) @@ -137,7 +137,7 @@ public: } else { - for(uint32_t i=0;i +#include "util/tc_ex.h" #include "util/tc_common.h" using namespace std; @@ -41,6 +42,15 @@ namespace tars } #endif +/** + * @brief md5异常. + */ +struct TC_MD5_Exception : public TC_Exception +{ + TC_MD5_Exception(const string &buffer, int err) : TC_Exception(buffer, err){}; + ~TC_MD5_Exception() throw(){}; +}; + class TC_MD5 { typedef unsigned char *POINTER; @@ -75,7 +85,8 @@ public: * @param sString 输入字符串 * @return string 输出,16个字节的二进制数据 */ - static string md5bin(const string &sString); + static vector md5bin(const string &sString); + static vector md5bin(const char *buffer, size_t length); /** * @brief 对字符串进行md5处理 , @@ -83,12 +94,14 @@ public: * @param sString 输入字符串 * @return string 输出,32个字符 */ - static string md5str (const string &sString); + static string md5str(const string &sString); + static string md5str (const char *buffer, size_t length); /** * @brief 对文件进行md5处理. * * @param fileName 要处理的文件名 + * @throw TC_MD5_Exception, 文件读取错误会抛出异常 * @return string 处理后的字符串 */ static string md5file(const string& fileName); diff --git a/util/include/util/tc_mem_chunk.h b/util/include/util/tc_mem_chunk.h index 65cf028..64a20d1 100644 --- a/util/include/util/tc_mem_chunk.h +++ b/util/include/util/tc_mem_chunk.h @@ -159,7 +159,6 @@ public: * @brief chunk头部 */ #pragma pack(1) - struct tagChunkHead { size_t _iBlockSize; /**区块大小*/ @@ -326,7 +325,6 @@ public: * @brief 头部内存块 */ #pragma pack(1) - struct tagChunkAllocatorHead { size_t _iSize; @@ -540,7 +538,6 @@ public: * @brief 头部内存块 */ #pragma pack(1) - struct tagChunkAllocatorHead { size_t _iSize; /**当前块大小*/ diff --git a/util/include/util/tc_mem_queue.h b/util/include/util/tc_mem_queue.h index 4171e4b..440071c 100644 --- a/util/include/util/tc_mem_queue.h +++ b/util/include/util/tc_mem_queue.h @@ -64,6 +64,15 @@ public: * @param pAddr 指令队列空间的指针 */ void connect(void *pAddr, size_t iSize); + + /** + * @author goodenpei + * 2016-09-12 + * @brief 取第一个数据 + * @param sOut 输出的数据快 + * @return bool,true:正确, false: 错误,无数据输出,队列空 + */ + bool front(string &sOut); /** * @brief 弹出数据 @@ -151,7 +160,6 @@ protected: * @brief 队列控制结构 */ #pragma pack(1) - struct CONTROL_BLOCK { size_t iMemSize; /**内存大小*/ diff --git a/util/include/util/tc_mem_vector.h b/util/include/util/tc_mem_vector.h index b82fc85..413f5fd 100644 --- a/util/include/util/tc_mem_vector.h +++ b/util/include/util/tc_mem_vector.h @@ -37,7 +37,6 @@ namespace tars struct TC_MemVectorException : public TC_Exception { TC_MemVectorException(const string &buffer) : TC_Exception(buffer){}; - TC_MemVectorException(const string &buffer, int err) : TC_Exception(buffer, err){}; ~TC_MemVectorException() throw(){}; }; @@ -94,7 +93,7 @@ public: /** * @brief 计算需要的内存空间 - * @param iCount 数据个数 + * @param iCount 数据个数 * @return size_t 内存空间大小 */ static size_t calcMemSize(size_t iCount) @@ -233,14 +232,14 @@ public: * * @return TC_MemVectorIterator */ - TC_MemVectorIterator begin() { return TC_MemVectorIterator(this, 0); } + TC_MemVectorIterator begin() { return TC_MemVectorIterator(this, 0); } /** * * * @return TC_MemVectorIterator */ - TC_MemVectorIterator end() { return TC_MemVectorIterator(this, _pHead->_iBlockCount); } + TC_MemVectorIterator end() { return TC_MemVectorIterator(this, _pHead->_iBlockCount); } /** * @brief 获取数据 @@ -251,8 +250,8 @@ public: { if(iIndex >= _pHead->_iBlockCount) { - ostringstream s; - s << string("[TC_MemVector::get] index beyond : index = ") << iIndex << " > " << _pHead->_iBlockCount; + ostringstream s; + s << string("[TC_MemVector::get] index beyond : index = ") << iIndex << " > " << _pHead->_iBlockCount; throw TC_MemVectorException(s.str()); } @@ -271,7 +270,6 @@ public: * @brief 队列控制结构 */ #pragma pack(1) - struct tagMemQueueHead { size_t _iSize; //内存大小 diff --git a/util/include/util/tc_multi_hashmap.h b/util/include/util/tc_multi_hashmap.h index 12359e9..a176568 100644 --- a/util/include/util/tc_multi_hashmap.h +++ b/util/include/util/tc_multi_hashmap.h @@ -44,7 +44,6 @@ namespace tars struct TC_Multi_HashMap_Exception : public TC_Exception { TC_Multi_HashMap_Exception(const string &buffer) : TC_Exception(buffer){}; - TC_Multi_HashMap_Exception(const string &buffer, int err) : TC_Exception(buffer, err){}; ~TC_Multi_HashMap_Exception() throw(){}; }; @@ -142,7 +141,7 @@ public: uint32_t _iGetNext; /**主key Get链的下一个主key*/ uint32_t _iGetPrev; /**主key Get链的上一个主key*/ uint32_t _iBlockCount; /**主key下数据个数*/ - uint8_t _iBitset; /** 8个bit,用于标识不同的bool值,各bit的含义见BITWISE枚举定义*/ + uint8_t _iBitset; /** 8个bit,用于标识不同的bool值,各bit的含义见BITWISE枚举定义*/ union { uint32_t _iNextChunk; /** 下一个Chunk块地址, _bNextChunk=true时有效*/ @@ -435,7 +434,6 @@ public: * @brief block数据头 */ #pragma pack(1) - struct tagBlockHead { uint32_t _iSize; /**block的容量大小*/ @@ -447,9 +445,9 @@ public: uint32_t _iSetNext; /**Set链上的上一个Block, 没有则为0*/ uint32_t _iSetPrev; /**Set链上的上一个Block, 没有则为0*/ uint32_t _iMainKey; /**指向所属主key头*/ - time_t _iSyncTime; /**上次缓写时间*/ - uint8_t _iVersion; /**数据版本,1为初始版本,0为保留*/ - uint8_t _iBitset; /**8个bit,用于标识不同的bool值,各bit的含义见BITWISE枚举定义*/ + time_t _iSyncTime; /**上次缓写时间*/ + uint8_t _iVersion; /**数据版本,1为初始版本,0为保留*/ + uint8_t _iBitset; /**8个bit,用于标识不同的bool值,各bit的含义见BITWISE枚举定义*/ union { uint32_t _iNextChunk; /**下一个Chunk块, _iBitwise中的NEXTCHUNK_BIT为1时有效*/ @@ -1434,15 +1432,15 @@ public: bool _bReadOnly; /**是否只读*/ bool _bAutoErase; /**是否可以自动淘汰*/ char _cEraseMode; /**淘汰方式:0x00:按照Get链淘汰, 0x01:按照Set链淘汰*/ - size_t _iMemSize; /**内存大小*/ - size_t _iMinDataSize; /**最小数据块大小*/ - size_t _iMaxDataSize; /**最大数据块大小*/ - float _fFactor; /**因子*/ - float _fHashRatio; /**chunks个数/hash个数*/ - float _fMainKeyRatio; /**chunks个数/主key hash个数*/ - size_t _iElementCount; /**总元素个数*/ - size_t _iEraseCount; /**每次淘汰个数*/ - size_t _iDirtyCount; /**脏数据个数*/ + size_t _iMemSize; /**内存大小*/ + size_t _iMinDataSize; /**最小数据块大小*/ + size_t _iMaxDataSize; /**最大数据块大小*/ + float _fFactor; /**因子*/ + float _fHashRatio; /**chunks个数/hash个数*/ + float _fMainKeyRatio; /**chunks个数/主key hash个数*/ + size_t _iElementCount; /**总元素个数*/ + size_t _iEraseCount; /**每次淘汰个数*/ + size_t _iDirtyCount; /**脏数据个数*/ uint32_t _iSetHead; /**Set时间链表头部*/ uint32_t _iSetTail; /**Set时间链表尾部*/ uint32_t _iGetHead; /**Get时间链表头部*/ @@ -1450,14 +1448,14 @@ public: uint32_t _iDirtyTail; /**脏数据链尾部*/ uint32_t _iBackupTail; /**热备指针*/ uint32_t _iSyncTail; /**回写链表*/ - time_t _iSyncTime; /**回写时间*/ - size_t _iUsedChunk; /**已经使用的内存块*/ - size_t _iGetCount; /**get次数*/ - size_t _iHitCount; /**命中次数*/ - size_t _iMKOnlyKeyCount; /**主key的onlykey个数*/ - size_t _iOnlyKeyCount; /**主键的OnlyKey个数, 这个数通常为0*/ - size_t _iMaxBlockCount; /**主key链下最大的记录数,这个数值要监控,不能太大,否则会导致查询变慢*/ - size_t _iReserve[4]; /**保留*/ + time_t _iSyncTime; /**回写时间*/ + size_t _iUsedChunk; /**已经使用的内存块*/ + size_t _iGetCount; /**get次数*/ + size_t _iHitCount; /**命中次数*/ + size_t _iMKOnlyKeyCount; /**主key的onlykey个数*/ + size_t _iOnlyKeyCount; /**主键的OnlyKey个数, 这个数通常为0*/ + size_t _iMaxBlockCount; /**主key链下最大的记录数,这个数值要监控,不能太大,否则会导致查询变慢*/ + size_t _iReserve[4]; /**保留*/ }; /** diff --git a/util/include/util/tc_mysql.h b/util/include/util/tc_mysql.h index a9dead4..55c4c07 100644 --- a/util/include/util/tc_mysql.h +++ b/util/include/util/tc_mysql.h @@ -17,15 +17,13 @@ #ifndef __TC_MYSQL_H #define __TC_MYSQL_H -#include "util/tc_ex.h" +#include "util/tc_platform.h" #include "mysql.h" +#include "util/tc_ex.h" #include #include #include - -struct st_mysql; - -typedef struct st_mysql MYSQL; +#include namespace tars { @@ -190,6 +188,13 @@ public: */ void init(const TC_DBConf& tcDBConf); + /** + * @brief 读取mysql配置 + * + * @return tcDBConf + */ + TC_DBConf getDBConf(); + /** * @brief 连接数据库. * @@ -219,13 +224,13 @@ public: MYSQL *getMysql(); /** - * @brief 字符转义. + * @brief 字符转义, 需要连接到数据库,考虑了字符集 * * @param sFrom 源字符串 * @param sTo 输出字符串 * @return 输出字符串 */ - string escapeString(const string& sFrom); + string realEscapeString(const string& sFrom); /** * @brief 更新或者插入数据. @@ -300,6 +305,16 @@ public: */ MysqlData queryRecord(const string& sSql); + /** + * @brief Query Record. + * + * @param sSql sql语句 + * @param pdatafunc ,函数参数为map ,key为column 名,value为数据 + * @throws TC_Mysql_Exception + * @return MysqlData类型的数据,可以根据字段获取相关信息 + */ + size_t travelRecord(const string& sSql, const std::function &)> & pdatafunc); + /** * @brief 定义字段类型, * DB_INT:数字类型 @@ -337,6 +352,16 @@ public: */ size_t insertRecord(const string &sTableName, const map > &mpColumns); + /** + * @brief 插入记录(一次插入多条). + * + * @param sTableName 表名 + * @param mpColumns 列名/值对数组 + * @throws TC_Mysql_Exception + * @return size_t 影响的行数 + */ + size_t insertRecord(const string &sTableName, const map>> &mpColumns); + /** * @brief 替换记录. * @@ -347,6 +372,16 @@ public: */ size_t replaceRecord(const string &sTableName, const map > &mpColumns); + /** + * @brief 替换记录(一次替换多条). + * + * @param sTableName 表名 + * @param mpColumns 列名/值对数组 + * @throws TC_Mysql_Exception + * @return size_t 影响的行数 + */ + size_t replaceRecord(const string &sTableName, const map>> &mpColumns); + /** * @brief 删除记录. * @@ -412,6 +447,15 @@ public: */ string buildInsertSQL(const string &sTableName, const map > &mpColumns); + /** + * @brief 构造Insert-SQL语句(一次插入多条). + * + * @param sTableName 表名 + * @param mpColumns 列名/值对 + * @return string insert-SQL语句 + */ + string buildInsertSQL(const string &sTableName, const map >> &mpColumns); + /** * @brief 构造Replace-SQL语句. * @@ -421,6 +465,15 @@ public: */ string buildReplaceSQL(const string &sTableName, const map > &mpColumns); + /** + * @brief 构造Replace-SQL语句(一次替换多条). + * + * @param sTableName 表名 + * @param mpColumns 列名/值对 + * @return string insert-SQL语句 + */ + string buildReplaceSQL(const string &sTableName, const map >> &mpColumns); + /** * @brief 构造Update-SQL语句. * @@ -443,6 +496,63 @@ public: * @return int */ size_t getAffectedRows(); + + + /** + * @brief 字符转义, 不考虑字符集(有一定的风险). + * + * @param sFrom 源字符串 + * @param sTo 输出字符串 + * @return 输出字符串 + */ + static string escapeString(const string& sFrom); + + /** + * @brief 构造Insert-SQL语句. + * + * @param sTableName 表名 + * @param mpColumns 列名/值对 + * @return string insert-SQL语句 + */ + static string buildInsertSQLNoSafe(const string &sTableName, const map > &mpColumns); + + /** + * @brief 构造Insert-SQL语句(批量). + * + * @param sTableName 表名 + * @param mpColumns 列名/值对 + * @return string insert-SQL语句 + */ + static string buildInsertSQLNoSafe(const string &sTableName, const map >> &mpColumns); + + /** + * @brief 构造Replace-SQL语句. + * + * @param sTableName 表名 + * @param mpColumns 列名/值对 + * @return string insert-SQL语句 + */ + static string buildReplaceSQLNoSafe(const string &sTableName, const map > &mpColumns); + + /** + * @brief 构造Replace-SQL语句(批量). + * + * @param sTableName 表名 + * @param mpColumns 列名/值对 + * @return string insert-SQL语句 + */ + static string buildReplaceSQLNoSafe(const string &sTableName, const map >> &mpColumns); + + /** + * @brief 构造Update-SQL语句. + * + * @param sTableName 表名 + * @param mpColumns 列名/值对 + * @param sCondition where子语句 + * @return string Update-SQL语句 + */ + static string buildUpdateSQLNoSafe(const string &sTableName,const map > &mpColumns, const string &sCondition); + protected: /** * @brief copy contructor,只申明,不定义,保证不被使用 @@ -455,6 +565,17 @@ protected: */ TC_Mysql &operator=(const TC_Mysql &tcMysql); + /** + * @brief 构造SQL语句(批量). + * + * @param sTableName 表名 + * @param mpColumns 列名/值对 + * @return string insert-SQL语句 + */ + string buildSQL(const string &sTableName, const string &command, const map > &mpColumns); + string buildBatchSQL(const string &sTableName, const string &command, const map >> &mpColumns); + static string buildSQLNoSafe(const string &sTableName, const string &command, const map > &mpColumns); + static string buildBatchSQLNoSafe(const string &sTableName, const string &command, const map >> &mpColumns); private: diff --git a/util/include/util/tc_option.h b/util/include/util/tc_option.h index 0ffb8e3..459c127 100644 --- a/util/include/util/tc_option.h +++ b/util/include/util/tc_option.h @@ -54,6 +54,14 @@ public: */ void decode(int argc, char *argv[]); + /** + * @brief 解码(和上面decode的区别是: 只有命令, 没有签名的argv[0]) + * + * @param command 命令 + * + */ + void decode(const char *command); + /** * @brief 是否存在某个--标识的参数. * diff --git a/util/include/util/tc_pack.h b/util/include/util/tc_pack.h index ddf42a3..78fdb69 100644 --- a/util/include/util/tc_pack.h +++ b/util/include/util/tc_pack.h @@ -46,8 +46,7 @@ namespace tars */ struct TC_PackIn_Exception : public TC_Exception { - TC_PackIn_Exception(const string &buffer) : TC_Exception(buffer){}; - TC_PackIn_Exception(const string &buffer, int err) : TC_Exception(buffer, err){}; + TC_PackIn_Exception(const string &buffer) : TC_Exception(buffer){}; ~TC_PackIn_Exception() throw(){}; }; @@ -105,11 +104,10 @@ protected: return; } - if(_nPos > _buffer.length()) - { - assert(false); - //throw TC_PackIn_Exception("TC_PackIn cur has beyond error."); - } + // if(_nPos > _buffer.length()) + // { + // throw TC_PackIn_Exception("TC_PackIn cur has beyond error."); + // } if(_bInsert) { diff --git a/util/include/util/tc_platform.h b/util/include/util/tc_platform.h index ad23845..5e34454 100644 --- a/util/include/util/tc_platform.h +++ b/util/include/util/tc_platform.h @@ -39,6 +39,8 @@ #if TARGET_PLATFORM_WINDOWS #include #include +#else +#include #endif #endif diff --git a/util/include/util/tc_rbtree.h b/util/include/util/tc_rbtree.h index 9ef9ea1..2d75f18 100644 --- a/util/include/util/tc_rbtree.h +++ b/util/include/util/tc_rbtree.h @@ -42,7 +42,6 @@ namespace tars struct TC_RBTree_Exception : public TC_Exception { TC_RBTree_Exception(const string &buffer) : TC_Exception(buffer){}; - TC_RBTree_Exception(const string &buffer, int err) : TC_Exception(buffer, err){}; ~TC_RBTree_Exception() throw(){}; }; /** @@ -68,6 +67,11 @@ public: struct RBTreeLockIterator; struct RBTreeIterator; + friend struct Block; + friend struct BlockAllocator; + friend struct RBTreeLockIterator; + friend struct RBTreeLockItem; + /** * @brief 操作数据 */ @@ -1744,11 +1748,6 @@ public: protected: - friend class Block; - friend class BlockAllocator; - friend struct RBTreeLockIterator; - friend class RBTreeLockItem; - //禁止copy构造 TC_RBTree(const TC_RBTree &mcm); //禁止复制 diff --git a/util/include/util/tc_sem_mutex.h b/util/include/util/tc_sem_mutex.h index 468aedd..a5a485e 100644 --- a/util/include/util/tc_sem_mutex.h +++ b/util/include/util/tc_sem_mutex.h @@ -17,11 +17,15 @@ #ifndef __TC_SEM_MUTEX_H #define __TC_SEM_MUTEX_H +#include "util/tc_platform.h" + #if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS #include #include #include +#endif + #include "util/tc_lock.h" namespace tars @@ -37,13 +41,16 @@ namespace tars /** * @brief 信号量锁异常类 */ -struct TC_SemMutex_Exception : public TC_Lock_Exception +struct TC_SemMutex_Exception : public TC_Exception { - TC_SemMutex_Exception(const string &buffer) : TC_Lock_Exception(buffer){}; - TC_SemMutex_Exception(const string &buffer, int err) : TC_Lock_Exception(buffer, err){}; + TC_SemMutex_Exception(const string &buffer, int err) : TC_Exception(buffer, err){}; ~TC_SemMutex_Exception() throw() {}; }; +//锁名称统一用数字类型 +#if TARGET_PLATFORM_WINDOWS +typedef int key_t; +#endif /** * @brief 进程间锁, 提供两种锁机制:共享锁和排斥锁. * @@ -60,8 +67,13 @@ public: TC_SemMutex(); /** - * @brief 构造函数. - * + * @brief 析构函数 + */ + ~TC_SemMutex(); + + /** + * @brief 构造函数. + * * @param iKey, key * @throws TC_SemMutex_Exception */ @@ -95,14 +107,14 @@ public: * *@return int */ - int rlock() const; + void rlock() const; /** * @brief 解读锁. * * @return int */ - int unrlock() const; + void unrlock() const; /** * @brief 尝试读锁. @@ -112,59 +124,75 @@ public: bool tryrlock() const; /** - * @brief 加写锁. - * + * @brief 加写锁. + * * @return int */ - int wlock() const; + void wlock() const; /** * @brief 解写锁 */ - int unwlock() const; + void unwlock() const; /** - * @brief 尝试写锁. - * + * @brief 尝试写锁. + * * @throws TC_SemMutex_Exception * @return bool : 加锁成功则返回false, 否则返回false */ bool trywlock() const; /** - * @brief 写锁. - * + * @brief 写锁. + * * @return int, 0 正确 */ - int lock() const {return wlock();}; + void lock() const {wlock();}; /** * @brief 解写锁 */ - int unlock() const {return unwlock();}; + void unlock() const {unwlock();}; /** - * @brief 尝试解锁. - * + * @brief 尝试解锁. + * * @throws TC_SemMutex_Exception * @return int, 0 正确 */ bool trylock() const {return trywlock();}; +#if TARGET_PLATFORM_WINDOWS protected: - /** + void addWriter() const; + void removeWriter() const; + void unlockImp() const; + DWORD tryReadLockOnce() const ; +protected: + + mutable HANDLE _mutex; + mutable HANDLE _readEvent; + mutable HANDLE _writeEvent; + mutable unsigned _readers; + mutable unsigned _writersWaiting; + mutable unsigned _writers; +#else + /** * 信号量ID */ int _semID; +#endif /** * 信号量key */ key_t _semKey; + }; } #endif -#endif +//#endif diff --git a/util/include/util/tc_sha.h b/util/include/util/tc_sha.h index 00007e5..95b8593 100644 --- a/util/include/util/tc_sha.h +++ b/util/include/util/tc_sha.h @@ -52,7 +52,7 @@ namespace tars */ struct TC_SHA_Exception : public TC_Exception { - TC_SHA_Exception(const string &buffer, int err) : TC_Exception(buffer, err){}; + TC_SHA_Exception(const string &buffer, bool err) : TC_Exception(buffer, err){}; ~TC_SHA_Exception() throw(){}; }; diff --git a/util/include/util/tc_singleton.h b/util/include/util/tc_singleton.h index c67c3b8..615b852 100644 --- a/util/include/util/tc_singleton.h +++ b/util/include/util/tc_singleton.h @@ -93,8 +93,33 @@ public: } /** - * @brief 释放. - * + * @brief 释放. + * + * @param t + */ + static void destroy(T *t) + { + delete t; + } +}; + +template +class CreateUsingNew1 +{ +public: + /** + * @brief 创建. + * + * @return T* + */ + static T* create() + { + return new T; + } + + /** + * @brief 释放. + * * @param t */ static void destroy(T *t) @@ -194,14 +219,16 @@ struct NoDestroyLifetime template < typename T, - template class CreatePolicy = CreateUsingNew, - template class LifetimePolicy = DefaultLifetime + template class CreatePolicy = CreateUsingNew, + template class LifetimePolicy = DefaultLifetime > class TC_Singleton { public: typedef T instance_type; typedef volatile T volatile_type; + + typedef CreatePolicy TCreatePolicy; /** * @brief 获取实例 @@ -229,8 +256,6 @@ public: return (T*)_pInstance; } - virtual ~TC_Singleton(){}; - protected: static void destroySingleton() @@ -248,6 +273,7 @@ protected: protected: TC_Singleton(){} + virtual ~TC_Singleton(){}; TC_Singleton (const TC_Singleton &); TC_Singleton &operator=(const TC_Singleton &); }; diff --git a/util/include/util/tc_socket.h b/util/include/util/tc_socket.h index f5b2801..cadc49a 100644 --- a/util/include/util/tc_socket.h +++ b/util/include/util/tc_socket.h @@ -138,7 +138,7 @@ public: * * @return socket句柄 */ - int getfd() const { return _sock; } + SOCKET_TYPE getfd() const { return _sock; } /** * @brief socket是否有效. @@ -162,8 +162,7 @@ public: * @throws TC_Socket_Exception * @return */ - void getPeerName(string &sPeerAddress, uint16_t &iPeerPort); - + void getPeerName(string &sPeerAddress, uint16_t &iPeerPort) const; #if TARGET_PLATFORM_LINUX||TARGET_PLATFORM_IOS @@ -227,7 +226,7 @@ public: * @param level socket操作层次, 默认是socket层 * @return int */ - int setSockOpt(int opt, const void *pvOptVal, socklen_t optLen, int level = SOL_SOCKET); + int setSockOpt(int opt, const void *pvOptVal, SOCKET_LEN_TYPE optLen, int level = SOL_SOCKET); /** * @brief 获取socket选项值. @@ -238,7 +237,7 @@ public: * @param level socket操作层次, 默认是socket层 * @return socket选项值 */ - int getSockOpt(int opt, void *pvOptVal, socklen_t &optLen, int level = SOL_SOCKET); + int getSockOpt(int opt, void *pvOptVal, SOCKET_LEN_TYPE &optLen, int level = SOL_SOCKET) const; /** * @brief accept. @@ -248,7 +247,7 @@ public: * @param iSockLen pstSockAddr长度 * @return int : > 0 ,客户端socket; <0, 出错 */ - int accept(TC_Socket &tcSock, struct sockaddr *pstSockAddr, socklen_t &iSockLen); + SOCKET_TYPE accept(TC_Socket &tcSock, struct sockaddr *pstSockAddr, SOCKET_LEN_TYPE &iSockLen); /** * @brief 绑定,对AF_INET的socket有效. @@ -299,6 +298,16 @@ public: */ void listen(int connBackLog); + /** + * @brief 绑定. + * + * @param pstBindAddr 需要绑定的地址 + * @param iAddrLen pstBindAddr指向的结构的长度 + * @throws TC_Socket_Exception + * @return + */ + void bind(const struct sockaddr *pstBindAddr, SOCKET_LEN_TYPE iAddrLen); + /** * @brief 接收数据(一般用于tcp). * @@ -341,7 +350,7 @@ public: * @param iFlag 标示 * @return int 接收了的数据长度 */ - int recvfrom(void *pvBuf, size_t iLen, struct sockaddr *pstFromAddr, socklen_t &iFromLen, int iFlags = 0); + int recvfrom(void *pvBuf, size_t iLen, struct sockaddr *pstFromAddr, SOCKET_LEN_TYPE &iFromLen, int iFlags = 0); /** * @brief 发送数据(一般用于udp). @@ -365,7 +374,7 @@ public: * @param iFlag 标示 * @return int : >0 发送的数据长度 ;<=0, 出错 */ - int sendto(const void *pvBuf, size_t iLen, struct sockaddr *pstToAddr, socklen_t iToLen, int iFlags = 0); + int sendto(const void *pvBuf, size_t iLen, struct sockaddr *pstToAddr, SOCKET_LEN_TYPE iToLen, int iFlags = 0); /** * @brief 关闭. @@ -429,7 +438,7 @@ public: * @throws TC_Socket_Exception * @return recv buffer 的大小 */ - int getRecvBufferSize(); + int getRecvBufferSize() const; /** * @brief 设置recv buffer 大小. @@ -443,7 +452,7 @@ public: * @param 发送buffer大小 * @throws TC_Socket_Exception */ - int getSendBufferSize(); + int getSendBufferSize() const; /** * @brief 设置发送buffer大小. @@ -458,14 +467,6 @@ public: */ void ignoreSigPipe(); - /** - * @brief 获取本地所有ip. - * - * @throws TC_Socket_Exception - * @return 本地所有ip - */ - static vector getLocalHosts(int domain = AF_INET); - /** * @brief 设置socket方式. * @@ -474,11 +475,18 @@ public: * @throws TC_Socket_Exception * @return */ - static void setblock(int fd, bool bBlock); + static void setblock(SOCKET_TYPE fd, bool bBlock); + + /** + * @brief 获取本地所有ip. + * + * @throws TC_Socket_Exception + * @return 本地所有ip + */ + static vector getLocalHosts(int domain = AF_INET); /** * @brief 生成管道,抛出异常时会关闭fd. - * * @param fds 句柄 * @param bBlock true, 阻塞; false, 非阻塞 * @throws TC_Socket_Exception @@ -519,16 +527,6 @@ public: #undef IPv6_ADDRESS_CHAR } - /** - * @brief 绑定. - * - * @param pstBindAddr 需要绑定的地址 - * @param iAddrLen pstBindAddr指向的结构的长度 - * @throws TC_Socket_Exception - * @return - */ - void bind(struct sockaddr *pstBindAddr, socklen_t iAddrLen); - /** * @brief 解析地址, 从字符串(ip或域名)端口, 解析到sockaddr_in结构. * @@ -561,7 +559,6 @@ public: */ static void closeSocketNoThrow(int); - #if 0 /** * @brief no implementation. @@ -585,7 +582,7 @@ protected: * @param serverLen pstServerAddr指向的结构的长度 * @return int */ - int connect(const struct sockaddr *pstServerAddr, socklen_t serverLen); + int connect(const struct sockaddr *pstServerAddr, SOCKET_LEN_TYPE serverLen); /** * @brief 获取对点的地址. @@ -595,7 +592,7 @@ protected: * @throws TC_Socket_Exception * @return */ - void getPeerName(struct sockaddr *pstPeerAddr, socklen_t &iPeerLen) const; + void getPeerName(struct sockaddr *pstPeerAddr, SOCKET_LEN_TYPE &iPeerLen) const; /** * @brief 获取自己的的ip和端口. @@ -605,12 +602,9 @@ protected: * @throws TC_Socket_Exception * @return */ - void getSockName(struct sockaddr *pstSockAddr, socklen_t &iSockLen) const; - -private: + void getSockName(struct sockaddr *pstSockAddr, SOCKET_LEN_TYPE &iSockLen) const; protected: - // static const int INVALID_SOCKET = -1; /** * socket句柄 diff --git a/util/include/util/tc_spin_lock.h b/util/include/util/tc_spin_lock.h index d396723..1bb3ec3 100755 --- a/util/include/util/tc_spin_lock.h +++ b/util/include/util/tc_spin_lock.h @@ -2,9 +2,7 @@ #ifndef __TC_SPIN_LOCK_H #define __TC_SPIN_LOCK_H -//#include #include -//#include #include using namespace std; diff --git a/util/include/util/tc_squeue.h b/util/include/util/tc_squeue.h index 5a14a43..d772967 100644 --- a/util/include/util/tc_squeue.h +++ b/util/include/util/tc_squeue.h @@ -18,13 +18,14 @@ #define __TC_SQueue_H__ #include -#include +// #include #include #include #include #include #include - +#include +#include "util/tc_ex.h" /** * 结构化的queue,在一边读一边写的情况下可以不用加锁,是线程(进程)安全的 * 如果多个同时读写,需要加锁 @@ -34,231 +35,215 @@ namespace tars { +/** + * @brief 异常 + */ +struct TC_SQueue_Exception : public TC_Exception +{ + TC_SQueue_Exception(const std::string &buffer) : TC_Exception(buffer){}; + ~TC_SQueue_Exception() throw(){}; +}; + class TC_SQueue { public: - TC_SQueue() {_header = NULL;_data = NULL;} - ~TC_SQueue() {_header = NULL;_data = NULL;} + TC_SQueue() {_header = NULL;_data = NULL;} + ~TC_SQueue() {_header = NULL;_data = NULL;} - void attach(char* pBuf, unsigned long iBufSize) throw (TC_Exception) - { - if(iBufSize <= sizeof(Header)+MarkLen+ReserveLen) - { - throw TC_Exception("TC_SQueue::attach fail:iBufSize is too small"); - } + void attach(char* pBuf, size_t iBufSize) + { + if(iBufSize <= sizeof(Header)+MarkLen+ReserveLen) { + throw TC_SQueue_Exception("TC_SQueue::attach fail:iBufSize is too small"); + } - _header = (Header *)pBuf; - _data = pBuf+sizeof(Header); - if(_header->iBufSize != iBufSize - sizeof(Header)) - throw TC_Exception("TC_SQueue::attach fail: iBufSize != iBufSize - sizeof(Header);"); - if(_header->iReserveLen != ReserveLen) - throw TC_Exception("TC_SQueue::attach fail: iReserveLen != ReserveLen"); - if(_header->iBegin >= _header->iBufSize) - throw TC_Exception("TC_SQueue::attach fail: iBegin > iBufSize - sizeof(Header);"); - if(_header->iEnd > iBufSize - sizeof(Header)) - throw TC_Exception("TC_SQueue::attach fail: iEnd > iBufSize - sizeof(Header);"); - } + _header = (Header *)pBuf; + _data = pBuf+sizeof(Header); + if(_header->iBufSize != iBufSize - sizeof(Header)) + throw TC_SQueue_Exception("TC_SQueue::attach fail: iBufSize != iBufSize - sizeof(Header);"); + if(_header->iReserveLen != ReserveLen) + throw TC_SQueue_Exception("TC_SQueue::attach fail: iReserveLen != ReserveLen"); + if(_header->iBegin >= _header->iBufSize) + throw TC_SQueue_Exception("TC_SQueue::attach fail: iBegin > iBufSize - sizeof(Header);"); + if(_header->iEnd > iBufSize - sizeof(Header)) + throw TC_SQueue_Exception("TC_SQueue::attach fail: iEnd > iBufSize - sizeof(Header);"); + } - void create(char* pBuf, unsigned long iBufSize) throw (TC_Exception) - { - if(iBufSize <= sizeof(Header)+MarkLen+ReserveLen) - { - throw TC_Exception("TC_SQueue::create fail:iBufSize is too small"); - } + void create(char* pBuf, size_t iBufSize) + { + if(iBufSize <= sizeof(Header)+MarkLen+ReserveLen) { + throw TC_SQueue_Exception("TC_SQueue::create fail:iBufSize is too small"); + } - _header = (Header *)pBuf; - _data = pBuf+sizeof(Header); - _header->iBufSize = iBufSize - sizeof(Header); - _header->iReserveLen = ReserveLen; - _header->iBegin = 0; - _header->iEnd = 0; - _header->iNum = 0; - } + _header = (Header *)pBuf; + _data = pBuf+sizeof(Header); + _header->iBufSize = iBufSize - sizeof(Header); + _header->iReserveLen = ReserveLen; + _header->iBegin = 0; + _header->iEnd = 0; + _header->iNum = 0; + } - bool pop(string& buffer) - { - unsigned long iEnd=_header->iEnd; - unsigned tmp_num; - if(_header->iBegin == iEnd) - { + bool pop(std::string& buffer) + { + size_t iEnd=_header->iEnd; + size_t tmp_num; + if(_header->iBegin == iEnd) { _header->iNum = 0; - return false; + return false; } - else if(_header->iBeginiBegin+MarkLen < iEnd); - unsigned long len = GetLen(_data+_header->iBegin); - assert(_header->iBegin+MarkLen+len <= iEnd); - - buffer.assign(_data+_header->iBegin+MarkLen, len); - _header->iBegin += len+MarkLen; - tmp_num = _header->iNum; - if(tmp_num > 0) - _header->iNum = tmp_num-1; - } - else - { - // 被分段 - assert(iEnd+ReserveLen <= _header->iBegin); - unsigned long len = 0; - unsigned long new_begin = 0; - char *data_from = NULL; - char *data_to = NULL; - assert(_header->iBegin < _header->iBufSize); - // 长度字段也被分段 - if(_header->iBegin+MarkLen > _header->iBufSize) - { - char tmp[16]; - memcpy(tmp,_data+_header->iBegin,_header->iBufSize-_header->iBegin); - memcpy(tmp+_header->iBufSize-_header->iBegin,_data,_header->iBegin+MarkLen-_header->iBufSize); - len = GetLen(tmp); - data_from = _data+(_header->iBegin+MarkLen-_header->iBufSize); // - new_begin = _header->iBegin+MarkLen-_header->iBufSize+len; - assert(new_begin <= iEnd); - } - else - { - len = GetLen(_data+_header->iBegin); - data_from = _data+_header->iBegin+MarkLen; - if(data_from == _data+_header->iBufSize) data_from = _data; - if(_header->iBegin+MarkLen+len < _header->iBufSize) { - new_begin = _header->iBegin+MarkLen+len; - } else { // 数据被分段 - new_begin = _header->iBegin+MarkLen+len-_header->iBufSize; - assert(new_begin <= iEnd); - } - } - data_to = _data+new_begin; + else if(_header->iBeginiBegin+MarkLen < iEnd); + size_t len = GetLen(_data+_header->iBegin); + assert(_header->iBegin+MarkLen+len <= iEnd); + + buffer.assign(_data+_header->iBegin+MarkLen, len); + _header->iBegin += len+MarkLen; + tmp_num = _header->iNum; + if(tmp_num > 0) + _header->iNum = tmp_num-1; + } else { + // 被分段 + assert(iEnd+ReserveLen <= _header->iBegin); + size_t len = 0; + size_t new_begin = 0; + char *data_from = NULL; + char *data_to = NULL; + assert(_header->iBegin < _header->iBufSize); + // 长度字段也被分段 + if(_header->iBegin+MarkLen > _header->iBufSize) { + char tmp[16]; + memcpy(tmp,_data+_header->iBegin,_header->iBufSize-_header->iBegin); + memcpy(tmp+_header->iBufSize-_header->iBegin,_data,_header->iBegin+MarkLen-_header->iBufSize); + len = GetLen(tmp); + data_from = _data+(_header->iBegin+MarkLen-_header->iBufSize); // + new_begin = _header->iBegin+MarkLen-_header->iBufSize+len; + assert(new_begin <= iEnd); + } else { + len = GetLen(_data+_header->iBegin); + data_from = _data+_header->iBegin+MarkLen; + if(data_from == _data+_header->iBufSize) data_from = _data; + if(_header->iBegin+MarkLen+len < _header->iBufSize) { + new_begin = _header->iBegin+MarkLen+len; + } else { // 数据被分段 + new_begin = _header->iBegin+MarkLen+len-_header->iBufSize; + assert(new_begin <= iEnd); + } + } + data_to = _data+new_begin; - if(data_to > data_from) - { - assert(data_to - data_from == (long)len); - buffer.assign(data_from, len); - } - else - { - buffer.assign(data_from, _data+_header->iBufSize-data_from); - buffer.append(_data, data_to-_data); - assert(_header->iBufSize-(data_from-data_to)== len); - } - _header->iBegin = new_begin; - tmp_num = _header->iNum; - if(tmp_num > 0) - _header->iNum = tmp_num-1; - } + if(data_to > data_from) { + assert(data_to - data_from == (long)len); + buffer.assign(data_from, len); + } else { + buffer.assign(data_from, _data+_header->iBufSize-data_from); + buffer.append(_data, data_to-_data); + assert(_header->iBufSize-(data_from-data_to)== len); + } + _header->iBegin = new_begin; + tmp_num = _header->iNum; + if(tmp_num > 0) + _header->iNum = tmp_num-1; + } - return true; - } - - bool push(const string& buffer) - { - return push(buffer.c_str(), buffer.length()); - } - // 写端使用 - bool push(const char *buffer,unsigned long len) - { - if(len == 0) return true; - unsigned long iBegin = _header->iBegin; - if(_header->iEnd == iBegin) - { + return true; + } + + bool push(const std::string& buffer) + { + return push(buffer.c_str(), buffer.length()); + } + // 写端使用 + bool push(const char *buffer, size_t len) + { + if(len == 0) return true; + size_t iBegin = _header->iBegin; + if(_header->iEnd == iBegin) { _header->iNum = 0; - if(MarkLen+len+ReserveLen>_header->iBufSize) - return false; - } - else if(_header->iEnd > iBegin) - { - assert(iBegin+MarkLen < _header->iEnd); - if(_header->iBufSize - _header->iEnd + iBegin < MarkLen+len+ReserveLen) - return false; - } - else - { - assert(_header->iEnd+ReserveLen <= iBegin); - if(iBegin - _header->iEnd < MarkLen+len+ReserveLen) - return false; - } + if(MarkLen+len+ReserveLen>_header->iBufSize) + return false; + } else if(_header->iEnd > iBegin) { + assert(iBegin+MarkLen < _header->iEnd); + if(_header->iBufSize - _header->iEnd + iBegin < MarkLen+len+ReserveLen) + return false; + } else { + assert(_header->iEnd+ReserveLen <= iBegin); + if(iBegin - _header->iEnd < MarkLen+len+ReserveLen) + return false; + } - // 长度字段被分段 - if(_header->iEnd+MarkLen > _header->iBufSize) - { - char tmp[16]; SetLen(tmp,len); - memcpy(_data+_header->iEnd,tmp,_header->iBufSize-_header->iEnd); - memcpy(_data,tmp+_header->iBufSize-_header->iEnd,_header->iEnd+MarkLen-_header->iBufSize); - memcpy(_data+_header->iEnd+MarkLen-_header->iBufSize,buffer,len); - _header->iEnd = len+_header->iEnd+MarkLen-_header->iBufSize; - assert(_header->iEnd+ReserveLen <= iBegin); - _header->iNum++; - } - // 数据被分段 - else if(_header->iEnd+MarkLen+len > _header->iBufSize) - { - SetLen(_data+_header->iEnd,len); - memcpy(_data+_header->iEnd+MarkLen,buffer,_header->iBufSize-_header->iEnd-MarkLen); - memcpy(_data,buffer+_header->iBufSize-_header->iEnd-MarkLen,len-(_header->iBufSize-_header->iEnd-MarkLen)); - _header->iEnd = len-(_header->iBufSize-_header->iEnd-MarkLen); - assert(_header->iEnd+ReserveLen <= iBegin); - _header->iNum++; - } - else - { - SetLen(_data+_header->iEnd,len); - memcpy(_data+_header->iEnd+MarkLen,buffer,len); - _header->iEnd = (_header->iEnd+MarkLen+len)%_header->iBufSize; - _header->iNum++; - } - return true; - } + // 长度字段被分段 + if(_header->iEnd+MarkLen > _header->iBufSize) { + char tmp[16]; SetLen(tmp,len); + memcpy(_data+_header->iEnd,tmp,_header->iBufSize-_header->iEnd); + memcpy(_data,tmp+_header->iBufSize-_header->iEnd,_header->iEnd+MarkLen-_header->iBufSize); + memcpy(_data+_header->iEnd+MarkLen-_header->iBufSize,buffer,len); + _header->iEnd = len+_header->iEnd+MarkLen-_header->iBufSize; + assert(_header->iEnd+ReserveLen <= iBegin); + _header->iNum++; + } + // 数据被分段 + else if(_header->iEnd+MarkLen+len > _header->iBufSize){ + SetLen(_data+_header->iEnd,len); + memcpy(_data+_header->iEnd+MarkLen,buffer,_header->iBufSize-_header->iEnd-MarkLen); + memcpy(_data,buffer+_header->iBufSize-_header->iEnd-MarkLen,len-(_header->iBufSize-_header->iEnd-MarkLen)); + _header->iEnd = len-(_header->iBufSize-_header->iEnd-MarkLen); + assert(_header->iEnd+ReserveLen <= iBegin); + _header->iNum++; + } else { + SetLen(_data+_header->iEnd,len); + memcpy(_data+_header->iEnd+MarkLen,buffer,len); + _header->iEnd = (_header->iEnd+MarkLen+len)%_header->iBufSize; + _header->iNum++; + } + return true; + } - // 读端使用 - //bool isEmpty() const {unsigned long iEnd=_header->iEnd;return _header->iBegin == iEnd;} - bool empty() const {unsigned long iEnd=_header->iEnd;return _header->iBegin == iEnd;} - // 写端使用 - bool full(unsigned long len) const + // 读端使用 + //bool isEmpty() const {size_t iEnd=_header->iEnd;return _header->iBegin == iEnd;} + bool empty() const {size_t iEnd=_header->iEnd;return _header->iBegin == iEnd;} + // 写端使用 + bool full(size_t len) const + { + size_t iBegin = _header->iBegin; + if(len==0) return false; + + if(_header->iEnd == iBegin) { + if(len+MarkLen+ReserveLen > _header->iBufSize) return true; + return false; + } else if(_header->iEnd > iBegin) { + assert(iBegin+MarkLen < _header->iEnd); + return _header->iBufSize - _header->iEnd + iBegin < MarkLen+len+ReserveLen; + } + assert(_header->iEnd+ReserveLen <= iBegin); + return (iBegin - _header->iEnd < MarkLen+len+ReserveLen); + } + // 返回队列里的元素数量,不一定绝对准确,只能作为参考 + size_t size() const { - unsigned long iBegin = _header->iBegin; - if(len==0) return false; - - if(_header->iEnd == iBegin) - { - if(len+MarkLen+ReserveLen > _header->iBufSize) return true; - return false; - } - else if(_header->iEnd > iBegin) - { - assert(iBegin+MarkLen < _header->iEnd); - return _header->iBufSize - _header->iEnd + iBegin < MarkLen+len+ReserveLen; - } - assert(_header->iEnd+ReserveLen <= iBegin); - return (iBegin - _header->iEnd < MarkLen+len+ReserveLen); - } - // 返回队列里的元素数量,不一定绝对准确,只能作为参考 - unsigned long size() const - { - if (empty()) - { - _header->iNum = 0; + if (empty()) { + _header->iNum = 0; } return _header->iNum; } private: - unsigned long GetLen(char *buf) {unsigned long u; memcpy((void *)&u,buf,MarkLen); return u;} - void SetLen(char *buf,unsigned long u) {memcpy(buf,(void *)&u,MarkLen);} + size_t GetLen(char *buf) {size_t u; memcpy((void *)&u,buf,MarkLen); return u;} + void SetLen(char *buf, size_t u) {memcpy(buf,(void *)&u,MarkLen);} private: - const static unsigned long ReserveLen = 8; - const static unsigned long MarkLen = sizeof(unsigned long); - struct Header - { - unsigned long iBufSize; - unsigned long iReserveLen; // must be 8 - unsigned long iBegin; - unsigned long iEnd; - unsigned long iNum; // 增加一个数量标记,不一定准确 - }; + const static size_t ReserveLen = 8; + const static size_t MarkLen = sizeof(size_t); + struct Header + { + size_t iBufSize; + size_t iReserveLen; // must be 8 + size_t iBegin; + size_t iEnd; + size_t iNum; // 增加一个数量标记,不一定准确 + }; - Header *_header; - char *_data; + Header *_header; + char *_data; }; } diff --git a/util/include/util/tc_thread_cond.h b/util/include/util/tc_thread_cond.h index c359dff..83a2c22 100644 --- a/util/include/util/tc_thread_cond.h +++ b/util/include/util/tc_thread_cond.h @@ -17,7 +17,6 @@ #ifndef _TC_THREAD_COND_H #define _TC_THREAD_COND_H - #include #include #include diff --git a/util/include/util/tc_thread_pool.h b/util/include/util/tc_thread_pool.h index 2d56217..d584acc 100644 --- a/util/include/util/tc_thread_pool.h +++ b/util/include/util/tc_thread_pool.h @@ -20,7 +20,6 @@ #include "util/tc_platform.h" #include "util/tc_thread.h" #include -#include #include #include #include diff --git a/util/include/util/tc_thread_rwlock.h b/util/include/util/tc_thread_rwlock.h index 8160601..2a6d6e5 100644 --- a/util/include/util/tc_thread_rwlock.h +++ b/util/include/util/tc_thread_rwlock.h @@ -31,22 +31,11 @@ namespace tars /** * @file tc_thread_rwlock.h * @brief 读写锁 - * @author jarodruan@upchina.com + * @author ruanshudong@qq.com */ ///////////////////////////////////////////////// -/** - * @brief读写锁异常类 - */ -// struct TC_ThreadRW_Exception : public TC_Exception -// { -// TC_ThreadRW_Exception(const string &buffer) : TC_Exception(buffer){}; -// TC_ThreadRW_Exception(const string &buffer, bool err) : TC_Exception(buffer, err){}; -// ~TC_ThreadRW_Exception() throw() {}; -// }; - - class TC_ThreadRWLocker { protected: diff --git a/util/include/util/tc_timeout_queue_map.h b/util/include/util/tc_timeout_queue_map.h index 1a678d4..dbef74c 100644 --- a/util/include/util/tc_timeout_queue_map.h +++ b/util/include/util/tc_timeout_queue_map.h @@ -212,7 +212,7 @@ private: void delFromNoSend(uint16_t id); protected: - uint32_t _uniqId; + uint32_t _uniqId; uint16_t _dataSize; @@ -314,7 +314,7 @@ template uint32_t TC_TimeoutQueueMap::generateId() { _freeTail = 0; } - //cerr<<"generateId:"< #include #include -#include #include "util/tc_autoptr.h" -// #include "util/tc_monitor.h" +#include "util/tc_monitor.h" +// #include "util/tc_functor.h" #include "util/tc_timeprovider.h" using namespace std; @@ -71,8 +71,8 @@ public: typename data_type::iterator dataIter; }; /** - * @brief 超时队列,缺省5s超时. - * + * @brief 超时队列,缺省5s超时. + * * @param timeout 超时设定时间 * @param size */ @@ -113,8 +113,8 @@ public: } /** - * @brief 获取指定id的数据. - * + * @brief 获取指定id的数据. + * * @param id 指定的数据的id * @param T 指定id的数据 * @return bool get的结果 @@ -122,17 +122,17 @@ public: bool get(uint32_t uniqId, T & t,bool bErase = true); /** - * @brief 删除. - * - * @param uniqId 要删除的数据的id + * @brief 删除. + * + * @param uniqId 要删除的数据的id * @param T 被删除的数据 * @return bool 删除结果 */ bool erase(uint32_t uniqId, T & t); /** - * @brief 设置消息到队列尾端. - * + * @brief 设置消息到队列尾端. + * * @param ptr 要插入到队列尾端的消息 * @param uniqId 序列号 * @param timeout 超时时间 @@ -151,9 +151,9 @@ public: bool timeout(T & t); /** - * @brief 删除超时的数据,并用df对数据做处理 + * @brief 删除超时的数据,并用df对数据做处理 */ - void timeout(const data_functor &df); + void timeout(data_functor &df); /** * @brief 队列中的数据. @@ -163,7 +163,7 @@ public: size_t size() const { return _data.size(); } protected: - uint32_t _uniqId; + atomic _uniqId; data_type _data; time_type _time; send_type _send; @@ -296,7 +296,7 @@ template bool TC_TimeoutQueueNew::timeout(T & t) return true; } -template void TC_TimeoutQueueNew::timeout(const data_functor& df) +template void TC_TimeoutQueueNew::timeout(data_functor &df) { while(true) { diff --git a/util/include/util/tc_timer.h b/util/include/util/tc_timer.h new file mode 100644 index 0000000..ac16e70 --- /dev/null +++ b/util/include/util/tc_timer.h @@ -0,0 +1,217 @@ +#ifndef __TC_TIMER_H_ +#define __TC_TIMER_H_ + +#include +#include +#include +#include +#include + +#include "util/tc_thread_pool.h" +#include "util/tc_timeprovider.h" +#include "util/tc_cron.h" + +namespace tars +{ +///////////////////////////////////////////////// +/** + * @file tc_timer.h + * @brief 定时器类, 用于设置定时器, 可以定时回调function + * 使用说明: + * 设定函数的定时时间, 定时时间到, 则回调 + * 可以设定回调线程数, 默认只有一个, 底层用tc_thread_pool实现线程池的 + * 任何可以丢进tc_thread_pool的function对象(std::bind的对象), 都可以丢该tc_timer + * + * @author ruanshuodong@qq.com + */ +///////////////////////////////////////////////// + +/** + * @brief 定时器类 + */ +class TC_Timer +{ +protected: + struct Func + { + Func( uint64_t fireMillseconds) : _fireMillseconds(fireMillseconds) { } + + std::function _func; + uint64_t _fireMillseconds = 0; //事件触发时间 + TC_Cron _cron; //crontab + }; + + typedef std::unordered_set EVENT_SET; + + typedef std::unordered_map> MAP_EVENT; + + typedef map> MAP_TIMER; + +public: + + /** + * 析构 + */ + ~TC_Timer(); + + /** + * 系统定时器 + * @param numThread, 回调线程数, 默认是1个 + */ + void startTimer(int numThread = 1); + + /** + * 停止定时器 + * 如果当前有定时任务正在执行, 会等执行完毕 + */ + void stopTimer(); + + /** + * @brief 指定fireMillseconds时间执行 + * @param fireMillseconds, 触发时间(毫秒) + * @return 返回事件Id + */ + template + int64_t postAtTime(int64_t fireMillseconds, F &&f, Args &&... args) + { + return post(create(fireMillseconds, 0, f, args...)); + } + + /** + * @brief 延时delayMillseconds时间执行 + * @param delayMillseconds, 延时时间 + * @return 返回事件Id + */ + template + int64_t postDelayed(int64_t delayMillseconds, F &&f, Args &&... args) + { + //定义返回值类型 + using RetType = decltype(f(args...)); + + auto task = std::make_shared < std::packaged_task + < RetType() >> (std::bind(std::forward(f), std::forward(args)...)); + + uint64_t fireMillseconds = TC_TimeProvider::getInstance()->getNowMs() + delayMillseconds; + + return post(create(fireMillseconds, 0,"", f, args...)); + } + + /** + * @brief 重复repeatTime(毫秒)执行一次, 注意repeat是上一次执行完, 才会重新触发下一次事件的计时 + * @param repeatTime, 重复时间 + * @param execNow, 第一次是否马上执行 + * @return 返回事件Id + */ + template + int64_t postRepeated(int64_t repeatTime, bool execNow, F &&f, Args &&... args) + { + //定义返回值类型 + using RetType = decltype(f(args...)); + + auto task = std::make_shared < std::packaged_task + < RetType() >> (std::bind(std::forward(f), std::forward(args)...)); + + uint64_t fireMillseconds; + + if(execNow) { + fireMillseconds = TC_TimeProvider::getInstance()->getNowMs(); + }else { + fireMillseconds = TC_TimeProvider::getInstance()->getNowMs() + repeatTime; + } + + return post(create(fireMillseconds, repeatTime,"", f, args...)); + } + + /** + * @brief + * @param cronexpr, crontab 语法 ,具体例子参考 tc_cron.h + * @return 返回事件Id + */ + // CRON Description + // * * * * * * Every second + // */5 * * * * * Every 5 seconds + // 0 */5 */2 * * * Every 5 minutes, every 2 hours + // 0 */2 */2 * */2 */2 Every 2 minutes, every 2 hours, every 2 days of the week, every 2 months + // 0 15 10 * * * 10:15 AM every day + // 0 0/5 14 * * * Every 5 minutes starting at 2 PM and ending at 2:55 PM, every day + // 0 10,44 14 * 3 WED 2:10 PM and at 2:44 PM every Wednesday of March + // 0 15 10 * * MON-FRI 10:15 AM every Monday, Tuesday, Wednesday, Thursday and Friday + // 0 0 12 1/5 * * 12 PM every 5 days every month, starting on the first day of the month + // 0 11 11 11 11 * Every November 11th at 11:11 AM + template + int64_t postCron(const string&cronexpr, F&& f, Args&&... args) + { + //定义返回值类型 + using RetType = decltype(f(args...)); + + auto task = std::make_shared < std::packaged_task + < RetType() >> (std::bind(std::forward(f), std::forward(args)...)); + + return post(create(0, 0,cronexpr, f, args...)); + } + + /** + * 删除事件 + * @param uniqId + */ + void erase(int64_t uniqId); + +protected: + template + shared_ptr create(int64_t fireMillseconds, int64_t repeatTime, const string & cronexpr, F &&f, Args &&... args) + { + //定义返回值类型 + using RetType = decltype(f(args...)); + + auto task = std::make_shared>(std::bind(std::forward(f), std::forward(args)...)); + + shared_ptr fPtr = std::make_shared(fireMillseconds); + + if (!cronexpr.empty()) + { + fPtr->_cron = TC_Cron::makecron(cronexpr); + fPtr->_fireMillseconds = TC_Cron::nextcron(fPtr->_cron) * 1000; + } + + fPtr->_func = [task, this, fPtr, repeatTime]() { + (*task)(); + task->reset(); + if (fPtr->_cron.isset) + { + fPtr->_fireMillseconds = TC_Cron::nextcron(fPtr->_cron,fPtr->_fireMillseconds/1000) * 1000; + this->post(fPtr); + } + else if(repeatTime > 0) + { + fPtr->_fireMillseconds = TC_TimeProvider::getInstance()->getNowMs() + repeatTime; + this->post(fPtr); + } + }; + + return fPtr; + } + + int64_t post(const shared_ptr &event); + + void fireEvent(const EVENT_SET &el); + + void run(); + +protected: + std::mutex _mutex; + + std::condition_variable _cond; + + bool _terminate = false; + + MAP_EVENT _mapEvent; //id, 事件 + + MAP_TIMER _mapTimer; //时间, 事件 + + TC_ThreadPool _tpool; +}; + +} + +#endif + diff --git a/util/src/tc_base64.cpp b/util/src/tc_base64.cpp index 35c6da3..e7f460d 100644 --- a/util/src/tc_base64.cpp +++ b/util/src/tc_base64.cpp @@ -54,7 +54,7 @@ string TC_Base64::encode(const string &data, bool bChangeLine/* = false*/) pDst = new char[iBufSize]; if(pDst == NULL) return ""; - int iDstLen = encode((unsigned char*)data.c_str(), data.size(), pDst, bChangeLine); + size_t iDstLen = encode((unsigned char*)data.c_str(), (int)data.size(), pDst, bChangeLine); string ret(pDst,iDstLen); delete [] pDst; return ret; @@ -68,21 +68,37 @@ string TC_Base64::decode(const string &data) pDst = new unsigned char[data.size()]; if(pDst == NULL) return ""; - int iDstLen = decode(data.c_str(), data.size(), pDst); + size_t iDstLen = decode(data.c_str(), data.size(), pDst); string ret((char*)pDst,iDstLen); delete [] pDst; return ret; } -int TC_Base64::encode(const unsigned char* pSrc, int nSrcLen, char* pDst, bool bChangeLine/* = false*/) +string TC_Base64::encode(const char *buffer, size_t length, bool bChangeLine) +{ + if(buffer == NULL || length == 0) + return ""; + //设原始串长度为a,结果串中算上回车换行及'/0',最终长度为(a/3+1)*4+(a/3+1)*4*2/76+1,约为1.369*a+6 + char *pDst = NULL; + int iBufSize = (int)(length*1.4) + 6; + pDst = new char[iBufSize]; + if(pDst == NULL) + return ""; + size_t iDstLen = encode((unsigned char*)buffer, length, pDst, bChangeLine); + string ret(pDst,iDstLen); + delete [] pDst; + return ret; +} + +int TC_Base64::encode(const unsigned char* pSrc, size_t nSrcLen, char* pDst, bool bChangeLine/* = false*/) { unsigned char c1, c2, c3; int nDstLen = 0; int nLineLen = 0; - int nDiv = nSrcLen / 3; - int nMod = nSrcLen % 3; + size_t nDiv = nSrcLen / 3; + size_t nMod = nSrcLen % 3; // 每次取3个字节,编码成4个字符 - for (int i = 0; i < nDiv; i ++) + for (size_t i = 0; i < nDiv; i ++) { c1 = *pSrc++; c2 = *pSrc++; @@ -131,11 +147,11 @@ int TC_Base64::encode(const unsigned char* pSrc, int nSrcLen, char* pDst, bool b } -int TC_Base64::decode(const char* pSrc, int nSrcLen, unsigned char* pDst) +int TC_Base64::decode(const char* pSrc, size_t nSrcLen, unsigned char* pDst) { int nDstLen; // 输出的字符计数 - int nValue; // 解码用到的整数 - int i; + size_t nValue; // 解码用到的整数 + size_t i; i = 0; nDstLen = 0; @@ -150,7 +166,7 @@ int TC_Base64::decode(const char* pSrc, int nSrcLen, unsigned char* pDst) nValue = DeBase64Tab[int(*pSrc++)] << 18; nValue += DeBase64Tab[int(*pSrc++)] << 12; - *pDst++ = (nValue & 0x00ff0000) >> 16; + *pDst++ = (unsigned char)((nValue & 0x00ff0000) >> 16); nDstLen++; if (*pSrc != '=') { diff --git a/util/src/tc_clientsocket.cpp b/util/src/tc_clientsocket.cpp index 164e4c0..517e5a5 100644 --- a/util/src/tc_clientsocket.cpp +++ b/util/src/tc_clientsocket.cpp @@ -32,12 +32,12 @@ TC_Endpoint::TC_Endpoint() _grid = 0; _qos = 0; _weight = -1; - _weighttype = 0; - _authType = 0; - _isIPv6 = false; + _weighttype = 0; + _authType = 0; + _isIPv6 = TC_Socket::addressIsIPv6(_host); } -void TC_Endpoint::init(const string& host, int port, int timeout, int type, int grid, int qos, int weight, unsigned int weighttype, int authType) +void TC_Endpoint::init(const string& host, int port, int timeout, EType type, int grid, int qos, int weight, unsigned int weighttype, int authType) { _host = host; _port = port; @@ -219,10 +219,10 @@ void TC_Endpoint::parse(const string &str) break; } default: - { + { ///throw TC_EndpointParse_Exception("TC_Endpoint::parse error : " + str); - } - } + } + } } if(_weighttype != 0) @@ -253,8 +253,6 @@ void TC_Endpoint::parse(const string &str) /*************************************TC_TCPClient**************************************/ -#define LEN_MAXRECV 8196 - TC_ClientSocket::TC_ClientSocket() : _port(0),_timeout(3000) { } @@ -284,6 +282,14 @@ void TC_ClientSocket::init(const string &sIp, int iPort, int iTimeout) _isIPv6 = TC_Socket::addressIsIPv6(sIp); } +void TC_ClientSocket::close() +{ + _socket.close(); +} + +/*************************************TC_TCPClient**************************************/ + +#define LEN_MAXRECV 8196 int TC_TCPClient::checkSocket() { @@ -299,20 +305,22 @@ int TC_TCPClient::checkSocket() _epoller->add(_socket.getfd(), 0, EPOLLOUT | EPOLLIN); - //设置非阻塞模式 + //设置非阻塞模式 _socket.setblock(false); _socket.setNoCloseWait(); + + int iRet; - int iRet; #if TARGET_PLATFORM_LINUX + if(_port == 0) { iRet = _socket.connectNoThrow(_ip.c_str()); } else -#endif +#endif { - iRet = _socket.connectNoThrow(_ip, _port); + iRet = _socket.connectNoThrow(_ip, _port); } if(iRet < 0 && !TC_Socket::isInProgress()) @@ -321,7 +329,6 @@ int TC_TCPClient::checkSocket() return EM_CONNECT; } int iRetCode = _epoller->wait(_timeout); - if (iRetCode < 0) { _socket.close(); @@ -452,7 +459,6 @@ int TC_TCPClient::recvBySep(string &sRecvBuffer, const string &sSep) while(true) { int iRetCode = _epoller->wait(_timeout); - // int iRetCode = epoller.wait(_timeout); if (iRetCode < 0) { _socket.close(); @@ -465,7 +471,6 @@ int TC_TCPClient::recvBySep(string &sRecvBuffer, const string &sSep) } const epoll_event &ev = _epoller->get(0); - if(TC_Epoller::errorEvent(ev)) { _socket.close(); @@ -590,7 +595,7 @@ int TC_TCPClient::recvLength(char *sRecvBuffer, size_t iRecvLen) if(TC_Epoller::errorEvent(ev)) { _socket.close(); - return EM_SELECT; + return EM_CLOSE; } #if TARGET_PLATFORM_IOS else @@ -679,7 +684,7 @@ int TC_UDPClient::checkSocket() _epoller->add(_socket.getfd(), 0, EPOLLIN | EPOLLOUT); - try + try { #if TARGET_PLATFORM_LINUX @@ -692,7 +697,7 @@ int TC_UDPClient::checkSocket() } } else -#endif +#endif { _socket.connect(_ip, _port); } @@ -758,7 +763,7 @@ int TC_UDPClient::recv(char *sRecvBuffer, size_t &iRecvLen, string &sRemoteIp, u if(TC_Epoller::errorEvent(ev)) { _socket.close(); - return EM_SELECT; + return EM_CLOSE; } #if TARGET_PLATFORM_IOS else diff --git a/util/src/tc_common.cpp b/util/src/tc_common.cpp index 4c9b923..2786d28 100644 --- a/util/src/tc_common.cpp +++ b/util/src/tc_common.cpp @@ -112,88 +112,87 @@ bool TC_Common::equal(const vector& vx, const vector& vy, double e { return equal(vx, vy, float(epsilon)); } - template <> string TC_Common::tostr(const bool &t) { - char buf[2]; - buf[0] = t ? '1' : '0'; - buf[1] = '\0'; - return string(buf); + char buf[2]; + buf[0] = t ? '1' : '0'; + buf[1] = '\0'; + return string(buf); } template <> string TC_Common::tostr(const char &t) { - char buf[2]; - snprintf(buf, 2, "%c", t); - return string(buf); + char buf[2]; + snprintf(buf, 2, "%c", t); + return string(buf); } template <> string TC_Common::tostr(const unsigned char &t) { - char buf[2]; - snprintf(buf, 2, "%c", t); - return string(buf); + char buf[2]; + snprintf(buf, 2, "%c", t); + return string(buf); } template <> string TC_Common::tostr(const short &t) { - char buf[16]; - snprintf(buf, 16, "%d", t); - return string(buf); + char buf[16]; + snprintf(buf, 16, "%d", t); + return string(buf); } template <> string TC_Common::tostr(const unsigned short &t) { - char buf[16]; - snprintf(buf, 16, "%u", t); - return string(buf); + char buf[16]; + snprintf(buf, 16, "%u", t); + return string(buf); } template <> string TC_Common::tostr(const int &t) { - char buf[16]; - snprintf(buf, 16, "%d", t); - return string(buf); + char buf[16]; + snprintf(buf, 16, "%d", t); + return string(buf); } template <> string TC_Common::tostr(const unsigned int &t) { - char buf[16]; - snprintf(buf, 16, "%u", t); - return string(buf); + char buf[16]; + snprintf(buf, 16, "%u", t); + return string(buf); } template <> string TC_Common::tostr(const long &t) { - char buf[32]; - snprintf(buf, 32, "%ld", t); - return string(buf); + char buf[32]; + snprintf(buf, 32, "%ld", t); + return string(buf); } template <> string TC_Common::tostr(const long long &t) { - char buf[32]; - snprintf(buf, 32, "%lld", t); - return string(buf); + char buf[32]; + snprintf(buf, 32, "%lld", t); + return string(buf); } template <> string TC_Common::tostr(const unsigned long &t) { - char buf[32]; - snprintf(buf, 32, "%lu", t); - return string(buf); + char buf[32]; + snprintf(buf, 32, "%lu", t); + return string(buf); } template <> @@ -202,35 +201,31 @@ string TC_Common::tostr(const float &t) //C++11 to_string,默认保留后面6位小数 string s = std::to_string(t); - // char buf[32]; - // snprintf(buf, 32, "%.5f", t); - // string s(buf); + //去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1 + bool bFlag = false; + int pos = int(s.size() - 1); + for(; pos > 0; --pos) + { + if(s[pos] == '0') + { + bFlag = true; + if(s[pos-1] == '.') + { + //-2为了去掉"."号 + pos -= 2; + break; + } + } + else + { + break; + } + } - //去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1 - bool bFlag = false; - int pos = int(s.size() - 1); - for(; pos > 0; --pos) - { - if(s[pos] == '0') - { - bFlag = true; - if(s[pos-1] == '.') - { - //-2为了去掉"."号 - pos -= 2; - break; - } - } - else - { - break; - } - } + if(bFlag) + s = s.substr(0, pos + 1); - if(bFlag) - s = s.substr(0, pos+1); - - return s; + return s; } template <> @@ -238,78 +233,73 @@ string TC_Common::tostr(const double &t) { //C++11 to_string,默认保留后面6位小数 string s = std::to_string(t); + //去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1 + bool bFlag = false; + int pos = int(s.size() - 1); + for(; pos > 0; --pos) + { + if(s[pos] == '0') + { + bFlag = true; + if(s[pos-1] == '.') + { + //-2为了去掉"."号 + pos -= 2; + break; + } + } + else + { + break; + } + } - // char buf[32]; - // snprintf(buf, 32, "%.5f", t); - // string s(buf); + if(bFlag) + s = s.substr(0, pos + 1); - //去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1 - bool bFlag = false; - int pos = int(s.size() - 1); - for(; pos > 0; --pos) - { - if(s[pos] == '0') - { - bFlag = true; - if(s[pos-1] == '.') - { - //-2为了去掉"."号 - pos -= 2; - break; - } - } - else - { - break; - } - } - - if(bFlag) - s = s.substr(0, pos+1); - - return s; + return s; } template <> string TC_Common::tostr(const long double &t) { - char buf[32]; - snprintf(buf, 32, "%Lf", t); - string s(buf); + char buf[32]; + snprintf(buf, 32, "%Lf", t); + string s(buf); - //去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1 - bool bFlag = false; - int pos = int(s.size() - 1); - for(; pos > 0; --pos) - { - if(s[pos] == '0') - { - bFlag = true; - if(s[pos-1] == '.') - { - //-2为了去掉"."号 - pos -= 2; - break; - } - } - else - { - break; - } - } + //去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1 + bool bFlag = false; + int pos = int(s.size() - 1); + for(; pos > 0; --pos) + { + if(s[pos] == '0') + { + bFlag = true; + if(s[pos-1] == '.') + { + //-2为了去掉"."号 + pos -= 2; + break; + } + } + else + { + break; + } + } - if(bFlag) - s = s.substr(0, pos+1); + if(bFlag) + s = s.substr(0, pos + 1); - return s; + return s; } template <> string TC_Common::tostr(const std::string &t) { - return t; + return t; } string TC_Common::trim(const string &sStr, const string &s, bool bChar) @@ -324,10 +314,10 @@ string TC_Common::trim(const string &sStr, const string &s, bool bChar) */ if(!bChar) { - return trimright(trimleft(sStr, s, false), s, false); + return trimright(trimleft(sStr, s, false), s, false); } - return trimright(trimleft(sStr, s, true), s, true); + return trimright(trimleft(sStr, s, true), s, true); } string TC_Common::trimleft(const string &sStr, const string &s, bool bChar) @@ -349,7 +339,7 @@ string TC_Common::trimleft(const string &sStr, const string &s, bool bChar) if(sStr.compare(0, s.length(), s) == 0) { - return sStr.substr(s.length()); + return sStr.substr(s.length()); } return sStr; @@ -371,7 +361,7 @@ string TC_Common::trimleft(const string &sStr, const string &s, bool bChar) if(pos == 0) return sStr; - return sStr.substr(pos); + return sStr.substr(pos); } string TC_Common::trimright(const string &sStr, const string &s, bool bChar) @@ -393,7 +383,7 @@ string TC_Common::trimright(const string &sStr, const string &s, bool bChar) if(sStr.compare(sStr.length() - s.length(), s.length(), s) == 0) { - return sStr.substr(0, sStr.length() - s.length()); + return sStr.substr(0, sStr.length() - s.length()); } return sStr; @@ -415,7 +405,7 @@ string TC_Common::trimright(const string &sStr, const string &s, bool bChar) if(pos == sStr.length()) return sStr; - return sStr.substr(0, pos); + return sStr.substr(0, pos); } string TC_Common::lower(const string &s) @@ -426,7 +416,7 @@ string TC_Common::lower(const string &s) *iter = tolower(*iter); } - return sString; + return sString; } string TC_Common::upper(const string &s) @@ -438,7 +428,7 @@ string TC_Common::upper(const string &s) *iter = toupper(*iter); } - return sString; + return sString; } bool TC_Common::isdigit(const string &sInput) @@ -472,26 +462,14 @@ public: time_t secs, local_secs, gmt_secs; time(&secs); + //带时区时间 TC_Port::localtime_r(&secs, &timeinfo); -// //带时区时间 -// #if TARGET_PLATFORM_WINDOWS -// localtime_s(&timeinfo, &secs); -// #else -// localtime_r(&secs, &timeinfo); -// #endif - local_secs = ::mktime(&timeinfo); //不带时区时间 TC_Port::gmtime_r(&secs, &timeinfo); -// #if TARGET_PLATFORM_WINDOWS -// gmtime_s(&timeinfo, &secs); -// #else -// gmtime_r(&secs, &timeinfo); -// #endif - gmt_secs = ::mktime(&timeinfo); timezone_diff_secs = local_secs - gmt_secs; } @@ -501,6 +479,7 @@ public: int64_t TimezoneHelper::timezone_diff_secs = 0; + int TC_Common::str2tm(const string &sString, const string &sFormat, struct tm &stTm) { char *p = strptime(sString.c_str(), sFormat.c_str(), &stTm); @@ -521,7 +500,7 @@ time_t TC_Common::str2time(const string &sString, const string &sFormat) int TC_Common::strgmt2tm(const string &sString, struct tm &stTm) { - return str2tm(sString, "%a, %d %b %Y %H:%M:%S GMT", stTm); + return str2tm(sString, "%a, %d %b %Y %H:%M:%S GMT", stTm); } string TC_Common::tm2str(const struct tm &stTm, const string &sFormat) @@ -530,31 +509,13 @@ string TC_Common::tm2str(const struct tm &stTm, const string &sFormat) strftime(sTimeString, sizeof(sTimeString), sFormat.c_str(), &stTm); - return string(sTimeString); + return string(sTimeString); } int TC_Common::gettimeofday(struct timeval &tv) { return TC_Port::gettimeofday(tv); -// #if TARGET_PLATFORM_WINDOWS -// static const DWORDLONG FILETIME_to_timeval_skew = 116444736000000000; -// FILETIME tfile; -// ::GetSystemTimeAsFileTime(&tfile); - -// ULARGE_INTEGER tmp; -// tmp.LowPart = tfile.dwLowDateTime; -// tmp.HighPart = tfile.dwHighDateTime; -// tmp.QuadPart -= FILETIME_to_timeval_skew; - -// ULARGE_INTEGER largeInt; -// largeInt.QuadPart = tmp.QuadPart / (10000 * 1000); -// tv.tv_sec = (long)(tmp.QuadPart / (10000 * 1000)); -// tv.tv_usec = (long)((tmp.QuadPart % (10000 * 1000)) / 10); -// return 0; -// #else -// return ::gettimeofday(&tv, 0); -// #endif } void TC_Common::tm2time(const time_t &t, struct tm &tt) @@ -565,90 +526,67 @@ void TC_Common::tm2time(const time_t &t, struct tm &tt) TC_Port::gmtime_r(&localt, &tt); -// #if TARGET_PLATFORM_WINDOWS -// //localtime_s -// gmtime_s(&tt, &localt); -// #else -// gmtime_r(&localt, &tt); -// #endif } string TC_Common::tm2str(const time_t &t, const string &sFormat) { - struct tm tt; - tm2time(t, tt); - // localtime_r(&t, &tt); + struct tm tt; + tm2time(t, tt); - return tm2str(tt, sFormat); + return tm2str(tt, sFormat); } - void TC_Common::tm2tm(const time_t &t, struct tm &tt) { static TimezoneHelper helper; time_t localt = t + TimezoneHelper::timezone_diff_secs; TC_Port::gmtime_r(&localt, &tt); -// #if TARGET_PLATFORM_WINDOWS -// gmtime_s(&tt, &localt); -// #else -// gmtime_r(&localt, &tt); -// #endif -// // gmtime_r(&localt, &stTm); + } string TC_Common::now2str(const string &sFormat) { time_t t = time(NULL); - return tm2str(t, sFormat.c_str()); + return tm2str(t, sFormat.c_str()); } string TC_Common::now2GMTstr() { time_t t = time(NULL); - return tm2GMTstr(t); + return tm2GMTstr(t); } string TC_Common::tm2GMTstr(const time_t &t) { struct tm tt; - TC_Port::gmtime_r(&t, &tt); - -// #if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS -// gmtime_r(&t, &tt); -// #elif TARGET_PLATFORM_WINDOWS -// _gmtime64_s(&tt, &t); -// #endif + TC_Port::gmtime_r(&t, &tt); return tm2str(tt, "%a, %d %b %Y %H:%M:%S GMT"); - - // gmtime_r(&t, &tt); - // return tm2str(tt, "%a, %d %b %Y %H:%M:%S GMT"); } string TC_Common::tm2GMTstr(const struct tm &stTm) { - return tm2str(stTm, "%a, %d %b %Y %H:%M:%S GMT"); + return tm2str(stTm, "%a, %d %b %Y %H:%M:%S GMT"); } string TC_Common::nowdate2str() { - return now2str("%Y%m%d"); + return now2str("%Y%m%d"); } string TC_Common::nowtime2str() { - return now2str("%H%M%S"); + return now2str("%H%M%S"); } int64_t TC_Common::now2ms() { - struct timeval tv; + struct timeval tv; - // gettimeofday(&tv, 0); TC_Common::gettimeofday(tv); - return tv.tv_sec * (int64_t)1000 + tv.tv_usec/1000; + return tv.tv_sec * (int64_t)1000 + tv.tv_usec/1000; } int64_t TC_Common::now2us() @@ -656,7 +594,6 @@ int64_t TC_Common::now2us() struct timeval tv; TC_Common::gettimeofday(tv); - // gettimeofday(&tv, 0); return tv.tv_sec * (int64_t)1000000 + tv.tv_usec; } @@ -687,17 +624,17 @@ string TC_Common::bin2str(const void *buf, size_t len, const string &sSep, size_ } } - return sOut; + return sOut; } string TC_Common::bin2str(const string &sBinData, const string &sSep, size_t lines) { - return bin2str((const void *)sBinData.data(), sBinData.length(), sSep, lines); + return bin2str((const void *) sBinData.data(), sBinData.length(), sSep, lines); } int TC_Common::str2bin(const char *psAsciiData, unsigned char *sBinData, int iBinSize) { - int iAsciiLength = strlen(psAsciiData); + int iAsciiLength = (int)strlen(psAsciiData); int iRealLength = (iAsciiLength/2 > iBinSize)?iBinSize:(iAsciiLength/2); for (int i = 0 ; i < iRealLength ; i++) @@ -711,9 +648,9 @@ string TC_Common::str2bin(const string &sString, const string &sSep, size_t line { const char *psAsciiData = sString.c_str(); - int iAsciiLength = sString.length(); + size_t iAsciiLength = sString.length(); string sBinData; - for (int i = 0 ; i < iAsciiLength ; i++) + for (size_t i = 0 ; i < iAsciiLength ; i++) { sBinData += x2c(psAsciiData + i); i++; @@ -725,7 +662,7 @@ string TC_Common::str2bin(const string &sString, const string &sSep, size_t line } } - return sBinData; + return sBinData; } char TC_Common::x2c(const string &sWhat) @@ -761,33 +698,33 @@ string TC_Common::replace(const string &sString, const string &sSrc, const strin pos += sDest.length(); } - return sBuf; + return sBuf; } string TC_Common::replace(const string &sString, const map& mSrcDest) { - if(sString.empty()) - { - return sString; - } + if(sString.empty()) + { + return sString; + } - string tmp = sString; - map::const_iterator it = mSrcDest.begin(); + string tmp = sString; + map::const_iterator it = mSrcDest.begin(); - while(it != mSrcDest.end()) - { + while(it != mSrcDest.end()) + { - string::size_type pos = 0; - while((pos = tmp.find(it->first, pos)) != string::npos) - { - tmp.replace(pos, it->first.length(), it->second); - pos += it->second.length(); - } + string::size_type pos = 0; + while((pos = tmp.find(it->first, pos)) != string::npos) + { + tmp.replace(pos, it->first.length(), it->second); + pos += it->second.length(); + } - ++it; - } + ++it; + } - return tmp; + return tmp; } bool TC_Common::matchPeriod(const string& s, const string& pat) @@ -954,7 +891,6 @@ size_t TC_Common::toSize(const string &s, size_t iDefaultSize) return iDefaultSize; } - string TC_Common::getHostName() { string hostName; @@ -971,6 +907,7 @@ string TC_Common::getHostName() return hostName; } + #if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS // Generate the randome string, a SHA1-sized random number @@ -991,6 +928,7 @@ void TC_Common::getRandomHexChars(char* p, unsigned int len) } + #endif } diff --git a/util/src/tc_config.cpp b/util/src/tc_config.cpp index 49185b3..8e526af 100644 --- a/util/src/tc_config.cpp +++ b/util/src/tc_config.cpp @@ -66,38 +66,38 @@ TC_ConfigDomain::DomainPath TC_ConfigDomain::parseDomainName(const string& path, if(bWithParam) { - string::size_type pos1 = path.find_first_of(TC_CONFIG_PARAM_BEGIN); - if(pos1 == string::npos) - { - throw TC_Config_Exception("[TC_Config::parseDomainName] : param path '" + path + "' is invalid!" ); - } + string::size_type pos1 = path.find_first_of(TC_CONFIG_PARAM_BEGIN); + if(pos1 == string::npos) + { + throw TC_Config_Exception("[TC_Config::parseDomainName] : param path '" + path + "' is invalid!" ); + } - if(path[0] != TC_CONFIG_DOMAIN_SEP) - { - throw TC_Config_Exception("[TC_Config::parseDomainName] : param path '" + path + "' must start with '/'!" ); - } + if(path[0] != TC_CONFIG_DOMAIN_SEP) + { + throw TC_Config_Exception("[TC_Config::parseDomainName] : param path '" + path + "' must start with '/'!" ); + } - string::size_type pos2 = path.find_first_of(TC_CONFIG_PARAM_END); - if(pos2 == string::npos) - { - throw TC_Config_Exception("[TC_Config::parseDomainName] : param path '" + path + "' is invalid!" ); - } + string::size_type pos2 = path.find_first_of(TC_CONFIG_PARAM_END); + if(pos2 == string::npos) + { + throw TC_Config_Exception("[TC_Config::parseDomainName] : param path '" + path + "' is invalid!" ); + } dp._domains = TC_Common::sepstr(path.substr(1, pos1-1), TC_Common::tostr(TC_CONFIG_DOMAIN_SEP)); - dp._param = path.substr(pos1+1, pos2 - pos1 - 1); + dp._param = path.substr(pos1 + 1, pos2 - pos1 - 1); } else { -// if(path.length() <= 1 || path[0] != TC_CONFIG_DOMAIN_SEP) +// if(path.length() <= 1 || path[0] != TC_CONFIG_DOMAIN_SEP) if(path[0] != TC_CONFIG_DOMAIN_SEP) - { - throw TC_Config_Exception("[TC_Config::parseDomainName] : param path '" + path + "' must start with '/'!" ); - } + { + throw TC_Config_Exception("[TC_Config::parseDomainName] : param path '" + path + "' must start with '/'!" ); + } dp._domains = TC_Common::sepstr(path.substr(1), TC_Common::tostr(TC_CONFIG_DOMAIN_SEP)); } - return dp; + return dp; } TC_ConfigDomain* TC_ConfigDomain::addSubDomain(const string& name) @@ -114,12 +114,12 @@ TC_ConfigDomain* TC_ConfigDomain::addSubDomain(const string& name) string TC_ConfigDomain::getParamValue(const string &name) const { map::const_iterator it = _param.find(name); - if( it == _param.end()) - { - throw TC_ConfigNoParam_Exception("[TC_ConfigDomain::getParamValue] param '" + name + "' not exits!"); + if( it == _param.end()) + { + throw TC_ConfigNoParam_Exception("[TC_ConfigDomain::getParamValue] param '" + name + "' not exits!"); } - return it->second; + return it->second; } TC_ConfigDomain *TC_ConfigDomain::getSubTcConfigDomain(vector::const_iterator itBegin, vector::const_iterator itEnd) @@ -131,14 +131,14 @@ TC_ConfigDomain *TC_ConfigDomain::getSubTcConfigDomain(vector::const_ite map::const_iterator it = _subdomain.find(*itBegin); - //根据匹配规则找不到匹配的子域 - if(it == _subdomain.end()) - { - return NULL; - } + //根据匹配规则找不到匹配的子域 + if(it == _subdomain.end()) + { + return NULL; + } - //继续在子域下搜索 - return it->second->getSubTcConfigDomain(itBegin + 1, itEnd); + //继续在子域下搜索 + return it->second->getSubTcConfigDomain(itBegin + 1, itEnd); } const TC_ConfigDomain *TC_ConfigDomain::getSubTcConfigDomain(vector::const_iterator itBegin, vector::const_iterator itEnd) const @@ -150,19 +150,22 @@ const TC_ConfigDomain *TC_ConfigDomain::getSubTcConfigDomain(vector::con map::const_iterator it = _subdomain.find(*itBegin); - //根据匹配规则找不到匹配的子域 - if(it == _subdomain.end()) - { - return NULL; - } + //根据匹配规则找不到匹配的子域 + if(it == _subdomain.end()) + { + return NULL; + } - //继续在子域下搜索 - return it->second->getSubTcConfigDomain(itBegin + 1, itEnd); + //继续在子域下搜索 + return it->second->getSubTcConfigDomain(itBegin + 1, itEnd); } void TC_ConfigDomain::insertParamValue(const map &m) { - _param.insert(m.begin(), m.end()); + for(auto e : m) + { + _param[e.first] = e.second; + } map::const_iterator it = m.begin(); while(it != m.end()) @@ -290,7 +293,7 @@ string TC_ConfigDomain::parse(const string& s) } } - return param; + return param; } string TC_ConfigDomain::reverse_parse(const string &s) @@ -330,12 +333,12 @@ string TC_ConfigDomain::reverse_parse(const string &s) } } - return param; + return param; } string TC_ConfigDomain::getName() const { - return _name; + return _name; } void TC_ConfigDomain::setName(const string& name) @@ -416,13 +419,13 @@ string TC_ConfigDomain::tostr(int i) const } - buf << sTab << "" << endl; + buf << sTab << "" << endl; - return buf.str(); + return buf.str(); } /********************************************************************/ -/* TC_Config implement */ +/* TC_Config implement */ /********************************************************************/ TC_Config::TC_Config() : _root("") @@ -454,60 +457,60 @@ void TC_Config::parse(istream &is) string line; while(getline(is, line)) - { - line = TC_Common::trim(line, " \r\n\t"); + { + line = TC_Common::trim(line, " \r\n\t"); - if(line.length() == 0) - { - continue; - } + if(line.length() == 0) + { + continue; + } - if(line[0] == '#') - { - continue; - } - else if(line[0] == '<') - { - string::size_type posl = line.find_first_of('>'); + if(line[0] == '#') + { + continue; + } + else if(line[0] == '<') + { + string::size_type posl = line.find_first_of('>'); - if(posl == string::npos) - { - throw TC_Config_Exception("[TC_Config::parse]:parse error! line : " + line); - } + if(posl == string::npos) + { + throw TC_Config_Exception("[TC_Config::parse]:parse error! line : " + line); + } - if(line[1] == '/') - { - string sName(line.substr(2, (posl - 2))); + if(line[1] == '/') + { + string sName(line.substr(2, (posl - 2))); - if(stkTcCnfDomain.size() <= 0) + if(stkTcCnfDomain.size() <= 0) { throw TC_Config_Exception("[TC_Config::parse]:parse error! <" + sName + "> hasn't matched domain."); } if(stkTcCnfDomain.top()->getName() != sName) - { - throw TC_Config_Exception("[TC_Config::parse]:parse error! <" + stkTcCnfDomain.top()->getName() + "> hasn't match <" + sName +">."); - } + { + throw TC_Config_Exception("[TC_Config::parse]:parse error! <" + stkTcCnfDomain.top()->getName() + "> hasn't match <" + sName +">."); + } //弹出 - stkTcCnfDomain.pop(); - } - else - { - string name(line.substr(1, posl - 1)); + stkTcCnfDomain.pop(); + } + else + { + string name(line.substr(1, posl - 1)); stkTcCnfDomain.push(stkTcCnfDomain.top()->addSubDomain(name)); - } - } - else - { + } + } + else + { stkTcCnfDomain.top()->setParamValue(line); - } - } + } + } - if(stkTcCnfDomain.size() != 1) - { - throw TC_Config_Exception("[TC_Config::parse]:parse error : hasn't match"); + if(stkTcCnfDomain.size() != 1) + { + throw TC_Config_Exception("[TC_Config::parse]:parse error : hasn't match"); } } @@ -515,7 +518,7 @@ void TC_Config::parseFile(const string &sFileName) { if(sFileName.length() == 0) { - throw TC_Config_Exception("[TC_Config::parseFile]:file name is empty"); + throw TC_Config_Exception("[TC_Config::parseFile]:file name is empty"); } ifstream ff; @@ -536,18 +539,18 @@ void TC_Config::parseString(const string& buffer) parse(iss); } -string TC_Config::operator[](const string &path) +string TC_Config::operator[](const string &path) const { TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(path, true); - TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); + const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); - if(pTcConfigDomain == NULL) - { - throw TC_ConfigNoParam_Exception("[TC_Config::operator[]] path '" + path + "' not exits!"); - } + if(pTcConfigDomain == NULL) + { + throw TC_ConfigNoParam_Exception("[TC_Config::operator[]] path '" + path + "' not exits!"); + } - return pTcConfigDomain->getParamValue(dp._param); + return pTcConfigDomain->getParamValue(dp._param); } string TC_Config::get(const string &sName, const string &sDefault) const @@ -556,14 +559,15 @@ string TC_Config::get(const string &sName, const string &sDefault) const { TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(sName, true); - const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); + const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); - if(pTcConfigDomain == NULL) - { - throw TC_ConfigNoParam_Exception("[TC_Config::get] path '" + sName + "' not exits!"); - } + if(pTcConfigDomain == NULL) + { + return sDefault; + // throw TC_ConfigNoParam_Exception("[TC_Config::get] path '" + sName + "' not exits!"); + } - return pTcConfigDomain->getParamValue(dp._param); + return pTcConfigDomain->getParamValue(dp._param); } catch ( TC_ConfigNoParam_Exception &ex ) { @@ -571,18 +575,40 @@ string TC_Config::get(const string &sName, const string &sDefault) const } } +void TC_Config::set(const string &sName, const string &value) +{ + TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(sName, true); + + map v; + v[dp._param] = value; + + TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); + + if(pTcConfigDomain == NULL) + { + pTcConfigDomain = &_root; + + for(size_t i = 0; i < dp._domains.size(); i++) + { + pTcConfigDomain = pTcConfigDomain->addSubDomain(dp._domains[i]); + } + } + + pTcConfigDomain->insertParamValue(v); +} + bool TC_Config::getDomainMap(const string &path, map &m) const { TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(path, false); - const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); + const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); - if(pTcConfigDomain == NULL) - { - return false; - } + if(pTcConfigDomain == NULL) + { + return false; + } - m = pTcConfigDomain->getParamMap(); + m = pTcConfigDomain->getParamMap(); return true; } @@ -593,10 +619,10 @@ map TC_Config::getDomainMap(const string &path) const TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(path, false); - const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); + const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); - if(pTcConfigDomain != NULL) - { + if(pTcConfigDomain != NULL) + { m = pTcConfigDomain->getParamMap(); } @@ -609,14 +635,14 @@ vector TC_Config::getDomainKey(const string &path) const TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(path, false); - const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); + const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); - if(pTcConfigDomain != NULL) - { + if(pTcConfigDomain != NULL) + { v = pTcConfigDomain->getKey(); } - return v; + return v; } vector TC_Config::getDomainLine(const string &path) const @@ -632,7 +658,7 @@ vector TC_Config::getDomainLine(const string &path) const v = pTcConfigDomain->getLine(); } - return v; + return v; } bool TC_Config::hasDomainVector(const string &path) const @@ -666,16 +692,16 @@ bool TC_Config::getDomainVector(const string &path, vector &vtDomains) c return !vtDomains.empty(); } - const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); + const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); - if(pTcConfigDomain == NULL) - { + if(pTcConfigDomain == NULL) + { return false; - } + } vtDomains = pTcConfigDomain->getSubDomain(); - return true; + return true; } vector TC_Config::getDomainVector(const string &path) const @@ -688,12 +714,12 @@ vector TC_Config::getDomainVector(const string &path) const return _root.getSubDomain(); } - const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); + const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); - if(pTcConfigDomain == NULL) - { + if(pTcConfigDomain == NULL) + { return vector(); - } + } return pTcConfigDomain->getSubDomain(); } @@ -701,27 +727,27 @@ vector TC_Config::getDomainVector(const string &path) const TC_ConfigDomain *TC_Config::newTcConfigDomain(const string &sName) { - return new TC_ConfigDomain(sName); + return new TC_ConfigDomain(sName); } TC_ConfigDomain *TC_Config::searchTcConfigDomain(const vector& domains) { - return _root.getSubTcConfigDomain(domains.begin(), domains.end()); + return _root.getSubTcConfigDomain(domains.begin(), domains.end()); } const TC_ConfigDomain *TC_Config::searchTcConfigDomain(const vector& domains) const { - return _root.getSubTcConfigDomain(domains.begin(), domains.end()); + return _root.getSubTcConfigDomain(domains.begin(), domains.end()); } int TC_Config::insertDomain(const string &sCurDomain, const string &sAddDomain, bool bCreate) { TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(sCurDomain, false); - TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); + TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains); - if(pTcConfigDomain == NULL) - { + if(pTcConfigDomain == NULL) + { if(bCreate) { pTcConfigDomain = &_root; @@ -735,7 +761,7 @@ int TC_Config::insertDomain(const string &sCurDomain, const string &sAddDomain, { return -1; } - } + } pTcConfigDomain->addSubDomain(sAddDomain); @@ -746,10 +772,10 @@ int TC_Config::insertDomainParam(const string &sCurDomain, const mapinsertParamValue(m); @@ -782,7 +808,7 @@ string TC_Config::tostr() const ++it; } - return buffer; + return buffer; } void TC_Config::joinConfig(const TC_Config &cf, bool bUpdate) diff --git a/util/src/tc_consistent_hash_new.cpp b/util/src/tc_consistent_hash_new.cpp index 6744452..b09b315 100755 --- a/util/src/tc_consistent_hash_new.cpp +++ b/util/src/tc_consistent_hash_new.cpp @@ -23,10 +23,10 @@ using namespace tars; namespace tars { -int32_t TC_KetamaHashAlg::hash(const string & sKey) +int32_t TC_KetamaHashAlg::hash(const char *sKey, size_t length) { - string sMd5 = TC_MD5::md5bin(sKey); - const char *p = (const char *) sMd5.c_str(); + vector sMd5 = TC_MD5::md5bin(sKey, length); + const char *p = (const char *) sMd5.data(); int32_t hash = ((int32_t)(p[3] & 0xFF) << 24) | ((int32_t)(p[2] & 0xFF) << 16) @@ -41,10 +41,10 @@ TC_HashAlgorithmType TC_KetamaHashAlg::getHashType() return E_TC_CONHASH_KETAMAHASH; } -int32_t TC_DefaultHashAlg::hash(const string & sKey) +int32_t TC_DefaultHashAlg::hash(const char *sKey, size_t length) { - string sMd5 = TC_MD5::md5bin(sKey); - const char *p = (const char *) sMd5.c_str(); + vector sMd5 = TC_MD5::md5bin(sKey, length); + const char *p = (const char *) sMd5.data(); int32_t hash = (*(int*)(p)) ^ (*(int*)(p+4)) ^ (*(int*)(p+8)) ^ (*(int*)(p+12)); @@ -165,8 +165,8 @@ int TC_ConsistentHashNew::addNode(const string & node, unsigned int index, int w // TODO: 其中KEMATA 为参考memcached client 的hash 算法,default 为原有的hash 算法,测试结论在表格里有 if (_ptrHashAlg->getHashType() == E_TC_CONHASH_KETAMAHASH) { - string sMd5 = TC_MD5::md5bin(virtualNode); - char *p = (char *) sMd5.c_str(); + vector sMd5 = TC_MD5::md5bin(virtualNode); + char *p = (char *) sMd5.data(); for (int i = 0; i < 4; i++) { @@ -180,7 +180,7 @@ int TC_ConsistentHashNew::addNode(const string & node, unsigned int index, int w } else { - stItem.iHashCode = _ptrHashAlg->hash(virtualNode); + stItem.iHashCode = _ptrHashAlg->hash(virtualNode.c_str(), virtualNode.length()); _vHashList.push_back(stItem); } } @@ -196,7 +196,8 @@ int TC_ConsistentHashNew::getIndex(const string & key, unsigned int & iIndex) return -1; } - int32_t iCode = _ptrHashAlg->hash(TC_MD5::md5bin(key)); + vector data = TC_MD5::md5bin(key); + int32_t iCode = _ptrHashAlg->hash(data.data(), data.size()); return getIndex(iCode, iIndex); } diff --git a/util/src/tc_cron.cpp b/util/src/tc_cron.cpp new file mode 100644 index 0000000..6c104d3 --- /dev/null +++ b/util/src/tc_cron.cpp @@ -0,0 +1,386 @@ +#include "util/tc_cron.h" +#include "util/tc_platform.h" + + +namespace tars +{ + +const std::vector TC_Cron::DAYS = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" }; +const std::vector TC_Cron::MONTHS = { "NIL", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" }; + +TC_Cron TC_Cron::makecron(const string& expr) +{ + TC_Cron cron; + + if (expr.empty()) + { + throw TC_CronException("[TC_Cron makecron] invalid empty cron expression"); + } + vector fields = TC_Common::sepstr(expr, " "); + + if (fields.size() != 6) + throw TC_CronException("[TC_Cron makecron] cron expression must have six fields"); + + setCronField(fields[0], cron.seconds, CRON_MIN_SECONDS, CRON_MAX_SECONDS); + setCronField(fields[1], cron.minutes, CRON_MIN_MINUTES, CRON_MAX_MINUTES); + setCronField(fields[2], cron.hours, CRON_MIN_HOURS, CRON_MAX_HOURS); + + setCronDaysOfWeek(fields[5], cron.days_of_week); + setCronDaysOfMonth(fields[3], cron.days_of_month); + setCronMonth(fields[4], cron.months); + + cron.isset = true; + return cron; +} + +std::time_t TC_Cron::nextcron(const TC_Cron& cron, std::time_t date) +{ + std::tm val; + std::tm* dt = time_to_tm(&date, &val); + if (dt == nullptr) return INVALID_TIME; + + time_t original = tm_to_time(*dt); + if (INVALID_TIME == original) return INVALID_TIME; + + if (!findNext(cron, *dt, dt->tm_year)) + return INVALID_TIME; + + time_t calculated = tm_to_time(*dt); + if (INVALID_TIME == calculated) return calculated; + + if (calculated == original) + { + addToField(*dt, CronField::second, 1); + if (!findNext(cron, *dt, dt->tm_year)) + return INVALID_TIME; + } + + return tm_to_time(*dt); +} + +std::time_t TC_Cron::nextcron(const TC_Cron& cron) +{ + std::time_t now = std::time(0); + return nextcron(cron, now); +} + +std::tm* TC_Cron::time_to_tm(std::time_t const* date, std::tm* const out) +{ +#if TARGET_PLATFORM_WINDOWS + errno_t err = localtime_s(out, date); + return 0 == err ? out : nullptr; +#else + return localtime_r(date, out); +#endif +} + +std::time_t TC_Cron::tm_to_time(std::tm& tmt) +{ + return std::mktime(&tmt); +} + +bool TC_Cron::contains(const std::string& text, char ch) +{ + return std::string::npos != text.find_first_of(ch); +} + + +cron_int TC_Cron::to_cron_int(const std::string& text) +{ + try + { + return static_cast(std::stoul(text.data())); + } + catch (std::exception const& ex) + { + throw TC_CronException(string("[TC_Cron to_cron_int] ") + ex.what()); + } +} + +std::string TC_Cron::replaceOrdinals(std::string text, const std::vector & replacement) +{ + for (size_t i = 0; i < replacement.size(); ++i) + { + auto pos = text.find(replacement[i]); + if (std::string::npos != pos) + { + text.replace(pos, 3, std::to_string(i)); + } + } + return text; +} + +std::pair TC_Cron::makeRange(std::string field, cron_int minval, cron_int maxval) +{ + cron_int first = 0; + cron_int last = 0; + if (field.size() == 1 && field[0] == '*') + { + first = minval; + last = maxval; + } + else if (!contains(field, '-')) + { + first = to_cron_int(field); + last = first; + } + else + { + auto parts = TC_Common::sepstr(field, "-"); + if (parts.size() != 2) + throw TC_CronException("TC_Cron::makeRange] specified range requires two fields"); + + first = to_cron_int(parts[0]); + last = to_cron_int(parts[1]); + } + + if (first > maxval || last > maxval) + { + throw TC_CronException("TC_Cron::makeRange] specified range exceeds maximum"); + } + if (first < minval || last < minval) + { + throw TC_CronException("TC_Cron::makeRange] specified range is less than minimum"); + } + if (first > last) + { + throw TC_CronException("TC_Cron::makeRange] specified range start exceeds range end"); + } + + return { first, last }; +} + + +void TC_Cron::setCronDaysOfWeek(std::string value, std::bitset<7>& target) +{ + auto days = TC_Common::upper(value); + auto days_replaced = replaceOrdinals(days, DAYS); + + if (days_replaced.size() == 1 && days_replaced[0] == '?') + days_replaced[0] = '*'; + + setCronField(days_replaced,target,CRON_MIN_DAYS_OF_WEEK,CRON_MAX_DAYS_OF_WEEK); +} + + +void TC_Cron::setCronDaysOfMonth(std::string value, std::bitset<31>& target) +{ + if (value.size() == 1 && value[0] == '?') + value[0] = '*'; + + setCronField(value, target, CRON_MIN_DAYS_OF_MONTH, CRON_MAX_DAYS_OF_MONTH); +} + +void TC_Cron::setCronMonth(std::string value, std::bitset<12>& target) +{ + auto month = TC_Common::upper(value); + auto month_replaced = replaceOrdinals(month, MONTHS); + + setCronField(month_replaced, target, CRON_MIN_MONTHS, CRON_MAX_MONTHS); +} + +void TC_Cron::addToField(std::tm& tmt, CronField field, int const val) +{ + switch (field) + { + case CronField::second: + tmt.tm_sec += val; + break; + case CronField::minute: + tmt.tm_min += val; + break; + case CronField::hour_of_day: + tmt.tm_hour += val; + break; + case CronField::day_of_week: + case CronField::day_of_month: + tmt.tm_mday += val; + break; + case CronField::month: + tmt.tm_mon += val; + break; + case CronField::year: + tmt.tm_year += val; + break; + } + + if (INVALID_TIME == tm_to_time(tmt)) + throw TC_CronException("TC_Cron::addToField] invalid time expression"); +} + +void TC_Cron::setField(std::tm& tmt, CronField field, int const val) +{ + switch (field) + { + case CronField::second: + tmt.tm_sec = val; + break; + case CronField::minute: + tmt.tm_min = val; + break; + case CronField::hour_of_day: + tmt.tm_hour = val; + break; + case CronField::day_of_week: + tmt.tm_wday = val; + break; + case CronField::day_of_month: + tmt.tm_mday = val; + break; + case CronField::month: + tmt.tm_mon = val; + break; + case CronField::year: + tmt.tm_year = val; + break; + } + + if (INVALID_TIME == tm_to_time(tmt)) + throw TC_CronException("TC_Cron::setField] invalid time expression"); +} + +void TC_Cron::resetField(std::tm& tmt, CronField field) +{ + switch (field) + { + case CronField::second: + tmt.tm_sec = 0; + break; + case CronField::minute: + tmt.tm_min = 0; + break; + case CronField::hour_of_day: + tmt.tm_hour = 0; + break; + case CronField::day_of_week: + tmt.tm_wday = 0; + break; + case CronField::day_of_month: + tmt.tm_mday = 1; + break; + case CronField::month: + tmt.tm_mon = 0; + break; + case CronField::year: + tmt.tm_year = 0; + break; + } + + if (INVALID_TIME == tm_to_time(tmt)) + throw TC_CronException("TC_Cron::resetField] invalid time expression"); +} + +void TC_Cron::resetAllFields(std::tm& tmt, const std::bitset<7> & marked_fields) +{ + for (size_t i = 0; i < marked_fields.size(); ++i) + { + if (marked_fields.test(i)) + resetField(tmt, static_cast(i)); + } +} + +void TC_Cron::markField(std::bitset<7>& orders, CronField field) +{ + if (!orders.test(static_cast(field))) + orders.set(static_cast(field)); +} + +size_t TC_Cron::findNextDay( + std::tm& tmt, + std::bitset<31> const& days_of_month, + size_t day_of_month, + const std::bitset<7> & days_of_week, + size_t day_of_week, + const std::bitset<7> & marked_fields) +{ + unsigned int count = 0; + unsigned int maximum = 366; + while ( + (!days_of_month.test(day_of_month - CRON_MIN_DAYS_OF_MONTH) || + !days_of_week.test(day_of_week - CRON_MIN_DAYS_OF_WEEK)) + && count++ < maximum) + { + addToField(tmt, CronField::day_of_month, 1); + + day_of_month = tmt.tm_mday; + day_of_week = tmt.tm_wday; + + resetAllFields(tmt, marked_fields); + } + + return day_of_month; +} + +bool TC_Cron::findNext(const TC_Cron & cron, std::tm& tmt, size_t const dot) +{ + bool res = true; + + std::bitset<7> marked_fields{ 0 }; + std::bitset<7> empty_list{ 0 }; + + unsigned int second = tmt.tm_sec; + auto updated_second = findNext(cron.seconds,tmt,CRON_MIN_SECONDS,CRON_MAX_SECONDS,second,CronField::second,CronField::minute,empty_list); + + if (second == updated_second) + { + markField(marked_fields, CronField::second); + } + + unsigned int minute = tmt.tm_min; + auto update_minute = findNext(cron.minutes,tmt,CRON_MIN_MINUTES,CRON_MAX_MINUTES,minute,CronField::minute,CronField::hour_of_day,marked_fields); + if (minute == update_minute) + { + markField(marked_fields, CronField::minute); + } + else + { + res = findNext(cron, tmt, dot); + if (!res) return res; + } + + unsigned int hour = tmt.tm_hour; + auto updated_hour = findNext(cron.hours,tmt,CRON_MIN_HOURS,CRON_MAX_HOURS,hour,CronField::hour_of_day,CronField::day_of_week,marked_fields); + if (hour == updated_hour) + { + markField(marked_fields, CronField::hour_of_day); + } + else + { + res = findNext(cron, tmt, dot); + if (!res) return res; + } + + unsigned int day_of_week = tmt.tm_wday; + unsigned int day_of_month = tmt.tm_mday; + auto updated_day_of_month = findNextDay(tmt,cron.days_of_month,day_of_month,cron.days_of_week,day_of_week,marked_fields); + if (day_of_month == updated_day_of_month) + { + markField(marked_fields, CronField::day_of_month); + } + else + { + res = findNext(cron, tmt, dot); + if (!res) return res; + } + + unsigned int month = tmt.tm_mon; + auto updated_month = findNext(cron.months,tmt,CRON_MIN_MONTHS,CRON_MAX_MONTHS,month, + CronField::month,CronField::year,marked_fields); + if (month != updated_month) + { + if (tmt.tm_year - dot > CRON_MAX_YEARS_DIFF) + return false; + + res = findNext(cron, tmt, dot); + if (!res) return res; + } + + return res; +} + +} + + + + + diff --git a/util/src/tc_des.cpp b/util/src/tc_des.cpp new file mode 100644 index 0000000..d15a996 --- /dev/null +++ b/util/src/tc_des.cpp @@ -0,0 +1,581 @@ +#include "util/tc_des.h" +#include +#include +#include + +namespace tars +{ + +static const unsigned short bytebit[8] = { + 0200, 0100, 040, 020, 010, 04, 02, 01 }; + +static const uint32_t bigbyte[24] = { + 0x800000L, 0x400000L, 0x200000L, 0x100000L, + 0x80000L, 0x40000L, 0x20000L, 0x10000L, + 0x8000L, 0x4000L, 0x2000L, 0x1000L, + 0x800L, 0x400L, 0x200L, 0x100L, + 0x80L, 0x40L, 0x20L, 0x10L, + 0x8L, 0x4L, 0x2L, 0x1L }; + +static const unsigned char pc1[56] = { + 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; + +static const unsigned char totrot[16] = { + 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 }; + +static const unsigned char pc2[48] = { + 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; + +static const uint32_t SP1[64] = { + 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, + 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, + 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, + 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, + 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, + 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, + 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, + 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, + 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, + 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, + 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, + 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, + 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, + 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; + +static const uint32_t SP2[64] = { + 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, + 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, + 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, + 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, + 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, + 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, + 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, + 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, + 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, + 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, + 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, + 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, + 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, + 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, + 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, + 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; + +static const uint32_t SP3[64] = { + 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, + 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, + 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, + 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, + 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, + 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, + 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, + 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, + 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, + 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, + 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, + 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, + 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, + 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, + 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, + 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; + +static const uint32_t SP4[64] = { + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, + 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, + 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, + 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, + 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, + 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, + 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, + 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, + 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; + +static const uint32_t SP5[64] = { + 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, + 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, + 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, + 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, + 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, + 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, + 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, + 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, + 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, + 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, + 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, + 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, + 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, + 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, + 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, + 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; + +static const uint32_t SP6[64] = { + 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, + 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, + 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, + 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, + 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, + 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, + 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, + 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, + 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, + 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, + 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, + 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, + 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, + 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; + +static const uint32_t SP7[64] = { + 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, + 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, + 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, + 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, + 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, + 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, + 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, + 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, + 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, + 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, + 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, + 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, + 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, + 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, + 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, + 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; + +static const uint32_t SP8[64] = { + 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, + 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, + 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, + 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, + 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, + 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, + 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, + 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, + 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, + 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, + 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, + 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, + 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, + 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, + 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, + 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; + +void TC_Des::scrunch(register const char *outof, register uint32_t *into) +{ + *into = (*outof++ & 0xffL) << 24; + *into |= (*outof++ & 0xffL) << 16; + *into |= (*outof++ & 0xffL) << 8; + *into++ |= (*outof++ & 0xffL); + *into = (*outof++ & 0xffL) << 24; + *into |= (*outof++ & 0xffL) << 16; + *into |= (*outof++ & 0xffL) << 8; + *into |= (*outof & 0xffL); + return; +} + +void TC_Des::unscrun(register uint32_t *outof, register char *into) +{ + *into++ = (*outof >> 24) & 0xffL; + *into++ = (*outof >> 16) & 0xffL; + *into++ = (*outof >> 8) & 0xffL; + *into++ = *outof++ & 0xffL; + *into++ = (*outof >> 24) & 0xffL; + *into++ = (*outof >> 16) & 0xffL; + *into++ = (*outof >> 8) & 0xffL; + *into = *outof & 0xffL; + return; +} + +void TC_Des::desfunc(register uint32_t *block, register uint32_t *keys) +{ + register uint32_t fval, work, right, leftt; + register int round; + + leftt = block[0]; + right = block[1]; + work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; + right ^= work; + leftt ^= (work << 4); + work = ((leftt >> 16) ^ right) & 0x0000ffffL; + right ^= work; + leftt ^= (work << 16); + work = ((right >> 2) ^ leftt) & 0x33333333L; + leftt ^= work; + right ^= (work << 2); + work = ((right >> 8) ^ leftt) & 0x00ff00ffL; + leftt ^= work; + right ^= (work << 8); + right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL; + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL; + + for( round = 0; round < 8; round++ ) + { + work = (right << 28) | (right >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3fL]; + fval |= SP5[(work >> 8) & 0x3fL]; + fval |= SP3[(work >> 16) & 0x3fL]; + fval |= SP1[(work >> 24) & 0x3fL]; + work = right ^ *keys++; + fval |= SP8[ work & 0x3fL]; + fval |= SP6[(work >> 8) & 0x3fL]; + fval |= SP4[(work >> 16) & 0x3fL]; + fval |= SP2[(work >> 24) & 0x3fL]; + leftt ^= fval; + work = (leftt << 28) | (leftt >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3fL]; + fval |= SP5[(work >> 8) & 0x3fL]; + fval |= SP3[(work >> 16) & 0x3fL]; + fval |= SP1[(work >> 24) & 0x3fL]; + work = leftt ^ *keys++; + fval |= SP8[ work & 0x3fL]; + fval |= SP6[(work >> 8) & 0x3fL]; + fval |= SP4[(work >> 16) & 0x3fL]; + fval |= SP2[(work >> 24) & 0x3fL]; + right ^= fval; + } + + right = (right << 31) | (right >> 1); + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = (leftt << 31) | (leftt >> 1); + work = ((leftt >> 8) ^ right) & 0x00ff00ffL; + right ^= work; + leftt ^= (work << 8); + work = ((leftt >> 2) ^ right) & 0x33333333L; + right ^= work; + leftt ^= (work << 2); + work = ((right >> 16) ^ leftt) & 0x0000ffffL; + leftt ^= work; + right ^= (work << 16); + work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; + leftt ^= work; + right ^= (work << 4); + *block++ = right; + *block = leftt; + return; +} + +void TC_Des::cookey(register uint32_t *raw1, uint32_t *k) +{ + register uint32_t *cook, *raw0; + uint32_t dough[32]; + register int i; + + cook = dough; + for( i = 0; i < 16; i++, raw1++ ) + { + raw0 = raw1++; + *cook = (*raw0 & 0x00fc0000L) << 6; + *cook |= (*raw0 & 0x00000fc0L) << 10; + *cook |= (*raw1 & 0x00fc0000L) >> 10; + *cook++ |= (*raw1 & 0x00000fc0L) >> 6; + *cook = (*raw0 & 0x0003f000L) << 12; + *cook |= (*raw0 & 0x0000003fL) << 16; + *cook |= (*raw1 & 0x0003f000L) >> 4; + *cook++ |= (*raw1 & 0x0000003fL); + } + + register uint32_t *to, *endp, *p; + to = k, endp = &k[32], p = dough; + while( to < endp ) + *to++ = *p++; +} + +void TC_Des::deskey(const char *key, short edf, uint32_t *k) +{ + register int i, j, l, m, n; + unsigned char pc1m[56], pcr[56]; + uint32_t kn[32]; + + for ( j = 0; j < 56; j++ ) + { + l = pc1[j]; + m = l & 07; + pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0; + } + for( i = 0; i < 16; i++ ) + { + if( edf == DE1 ) m = (15 - i) << 1; + else m = i << 1; + n = m + 1; + kn[m] = kn[n] = 0L; + for( j = 0; j < 28; j++ ) + { + l = j + totrot[i]; + if( l < 28 ) pcr[j] = pc1m[l]; + else pcr[j] = pc1m[l - 28]; + } + for( j = 28; j < 56; j++ ) + { + l = j + totrot[i]; + if( l < 56 ) pcr[j] = pc1m[l]; + else pcr[j] = pc1m[l - 28]; + } + for( j = 0; j < 24; j++ ) + { + if( pcr[pc2[j]] ) kn[m] |= bigbyte[j]; + if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j]; + } + } + cookey(kn, k); +} + +void TC_Des::des(const char *inblock, char *outblock, uint32_t *KnL) +{ + uint32_t work[2]; + + scrunch(inblock, work); + desfunc(work, KnL); + unscrun(work, outblock); +} + +void TC_Des::des3key(const char *hexkey, short mode, uint32_t *KnL, uint32_t *KnR, uint32_t *Kn3) +{ + const char *first, *third; + short revmod; + + if( mode == EN0 ) + { + revmod = DE1; + first = hexkey; + third = &hexkey[16]; + } + else + { + revmod = EN0; + first = &hexkey[16]; + third = hexkey; + } + deskey(&hexkey[8], revmod, KnR); + deskey(third, mode, Kn3); + deskey(first, mode, KnL); +} + +void TC_Des::des3(const char *from, char *into, uint32_t *KnL, uint32_t *KnR, uint32_t *Kn3) +{ + uint32_t work[2]; + + scrunch(from, work); + desfunc(work, KnL); + desfunc(work, KnR); + desfunc(work, Kn3); + unscrun(work, into); +} + +string TC_Des::encrypt(const char *key, const char * sIn, size_t iInlen) +{ + char des_key[8] = {0}; + char des_input[8] = {0}; + char des_output[8] = {0}; + + //准备key + memcpy(des_key, key, sizeof(des_key)); + uint32_t KnL[32] = {0}; + deskey(des_key, EN0, KnL); + + int mod = iInlen % sizeof(des_input); + size_t k = 0; + string ret; + for(k = 0; k < iInlen / sizeof(des_input); k++) + { + memcpy(des_input, (sIn + k * sizeof(des_input)), sizeof(des_input)); + + des(des_input, des_output, KnL); + + for(size_t i = 0; i < sizeof(des_output); i++) + { + ret += des_output[i]; + } + } + + //设置填充值 + memset(des_input, sizeof(des_input) - mod, sizeof(des_input)); + memcpy(des_input, sIn + k * sizeof(des_input), mod); + des(des_input, des_output, KnL); + + for(unsigned int i = 0; i < sizeof(des_output); i++) + { + ret += des_output[i]; + } + + return ret; +} + +string TC_Des::decrypt(const char *key, const char * sIn, size_t iInlen) +{ + char des_key[8] = {0}; + char des_input[8] = {0}; + char des_output[8] = {0}; + + //准备key + memcpy(des_key, key, sizeof(des_key)); + uint32_t KnL[32] = {0}; + deskey(des_key, DE1, KnL); + + string ret; + size_t k = 0; + for(k = 0; k < iInlen / sizeof(des_input); k++) + { + memcpy(des_input, (sIn + k * sizeof(des_input)), sizeof(des_input)); + + des(des_input, des_output, KnL); + ret.append(des_output,sizeof(des_output)); + +#if 0 + for(size_t i = 0; i < sizeof(des_output); i++) + { + ret += des_output[i]; + } + #endif + } + + if(ret.length() > 0) + { + //去掉填充字符 + int pad = (int)(*(ret.end() - 1)); + if(pad>0 && pad<=(int)sizeof(des_output)&& (size_t)pad<=ret.length()) + { + bool bOk=true; + size_t iLengthBuf=ret.size(); + for(size_t iBuf=0;iBuf<(size_t)(pad-1);iBuf++) + { + if(ret[iLengthBuf-iBuf-2] != ret[iLengthBuf-1]) + { + bOk=false; + break; + } + } + if(bOk) + ret.erase(ret.end() - pad, ret.end()); + } + } + + return ret; +} + +string TC_Des::encrypt3(const char *key, const char * sIn, size_t iInlen) +{ + char des_key[24] = {0}; + memcpy(des_key, key, std::min(sizeof(des_key), strlen(key))); + + size_t len = (iInlen + ((size_t) 7)) & (~((size_t)7)); + size_t post_len = iInlen % 8; + if(post_len == 0) + { + len += 8; + } + + char *in_data = new char[len]; + char *out_data = new char[len]; + + memcpy(in_data, sIn, iInlen); + + //in_data不是8 的整数倍的话 + if ( post_len != 0) + { + for(size_t i = 0; i < 8 - post_len; i++) + { + *(in_data + iInlen + i) = (char)(8-post_len); + } + } + else + { + for(size_t i = 0; i < 8; i++) + { + *(in_data + iInlen + i) = 0x08; + } + } + + uint32_t KnL[32] = {0}; + uint32_t KnR[32] = {0}; + uint32_t Kn3[32] = {0}; + des3key(des_key, EN0, KnL, KnR, Kn3); + + size_t count = len/8; + + for(size_t i = 0; i < count; ++i) + { + des3(in_data + i * 8, out_data + i * 8, KnL, KnR, Kn3); + } + + string ret(out_data, len); + + delete []in_data; + delete []out_data; + + return ret; +} + +string TC_Des::decrypt3(const char *key, const char * sIn, size_t iInlen) +{ + try + { + char des_key[24] = {0}; + memcpy(des_key, key, min(sizeof(des_key), strlen(key))); + + size_t len = iInlen; + + char *in_data = new char[len]; + char *out_data = new char[len]; + + memcpy(in_data, sIn, iInlen); + + uint32_t KnL[32] = {0}; + uint32_t KnR[32] = {0}; + uint32_t Kn3[32] = {0}; + des3key(des_key, DE1, KnL, KnR, Kn3); + + size_t count = len/8; + + for(size_t i = 0; i < count; ++i) + { + des3(in_data + i * 8, out_data + i * 8, KnL, KnR, Kn3); + } + + string ret((char*)out_data, len); + + if(ret.length() > 0) + { + //去掉填充字符 + int pad = (int)(*(ret.end() - 1)); + ret.erase(ret.end() - pad, ret.end()); + } + + delete []in_data; + delete []out_data; + + return ret; + } + catch(TC_DES_Exception &e) + { + string res = "TC_Des::decrypt3 error" + string(e.what()); + throw TC_DES_Exception(res); + } +} + +} + + + diff --git a/util/src/tc_epoll_server.cpp b/util/src/tc_epoll_server.cpp index eaf74ef..45e9226 100644 --- a/util/src/tc_epoll_server.cpp +++ b/util/src/tc_epoll_server.cpp @@ -52,7 +52,7 @@ static const int BUFFER_SIZE = 8 * 1024; ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // handle的实现 -TC_EpollServer::Handle::Handle() +TC_EpollServer::Handle::Handle() : _pEpollServer(NULL) , _iWaitTime(100) { @@ -305,7 +305,6 @@ TC_EpollServer::BindAdapter::BindAdapter(TC_EpollServer *pEpollServer) , _iHeaderLen(0) , _iHeartBeatTime(0) , _protocolName("tars") -, _iBackPacketBuffLimit(0) { } @@ -317,14 +316,16 @@ TC_EpollServer::BindAdapter::~BindAdapter() void TC_EpollServer::BindAdapter::setProtocolName(const string& name) { - TC_ThreadLock::Lock lock(*this); + std::lock_guard lock (_mutex); _protocolName = name; } const string& TC_EpollServer::BindAdapter::getProtocolName() { - return _protocolName; + std::lock_guard lock (_mutex); + + return _protocolName; } bool TC_EpollServer::BindAdapter::isTarsProtocol() @@ -334,26 +335,26 @@ bool TC_EpollServer::BindAdapter::isTarsProtocol() bool TC_EpollServer::BindAdapter::isIpAllow(const string& ip) const { - TC_ThreadLock::Lock lock(*this); + std::lock_guard lock (_mutex); if(_eOrder == ALLOW_DENY) { - if(TC_Common::matchPeriod(ip,_vtAllow)) + if(TC_Common::matchPeriod(ip, _vtAllow)) { return true; } - if(TC_Common::matchPeriod(ip,_vtDeny)) + if(TC_Common::matchPeriod(ip, _vtDeny)) { return false; } } else { - if(TC_Common::matchPeriod(ip,_vtDeny)) + if(TC_Common::matchPeriod(ip, _vtDeny)) { return false; } - if(TC_Common::matchPeriod(ip,_vtAllow)) + if(TC_Common::matchPeriod(ip, _vtAllow)) { return true; } @@ -465,12 +466,6 @@ size_t TC_EpollServer::BindAdapter::getRecvBufferSize() const return _iBufferSize; } -TC_EpollServer* TC_EpollServer::BindAdapter::getEpollServer() -{ - return _pEpollServer; -} - - TC_NetWorkBuffer::PACKET_TYPE TC_EpollServer::BindAdapter::echo_protocol(TC_NetWorkBuffer &r, vector &o) { o = r.getBuffers(); @@ -487,13 +482,13 @@ TC_NetWorkBuffer::PACKET_TYPE TC_EpollServer::BindAdapter::echo_header_filter(TC void TC_EpollServer::BindAdapter::setName(const string &name) { - TC_ThreadLock::Lock lock(*this); - + std::lock_guard lock (_mutex); _name = name; } string TC_EpollServer::BindAdapter::getName() const { + std::lock_guard lock (_mutex); return _name; } @@ -502,11 +497,6 @@ int TC_EpollServer::BindAdapter::getHandleNum() return _iHandleNum; } -void TC_EpollServer::BindAdapter::setHandleNum(int n) -{ - _iHandleNum = n; -} - int TC_EpollServer::BindAdapter::getQueueCapacity() const { return _iQueueCapacity; @@ -519,22 +509,17 @@ void TC_EpollServer::BindAdapter::setQueueCapacity(int n) int TC_EpollServer::BindAdapter::isOverloadorDiscard() { - // int iRecvBufferSize = _rbuffer.size(); int iRecvBufferSize = _iBufferSize; - if(iRecvBufferSize <= (_iQueueCapacity / 2))//未过载 - { - return 0; - } - else if(iRecvBufferSize > (_iQueueCapacity / 2) && (iRecvBufferSize < _iQueueCapacity) && (_iQueueCapacity > 0))//overload + if(iRecvBufferSize > (int)(_iQueueCapacity / 5.*4) && (iRecvBufferSize < _iQueueCapacity) && (_iQueueCapacity > 0)) //overload { + //超过队列4/5开始认为过载 return -1; } - else//队列满需要丢弃接受的数据包 + else if(iRecvBufferSize > (int)(_iQueueCapacity) && _iQueueCapacity > 0)//队列满需要丢弃接受的数据包 { return -2; } - return 0; } @@ -558,7 +543,6 @@ int TC_EpollServer::BindAdapter::getQueueTimeout() const void TC_EpollServer::BindAdapter::setEndpoint(const string &str) { std::lock_guard lock (_mutex); - // TC_ThreadLock::Lock lock(*this); _ep.parse(str); } @@ -569,7 +553,7 @@ TC_Endpoint TC_EpollServer::BindAdapter::getEndpoint() const return _ep; } -TC_Socket& TC_EpollServer::BindAdapter::getSocket() +TC_Socket &TC_EpollServer::BindAdapter::getSocket() { return _s; } @@ -618,33 +602,29 @@ TC_EpollServer::BindAdapter::EOrder TC_EpollServer::BindAdapter::getOrder() cons return _eOrder; } -vector TC_EpollServer::BindAdapter::getAllow() const +const vector &TC_EpollServer::BindAdapter::getAllow() const { - std::lock_guard lock (_mutex); - return _vtAllow; } -vector TC_EpollServer::BindAdapter::getDeny() const +const vector &TC_EpollServer::BindAdapter::getDeny() const { - std::lock_guard lock (_mutex); - return _vtDeny; } bool TC_EpollServer::BindAdapter::isLimitMaxConnection() const { - return (_iCurConns + 1 > _iMaxConns) || (_iCurConns + 1 > ((int)((uint32_t)1 << 22) -1)); + return (_iCurConns + 1 > (size_t)_iMaxConns) || (_iCurConns + 1 > (int)((uint32_t)1 << 22) - 1); } void TC_EpollServer::BindAdapter::decreaseNowConnection() { - _iCurConns++; + --_iCurConns; } void TC_EpollServer::BindAdapter::increaseNowConnection() { - _iCurConns--; + ++_iCurConns; } int TC_EpollServer::BindAdapter::getNowConnection() const @@ -657,7 +637,6 @@ vector TC_EpollServer::BindAdapter::getConnStatus() return _pEpollServer->getConnStatus(_s.getfd()); } - void TC_EpollServer::BindAdapter::setProtocol(const TC_NetWorkBuffer::protocol_functor &pf, int iHeaderLen, const TC_EpollServer::header_filter_functor &hf) { _pf = pf; @@ -682,19 +661,18 @@ int TC_EpollServer::BindAdapter::getHeaderFilterLen() return _iHeaderLen; } -void TC_EpollServer::BindAdapter::setBackPacketBuffLimit(size_t iLimitSize) -{ - _iBackPacketBuffLimit = iLimitSize; -} +// void TC_EpollServer::BindAdapter::setBackPacketBuffLimit(size_t iLimitSize) +// { +// _iBackPacketBuffLimit = iLimitSize; +// } -size_t TC_EpollServer::BindAdapter::getBackPacketBuffLimit() -{ - return _iBackPacketBuffLimit; -} +// size_t TC_EpollServer::BindAdapter::getBackPacketBuffLimit() +// { +// return _iBackPacketBuffLimit; +// } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 服务连接 - TC_EpollServer::Connection::Connection(TC_EpollServer::BindAdapter *pBindAdapter, int lfd, int timeout, int fd, const string& ip, uint16_t port) : _pBindAdapter(pBindAdapter) , _uid(0) @@ -708,10 +686,14 @@ TC_EpollServer::Connection::Connection(TC_EpollServer::BindAdapter *pBindAdapter , _bClose(false) , _enType(EM_TCP) , _bEmptyConn(true) +, _pRecvBuffer(NULL) +, _nRecvBufferSize(DEFAULT_RECV_BUFFERSIZE) { assert(fd != -1); + _iLastRefreshTime = TNOW; + _sock.init(fd, true, pBindAdapter->_ep.isIPv6() ? AF_INET6 : AF_INET); } @@ -727,21 +709,23 @@ TC_EpollServer::Connection::Connection(BindAdapter *pBindAdapter, int fd) , _bClose(false) , _enType(EM_UDP) , _bEmptyConn(false) /*udp is always false*/ +, _pRecvBuffer(NULL) +, _nRecvBufferSize(DEFAULT_RECV_BUFFERSIZE) { _iLastRefreshTime = TNOW; + _sock.init(fd, false, pBindAdapter->_ep.isIPv6() ? AF_INET6 : AF_INET); } TC_EpollServer::Connection::~Connection() { - if(_pRecvBuffer) + if (_pRecvBuffer) { delete _pRecvBuffer; _pRecvBuffer = NULL; } - // clearSlices(_sendBuffer); if (isTcp()) { assert(!_sock.isValid()); @@ -759,8 +743,6 @@ void TC_EpollServer::Connection::tryInitAuthState(int initState) void TC_EpollServer::Connection::close() { - if(isTcp()) - { #if TARS_SSL if (_openssl) { @@ -768,10 +750,10 @@ void TC_EpollServer::Connection::close() _openssl.reset(); } #endif - if(_sock.isValid()) - { - _sock.close(); - } + + if (isTcp() && _sock.isValid()) + { + _sock.close(); } } @@ -814,7 +796,7 @@ int TC_EpollServer::Connection::parseProtocol(TC_NetWorkBuffer &rbuf) //需要过滤首包包头 if(_iHeaderLen > 0) { - if(rbuf.getBufferLength() >= (unsigned) _iHeaderLen) + if(rbuf.getBufferLength() >= (unsigned)_iHeaderLen) { vector header; rbuf.getHeader(_iHeaderLen, header); @@ -835,6 +817,7 @@ int TC_EpollServer::Connection::parseProtocol(TC_NetWorkBuffer &rbuf) vector ro; TC_NetWorkBuffer::PACKET_TYPE b = _pBindAdapter->getProtocol()(rbuf, ro); + if(b == TC_NetWorkBuffer::PACKET_LESS) { break; @@ -856,8 +839,8 @@ int TC_EpollServer::Connection::parseProtocol(TC_NetWorkBuffer &rbuf) } else { - _pBindAdapter->getEpollServer()->error("recv [" + _ip + ":" + TC_Common::tostr(_port) + "],packet error."); - return -1; //协议解析错误 + _pBindAdapter->getEpollServer()->error("recv [" + _ip + ":" + TC_Common::tostr(_port) + "], packet parse error."); + return -1; //协议解析错误 } } } @@ -891,9 +874,6 @@ int TC_EpollServer::Connection::recvTcp() { if (TC_Socket::isPending()) { -//#if TARGET_PLATFORM_WINDOWS -// _pBindAdapter->getNetThreadOfFd(_sock.getfd())->getEpoller()->mod(_sock.getfd(), getId(), EPOLLIN | EPOLLOUT); -//#endif //没有数据了 break; } @@ -912,7 +892,6 @@ int TC_EpollServer::Connection::recvTcp() } else { -// cout << "totalRecv:" << totalRecv << endl; #if TARS_SSL if (_pBindAdapter->getEndpoint().isSSL()) @@ -977,9 +956,6 @@ int TC_EpollServer::Connection::recvUdp() { if (TC_Socket::isPending())//errno == EAGAIN) { -//#if TARGET_PLATFORM_WINDOWS -// _pBindAdapter->getNetThreadOfFd(_sock.getfd())->getEpoller()->mod(_sock.getfd(), getId(), EPOLLIN | EPOLLOUT); -//#endif //没有数据了 break; } @@ -1044,10 +1020,6 @@ int TC_EpollServer::Connection::sendBuffer() { if (TC_Socket::isPending()) { -//#if TARGET_PLATFORM_WINDOWS -// _pBindAdapter->getNetThreadOfFd(_sock.getfd())->getEpoller()->mod(_sock.getfd(), getId(), EPOLLIN | EPOLLOUT); -//#endif - break; } else @@ -1110,15 +1082,12 @@ int TC_EpollServer::Connection::sendUdp(const shared_ptr &sc) { //udp的直接发送即可 int iRet = _sock.sendto((const void *) sc->buffer()->buffer(), sc->buffer()->length(), sc->ip(), sc->port(), 0); - if (iRet < 0 && !TC_Socket::isPending()) + if (iRet < 0) { _pBindAdapter->getEpollServer()->error("[TC_EpollServer::Connection] send [" + _ip + ":" + TC_Common::tostr(_port) + "] error"); return -1; } -//#if TARGET_PLATFORM_WINDOWS -// _pBindAdapter->getNetThreadOfFd(_sock.getfd())->getEpoller()->mod(_sock.getfd(), getId(), EPOLLIN | EPOLLOUT); -//#endif return 0; } @@ -1155,12 +1124,12 @@ bool TC_EpollServer::Connection::setClose() //////////////////////////////////////////////////////////////// // TC_EpollServer::ConnectionList::ConnectionList(TC_EpollServer::NetThread *pEpollServer) -:_pEpollServer(pEpollServer) -,_total(0) -,_free_size(0) -,_vConn(NULL) -,_lastTimeoutTime(0) -,_iConnectionMagic(0) +: _pEpollServer(pEpollServer) +, _total(0) +, _free_size(0) +, _vConn(NULL) +, _lastTimeoutTime(0) +, _iConnectionMagic(0) { } @@ -1170,10 +1139,10 @@ void TC_EpollServer::ConnectionList::init(uint32_t size, uint32_t iIndex) _total = size; - _free_size = 0; + _free_size = 0; //初始化链接链表 - if(_vConn) delete[] _vConn; + if (_vConn) delete[] _vConn; //分配total+1个空间(多分配一个空间, 第一个空间其实无效) _vConn = new list_data[_total+1]; @@ -1193,7 +1162,7 @@ void TC_EpollServer::ConnectionList::init(uint32_t size, uint32_t iIndex) uint32_t TC_EpollServer::ConnectionList::getUniqId() { - TC_ThreadLock::Lock lock(*this); + TC_LockT lock(_mutex); uint32_t uid = _free.front(); @@ -1218,7 +1187,7 @@ TC_EpollServer::Connection* TC_EpollServer::ConnectionList::get(uint32_t uid) void TC_EpollServer::ConnectionList::add(Connection *cPtr, time_t iTimeOutStamp) { - TC_LockT lock(_mutex); + TC_LockT lock(_mutex); uint32_t muid = cPtr->getId(); uint32_t magi = muid & (0xFFFFFFFF << 22); @@ -1231,7 +1200,7 @@ void TC_EpollServer::ConnectionList::add(Connection *cPtr, time_t iTimeOutStamp) void TC_EpollServer::ConnectionList::refresh(uint32_t uid, time_t iTimeOutStamp) { - TC_LockT lock(_mutex); + TC_LockT lock(_mutex); uint32_t magi = uid & (0xFFFFFFFF << 22); uid = uid & (0x7FFFFFFF >> 9); @@ -1261,7 +1230,6 @@ void TC_EpollServer::ConnectionList::checkTimeout(time_t iCurTime) _lastTimeoutTime = iCurTime; TC_LockT lock(_mutex); - // TC_ThreadLock::Lock lock(*this); multimap::iterator it = _tl.begin(); @@ -1284,13 +1252,12 @@ void TC_EpollServer::ConnectionList::checkTimeout(time_t iCurTime) } //超时关闭 - _pEpollServer->delConnection(_vConn[uid].first, false,EM_SERVER_TIMEOUT_CLOSE); + _pEpollServer->delConnection(_vConn[uid].first, false, EM_SERVER_TIMEOUT_CLOSE); //从链表中删除 _del(uid); } - if(_pEpollServer->isEmptyConnCheck()) { it = _tl.begin(); @@ -1304,7 +1271,7 @@ void TC_EpollServer::ConnectionList::checkTimeout(time_t iCurTime) //获取空连接的超时时间点 time_t iEmptyTimeout = (it->first - _vConn[uid].first->getTimeout()) + (_pEpollServer->getEmptyConnTimeout()/1000); - //已经检查到当前时间点了, 后续不用在检查了 + //已经检查到当前时间点了, 后续不用在检查了 if(iEmptyTimeout > iCurTime) { break; @@ -1318,7 +1285,7 @@ void TC_EpollServer::ConnectionList::checkTimeout(time_t iCurTime) } //超时关闭 - _pEpollServer->delConnection(_vConn[uid].first, false,EM_SERVER_TIMEOUT_CLOSE); + _pEpollServer->delConnection(_vConn[uid].first, false, EM_SERVER_TIMEOUT_CLOSE); //从链表中删除 _del(uid); @@ -1342,11 +1309,11 @@ vector TC_EpollServer::ConnectionList::getConnStatus { TC_EpollServer::ConnStatus cs; - cs.iLastRefreshTime = _vConn[i].first->_iLastRefreshTime; - cs.ip = _vConn[i].first->getIp(); - cs.port = _vConn[i].first->getPort(); - cs.timeout = _vConn[i].first->getTimeout(); - cs.uid = _vConn[i].first->getId(); + cs.iLastRefreshTime = _vConn[i].first->_iLastRefreshTime; + cs.ip = _vConn[i].first->getIp(); + cs.port = _vConn[i].first->getPort(); + cs.timeout = _vConn[i].first->getTimeout(); + cs.uid = _vConn[i].first->getId(); v.push_back(cs); } @@ -1390,11 +1357,10 @@ size_t TC_EpollServer::ConnectionList::size() } //////////////////////////////NetThread////////////////////////////////// -TC_EpollServer::NetThread::NetThread(TC_EpollServer *epollServer, int index) +TC_EpollServer::NetThread::NetThread(TC_EpollServer *epollServer, int threadIndex) : _epollServer(epollServer) -, _threadIndex(index) +, _threadIndex(threadIndex) , _bTerminate(false) -, _handleStarted(false) , _list(this) , _bEmptyConnAttackCheck(false) , _iEmptyCheckTimeout(MIN_EMPTY_CONN_TIMEOUT) @@ -1410,47 +1376,47 @@ TC_EpollServer::NetThread::~NetThread() { } -void TC_EpollServer::NetThread::debug(const string &s) +void TC_EpollServer::NetThread::debug(const string &s) const { _epollServer->debug(s); } -void TC_EpollServer::NetThread::info(const string &s) +void TC_EpollServer::NetThread::info(const string &s) const { _epollServer->info(s); } -void TC_EpollServer::NetThread::tars(const string &s) +void TC_EpollServer::NetThread::tars(const string &s) const { _epollServer->tars(s); } -void TC_EpollServer::NetThread::error(const string &s) +void TC_EpollServer::NetThread::error(const string &s) const { _epollServer->error(s); } void TC_EpollServer::NetThread::enAntiEmptyConnAttack(bool bEnable) { - _bEmptyConnAttackCheck = bEnable; + _bEmptyConnAttackCheck = bEnable; } void TC_EpollServer::NetThread::setEmptyConnTimeout(int timeout) { - _iEmptyCheckTimeout = (timeout>=MIN_EMPTY_CONN_TIMEOUT)?timeout:MIN_EMPTY_CONN_TIMEOUT; + _iEmptyCheckTimeout = (timeout >= MIN_EMPTY_CONN_TIMEOUT) ? timeout : MIN_EMPTY_CONN_TIMEOUT; } void TC_EpollServer::NetThread::setUdpRecvBufferSize(size_t nSize) { - _nUdpRecvBufferSize = (nSize >= 8192 && nSize <=DEFAULT_RECV_BUFFERSIZE)?nSize:DEFAULT_RECV_BUFFERSIZE; + _nUdpRecvBufferSize = (nSize >= 8192 && nSize <= DEFAULT_RECV_BUFFERSIZE) ? nSize : DEFAULT_RECV_BUFFERSIZE; } bool TC_EpollServer::NetThread::isEmptyConnCheck() const { - return _bEmptyConnAttackCheck; + return _bEmptyConnAttackCheck; } -int TC_EpollServer::NetThread::getEmptyConnTimeout() const +int TC_EpollServer::NetThread::getEmptyConnTimeout() const { return _iEmptyCheckTimeout; } @@ -1531,7 +1497,7 @@ void TC_EpollServer::NetThread::addTcpConnection(TC_EpollServer::Connection *cPt } } #endif - //注意epoll add必须放在最后, 否则可能导致执行完, 才调用上面语句 + //注意epoll add必须放在最后, 否则可能导致执行完, 才调用上面语句 _epoller.add(cPtr->getfd(), cPtr->getId(), EPOLLIN | EPOLLOUT); } @@ -1551,7 +1517,7 @@ vector TC_EpollServer::NetThread::getConnStatus(int return _list.getConnStatus(lfd); } -void TC_EpollServer::NetThread::delConnection(TC_EpollServer::Connection *cPtr, bool bEraseList,EM_CLOSE_T closeType) +void TC_EpollServer::NetThread::delConnection(TC_EpollServer::Connection *cPtr, bool bEraseList, EM_CLOSE_T closeType) { //如果是TCP的连接才真正的关闭连接 if (cPtr->getListenfd() != -1) @@ -1559,7 +1525,7 @@ void TC_EpollServer::NetThread::delConnection(TC_EpollServer::Connection *cPtr, //false的情况,是超时被主动删除 if(!bEraseList) { - info("timeout [" + cPtr->getIp() + ":" + TC_Common::tostr(cPtr->getPort()) + "] del from list"); + tars("timeout [" + cPtr->getIp() + ":" + TC_Common::tostr(cPtr->getPort()) + "] del from list"); } uint32_t uid = cPtr->getId(); @@ -1635,44 +1601,50 @@ void TC_EpollServer::NetThread::processPipe() while(!_sbuffer.empty()) { - shared_ptr sc = _sbuffer.front(); - + shared_ptr sc = _sbuffer.front(); Connection *cPtr = getConnectionPtr(sc->uid()); - if (cPtr) { - switch (sc->cmd()) { - case 'c': { - if (cPtr->setClose()) { - delConnection(cPtr, true, EM_SERVER_CLOSE); - } - break; - } - case 's': { - int ret = 0; -#if TARS_SSL - if (cPtr->getBindAdapter()->getEndpoint().isSSL()) { - if (!cPtr->_openssl->isHandshaked()) { - return; - } - } - ret = cPtr->send(sc); -#else - ret = cPtr->send(sc); -#endif - if (ret < 0) { - delConnection(cPtr, true, (ret == -1) ? EM_CLIENT_CLOSE : EM_SERVER_CLOSE); - } - else { - _list.refresh(sc->uid(), cPtr->getTimeout() + TNOW); - } - break; - } - default: - assert(false); - } + if (!cPtr) + { + continue; } - - _sbuffer.pop_front(); + switch (sc->cmd()) + { + case 'c': + { + if (cPtr->setClose()) + { + delConnection(cPtr, true, EM_SERVER_CLOSE); + } + break; + } + case 's': + { + int ret = 0; +#if TARS_SSL + if (cPtr->getBindAdapter()->getEndpoint().isSSL()) { + if (!cPtr->_openssl->isHandshaked()) { + return; + } + } + ret = cPtr->send(sc); +#else + ret = cPtr->send(sc); +#endif + if (ret < 0) + { + delConnection(cPtr, true, (ret == -1) ? EM_CLIENT_CLOSE : EM_SERVER_CLOSE); + } + else + { + _list.refresh(sc->uid(), cPtr->getTimeout() + TNOW); + } + break; + } + default: + assert(false); + } + _sbuffer.pop_front(); } } @@ -1697,7 +1669,6 @@ void TC_EpollServer::NetThread::processNet(const epoll_event &ev) if (TC_Epoller::readEvent(ev)) { int ret = cPtr->recv(); - if (ret < 0) { delConnection(cPtr, true, EM_CLIENT_CLOSE); @@ -1735,7 +1706,7 @@ void TC_EpollServer::NetThread::run() } } - //循环监听网路连接请求 + //循环监听网路连接请求 while(!_bTerminate) { _list.checkTimeout(TNOW); @@ -1783,6 +1754,7 @@ void TC_EpollServer::NetThread::run() } } } + size_t TC_EpollServer::NetThread::getSendRspSize() { return _sbuffer.size(); @@ -1792,7 +1764,7 @@ TC_EpollServer::TC_EpollServer(unsigned int iNetThreadNum) : _netThreadNum(iNetThreadNum) , _bTerminate(false) , _handleStarted(false) -, _pLocalLogger(NULL) +, _pLocalLogger(NULL) { #if TARGET_PLATFORM_WINDOWS WSADATA wsadata; @@ -1816,7 +1788,7 @@ TC_EpollServer::TC_EpollServer(unsigned int iNetThreadNum) _notify.init(&_epoller); _notify.add(_notify.notifyFd()); - for (size_t i = 0; i < _netThreadNum; ++i) + for (size_t i = 0; i < _netThreadNum; ++i) { TC_EpollServer::NetThread* netThreads = new TC_EpollServer::NetThread(this, i); _netThreads.push_back(netThreads); @@ -1854,7 +1826,6 @@ void TC_EpollServer::applicationCallback(TC_EpollServer *epollServer) { } - bool TC_EpollServer::accept(int fd, int domain) { struct sockaddr_in stSockAddr4; @@ -1946,7 +1917,7 @@ void TC_EpollServer::waitForShutdown() while (!_bTerminate) { - int iEvNum = _epoller.wait(1000); + int iEvNum = _epoller.wait(300); if (_bTerminate) break; @@ -2002,7 +1973,7 @@ void TC_EpollServer::waitForShutdown() } catch (...) { - error("run exception"); + error("TC_EpollServer::waitForShutdown unknown error"); } } } @@ -2049,7 +2020,6 @@ void TC_EpollServer::setEmptyConnTimeout(int timeout) } } - void TC_EpollServer::bind(const TC_Endpoint &ep, TC_Socket &s, bool manualListen) { #if TARGET_PLATFORM_WINDOWS @@ -2124,7 +2094,7 @@ int TC_EpollServer::bind(BindAdapterPtr &lsPtr) return s.getfd(); } -void TC_EpollServer::addConnection(TC_EpollServer::Connection * cPtr, int fd, TC_EpollServer::CONN_TYPE iType) +void TC_EpollServer::addConnection(TC_EpollServer::Connection *cPtr, int fd, TC_EpollServer::CONN_TYPE iType) { TC_EpollServer::NetThread* netThread = getNetThreadOfFd(fd); @@ -2265,7 +2235,7 @@ void TC_EpollServer::send(const shared_ptr &data) netThread->send(data); } -void TC_EpollServer::debug(const string &s) +void TC_EpollServer::debug(const string &s) const { if(_pLocalLogger) { @@ -2273,7 +2243,7 @@ void TC_EpollServer::debug(const string &s) } } -void TC_EpollServer::info(const string &s) +void TC_EpollServer::info(const string &s) const { if(_pLocalLogger) { @@ -2281,7 +2251,7 @@ void TC_EpollServer::info(const string &s) } } -void TC_EpollServer::tars(const string &s) +void TC_EpollServer::tars(const string &s) const { if(_pLocalLogger) { @@ -2289,7 +2259,7 @@ void TC_EpollServer::tars(const string &s) } } -void TC_EpollServer::error(const string &s) +void TC_EpollServer::error(const string &s) const { if(_pLocalLogger) { @@ -2311,7 +2281,6 @@ vector TC_EpollServer::getConnStatus(int lfd) return vConnStatus; } - unordered_map TC_EpollServer::getListenSocketInfo() { return _listeners; diff --git a/util/src/tc_gzip.cpp b/util/src/tc_gzip.cpp index 969e213..6102677 100644 --- a/util/src/tc_gzip.cpp +++ b/util/src/tc_gzip.cpp @@ -22,10 +22,66 @@ #include #include - namespace tars { +bool TC_GZip::compress(const char *src, size_t length, string& buffer) +{ + z_stream stream; + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + + if (deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK) + { + return false; + } + + buffer.clear(); + + static char gz_simple_header[] = { '\037', '\213', '\010', '\000', '\000', '\000', '\000', '\000', '\002', '\377' }; + + size_t destLen = sizeof(gz_simple_header) + length * 2; + char *out = new char[destLen]; + + stream.next_out = (Bytef *)out; + stream.avail_out = destLen; + + stream.next_in = (Bytef *)src; + stream.avail_in = length; + + memcpy(stream.next_out, gz_simple_header, sizeof(gz_simple_header)); + stream.next_out += sizeof(gz_simple_header); + stream.avail_out -= sizeof(gz_simple_header); + + int r = deflate(&stream, Z_FINISH); + if (r != Z_STREAM_END) + { + delete[] out; + return false; + } + + destLen = destLen - stream.avail_out; + + uLong crc = crc32(0, Z_NULL, 0); + + crc = crc32(crc, (const Bytef *)src, length); + + memcpy(out + destLen, &crc, 4); + + memcpy(out + destLen + 4, &length, 4); + + destLen += 8; + + buffer.append(out, destLen); + + delete[] out; + + deflateEnd(&stream); + + return true; +} + bool TC_GZip::compress(const char *src, size_t length, vector& buffer) { buffer.clear(); diff --git a/util/src/tc_hashmap.cpp b/util/src/tc_hashmap.cpp index e57ee1e..8456a10 100755 --- a/util/src/tc_hashmap.cpp +++ b/util/src/tc_hashmap.cpp @@ -27,7 +27,7 @@ int TC_HashMap::Block::getBlockData(TC_HashMap::BlockData &data) data._synct = getSyncTime(); string s; - int ret = get(s); + int ret = get(s); if(ret != TC_HashMap::RT_OK) { @@ -59,238 +59,241 @@ int TC_HashMap::Block::getBlockData(TC_HashMap::BlockData &data) size_t TC_HashMap::Block::getLastBlockHead() { - size_t iHead = _iHead; + size_t iHead = _iHead; - while(getBlockHead(iHead)->_iBlockNext != 0) - { - iHead = getBlockHead(iHead)->_iBlockNext; - } - return iHead; + while(getBlockHead(iHead)->_iBlockNext != 0) + { + iHead = getBlockHead(iHead)->_iBlockNext; + } + return iHead; } int TC_HashMap::Block::get(void *pData, size_t &iDataLen) { - //没有下一个chunk, 一个chunk就可以装下数据了 - if(!getBlockHead()->_bNextChunk) - { - memcpy(pData, getBlockHead()->_cData, min(getBlockHead()->_iDataLen, iDataLen)); - iDataLen = getBlockHead()->_iDataLen; - return TC_HashMap::RT_OK; - } - else - { - size_t iUseSize = getBlockHead()->_iSize - sizeof(tagBlockHead); - size_t iCopyLen = min(iUseSize, iDataLen); + //没有下一个chunk, 一个chunk就可以装下数据了 + if(!getBlockHead()->_bNextChunk) + { + memcpy(pData, getBlockHead()->_cData, min(getBlockHead()->_iDataLen, iDataLen)); + iDataLen = getBlockHead()->_iDataLen; + return TC_HashMap::RT_OK; + } + else + { + size_t iUseSize = getBlockHead()->_iSize - sizeof(tagBlockHead); + size_t iCopyLen = min(iUseSize, iDataLen); - //copy到当前的block中 - memcpy(pData, getBlockHead()->_cData, iCopyLen); - if (iDataLen < iUseSize) - { - return TC_HashMap::RT_NOTALL_ERR; //copy数据不完全 - } + //copy到当前的block中 + memcpy(pData, getBlockHead()->_cData, iCopyLen); + if (iDataLen < iUseSize) + { + return TC_HashMap::RT_NOTALL_ERR; //copy数据不完全 + } - //已经copy长度 - size_t iHasLen = iCopyLen; - //最大剩余长度 - size_t iLeftLen = iDataLen - iCopyLen; + //已经copy长度 + size_t iHasLen = iCopyLen; + //最大剩余长度 + size_t iLeftLen = iDataLen - iCopyLen; - tagChunkHead *pChunk = getChunkHead(getBlockHead()->_iNextChunk); - while(iHasLen < iDataLen) - { + tagChunkHead *pChunk = getChunkHead(getBlockHead()->_iNextChunk); + while(iHasLen < iDataLen) + { iUseSize = pChunk->_iSize - sizeof(tagChunkHead); - if(!pChunk->_bNextChunk) - { - //copy到当前的chunk中 - size_t iCopyLen = min(pChunk->_iDataLen, iLeftLen); - memcpy((char*)pData + iHasLen, pChunk->_cData, iCopyLen); - iDataLen = iHasLen + iCopyLen; + if(!pChunk->_bNextChunk) + { + //copy到当前的chunk中 + size_t iCopyLen = min(pChunk->_iDataLen, iLeftLen); + memcpy((char*)pData + iHasLen, pChunk->_cData, iCopyLen); + iDataLen = iHasLen + iCopyLen; - if(iLeftLen < pChunk->_iDataLen) - { - return TC_HashMap::RT_NOTALL_ERR; //copy不完全 - } + if(iLeftLen < pChunk->_iDataLen) + { + return TC_HashMap::RT_NOTALL_ERR; //copy不完全 + } - return TC_HashMap::RT_OK; - } - else - { - size_t iCopyLen = min(iUseSize, iLeftLen); - //copy当前的chunk - memcpy((char*)pData + iHasLen, pChunk->_cData, iCopyLen); - if (iLeftLen <= iUseSize) - { - iDataLen = iHasLen + iCopyLen; - return TC_HashMap::RT_NOTALL_ERR; //copy不完全 - } + return TC_HashMap::RT_OK; + } + else + { + size_t iCopyLen = min(iUseSize, iLeftLen); + //copy当前的chunk + memcpy((char*)pData + iHasLen, pChunk->_cData, iCopyLen); - //copy当前chunk完全 - iHasLen += iCopyLen; - iLeftLen -= iCopyLen; + // 这里有bug, = 的时候正好可以,不能返回出错! + //if (iLeftLen <= iUseSize) + if (iLeftLen < iUseSize) + { + iDataLen = iHasLen + iCopyLen; + return TC_HashMap::RT_NOTALL_ERR; //copy不完全 + } - pChunk = getChunkHead(pChunk->_iNextChunk); - } - } - } + //copy当前chunk完全 + iHasLen += iCopyLen; + iLeftLen -= iCopyLen; - return TC_HashMap::RT_OK; + pChunk = getChunkHead(pChunk->_iNextChunk); + } + } + } + + return TC_HashMap::RT_OK; } int TC_HashMap::Block::get(string &s) { - size_t iLen = getDataLen(); + size_t iLen = getDataLen(); - char *cData = new char[iLen]; - size_t iGetLen = iLen; - int ret = get(cData, iGetLen); - if(ret == TC_HashMap::RT_OK) - { - s.assign(cData, iGetLen); - } + char *cData = new char[iLen]; + size_t iGetLen = iLen; + int ret = get(cData, iGetLen); + if(ret == TC_HashMap::RT_OK) + { + s.assign(cData, iGetLen); + } - delete[] cData; + delete[] cData; - return ret; + return ret; } int TC_HashMap::Block::set(const void *pData, size_t iDataLen, bool bOnlyKey, vector &vtData) { - //首先分配刚刚够的长度, 不能多一个chunk, 也不能少一个chunk - int ret = allocate(iDataLen, vtData); - if(ret != TC_HashMap::RT_OK) - { - return ret; - } + //首先分配刚刚够的长度, 不能多一个chunk, 也不能少一个chunk + int ret = allocate(iDataLen, vtData); + if(ret != TC_HashMap::RT_OK) + { + return ret; + } - if(bOnlyKey) - { - //原始数据是脏数据 - if(getBlockHead()->_bDirty) - { - _pMap->delDirtyCount(); - } + if(bOnlyKey) + { + //原始数据是脏数据 + if(getBlockHead()->_bDirty) + { + _pMap->delDirtyCount(); + } - //数据被修改, 设置为脏数据 - getBlockHead()->_bDirty = false; + //数据被修改, 设置为脏数据 + getBlockHead()->_bDirty = false; - //原始数据不是OnlyKey数据 - if(!getBlockHead()->_bOnlyKey) - { - _pMap->incOnlyKeyCount(); - } - } - else - { - //原始数据不是脏数据 - if(!getBlockHead()->_bDirty) - { - _pMap->incDirtyCount(); - } + //原始数据不是OnlyKey数据 + if(!getBlockHead()->_bOnlyKey) + { + _pMap->incOnlyKeyCount(); + } + } + else + { + //原始数据不是脏数据 + if(!getBlockHead()->_bDirty) + { + _pMap->incDirtyCount(); + } - //数据被修改, 设置为脏数据 - getBlockHead()->_bDirty = true; + //数据被修改, 设置为脏数据 + getBlockHead()->_bDirty = true; - //原始数据是OnlyKey数据 - if(getBlockHead()->_bOnlyKey) - { - _pMap->delOnlyKeyCount(); - } - } + //原始数据是OnlyKey数据 + if(getBlockHead()->_bOnlyKey) + { + _pMap->delOnlyKeyCount(); + } + } //设置是否只有Key getBlockHead()->_bOnlyKey = bOnlyKey; - size_t iUseSize = getBlockHead()->_iSize - sizeof(tagBlockHead); - //没有下一个chunk, 一个chunk就可以装下数据了 - if(!getBlockHead()->_bNextChunk) - { - memcpy(getBlockHead()->_cData, (char*)pData, iDataLen); - //先copy数据, 再复制数据长度 - getBlockHead()->_iDataLen = iDataLen; - } - else - { - //copy到当前的block中 - memcpy(getBlockHead()->_cData, (char*)pData, iUseSize); - //剩余程度 - size_t iLeftLen = iDataLen - iUseSize; - size_t iCopyLen = iUseSize; + size_t iUseSize = getBlockHead()->_iSize - sizeof(tagBlockHead); + //没有下一个chunk, 一个chunk就可以装下数据了 + if(!getBlockHead()->_bNextChunk) + { + memcpy(getBlockHead()->_cData, (char*)pData, iDataLen); + //先copy数据, 再复制数据长度 + getBlockHead()->_iDataLen = iDataLen; + } + else + { + //copy到当前的block中 + memcpy(getBlockHead()->_cData, (char*)pData, iUseSize); + //剩余程度 + size_t iLeftLen = iDataLen - iUseSize; + size_t iCopyLen = iUseSize; - tagChunkHead *pChunk = getChunkHead(getBlockHead()->_iNextChunk); - while(true) - { + tagChunkHead *pChunk = getChunkHead(getBlockHead()->_iNextChunk); + while(true) + { //计算chunk的可用大小 iUseSize = pChunk->_iSize - sizeof(tagChunkHead); - if(!pChunk->_bNextChunk) - { + if(!pChunk->_bNextChunk) + { assert(iUseSize >= iLeftLen); - //copy到当前的chunk中 - memcpy(pChunk->_cData, (char*)pData + iCopyLen, iLeftLen); - //最后一个chunk, 才有数据长度, 先copy数据再赋值长度 - pChunk->_iDataLen = iLeftLen; - iCopyLen += iLeftLen; - iLeftLen -= iLeftLen; - break; - } - else - { - //copy到当前的chunk中 - memcpy(pChunk->_cData, (char*)pData + iCopyLen, iUseSize); - iCopyLen += iUseSize; - iLeftLen -= iUseSize; + //copy到当前的chunk中 + memcpy(pChunk->_cData, (char*)pData + iCopyLen, iLeftLen); + //最后一个chunk, 才有数据长度, 先copy数据再赋值长度 + pChunk->_iDataLen = iLeftLen; + iCopyLen += iLeftLen; + iLeftLen -= iLeftLen; + break; + } + else + { + //copy到当前的chunk中 + memcpy(pChunk->_cData, (char*)pData + iCopyLen, iUseSize); + iCopyLen += iUseSize; + iLeftLen -= iUseSize; - pChunk = getChunkHead(pChunk->_iNextChunk); - } - } + pChunk = getChunkHead(pChunk->_iNextChunk); + } + } assert(iLeftLen == 0); - } + } - _pMap->doUpdate(true); - return TC_HashMap::RT_OK; + _pMap->doUpdate(true); + return TC_HashMap::RT_OK; } void TC_HashMap::Block::setDirty(bool b) { - if(getBlockHead()->_bDirty != b) - { - if (b) - { - _pMap->incDirtyCount(); - } - else - { - _pMap->delDirtyCount(); - } - _pMap->update(&getBlockHead()->_bDirty, b); + if(getBlockHead()->_bDirty != b) + { + if (b) + { + _pMap->incDirtyCount(); + } + else + { + _pMap->delDirtyCount(); + } + _pMap->update(&getBlockHead()->_bDirty, b); _pMap->doUpdate(true); - } + } } bool TC_HashMap::Block::nextBlock() { - _iHead = getBlockHead()->_iBlockNext; + _iHead = getBlockHead()->_iBlockNext; - return _iHead != 0; + return _iHead != 0; } bool TC_HashMap::Block::prevBlock() { - _iHead = getBlockHead()->_iBlockPrev; + _iHead = getBlockHead()->_iBlockPrev; - return _iHead != 0; + return _iHead != 0; } void TC_HashMap::Block::deallocate() { - vector v; - v.push_back(_iHead); + vector v; + v.push_back(_iHead); - if(getBlockHead()->_bNextChunk) - { - deallocate(getBlockHead()->_iNextChunk); - } + if(getBlockHead()->_bNextChunk) + { + deallocate(getBlockHead()->_iNextChunk); + } - _pMap->_pDataAllocator->deallocateMemBlock(v); + _pMap->_pDataAllocator->deallocateMemBlock(v); } void TC_HashMap::Block::makeNew(size_t index, size_t iAllocSize) @@ -309,68 +312,68 @@ void TC_HashMap::Block::makeNew(size_t index, size_t iAllocSize) getBlockHead()->_bDirty = true; getBlockHead()->_bOnlyKey = false; - _pMap->incDirtyCount(); - _pMap->incElementCount(); - _pMap->incListCount(index); + _pMap->incDirtyCount(); + _pMap->incElementCount(); + _pMap->incListCount((uint32_t)index); - //挂在block链表上 - if(_pMap->item(index)->_iBlockAddr == 0) - { - //当前hash桶没有元素 - _pMap->update(&_pMap->item(index)->_iBlockAddr, _iHead); - _pMap->update(&getBlockHead()->_iBlockNext, (size_t)0); - _pMap->update(&getBlockHead()->_iBlockPrev, (size_t)0); - } - else - { - //当然hash桶有元素, 挂在桶开头 - _pMap->update(&getBlockHead(_pMap->item(index)->_iBlockAddr)->_iBlockPrev, _iHead); - _pMap->update(&getBlockHead()->_iBlockNext, _pMap->item(index)->_iBlockAddr); - _pMap->update(&_pMap->item(index)->_iBlockAddr, _iHead); - _pMap->update(&getBlockHead()->_iBlockPrev, (size_t)0); - } + //挂在block链表上 + if(_pMap->item(index)->_iBlockAddr == 0) + { + //当前hash桶没有元素 + _pMap->update(&_pMap->item(index)->_iBlockAddr, _iHead); + _pMap->update(&getBlockHead()->_iBlockNext, (size_t)0); + _pMap->update(&getBlockHead()->_iBlockPrev, (size_t)0); + } + else + { + //当然hash桶有元素, 挂在桶开头 + _pMap->update(&getBlockHead(_pMap->item(index)->_iBlockAddr)->_iBlockPrev, _iHead); + _pMap->update(&getBlockHead()->_iBlockNext, _pMap->item(index)->_iBlockAddr); + _pMap->update(&_pMap->item(index)->_iBlockAddr, _iHead); + _pMap->update(&getBlockHead()->_iBlockPrev, (size_t)0); + } - //挂在Set链表的头部 - if(_pMap->_pHead->_iSetHead == 0) - { - assert(_pMap->_pHead->_iSetTail == 0); - _pMap->update(&_pMap->_pHead->_iSetHead, _iHead); - _pMap->update(&_pMap->_pHead->_iSetTail, _iHead); - } - else - { + //挂在Set链表的头部 + if(_pMap->_pHead->_iSetHead == 0) + { + assert(_pMap->_pHead->_iSetTail == 0); + _pMap->update(&_pMap->_pHead->_iSetHead, _iHead); + _pMap->update(&_pMap->_pHead->_iSetTail, _iHead); + } + else + { assert(_pMap->_pHead->_iSetTail != 0); - _pMap->update(&getBlockHead()->_iSetNext, _pMap->_pHead->_iSetHead); - _pMap->update(&getBlockHead(_pMap->_pHead->_iSetHead)->_iSetPrev, _iHead); - _pMap->update(&_pMap->_pHead->_iSetHead, _iHead); - } + _pMap->update(&getBlockHead()->_iSetNext, _pMap->_pHead->_iSetHead); + _pMap->update(&getBlockHead(_pMap->_pHead->_iSetHead)->_iSetPrev, _iHead); + _pMap->update(&_pMap->_pHead->_iSetHead, _iHead); + } //挂在Get链表头部 - if(_pMap->_pHead->_iGetHead == 0) - { - assert(_pMap->_pHead->_iGetTail == 0); - _pMap->update(&_pMap->_pHead->_iGetHead, _iHead); - _pMap->update(&_pMap->_pHead->_iGetTail, _iHead); - } - else - { + if(_pMap->_pHead->_iGetHead == 0) + { + assert(_pMap->_pHead->_iGetTail == 0); + _pMap->update(&_pMap->_pHead->_iGetHead, _iHead); + _pMap->update(&_pMap->_pHead->_iGetTail, _iHead); + } + else + { assert(_pMap->_pHead->_iGetTail != 0); - _pMap->update(&getBlockHead()->_iGetNext, _pMap->_pHead->_iGetHead); - _pMap->update(&getBlockHead(_pMap->_pHead->_iGetHead)->_iGetPrev, _iHead); - _pMap->update(&_pMap->_pHead->_iGetHead, _iHead); - } + _pMap->update(&getBlockHead()->_iGetNext, _pMap->_pHead->_iGetHead); + _pMap->update(&getBlockHead(_pMap->_pHead->_iGetHead)->_iGetPrev, _iHead); + _pMap->update(&_pMap->_pHead->_iGetHead, _iHead); + } - //一次写更新操作 - _pMap->doUpdate(true); + //一次写更新操作 + _pMap->doUpdate(true); } void TC_HashMap::Block::erase() { - //////////////////修改脏数据链表///////////// - if(_pMap->_pHead->_iDirtyTail == _iHead) - { - _pMap->update(&_pMap->_pHead->_iDirtyTail, getBlockHead()->_iSetPrev); - } + //////////////////修改脏数据链表///////////// + if(_pMap->_pHead->_iDirtyTail == _iHead) + { + _pMap->update(&_pMap->_pHead->_iDirtyTail, getBlockHead()->_iSetPrev); + } //////////////////修改回写数据链表///////////// if(_pMap->_pHead->_iSyncTail == _iHead) @@ -384,120 +387,120 @@ void TC_HashMap::Block::erase() _pMap->update(&_pMap->_pHead->_iBackupTail, getBlockHead()->_iGetPrev); } - ////////////////////修改Set链表的数据////////// + ////////////////////修改Set链表的数据////////// { - bool bHead = (_pMap->_pHead->_iSetHead == _iHead); - bool bTail = (_pMap->_pHead->_iSetTail == _iHead); + bool bHead = (_pMap->_pHead->_iSetHead == _iHead); + bool bTail = (_pMap->_pHead->_iSetTail == _iHead); - if(!bHead) - { - if(bTail) - { - assert(getBlockHead()->_iSetNext == 0); - //是尾部, 尾部指针指向上一个元素 - _pMap->update(&_pMap->_pHead->_iSetTail, getBlockHead()->_iSetPrev); - _pMap->update(&getBlockHead(getBlockHead()->_iSetPrev)->_iSetNext, (size_t)0); - } - else - { - //不是头部也不是尾部 - assert(getBlockHead()->_iSetNext != 0); - _pMap->update(&getBlockHead(getBlockHead()->_iSetPrev)->_iSetNext, getBlockHead()->_iSetNext); - _pMap->update(&getBlockHead(getBlockHead()->_iSetNext)->_iSetPrev, getBlockHead()->_iSetPrev); - } - } - else - { - if(bTail) - { - assert(getBlockHead()->_iSetNext == 0); - assert(getBlockHead()->_iSetPrev == 0); - //头部也是尾部, 指针都设置为0 - _pMap->update(&_pMap->_pHead->_iSetHead, (size_t)0); - _pMap->update(&_pMap->_pHead->_iSetTail, (size_t)0); - } - else - { - //头部不是尾部, 头部指针指向下一个元素 - assert(getBlockHead()->_iSetNext != 0); - _pMap->update(&_pMap->_pHead->_iSetHead, getBlockHead()->_iSetNext); + if(!bHead) + { + if(bTail) + { + assert(getBlockHead()->_iSetNext == 0); + //是尾部, 尾部指针指向上一个元素 + _pMap->update(&_pMap->_pHead->_iSetTail, getBlockHead()->_iSetPrev); + _pMap->update(&getBlockHead(getBlockHead()->_iSetPrev)->_iSetNext, (size_t)0); + } + else + { + //不是头部也不是尾部 + assert(getBlockHead()->_iSetNext != 0); + _pMap->update(&getBlockHead(getBlockHead()->_iSetPrev)->_iSetNext, getBlockHead()->_iSetNext); + _pMap->update(&getBlockHead(getBlockHead()->_iSetNext)->_iSetPrev, getBlockHead()->_iSetPrev); + } + } + else + { + if(bTail) + { + assert(getBlockHead()->_iSetNext == 0); + assert(getBlockHead()->_iSetPrev == 0); + //头部也是尾部, 指针都设置为0 + _pMap->update(&_pMap->_pHead->_iSetHead, (size_t)0); + _pMap->update(&_pMap->_pHead->_iSetTail, (size_t)0); + } + else + { + //头部不是尾部, 头部指针指向下一个元素 + assert(getBlockHead()->_iSetNext != 0); + _pMap->update(&_pMap->_pHead->_iSetHead, getBlockHead()->_iSetNext); //下一个元素上指针为0 _pMap->update(&getBlockHead(getBlockHead()->_iSetNext)->_iSetPrev, (size_t)0); - } - } + } + } } - ////////////////////修改Get链表的数据////////// - // + ////////////////////修改Get链表的数据////////// + // { - bool bHead = (_pMap->_pHead->_iGetHead == _iHead); - bool bTail = (_pMap->_pHead->_iGetTail == _iHead); + bool bHead = (_pMap->_pHead->_iGetHead == _iHead); + bool bTail = (_pMap->_pHead->_iGetTail == _iHead); - if(!bHead) - { - if(bTail) - { - assert(getBlockHead()->_iGetNext == 0); - //是尾部, 尾部指针指向上一个元素 - _pMap->update(&_pMap->_pHead->_iGetTail, getBlockHead()->_iGetPrev); - _pMap->update(&getBlockHead(getBlockHead()->_iGetPrev)->_iGetNext, (size_t)0); - } - else - { - //不是头部也不是尾部 - assert(getBlockHead()->_iGetNext != 0); - _pMap->update(&getBlockHead(getBlockHead()->_iGetPrev)->_iGetNext, getBlockHead()->_iGetNext); - _pMap->update(&getBlockHead(getBlockHead()->_iGetNext)->_iGetPrev, getBlockHead()->_iGetPrev); - } - } - else - { - if(bTail) - { - assert(getBlockHead()->_iGetNext == 0); - assert(getBlockHead()->_iGetPrev == 0); - //头部也是尾部, 指针都设置为0 - _pMap->update(&_pMap->_pHead->_iGetHead, (size_t)0); - _pMap->update(&_pMap->_pHead->_iGetTail, (size_t)0); - } - else - { - //头部不是尾部, 头部指针指向下一个元素 - assert(getBlockHead()->_iGetNext != 0); - _pMap->update(&_pMap->_pHead->_iGetHead, getBlockHead()->_iGetNext); + if(!bHead) + { + if(bTail) + { + assert(getBlockHead()->_iGetNext == 0); + //是尾部, 尾部指针指向上一个元素 + _pMap->update(&_pMap->_pHead->_iGetTail, getBlockHead()->_iGetPrev); + _pMap->update(&getBlockHead(getBlockHead()->_iGetPrev)->_iGetNext, (size_t)0); + } + else + { + //不是头部也不是尾部 + assert(getBlockHead()->_iGetNext != 0); + _pMap->update(&getBlockHead(getBlockHead()->_iGetPrev)->_iGetNext, getBlockHead()->_iGetNext); + _pMap->update(&getBlockHead(getBlockHead()->_iGetNext)->_iGetPrev, getBlockHead()->_iGetPrev); + } + } + else + { + if(bTail) + { + assert(getBlockHead()->_iGetNext == 0); + assert(getBlockHead()->_iGetPrev == 0); + //头部也是尾部, 指针都设置为0 + _pMap->update(&_pMap->_pHead->_iGetHead, (size_t)0); + _pMap->update(&_pMap->_pHead->_iGetTail, (size_t)0); + } + else + { + //头部不是尾部, 头部指针指向下一个元素 + assert(getBlockHead()->_iGetNext != 0); + _pMap->update(&_pMap->_pHead->_iGetHead, getBlockHead()->_iGetNext); //下一个元素上指针为0 _pMap->update(&getBlockHead(getBlockHead()->_iGetNext)->_iGetPrev, (size_t)0); - } - } + } + } } - ///////////////////从block链表中去掉/////////// - // - //上一个block指向下一个block - if(getBlockHead()->_iBlockPrev != 0) - { - _pMap->update(&getBlockHead(getBlockHead()->_iBlockPrev)->_iBlockNext, getBlockHead()->_iBlockNext); - } + ///////////////////从block链表中去掉/////////// + // + //上一个block指向下一个block + if(getBlockHead()->_iBlockPrev != 0) + { + _pMap->update(&getBlockHead(getBlockHead()->_iBlockPrev)->_iBlockNext, getBlockHead()->_iBlockNext); + } - //下一个block指向上一个 - if(getBlockHead()->_iBlockNext != 0) - { - _pMap->update(&getBlockHead(getBlockHead()->_iBlockNext)->_iBlockPrev, getBlockHead()->_iBlockPrev); - } + //下一个block指向上一个 + if(getBlockHead()->_iBlockNext != 0) + { + _pMap->update(&getBlockHead(getBlockHead()->_iBlockNext)->_iBlockPrev, getBlockHead()->_iBlockPrev); + } - //////////////////如果是hash头部, 需要修改hash索引数据指针////// - // - _pMap->delListCount(getBlockHead()->_iIndex); - if(getBlockHead()->_iBlockPrev == 0) - { - //如果是hash桶的头部, 则还需要处理 - TC_HashMap::tagHashItem *pItem = _pMap->item(getBlockHead()->_iIndex); - assert(pItem->_iBlockAddr == _iHead); - if(pItem->_iBlockAddr == _iHead) - { - _pMap->update(&pItem->_iBlockAddr, getBlockHead()->_iBlockNext); - } - } + //////////////////如果是hash头部, 需要修改hash索引数据指针////// + // + _pMap->delListCount(getBlockHead()->_iIndex); + if(getBlockHead()->_iBlockPrev == 0) + { + //如果是hash桶的头部, 则还需要处理 + TC_HashMap::tagHashItem *pItem = _pMap->item(getBlockHead()->_iIndex); + assert(pItem->_iBlockAddr == _iHead); + if(pItem->_iBlockAddr == _iHead) + { + _pMap->update(&pItem->_iBlockAddr, getBlockHead()->_iBlockNext); + } + } //////////////////脏数据/////////////////// // @@ -801,7 +804,7 @@ int TC_HashMap::Block::allocateChunk(size_t fn, vector &chunks, vector_iSize = iAllocSize; + getChunkHead(t)->_iSize = (uint32_t)iAllocSize; chunks.push_back(t); @@ -2515,7 +2518,7 @@ void TC_HashMap::doUpdate(bool bUpdate) { *(size_t*)((char*)_pHead + _pstModifyHead->_stModifyData[i]._iModifyAddr) = _pstModifyHead->_stModifyData[i]._iModifyValue; } -#if __WORDSIZE == 6|| defined _WIN644 +#if __WORDSIZE == 64 || defined _WIN64 else if(_pstModifyHead->_stModifyData[i]._cBytes == sizeof(uint32_t)) { *(uint32_t*)((char*)_pHead + _pstModifyHead->_stModifyData[i]._iModifyAddr) = (uint32_t)_pstModifyHead->_stModifyData[i]._iModifyValue; diff --git a/util/src/tc_hashmap_compact.cpp b/util/src/tc_hashmap_compact.cpp index ec9c53b..33b5a94 100644 --- a/util/src/tc_hashmap_compact.cpp +++ b/util/src/tc_hashmap_compact.cpp @@ -119,7 +119,7 @@ int TC_HashMapCompact::Block::get(void *pData, uint32_t &iDataLen) uint32_t iCopyLen = min(iUseSize, iLeftLen); //copy当前的chunk memcpy((char*)pData + iHasLen, pChunk->_cData, iCopyLen); - if (iLeftLen <= iUseSize) + if (iLeftLen < iUseSize) { iDataLen = iHasLen + iCopyLen; return TC_HashMapCompact::RT_NOTALL_ERR; //copy不完全 @@ -2675,17 +2675,17 @@ void TC_HashMapCompact::doUpdate() void TC_HashMapCompact::doUpdate2() { - if(_pstModifyHead->_cModifyStatus == 1) - { - for(size_t i=_pstModifyHead->_iNowIndex-1; i>=0; --i) - { - if(_pstModifyHead->_stModifyData[i]._cBytes == 0) - { - _pstModifyHead->_iNowIndex = i+1; - return; - } - } - } + if(_pstModifyHead->_cModifyStatus == 1) + { + for(int i=_pstModifyHead->_iNowIndex-1; i>=0; --i) + { + if(_pstModifyHead->_stModifyData[i]._cBytes == 0) + { + _pstModifyHead->_iNowIndex = i+1; + return; + } + } + } } void TC_HashMapCompact::doUpdate3() diff --git a/util/src/tc_http.cpp b/util/src/tc_http.cpp index 62f5b2a..c59a61e 100755 --- a/util/src/tc_http.cpp +++ b/util/src/tc_http.cpp @@ -15,12 +15,26 @@ */ #include "util/tc_http.h" +#include "util/tc_port.h" #include "util/tc_common.h" #include "util/tc_clientsocket.h" namespace tars { +bool TC_Http::CmpCase::operator()(const string &s1, const string &s2) const +{ + //return TC_Common::upper(s1) < TC_Common::upper(s2); + if (TC_Port::strcasecmp(s1.c_str(), s2.c_str()) < 0) + { + return true; + } + else + { + return false; + } +} + bool TC_URL::isValid() const { return !_sURL.empty(); @@ -33,7 +47,7 @@ string TC_URL::getURL() const string TC_URL::type2String() const { - switch(_iURLType) + switch (_iURLType) { case HTTP: return "http"; @@ -48,7 +62,7 @@ string TC_URL::type2String() const string TC_URL::getDefaultPort() const { - switch(_iURLType) + switch (_iURLType) { case HTTP: return "80"; @@ -73,21 +87,21 @@ string TC_URL::toURL() _sURL = _sScheme; _sURL += "://"; - if(!_sUser.empty()) + if (!_sUser.empty()) _sURL += _sUser; - if(!_sUser.empty() && !_sPass.empty()) + if (!_sUser.empty() && !_sPass.empty()) { _sURL += ":"; _sURL += _sPass; } - if(!_sUser.empty()) + if (!_sUser.empty()) _sURL += "@"; _sURL += _sDomain; - if(!isDefaultPort()) + if (!isDefaultPort()) { _sURL += ":"; _sURL += _sPort; @@ -102,13 +116,13 @@ string TC_URL::getRequest() const { string sURL; - if(!_sPath.empty()) + if (!_sPath.empty()) sURL += _sPath; - if(!_sQuery.empty()) + if (!_sQuery.empty()) sURL += "?" + _sQuery; - if(!_sRef.empty()) + if (!_sRef.empty()) sURL += "#" + _sRef; return sURL; @@ -118,7 +132,7 @@ bool TC_URL::parseURL(const string &sURL) { string originRequest = TC_Common::trim(sURL, " "); - if(originRequest.empty()) + if (originRequest.empty()) { return false; } @@ -127,21 +141,21 @@ bool TC_URL::parseURL(const string &sURL) int iPos = 0; - if(TC_Port::strncasecmp(originRequest.c_str(), "http://" ,7) == 0) + if (TC_Port::strncasecmp(originRequest.c_str(), "http://" , 7) == 0) { //http开头 _iURLType = HTTP; iPos = 7; _sScheme = "http"; } - else if(TC_Port::strncasecmp(originRequest.c_str(), "https://" ,8) == 0) + else if (TC_Port::strncasecmp(originRequest.c_str(), "https://" , 8) == 0) { //https开头 _iURLType = HTTPS; iPos = 8; _sScheme = "https"; } - else if(TC_Port::strncasecmp(originRequest.c_str(), "ftp://", 6) == 0) + else if (TC_Port::strncasecmp(originRequest.c_str(), "ftp://", 6) == 0) { //ftps开头 _iURLType = FTP; @@ -156,53 +170,51 @@ bool TC_URL::parseURL(const string &sURL) _sScheme = "http"; } - string::size_type index = originRequest.find("/", iPos); string::size_type nQuestionIndex = originRequest.find("?", iPos); string::size_type nNumbersignIndex = originRequest.find("#", iPos); - string sUrlAuthority; string sUrlPath; - if(nQuestionIndex < index) - { - sUrlAuthority = originRequest.substr(iPos, nQuestionIndex-iPos); + if (nQuestionIndex < index) + { + sUrlAuthority = originRequest.substr(iPos, nQuestionIndex - iPos); - string sTemp = originRequest.substr(nQuestionIndex); +// string sTemp = originRequest.substr(nQuestionIndex); sUrlPath += '/'; - sUrlPath += sTemp; - } - else if(nNumbersignIndex < index) - { - sUrlAuthority = originRequest.substr(iPos, nNumbersignIndex-iPos); + sUrlPath += originRequest.substr(nQuestionIndex); + } + else if (nNumbersignIndex < index) + { + sUrlAuthority = originRequest.substr(iPos, nNumbersignIndex - iPos); - string sTemp = originRequest.substr(nNumbersignIndex); +// string sTemp = originRequest.substr(nNumbersignIndex); sUrlPath += '/'; - sUrlPath += sTemp; - } + sUrlPath += originRequest.substr(nNumbersignIndex); + } else { - if(index == string::npos) + if (index == string::npos) { - sUrlAuthority = originRequest.substr(iPos, index); + sUrlAuthority = originRequest.substr(iPos, index); sUrlPath = ""; } else { - sUrlAuthority= originRequest.substr(iPos, index-iPos); - sUrlPath = originRequest.substr(index); + sUrlAuthority = originRequest.substr(iPos, index - iPos); + sUrlPath = originRequest.substr(index); } } //////解析Authority index = sUrlAuthority.find("@"); - if(index != string::npos) + if (index != string::npos) { - _sUser = sUrlAuthority.substr(0, index); - _sDomain = sUrlAuthority.substr(index + 1); + _sUser = sUrlAuthority.substr(0, index); + _sDomain = sUrlAuthority.substr(index + 1); } else { @@ -211,19 +223,19 @@ bool TC_URL::parseURL(const string &sURL) //////解析User:Pass index = _sUser.find(":"); - if(index != string::npos) + if (index != string::npos) { - _sPass = _sUser.substr(index + 1); - _sUser = _sUser.substr(0, index); + _sPass = _sUser.substr(index + 1); + _sUser = _sUser.substr(0, index); } //////解析Host:Port index = _sDomain.find(":"); - if(index != string::npos) + if (index != string::npos) { - _sPort = _sDomain.substr(index + 1); + _sPort = _sDomain.substr(index + 1); - _sDomain = _sDomain.substr(0, index); + _sDomain = _sDomain.substr(0, index); } else { @@ -232,32 +244,32 @@ bool TC_URL::parseURL(const string &sURL) //////解析Path Query Ref index = sUrlPath.find("?"); - if(index != string::npos) + if (index != string::npos) { - _sPath = sUrlPath.substr(0, index); - _sQuery = sUrlPath.substr(index + 1); + _sPath = sUrlPath.substr(0, index); + _sQuery = sUrlPath.substr(index + 1); index = _sQuery.rfind("#"); - if(index != string::npos) + if (index != string::npos) { - _sRef = _sQuery.substr(index + 1); - _sQuery = _sQuery.substr(0, index); + _sRef = _sQuery.substr(index + 1); + _sQuery = _sQuery.substr(0, index); } } else { - _sPath = sUrlPath; - _sQuery = ""; + _sPath = sUrlPath; + _sQuery = ""; index = _sPath.rfind("#"); - if(index != string::npos) + if (index != string::npos) { - _sRef = _sPath.substr(index + 1); - _sPath = _sPath.substr(0, index); + _sRef = _sPath.substr(index + 1); + _sPath = _sPath.substr(0, index); } } - if(_sPath.empty()) + if (_sPath.empty()) { _sPath = "/"; } @@ -265,7 +277,7 @@ bool TC_URL::parseURL(const string &sURL) toURL(); //域名或者IP必须包含一个点 - if(_sDomain.find(".") == string::npos) + if (_sDomain.find(".") == string::npos) { return false; } @@ -358,13 +370,13 @@ string TC_URL::getRelativePath() const pos = sURL.rfind("/"); - if(pos == string::npos) + if (pos == string::npos) { return "/"; } else { - return sURL.substr(0, pos + 1); + return sURL.substr(0, pos + 1); } } @@ -373,21 +385,21 @@ string TC_URL::getRootPath() const string sURL = _sScheme; sURL += "://"; - if(!_sUser.empty()) + if (!_sUser.empty()) sURL += _sUser; - if(!_sUser.empty() && !_sPass.empty()) + if (!_sUser.empty() && !_sPass.empty()) { sURL += ":"; sURL += _sPass; } - if(!_sUser.empty()) + if (!_sUser.empty()) sURL += "@"; sURL += _sDomain; - if(!isDefaultPort()) + if (!isDefaultPort()) { sURL += ":"; sURL += _sPort; @@ -395,23 +407,24 @@ string TC_URL::getRootPath() const sURL += "/"; - return sURL; + return sURL; } TC_URL TC_URL::buildWithRelativePath(const string &sRelativePath) const { string sURL; - if(!sRelativePath.empty() && sRelativePath[0] == '/') + if (!sRelativePath.empty() && sRelativePath[0] == '/') { - sURL = sRelativePath.substr(1); //如果链接是用"/"开头的相对地址,那么应该用Host+相对地址 + //如果链接是用"/"开头的相对地址,那么应该用Host+相对地址 + sURL = sRelativePath.substr(1); } - else if(sRelativePath[0] == '#') + else if (sRelativePath[0] == '#') { //# - sURL = getPath().substr(1); + sURL = getPath().substr(1); - if(!getQuery().empty()) + if (!getQuery().empty()) sURL += "?" + getQuery(); sURL += sRelativePath; @@ -429,7 +442,7 @@ TC_URL TC_URL::buildWithRelativePath(const string &sRelativePath) const url.parseURL(sURL); - return url; + return url; } string TC_URL::simplePath(const string &sPath) const @@ -460,7 +473,7 @@ string TC_URL::simplePath(const string &sPath) const } //如果路径是以.结尾的, 则.去掉 - if (((sNewPath.length() >= 2) && (sNewPath.substr(sNewPath.length()-2) == "/.")) || (sNewPath == ".")) + if (((sNewPath.length() >= 2) && (sNewPath.substr(sNewPath.length() - 2) == "/.")) || (sNewPath == ".")) { sNewPath.erase(sNewPath.length() - 1); } @@ -511,15 +524,28 @@ string TC_URL::simplePath(const string &sPath) const } } - return sNewPath; + return sNewPath; } //////////////////////////////////////////////////////////////////// +void TC_Http::setHeader(const string &sHeadName, const string &sHeadValue) +{ + //Set-Cookie和Cookie可以有多个头 + const char * pStr1 = "SET-COOKIE"; + const char * pStr2 = "COOKIE";//原则上COOKIE只有一个,担心有兼容性问题,保留 + if ((TC_Port::strcasecmp(sHeadName.c_str(), pStr1) != 0) && (TC_Port::strcasecmp(sHeadName.c_str(), pStr2) != 0)) + { + _headers.erase(sHeadName); + } + + _headers.insert(multimap::value_type(sHeadName, sHeadValue)); +} + string TC_Http::getHeader(const string& sHeader) const { http_header_type::const_iterator it = _headers.find(sHeader); - if(it == _headers.end()) + if (it == _headers.end()) { return ""; } @@ -540,7 +566,7 @@ string TC_Http::getHost() const size_t TC_Http::getContentLength() const { string s = getHeader("Content-Length"); - if(s.empty()) + if (s.empty()) { return 0; } @@ -552,9 +578,9 @@ string TC_Http::genHeader() const { string sHttpHeader; - for(http_header_type::const_iterator it = _headers.begin(); it != _headers.end(); ++it) + for (http_header_type::const_iterator it = _headers.begin(); it != _headers.end(); ++it) { - if(it->second != "") + if (it->second != "") { sHttpHeader += it->first; sHttpHeader += ": "; @@ -572,15 +598,15 @@ vector TC_Http::getHeaderMulti(const string &sHeadName) const http_header_type::const_iterator itEnd = _headers.end(); - for( http_header_type::const_iterator it = _headers.begin(); it != itEnd; ++it) + for ( http_header_type::const_iterator it = _headers.begin(); it != itEnd; ++it) { - if(TC_Port::strcasecmp(it->first.c_str(), sHeadName.c_str()) == 0) + if (TC_Port::strcasecmp(it->first.c_str(), sHeadName.c_str()) == 0) { v.push_back(it->second); } } - return v; + return v; } string TC_Http::getLine(const char** ppChar) @@ -589,20 +615,20 @@ string TC_Http::getLine(const char** ppChar) sTmp.reserve(512); - while((**ppChar) != '\r' && (**ppChar) != '\n' && (**ppChar) != '\0') + while ((**ppChar) != '\r' && (**ppChar) != '\n' && (**ppChar) != '\0') { sTmp.append(1, (**ppChar)); (*ppChar)++; } - if((**ppChar) == '\r') + if ((**ppChar) == '\r') { (*ppChar)++; /* pass the char '\n' */ } (*ppChar)++; - return sTmp; + return sTmp; } @@ -612,8 +638,8 @@ string TC_Http::getLine(const char** ppChar, int iBufLen) sTmp.reserve(512); - int iCurIndex= 0; - while( (**ppChar) != '\r' && (**ppChar) != '\n' && (**ppChar) != '\0') + int iCurIndex = 0; + while ( (**ppChar) != '\r' && (**ppChar) != '\n' && (**ppChar) != '\0') { if ( iCurIndex < iBufLen ) { @@ -628,7 +654,7 @@ string TC_Http::getLine(const char** ppChar, int iBufLen) } } - if( (**ppChar) == '\r') + if ( (**ppChar) == '\r') { if ( iCurIndex < iBufLen ) { @@ -641,7 +667,7 @@ string TC_Http::getLine(const char** ppChar, int iBufLen) } } - if( iCurIndex < iBufLen ) + if ( iCurIndex < iBufLen ) { (*ppChar)++; iCurIndex++; @@ -651,7 +677,7 @@ string TC_Http::getLine(const char** ppChar, int iBufLen) //MTT_ERRDAY << "parseHttp WARN: iCurIndex < iBufLen 3 " << endl; } - return sTmp; + return sTmp; } @@ -662,13 +688,13 @@ const char* TC_Http::parseHeader(const char* szBuffer, http_header_type &sHeader const char **ppChar = &szBuffer; size_t length = strlen(szBuffer); - size_t srcPtr = (size_t)(*ppChar); + size_t srcPtr = (size_t)(*ppChar); - while(true) + while (true) { string sLine = getLine(ppChar); - if(sLine.empty()) break; + if (sLine.empty()) break; //如果是第一行, 则忽略掉 if(TC_Port::strncasecmp(sLine.c_str(), "GET ", 4) ==0 @@ -723,7 +749,7 @@ bool TC_HttpCookie::matchDomain(const string &sCookieDomain, const string &sDoma string sCookieDomainNew = TC_Common::lower(sCookieDomain); //没有点的自动加点 - if(sCookieDomainNew.find(".") != 0) + if (sCookieDomainNew.find(".") != 0) { sCookieDomainNew = "." + sCookieDomainNew; } @@ -731,7 +757,7 @@ bool TC_HttpCookie::matchDomain(const string &sCookieDomain, const string &sDoma string::size_type pos = sCookieDomainNew.find("."); //sCookieDomain串至少有两个点 - if(pos == string::npos || (pos == 0 && sCookieDomainNew.rfind(".") == 0)) + if (pos == string::npos || (pos == 0 && sCookieDomainNew.rfind(".") == 0)) { return false; } @@ -739,14 +765,14 @@ bool TC_HttpCookie::matchDomain(const string &sCookieDomain, const string &sDoma string sLowerDomain = TC_Common::lower(sDomain); //后边是子域名 - if(sDomain.length() >= sCookieDomainNew.length() && - sLowerDomain.compare(sDomain.length() - sCookieDomainNew.length(), sCookieDomainNew.length(), sCookieDomainNew) == 0) + if (sDomain.length() >= sCookieDomainNew.length() && + sLowerDomain.compare(sDomain.length() - sCookieDomainNew.length(), sCookieDomainNew.length(), sCookieDomainNew) == 0) { return true; } //去掉.相等 - if(sLowerDomain == sCookieDomainNew.substr(1)) + if (sLowerDomain == sCookieDomainNew.substr(1)) { return true; } @@ -756,14 +782,14 @@ bool TC_HttpCookie::matchDomain(const string &sCookieDomain, const string &sDoma size_t TC_HttpCookie::matchPath(const string &sCookiePath, const string &sPath) { - if(sCookiePath.empty() || sPath.empty()) return 0; + if (sCookiePath.empty() || sPath.empty()) return 0; //都在最后加/再匹配 - string sCookiePath1 = (sCookiePath.at(sCookiePath.length() - 1) == '/') ? sCookiePath:sCookiePath + "/"; + string sCookiePath1 = (sCookiePath.at(sCookiePath.length() - 1) == '/') ? sCookiePath : sCookiePath + "/"; - string sPath1 = (sPath.at(sPath.length() - 1) == '/') ? sPath:sPath + "/"; + string sPath1 = (sPath.at(sPath.length() - 1) == '/') ? sPath : sPath + "/"; - if(sPath1.find(sCookiePath1) == 0) + if (sPath1.find(sCookiePath1) == 0) { return sCookiePath1.length(); } @@ -778,7 +804,7 @@ void TC_HttpCookie::clear() bool TC_HttpCookie::fixDomain(const string &sDomain, string &sFixDomain) { - if(sDomain.empty()) + if (sDomain.empty()) { return false; } @@ -786,13 +812,13 @@ bool TC_HttpCookie::fixDomain(const string &sDomain, string &sFixDomain) sFixDomain = sDomain; //自动加. - if(sDomain.at(0) != '.') + if (sDomain.at(0) != '.') { sFixDomain = "." + sDomain; } //domain至少两段 - if(sFixDomain.find(".") == sFixDomain.rfind(".")) + if (sFixDomain.find(".") == sFixDomain.rfind(".")) return false; return true; @@ -804,34 +830,34 @@ void TC_HttpCookie::addCookie(const Cookie &cookie, list &cookies) Cookie cookieNew = cookie; - if(!fixDomain(cookieNew._domain, sDomain)) + if (!fixDomain(cookieNew._domain, sDomain)) return; cookieNew._domain = sDomain; - if(cookieNew._path.empty()) + if (cookieNew._path.empty()) return; list::iterator it = cookies.begin(); string sName; - if(cookieNew._data.size() >= 1) + if (cookieNew._data.size() >= 1) { sName = cookieNew._data.begin()->first; } - while(it != cookies.end()) + while (it != cookies.end()) { //检查Cookie是否过期 - if(isCookieExpires(*it)) + if (isCookieExpires(*it)) { cookies.erase(it++); } - else if(TC_Port::strcasecmp(it->_domain.c_str(), cookieNew._domain.c_str()) == 0 - && strcmp(it->_path.c_str(), cookieNew._path.c_str()) == 0 - && it->_isSecure == cookieNew._isSecure) + else if (TC_Port::strcasecmp(it->_domain.c_str(), cookieNew._domain.c_str()) == 0 + && strcmp(it->_path.c_str(), cookieNew._path.c_str()) == 0 + && it->_isSecure == cookieNew._isSecure) { - if(it->_expires == cookieNew._expires) + if (it->_expires == cookieNew._expires) { //domain/path/expires都匹配的情况下, 覆盖老cookie的数据 cookieNew._data.insert(it->_data.begin(), it->_data.end()); @@ -841,7 +867,7 @@ void TC_HttpCookie::addCookie(const Cookie &cookie, list &cookies) else { //超时间不一样,但存在同样的key,需删除 - if(it->_data.find(sName) != it->_data.end()) + if (it->_data.find(sName) != it->_data.end()) { it->_data.erase(sName); } @@ -850,7 +876,7 @@ void TC_HttpCookie::addCookie(const Cookie &cookie, list &cookies) } else { - ++it; + ++it; } } @@ -866,7 +892,7 @@ void TC_HttpCookie::addCookie(const list &cookie) { list::const_iterator it = cookie.begin(); - while(it != cookie.end()) + while (it != cookie.end()) { addCookie(*it); @@ -880,11 +906,11 @@ void TC_HttpCookie::addCookie(const string &sRspURL, const vector &vCook cURL.parseURL(sRspURL); - string sRspURLDomain= TC_Common::lower(cURL.getDomain()); + string sRspURLDomain = TC_Common::lower(cURL.getDomain()); string sRspURLPath = cURL.getPath(); - for(size_t i = 0; i < vCookies.size(); i++) + for (size_t i = 0; i < vCookies.size(); i++) { //处理一行SetCookie vector v = TC_Common::sepstr(vCookies[i], ";"); @@ -895,7 +921,7 @@ void TC_HttpCookie::addCookie(const string &sRspURL, const vector &vCook cookie._expires = 0; //解析Cookie数据 - for(size_t j = 0; j < v.size(); ++j) + for (size_t j = 0; j < v.size(); ++j) { string::size_type index = v[j].find("="); @@ -903,7 +929,7 @@ void TC_HttpCookie::addCookie(const string &sRspURL, const vector &vCook string value; - if(index != string::npos) + if (index != string::npos) { name = TC_Common::trim(v[j].substr(0, index), " "); @@ -913,21 +939,21 @@ void TC_HttpCookie::addCookie(const string &sRspURL, const vector &vCook { name = TC_Common::trim(v[j]); } - if(TC_Port::strcasecmp(name.c_str(), "secure") == 0) + if (TC_Port::strcasecmp(name.c_str(), "secure") == 0) { cookie._isSecure = true; } - else if(TC_Port::strcasecmp(name.c_str(), "expires") == 0) + else if (TC_Port::strcasecmp(name.c_str(), "expires") == 0) { struct tm stTm; //兼容时间格式 //expires=Mon, 09-May-41 08:39:32 GMT //expires=Thu, 01-Jan-1970 01:00:00 GMT value = TC_Common::replace(value, "-", " "); - if(value.length() == 27 && value.at(11) == ' ' && value.at(14) == ' ') + if (value.length() == 27 && value.at(11) == ' ' && value.at(14) == ' ') { int year = TC_Common::strto (value.substr(12, 2)); - if(year >= 69 && year <= 99) + if (year >= 69 && year <= 99) value = value.substr(0, 12) + "19" + value.substr(12); else value = value.substr(0, 12) + "20" + value.substr(12); @@ -937,15 +963,15 @@ void TC_HttpCookie::addCookie(const string &sRspURL, const vector &vCook cookie._expires = TC_Port::timegm(&stTm); } - else if(TC_Port::strcasecmp(name.c_str(), "path") == 0) + else if (TC_Port::strcasecmp(name.c_str(), "path") == 0) { cookie._path = value; } - else if(TC_Port::strcasecmp(name.c_str(), "domain") == 0) + else if (TC_Port::strcasecmp(name.c_str(), "domain") == 0) { cookie._domain = value; } - else if(TC_Port::strcasecmp(name.c_str(), "httponly") == 0) + else if (TC_Port::strcasecmp(name.c_str(), "httponly") == 0) { //TODO //cookie._isHttpOnly = true; @@ -955,18 +981,18 @@ void TC_HttpCookie::addCookie(const string &sRspURL, const vector &vCook } ///修正和匹配domain///////////////////////////////////////// - if(cookie._domain.empty()) + if (cookie._domain.empty()) cookie._domain = sRspURLDomain; - if(!fixDomain(cookie._domain, cookie._domain)) + if (!fixDomain(cookie._domain, cookie._domain)) continue; //匹配域名 - if(!matchDomain(cookie._domain, sRspURLDomain)) + if (!matchDomain(cookie._domain, sRspURLDomain)) continue; //修改和匹配path///////////////////////////// - if(cookie._path.empty()) + if (cookie._path.empty()) { string sCookiePath; @@ -975,10 +1001,10 @@ void TC_HttpCookie::addCookie(const string &sRspURL, const vector &vCook string::size_type pos = sRequest.rfind("/"); - if(pos == string::npos) + if (pos == string::npos) sCookiePath = "/"; else - sCookiePath = sRequest.substr(0, pos+1); + sCookiePath = sRequest.substr(0, pos + 1); cookie._path = sCookiePath; } @@ -1108,7 +1134,7 @@ list TC_HttpCookie::getSerializeCookie(time_t t) return cookies; } -list TC_HttpCookie::getAllCookie() +const list & TC_HttpCookie::getAllCookie() { deleteExpires(time(NULL)); @@ -1189,12 +1215,18 @@ void TC_HttpResponse::reset() _version = "HTTP/1.1"; _iTmpContentLength = 0; + _iRecvContentLength = 0; } vector TC_HttpResponse::getSetCookie() const { return getHeaderMulti("Set-Cookie"); } +void TC_HttpResponse::addContent(const string &sBuffer) +{ + _content += sBuffer; + _iRecvContentLength += sBuffer.length(); +} bool TC_HttpResponse::incrementDecode(string &sBuffer) { @@ -1210,7 +1242,7 @@ bool TC_HttpResponse::incrementDecode(string &sBuffer) parseResponseHeader(sBuffer.c_str()); - if(_status == 204) + if ( (204 == _status) || (304 == _status) ) { return true; } @@ -1257,29 +1289,24 @@ bool TC_HttpResponse::incrementDecode(string &sBuffer) if(iChunkSize <= 0) break; //所有chunk都接收完毕 - if(sBuffer.length() >= pos + 2 + (size_t)iChunkSize + 2) //接收到一个完整的chunk了 + if (sBuffer.length() < pos + 2 + (size_t)iChunkSize + 2) { //获取一个chunk的内容 - _content += sBuffer.substr(pos + 2, iChunkSize); //删除一个chunk - sBuffer = sBuffer.substr(pos + 2 + iChunkSize + 2); - } - else - { //没有接收完整的chunk return false; } - setContentLength(getContent().length()); + addContent(sBuffer.substr(pos + 2, iChunkSize)); + sBuffer = sBuffer.substr(pos + 2 + iChunkSize + 2); + // setContentLength(getContent().length()); } sBuffer = ""; - if(_iTmpContentLength == 0 || _iTmpContentLength == (size_t)-1) - { - setContentLength(getContent().length()); - } + //接收到buffer长度设置好 + setContentLength(_iRecvContentLength); return true; } @@ -1287,44 +1314,44 @@ bool TC_HttpResponse::incrementDecode(string &sBuffer) { if(_iTmpContentLength == 0) { -#if 0 - _content += sBuffer; + //header长度为0, 但是有body数据 + addContent(sBuffer); sBuffer = ""; + setContentLength(_iRecvContentLength); //自动填写content-length - setContentLength(getContent().length()); -#endif + // setContentLength(getContent().length()); return true; } else if(_iTmpContentLength == (size_t)-1) { //304的返回码中头没有Content-Length,不会有数据体 - if(_status == 304) + if (_status == 304 || _status == 302) { return true; } -#if 0 - _content += sBuffer; + //header中没长度, 但是有body数据 + addContent(sBuffer); sBuffer = ""; + setContentLength(_iRecvContentLength); //自动填写content-length - setContentLength(getContent().length()); -#endif + // setContentLength(getContent().length()); return false; } else { - std::string body = sBuffer.substr(0, _iTmpContentLength); - _content += body; - sBuffer.erase(0, _iTmpContentLength); + //头部有长度, 接收到长度大于头部为止 + addContent(sBuffer); + sBuffer = ""; - size_t iNowLength = getContent().length(); + // size_t iNowLength = getContent().length(); //头部的长度小于接收的内容, 还需要继续增加解析后续的buffer - if(_iTmpContentLength > iNowLength) + if (_iTmpContentLength > _iRecvContentLength) return false; return true; @@ -1398,7 +1425,7 @@ void TC_HttpResponse::encode(vector &buffer) const string s = encode(); buffer.resize(s.length()); - memcpy(&buffer[0], s.c_str(), s.length()); + memcpy(buffer.data(), s.c_str(), s.length()); } void TC_HttpResponse::setResponse(int status, const string& about, const string& body) @@ -1496,7 +1523,7 @@ string TC_HttpRequest::requestType2str(int iRequestType) const { return "PATCH"; } - +// assert(true); return ""; } @@ -1605,6 +1632,36 @@ void TC_HttpRequest::setPostRequest(const string &sUrl, const string &sPostBody, setHeader("Content-Length", TC_Common::tostr(_content.length())); } +void TC_HttpRequest::setOptionsRequest(const string &sUrl, bool bNewCreateHost) +{ + if (bNewCreateHost) + { + eraseHeader("Host"); + } + parseURL(sUrl); + _requestType = REQUEST_OPTIONS; + _content = ""; + eraseHeader("Content-Length"); +} +void TC_HttpRequest::setPostRequest(const string &sUrl, const char *sBuffer, size_t iLength, bool bNewCreateHost) +{ + assert(sBuffer != NULL); + if (bNewCreateHost) + { + eraseHeader("Host"); + } + parseURL(sUrl); + _requestType = REQUEST_POST; + if (iLength > 0) + { + _content.assign(sBuffer, iLength); + } + else + { + _content.clear(); + } + setHeader("Content-Length", TC_Common::tostr(_content.length())); +} void TC_HttpRequest::setPutRequest(const string &sUrl, const string &sPostBody, bool bNewCreateHost ) { if(bNewCreateHost) @@ -1655,47 +1712,6 @@ void TC_HttpRequest::setDeleteRequest(const string &sUrl, const string &sPostBod } -void TC_HttpRequest::setOptionsRequest(const string &sUrl, bool bNewCreateHost) -{ - if(bNewCreateHost) - { - eraseHeader("Host"); - } - - parseURL(sUrl); - - _requestType = REQUEST_OPTIONS; - - _content = ""; - - eraseHeader("Content-Length"); -} - -void TC_HttpRequest::setPostRequest(const string &sUrl, const char *sBuffer, size_t iLength, bool bNewCreateHost) -{ - assert(sBuffer != NULL); - - if(bNewCreateHost) - { - eraseHeader("Host"); - } - - parseURL(sUrl); - - _requestType = REQUEST_POST; - - if(iLength > 0) - { - _content.assign(sBuffer, iLength); - } - else - { - _content.clear(); - } - - setHeader("Content-Length", TC_Common::tostr(_content.length())); -} - string TC_HttpRequest::encode() { // assert(_requestType == REQUEST_GET || _requestType == REQUEST_POST || !_originRequest.empty()); @@ -1794,7 +1810,7 @@ void TC_HttpRequest::encode(vector &buffer) string s = encode(); buffer.resize(s.length()); - memcpy(&buffer[0], s.c_str(), s.length()); + memcpy(buffer.data(), s.c_str(), s.length()); } bool TC_HttpRequest::decode(const string &sBuffer) @@ -1827,6 +1843,7 @@ bool TC_HttpRequest::decode(const char *sBuffer, size_t iLength) _headLength = parseRequestHeader(sBuffer); bool bChunk = (getHeader("Transfer-Encoding") == "chunked"); + int iChunkSuffixLen = 0; if(bChunk) { @@ -1841,8 +1858,12 @@ bool TC_HttpRequest::decode(const char *sBuffer, size_t iLength) string sChunkSize = sTmp.substr(0, pos); int iChunkSize = strtol(sChunkSize.c_str(), NULL, 16); - if(iChunkSize <= 0) break; //所有chunk都接收完毕 - + iChunkSuffixLen = iChunkSuffixLen + sChunkSize.length(); + if (iChunkSize <= 0) + { + iChunkSuffixLen = iChunkSuffixLen + 4; + break; //所有chunk都接收完毕 + } if(sTmp.length() >= pos + 2 + (size_t)iChunkSize + 2) //接收到一个完整的chunk了 { //获取一个chunk的内容 @@ -1850,6 +1871,7 @@ bool TC_HttpRequest::decode(const char *sBuffer, size_t iLength) //删除一个chunk sTmp = sTmp.substr(pos + 2 + iChunkSize + 2); + iChunkSuffixLen = iChunkSuffixLen + 4; } else { @@ -1866,7 +1888,7 @@ bool TC_HttpRequest::decode(const char *sBuffer, size_t iLength) // _content = sBuffer.substr(_headLength); } - return (getContentLength() + getHeadLength() == iLength); + return (getContentLength() + getHeadLength() + iChunkSuffixLen == iLength); } @@ -1909,14 +1931,14 @@ bool TC_HttpRequest::checkRequest(const char* sBuffer, size_t iLen) } size_t len = 0; - string sLine = getLine(ppChar, (int)(iHeadLen-iMoveLen)); + string sLine = getLine(ppChar, iHeadLen - iMoveLen); if(sLine == "") { len = 0; } else if(TC_Port::strncasecmp(sLine.c_str(), "Transfer-Encoding:", 18) == 0) { - bChunk = (tars::TC_Common::trim(sLine.substr(18)) == "chunked"); + bChunk = (TC_Common::trim(sLine.substr(18)) == "chunked"); if(bChunk) break; } else if(TC_Port::strncasecmp(sLine.c_str(), "Content-Length:", 15) != 0) @@ -1925,7 +1947,7 @@ bool TC_HttpRequest::checkRequest(const char* sBuffer, size_t iLen) } else { - len = tars::TC_Common::strto(TC_Common::trim(sLine.substr(15), " ")); + len = TC_Common::strto(TC_Common::trim(sLine.substr(15), " ")); } if(len + pos + 4 <= iLen) @@ -1973,7 +1995,7 @@ bool TC_HttpRequest::checkRequest(const char* sBuffer, size_t iLen) */ if(bChunk) { - int remain_len = (int)(iLen - iHeadLen); + int remain_len = iLen - iHeadLen; int move_len = 0; const char * pCur = p + 4; while(true) @@ -2072,9 +2094,10 @@ size_t TC_HttpRequest::parseRequestHeader(const char* szBuffer) string sURL = TC_Common::trim(sLine.substr(pos+1, pos1 - pos)); //HTTP协议版本 - string sVersion = TC_Common::upper(TC_Common::trim(sLine.substr(pos1+1))); + string sVersion = TC_Common::trim(sLine.substr(pos1 + 1)); - if(sVersion != "HTTP/1.1" && sVersion != "HTTP/1.0") +// if (sVersion != "HTTP/1.1" || sVersion != "HTTP/1.0") + if (TC_Port::strncasecmp(sVersion.c_str(), "HTTP/1.1", 8) != 0 || TC_Port::strncasecmp(sVersion.c_str(), "HTTP/1.0", 8) != 0) { sVersion = "HTTP/1.1"; } diff --git a/util/src/tc_json.cpp b/util/src/tc_json.cpp index dbb60c2..5509ef1 100644 --- a/util/src/tc_json.cpp +++ b/util/src/tc_json.cpp @@ -1,20 +1,4 @@ -/** - * Tencent is pleased to support the open source community by making Tars available. - * - * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -#include "util/tc_json.h" +#include "util/tc_json.h" #include #include @@ -27,615 +11,742 @@ namespace tars #define FILTER_SPACE while(isspace((int)c)) {c=reader.read();} -//json里面定义的空白字符 -bool JsonValue::isspace(char c) +JsonValuePtr TC_Json::getValue(BufferJsonReader & reader) { - if(c == ' ' || c == '\t' || c == '\r' || c == '\n') - return true; - return false; -} + char c=reader.read(); + FILTER_SPACE; -uint32_t JsonValue::getHex(BufferJsonReader & reader) -{ - uint32_t iCode=0; - char c; - for(int iLoop=0;iLoop<4;iLoop++) - { - c=reader.read(); - if(c>='a'&&c<='f') - iCode=iCode*16+c-'a'+10; - else if(c>='A'&&c<='F') - iCode=iCode*16+c-'A'+10; - else if(c>='0'&&c<='9') - iCode=iCode*16+c-'0'; - else - { - char s[64]; - snprintf(s, sizeof(s), "get string error3(\\u)[pos:%u]", (uint32_t)reader.getCur()); - throw TC_Json_Exception(s); - } - } - return iCode; -} - -void JsonValue::writeString(const string &str, ostream& ostr) -{ - ostr << "\""; - std::string::const_iterator it(str.begin()), itEnd(str.end()); - for (; it != itEnd; ++it) - { - switch(*it) - { - case '"': - ostr << "\\\""; - break; - case '\\': - ostr << "\\\\"; - break; - case '/': - ostr << "\\/"; - break; - case '\b': - ostr << "\\b"; + switch(c) + { + case '{': + return getObj(reader); break; - case '\f': - ostr << "\\f"; + case '[': + return getArray(reader); break; - case '\n': - ostr << "\\n"; + case '"': + //case '\'': + return getString(reader,c); break; - case '\r': - ostr << "\\r"; + case 'T': + case 't': + case 'F': + case 'f': + return getBoolean(reader,c); break; - case '\t': - ostr << "\\t"; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + return getNum(reader,c); break; + case 'n': + case 'N': + return getNull(reader,c); default: + char s[64]; + snprintf(s, sizeof(s), "buffer overflow when peekBuf, over %u.", (uint32_t)(uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } +} + +JsonValueObjPtr TC_Json::getObj(BufferJsonReader & reader) +{ + JsonValueObjPtr p = new JsonValueObj(); + bool bFirst=true; + while(1) + { + char c=reader.read(); + FILTER_SPACE; + if(c == '}' && bFirst) { - if((unsigned char)(*it)<0x20) + return p; + } + bFirst=false; + + if(c != '"') + { + char s[64]; + snprintf(s, sizeof(s), "get obj error(key is not string)[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } + JsonValueStringPtr pString=getString(reader); + c=reader.read(); + FILTER_SPACE; + if(c != ':') + { + char s[64]; + snprintf(s, sizeof(s), "get obj error(: not find)[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } + JsonValuePtr pValue=getValue(reader); + p->value[pString->value]=pValue; + + c=reader.read(); + FILTER_SPACE; + + if(c == ',') + continue; + if(c == '}') + return p; + + char s[64]; + snprintf(s, sizeof(s), "get obj error(, not find)[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } +} + +JsonValueArrayPtr TC_Json::getArray(BufferJsonReader & reader) +{ + JsonValueArrayPtr p = new JsonValueArray(); + bool bFirst=true; + while(1) + { + char c; + if(bFirst) + { + c=reader.read(); + FILTER_SPACE; + if(c == ']') { - char buf[16]; - snprintf(buf,sizeof(buf),"\\u%04x",(unsigned char)*it); - ostr << string(buf,6); + return p; + } + reader.back(); + } + bFirst=false; + + JsonValuePtr pValue=getValue(reader); + p->push_back(pValue); + + c=reader.read(); + FILTER_SPACE; + if(c == ',') + continue; + if(c == ']') + return p; + + char s[64]; + snprintf(s, sizeof(s), "get vector error(, not find )[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } +} + +JsonValueStringPtr TC_Json::getString(BufferJsonReader & reader,char head) +{ + JsonValueStringPtr p = new JsonValueString(); + const char * pChar=reader.getPoint(); + char c; + uint32_t i=0; + while(1) + { + c=reader.read(); + if(c == '\\') + { + p->value.append(pChar,i); + pChar=pChar+i+2; + i=0; + c=reader.read(); + if(c == '\\' || c == '\"' || c == '/') + p->value.append(1,c); + else if(c == 'b') + p->value.append(1,'\b'); + else if(c == 'f') + p->value.append(1,'\f'); + else if(c == 'n') + p->value.append(1,'\n'); + else if(c == 'r') + p->value.append(1,'\r'); + else if(c == 't') + p->value.append(1,'\t'); + else if(c == 'u') + { + uint32_t iCode=getHex(reader); + + if (iCode < 0x00080) + { + p->value.append(1,(char)(iCode & 0xFF)); + } + else if (iCode < 0x00800) + { + p->value.append(1,(char)(0xC0 + ((iCode >> 6) & 0x1F))); + p->value.append(1,(char)(0x80 + (iCode & 0x3F))); + } + else if (iCode < 0x10000) + { + p->value.append(1,(char)(0xE0 + ((iCode >> 12) & 0x0F))); + p->value.append(1,(char)(0x80 + ((iCode >> 6) & 0x3F))); + p->value.append(1,(char)(0x80 + (iCode & 0x3F))); + } + else + { + p->value.append(1,(char)(0xF0 + ((iCode >> 18) & 0x07))); + p->value.append(1,(char)(0x80 + ((iCode >> 12) & 0x3F))); + p->value.append(1,(char)(0x80 + ((iCode >> 6) & 0x3F))); + p->value.append(1,(char)(0x80 + (iCode & 0x3F))); + } + + pChar+=4; + +// char s[64]; +// snprintf(s, sizeof(s), "get string error1(\\u)[pos:%u], code:%x", (uint32_t)reader.getCur(), iCode); +// cout << s << endl; +// +// if(iCode>0xff) +// { +// char s[64]; +// snprintf(s, sizeof(s), "get string error1(\\u)[pos:%u], code:%x", (uint32_t)reader.getCur(), iCode); +// throw TC_Json_Exception(s); +// } +// pChar+=4; +// p->value.append(1,(char)iCode); +//#if 0 +// //还要再读一个 +// if(iCode<0xd800) +// { +// p->value.append(1,(char)(iCode>>2&0x00ff)); +// p->value.append(1,(char)(iCode&0x00ff)); +// } +// else +// { +// uint16_t iCodeTwelve=0; +// c=reader.read(); +// if(c == '\\' && (c=reader.read(),c=='u')) +// { +// iCodeTwelve=getHex(); +// } +// if(iCodeTwelve<0xdc00) +// { +// char s[64]; +// snprintf(s, sizeof(s), "get string error2(\\u)[pos:%u]", (uint32_t)reader.getCur()); +// throw TC_Json_Exception(s); +// } +// int iBuf=0; +// iCode=iCode&0x03ff; +// iBuf=(iCode<10); +// iBuf+=(iCodeTwelve&0x03ff); +// iBuf+=0x10000; +// } +//#endif + } + } + else if(c==head) + break; + else + i++; + } + p->value.append(pChar,i); + return p; +} + +JsonValueNumPtr TC_Json::getNum(BufferJsonReader & reader,char head) +{ + bool bOk=true; + bool bFloat=false; + bool bExponential=false; + bool bNegative=false; + bool bExponentialNegative=false; + int64_t iInt=0; + double dFloat=0; + double dFloatRat=0; + int64_t iExponential=0; + if(head == '-') + { + bOk=false; + bNegative=true; + } + else + iInt=head-0x30; + char c; + bool bNeedBack=false; + while(1) + { + if(reader.hasEnd()) + break; + c=reader.read(); + if(c>=0x30 && c<=0x39) + { + bOk=true; + if(bExponential) + iExponential=iExponential*10+c-0x30; + else if(bFloat) + { + dFloat=dFloat+dFloatRat*(c-0x30); + dFloatRat=dFloatRat*0.1; + } + else + iInt=iInt*10+c-0x30; + } + else if(c == '.' && !bFloat && !bExponential && bOk) + { + bOk=false; + bFloat=true; + dFloatRat=0.1; + } + else if((c == 'e' || c == 'E') && !bExponential && bOk) + { + bOk=false; + bExponential=true; + iExponential=0; + if(reader.hasEnd()) + break; + c=reader.read(); + if(c == '-') + bExponentialNegative=true; + else if(c == '+') + bExponentialNegative=false; + else if(c>=0x30 && c<=0x39) + { + bOk=true; + bExponential=(bool)(c-0x30); } else { - ostr << *it; + bNeedBack=true; + break; } + } + else + { + bNeedBack=true; break; } - } - } - ostr << "\""; -} - -void JsonValue::write(ostream& ostr) const -{ - switch(getType()) - { - case eJsonTypeString: - dynamic_cast(this)->write(ostr); - break; - case eJsonTypeNum: - dynamic_cast(this)->write(ostr); - break; - case eJsonTypeObj: - dynamic_cast(this)->write(ostr); - break; - case eJsonTypeArray: - dynamic_cast(this)->write(ostr); - break; - case eJsonTypeBoolean: - dynamic_cast(this)->write(ostr); - break; - case eJsonTypeNull: - dynamic_cast(this)->write(ostr); - break; - default: - assert(false); - } - -} - -JsonValuePtr JsonValue::createJsonValue(BufferJsonReader & reader) -{ - char c = reader.read(); - - FILTER_SPACE; - - JsonValue* obj = NULL; - switch(c) - { - case '{': - obj = new JsonValueObj(); - break; - case '[': - obj = new JsonValueArray(); - break; - case '"': - obj = new JsonValueString(); - break; - case 'T': - case 't': - case 'F': - case 'f': - obj = new JsonValueBoolean(); - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - obj = new JsonValueNum(); - break; - case 'n': - case 'N': - obj = new JsonValueNull(); - break; - default: - char s[64]; - snprintf(s, sizeof(s), "buffer overflow when peekBuf, over %u.", (uint32_t)reader.getCur()); - throw TC_Json_Exception(s); - } - obj->read(reader, c); - - return obj; - } - -void JsonValueString::write(ostream& ostr) const -{ - writeString(value, ostr); -} - -void JsonValueString::read(BufferJsonReader & reader, char head) -{ - const char * pChar=reader.getPoint(); - uint32_t i=0; - while(1) - { - char c = reader.read(); - if(c == '\\') - { - value.append(pChar,i); - pChar=pChar+i+2; - i=0; - c=reader.read(); - switch(c) - { - case '\\': - case '\"': - case '/': - value.append(1, c); - break; - case 'b': - value.append(1,'\b'); - break; - case 'f': - value.append(1,'\f'); - break; - case 'n': - value.append(1,'\n'); - break; - case 'r': - value.append(1,'\r'); - break; - case 't': - value.append(1,'\t'); - break; - case 'u': - // } - // if(c == '\\' || c == '\"' || c == '/') - // value.append(1,c); - // else if(c == 'b') - // value.append(1,'\b'); - // else if(c == 'f') - // value.append(1,'\f'); - // else if(c == 'n') - // value.append(1,'\n'); - // else if(c == 'r') - // value.append(1,'\r'); - // else if(c == 't') - // value.append(1,'\t'); - // else if(c == 'u') - { - uint32_t iCode=getHex(reader); - - if (iCode < 0x00080) - { - value.append(1,(char)(iCode & 0xFF)); - } - else if (iCode < 0x00800) - { - value.append(1,(char)(0xC0 + ((iCode >> 6) & 0x1F))); - value.append(1,(char)(0x80 + (iCode & 0x3F))); - } - else if (iCode < 0x10000) - { - value.append(1,(char)(0xE0 + ((iCode >> 12) & 0x0F))); - value.append(1,(char)(0x80 + ((iCode >> 6) & 0x3F))); - value.append(1,(char)(0x80 + (iCode & 0x3F))); - } - else - { - value.append(1,(char)(0xF0 + ((iCode >> 18) & 0x07))); - value.append(1,(char)(0x80 + ((iCode >> 12) & 0x3F))); - value.append(1,(char)(0x80 + ((iCode >> 6) & 0x3F))); - value.append(1,(char)(0x80 + (iCode & 0x3F))); - } - pChar+=4; - } - } - } - else if(c==head) - break; - else - i++; - } - value.append(pChar,i); -} - -void JsonValueNum::write(ostream& ostr) const -{ - if (!isInt) - { - ostr << TC_Common::tostr(value); - } - else - { - ostr << (int64_t)value; - } -} - -void JsonValueNum::read(BufferJsonReader & reader, char head) -{ - bool bOk=true; - bool bFloat=false; - bool bExponential=false; - bool bNegative=false; - bool bExponentialNegative=false; - int64_t iInt=0; - double dFloat=0; - double dFloatRat=0; - int64_t iExponential=0; - if(head == '-') - { - bOk=false; - bNegative=true; - } - else - iInt=head-0x30; - - char c; - bool bNeedBack=false; - - while(1) - { - if(reader.hasEnd()) - break; - c=reader.read(); - if(c>=0x30 && c<=0x39) - { - bOk=true; - if(bExponential) - iExponential=iExponential*10+c-0x30; - else if(bFloat) - { - dFloat=dFloat+dFloatRat*(c-0x30); - dFloatRat=dFloatRat*0.1; - } - else - iInt=iInt*10+c-0x30; - } - else if(c == '.' && !bFloat && !bExponential && bOk) - { - bOk=false; - bFloat=true; - dFloatRat=0.1; - } - else if((c == 'e' || c == 'E') && !bExponential && bOk) - { - bOk=false; - bExponential=true; - iExponential=0; - if(reader.hasEnd()) - break; - c=reader.read(); - if(c == '-') - bExponentialNegative=true; - else if(c == '+') - bExponentialNegative=false; - else if(c>=0x30 && c<=0x39) - { - bOk=true; - bExponential=(bool)(c-0x30); - } - else - { - bNeedBack=true; - break; - } - } - else - { - bNeedBack=true; - break; - } - } - if(!bOk) - { - char s[64]; - snprintf(s, sizeof(s), "get num error[pos:%u]", (uint32_t)reader.getCur()); - throw TC_Json_Exception(s); - } - if(bNeedBack) - reader.back(); - if(bExponentialNegative) - iExponential=0-iExponential; - double dResult=(iInt+dFloat)*pow(10,iExponential); - if(bNegative) - dResult=0-dResult; - - this->value=dResult; -} - -JsonValueObj::~JsonValueObj() -{ - // for(auto it = value.begin(); it != value.end(); ++it) - // { - // delete it->second; - // } - // value.clear(); -} - -const JsonValuePtr& JsonValueObj::get(const char *name) -{ - auto it = value.find(name); - - if(it == value.end()) - { - char s[64]; - snprintf(s, sizeof(s), "get obj error(key is not exists)[key:%s]", name); - throw TC_Json_Exception(s); - } - - return it->second; -} - -void JsonValueObj::write(ostream& ostr) const -{ - ostr << "{ "; - auto it = value.begin(); //unordered_map::const_iterator it(value.begin()), it_end(value.end()); - while (it != value.end()) - { - writeString(it->first, ostr); - - ostr << ": " ; - - it->second->write(ostr); - if(++it != value.end()) - { - ostr << ", "; - } - } - ostr << " }"; -} - -void JsonValueObj::read(BufferJsonReader & reader, char cc) -{ - bool bFirst=true; - while(1) - { - char c=reader.read(); - FILTER_SPACE; - if(c == '}' && bFirst) - { - return; - } - bFirst=false; - - if(c != '"') - { - char s[64]; - snprintf(s, sizeof(s), "get obj error(key is not string)[pos:%u]", (uint32_t)reader.getCur()); - throw TC_Json_Exception(s); - } - - JsonValueString vs; - vs.read(reader, c); - - c=reader.read(); - FILTER_SPACE; - if(c != ':') - { - char s[64]; - snprintf(s, sizeof(s), "get obj error(: not find)[pos:%u]", (uint32_t)reader.getCur()); - throw TC_Json_Exception(s); - } - - value.insert(make_pair(vs.value, JsonValue::createJsonValue(reader))); - - c=reader.read(); - FILTER_SPACE; - - if(c == ',') continue; - - if(c == '}') - { - return; - } - - char s[64]; - snprintf(s, sizeof(s), "get obj error(, not find)[pos:%u]", (uint32_t)reader.getCur()); - throw TC_Json_Exception(s); - } -} - -JsonValueArray::~JsonValueArray() -{ - // for(auto it = value.begin(); it != value.end(); ++it) - // { - // delete *it; - // } - // value.clear(); -} - -void JsonValueArray::write(ostream& ostr) const -{ - ostr << "[ "; - auto it = value.begin(); //vector::const_iterator it(value.begin()), it_end(value.end()); - while (it != value.end()) - { - (*it)->write(ostr); - - if (++it != value.end()) - { - ostr << ", "; - } - } - ostr << " ]"; -} - -void JsonValueArray::read(BufferJsonReader & reader, char cc) -{ - bool bFirst=true; - while(1) - { - char c; - if(bFirst) - { - c=reader.read(); - FILTER_SPACE; - if(c == ']') - { - return; - } - reader.back(); - } - bFirst=false; - - this->push_back(JsonValue::createJsonValue(reader)); - - c=reader.read(); - FILTER_SPACE; - if(c == ',') - continue; - if(c == ']') - return; - - char s[64]; - snprintf(s, sizeof(s), "get vector error(, not find )[pos:%u]", (uint32_t)reader.getCur()); - throw TC_Json_Exception(s); - } -} - -void JsonValueBoolean::write(ostream& ostr) const -{ - if(value) - ostr << "true"; - else - ostr << "false"; + } + if(!bOk) + { + char s[64]; + snprintf(s, sizeof(s), "get num error[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } + if(bNeedBack) + reader.back(); + if(bExponentialNegative) + iExponential=0-iExponential; + double dResult=(iInt+dFloat)*pow(10,iExponential); + if(bNegative) + dResult=0-dResult; + JsonValueNumPtr p = new JsonValueNum(); + p->value=dResult; + return p; } //为了提高效率和代码好写就先这么写了 -void JsonValueBoolean::read(BufferJsonReader & reader, char c) +JsonValueBooleanPtr TC_Json::getBoolean(BufferJsonReader & reader,char c) { - bool bOk=false; - // bool bValue; - if(c=='t'||c=='T') - { - c=reader.read(); - if(c=='r'||c=='R') - { - c=reader.read(); - if(c=='u'||c=='U') - { - c=reader.read(); - if(c=='e'||c=='E') - { - value=true; - bOk=true; - } - } - } - } - else if(c=='f'||c=='F') - { - c=reader.read(); - if(c=='a'||c=='A') - { - c=reader.read(); - if(c=='l'||c=='L') - { - c=reader.read(); - if(c=='s'||c=='S') - { - c=reader.read(); - if(c=='e'||c=='E') - { - value=false; - bOk=true; - } - } - } - } - } + bool bOk=false; + bool bValue; + if(c=='t'||c=='T') + { + c=reader.read(); + if(c=='r'||c=='R') + { + c=reader.read(); + if(c=='u'||c=='U') + { + c=reader.read(); + if(c=='e'||c=='E') + { + bValue=true; + bOk=true; + } + } + } + } + else if(c=='f'||c=='F') + { + c=reader.read(); + if(c=='a'||c=='A') + { + c=reader.read(); + if(c=='l'||c=='L') + { + c=reader.read(); + if(c=='s'||c=='S') + { + c=reader.read(); + if(c=='e'||c=='E') + { + bValue=false; + bOk=true; + } + } + } + } + } - if(!bOk) - { - char s[64]; - snprintf(s, sizeof(s), "get bool error[pos:%u]", (uint32_t)reader.getCur()); - throw TC_Json_Exception(s); - } + if(!bOk) + { + char s[64]; + snprintf(s, sizeof(s), "get bool error[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } + + JsonValueBooleanPtr p = new JsonValueBoolean(); + p->value=bValue; + return p; } -void JsonValueNull::write(ostream& ostr) const +JsonValuePtr TC_Json::getNull(BufferJsonReader & reader,char c) { - ostr << "null"; + assert(c=='n' || c=='N'); + bool bOk=false; + c=reader.read(); + if(c=='u'||c=='U') + { + c=reader.read(); + if(c=='l'||c=='L') + { + c=reader.read(); + if(c=='l'||c=='L') + { + bOk=true; + } + } + } + if(!bOk) + { + char s[64]; + snprintf(s, sizeof(s), "get NULL error[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } + return NULL; } -void JsonValueNull::read(BufferJsonReader & reader, char c) +uint32_t TC_Json::getHex(BufferJsonReader & reader) { - assert(c=='n' || c=='N'); - bool bOk=false; - c=reader.read(); - if(c=='u'||c=='U') - { - c=reader.read(); - if(c=='l'||c=='L') - { - c=reader.read(); - if(c=='l'||c=='L') - { - bOk=true; - } - } - } - if(!bOk) - { - char s[64]; - snprintf(s, sizeof(s), "get NULL error[pos:%u]", (uint32_t)reader.getCur()); - throw TC_Json_Exception(s); - } + uint32_t iCode=0; + char c; + for(int iLoop=0;iLoop<4;iLoop++) + { + c=reader.read(); + if(c>='a'&&c<='f') + iCode=iCode*16+c-'a'+10; + else if(c>='A'&&c<='F') + iCode=iCode*16+c-'A'+10; + else if(c>='0'&&c<='9') + iCode=iCode*16+c-'0'; + else + { + char s[64]; + snprintf(s, sizeof(s), "get string error3(\\u)[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } + } + return iCode; } -string TC_Json::writeValue(const JsonValuePtr& p) + +string TC_Json::writeValue(const JsonValuePtr & p) { - ostringstream ostr; - p->write(ostr); - return ostr.str(); + string ostr; + writeValue(p, ostr); + return ostr; +} + +void TC_Json::writeValue(const JsonValuePtr & p, string& ostr) +{ + if(!p) + { + ostr = "null"; + return; + } + switch(p->getType()) + { + case eJsonTypeString : + writeString(JsonValueStringPtr::dynamicCast(p), ostr); + break; + case eJsonTypeNum: + writeNum(JsonValueNumPtr::dynamicCast(p), ostr); + break; + case eJsonTypeObj: + writeObj(JsonValueObjPtr::dynamicCast(p), ostr); + break; + case eJsonTypeArray: + writeArray(JsonValueArrayPtr::dynamicCast(p), ostr); + break; + case eJsonTypeBoolean: + writeBoolean(JsonValueBooleanPtr::dynamicCast(p), ostr); + break; + default: + assert(false); + } +} + + +void TC_Json::writeString(const JsonValueStringPtr & p, string& ostr) +{ + writeString(p->value, ostr); +} + +void TC_Json::writeString(const string & s, string& ostr) +{ + ostr += "\""; + std::string::const_iterator it(s.begin()), + itEnd(s.end()); + for (; it != itEnd; ++it) + { + switch(*it) + { + case '"': + ostr += "\\\""; + break; + case '\\': + ostr += "\\\\"; + break; + case '/': + ostr += "\\/"; + break; + case '\b': + ostr += "\\b"; + break; + case '\f': + ostr += "\\f"; + break; + case '\n': + ostr += "\\n"; + break; + case '\r': + ostr += "\\r"; + break; + case '\t': + ostr += "\\t"; + break; + default: + { + if((unsigned char)(*it)<0x20) + { + char buf[16]; + snprintf(buf,sizeof(buf),"\\u%04x",(unsigned char)*it); + ostr += string(buf,6); + } + else + { + ostr.push_back(*it); + } + break; + } + } + } + ostr += "\""; +} + + +void TC_Json::writeNum(const JsonValueNumPtr & p, string& ostr) +{ + ostringstream ss; + if (!p->isInt) + { + ss << TC_Common::tostr(p->value) ; + } + else + { + ss << (int64_t)p->value; + } + + ostr += ss.str(); +} + + +void TC_Json::writeObj(const JsonValueObjPtr & p, string& ostr) +{ + ostr += "{ "; + unordered_map::const_iterator it(p->value.begin()), it_end(p->value.end()); + while (it != it_end) + { + writeString(it->first, ostr); + ostr += ": " ; + writeValue(it->second, ostr); + if(++it != it_end) + { + ostr += ", "; + } + } + ostr += " }"; +} + +void TC_Json::writeArray(const JsonValueArrayPtr & p, string& ostr) +{ + ostr += "[ "; + vector::const_iterator it(p->value.begin()), it_end(p->value.end()); + while (it != it_end) + { + writeValue(*it, ostr); + if (++it != it_end) + { + ostr += ", "; + } + } + ostr += " ]"; +} + +void TC_Json::writeBoolean(const JsonValueBooleanPtr & p, string& ostr) +{ + if(p->value) + ostr += "true"; + else + ostr += "false"; } JsonValuePtr TC_Json::getValue(const string & str) { - BufferJsonReader reader; - reader.setBuffer(str.c_str(),str.length()); - return JsonValue::createJsonValue(reader); + BufferJsonReader reader; + reader.setBuffer(str.c_str(),str.length()); + return getValue(reader); +} + +//json里面定义的空白字符 +bool TC_Json::isspace(char c) +{ + if(c == ' ' || c == '\t' || c == '\r' || c == '\n') + return true; + return false; +} + +////////////////////////////////////////////////////// +void TC_JsonWriteOstream::writeValue(const JsonValuePtr & p, ostream& ostr) +{ + if(!p) + { + ostr << "null"; + return; + } + switch(p->getType()) + { + case eJsonTypeString : + writeString(JsonValueStringPtr::dynamicCast(p), ostr); + break; + case eJsonTypeNum: + writeNum(JsonValueNumPtr::dynamicCast(p), ostr); + break; + case eJsonTypeObj: + writeObj(JsonValueObjPtr::dynamicCast(p), ostr); + break; + case eJsonTypeArray: + writeArray(JsonValueArrayPtr::dynamicCast(p), ostr); + break; + case eJsonTypeBoolean: + writeBoolean(JsonValueBooleanPtr::dynamicCast(p), ostr); + break; + default: + assert(false); + } +} + +void TC_JsonWriteOstream::writeString(const JsonValueStringPtr & p, ostream& sReturn) +{ + writeString(p->value, sReturn); +} + +void TC_JsonWriteOstream::writeString(const string & s, ostream& sReturn) +{ + sReturn << "\""; + std::string::const_iterator it(s.begin()), + itEnd(s.end()); + for (; it != itEnd; ++it) + { + switch(*it) + { + case '"': + sReturn << "\\\""; + break; + case '\\': + sReturn << "\\\\"; + break; + case '/': + sReturn <<"\\/"; + break; + case '\b': + sReturn << "\\b"; + break; + case '\f': + sReturn << "\\f"; + break; + case '\n': + sReturn << "\\n"; + break; + case '\r': + sReturn << "\\r"; + break; + case '\t': + sReturn << "\\t"; + break; + default: + { + if((unsigned char)(*it)<0x20) + { + char buf[16]; + snprintf(buf,sizeof(buf),"\\u%04x",(unsigned char)*it); + sReturn << string(buf,6); + } + else + { + sReturn << *it; + } + break; + } + } + } + sReturn << "\""; +} + + +void TC_JsonWriteOstream::writeNum(const JsonValueNumPtr & p, ostream& ostr) +{ + if (!p->isInt) + { + ostr << TC_Common::tostr(p->value); + } + else + { + ostr << (int64_t)p->value; + } +} + + +void TC_JsonWriteOstream::writeObj(const JsonValueObjPtr & p, ostream& ostr) +{ + ostr << "{ "; + unordered_map::const_iterator it(p->value.begin()), it_end(p->value.end()); + while (it != it_end) + { + writeString(it->first, ostr); + ostr << ": " ; + writeValue(it->second, ostr); + if(++it != it_end) + { + ostr << ", "; + } + } + ostr << " }"; +} + +void TC_JsonWriteOstream::writeArray(const JsonValueArrayPtr & p, ostream& ostr) +{ + ostr << "[ "; + vector::const_iterator it(p->value.begin()), it_end(p->value.end()); + while (it != it_end) + { + writeValue(*it, ostr); + if (++it != it_end) + { + ostr << ", "; + } + } + ostr << " ]"; +} + +void TC_JsonWriteOstream::writeBoolean(const JsonValueBooleanPtr & p, ostream& ostr) +{ + if(p->value) + ostr << "true"; + else + ostr << "false"; } } diff --git a/util/src/tc_malloc_chunk.cpp b/util/src/tc_malloc_chunk.cpp index 9fe7eb8..0aa511e 100644 --- a/util/src/tc_malloc_chunk.cpp +++ b/util/src/tc_malloc_chunk.cpp @@ -106,8 +106,8 @@ namespace tars int next_size = 0; for (size_t c = 1; c < kNumClasses; c++) { - const int max_size_in_class = class_to_size_[c]; - for (int s = next_size; s <= max_size_in_class; s += kAlignment) + const size_t max_size_in_class = class_to_size_[c]; + for (size_t s = next_size; s <= max_size_in_class; s += kAlignment) { class_array_[ClassIndex(s)] = c; } diff --git a/util/src/tc_md5.cpp b/util/src/tc_md5.cpp index 621141e..4fd6da6 100644 --- a/util/src/tc_md5.cpp +++ b/util/src/tc_md5.cpp @@ -153,20 +153,22 @@ void TC_MD5::md5_process( MD5_CTX *ctx, const unsigned char data[64] ) string TC_MD5::md5file(const string& fileFullName) { unsigned char sOutBuffer[16]; - unsigned char buf[1024]; + unsigned char buf[16*1024]; FILE *f; size_t n; MD5_CTX context; if(( f = fopen( fileFullName.c_str(), "rb" )) == NULL ) - return ""; + { + TARS_THROW_EXCEPTION_SYSCODE(TC_MD5_Exception, "[TC_MD5::md5file] fopen '" + fileFullName + "', error"); + } + md5init(&context); while((n = fread( buf, 1, sizeof( buf ),f)) > 0 ) md5update( &context, buf, (int)n ); md5final (sOutBuffer, &context); fclose(f); - memset(&context, 0, sizeof(MD5_CTX)); - string s((const char *)sOutBuffer, 16); - return bin2str((const void *)s.data(), s.length(), ""); + + return bin2str((const void *)sOutBuffer, sizeof(sOutBuffer), ""); } void TC_MD5::md5update(MD5_CTX *ctx, unsigned char *input, unsigned int ilen ) @@ -273,26 +275,38 @@ void TC_MD5::md5_memset (POINTER output,int value,unsigned int len) } } -string TC_MD5::md5bin(const string &sString) +vector TC_MD5::md5bin(const string &buffer) { - unsigned char sOutBuffer[16]; + return md5bin(buffer.c_str(), buffer.size()); +} +vector TC_MD5::md5bin(const char *buffer, size_t length) +{ + vector sOutBuffer; + sOutBuffer.resize(16); +// unsigned char sOutBuffer[16]; MD5_CTX context; md5init (&context); - md5update (&context, (unsigned char*)sString.c_str(), sString.length()); - md5final (sOutBuffer, &context); + md5update (&context, (unsigned char*)buffer, length); + md5final ((unsigned char*)&sOutBuffer[0], &context); - string sBinResult; + return sOutBuffer; +// string sBinResult; - sBinResult.assign((const char *)sOutBuffer, 16); +// sBinResult.assign((const char *)sOutBuffer, 16); - return sBinResult; +// return sBinResult; } -string TC_MD5::md5str(const string &sString) +string TC_MD5::md5str(const string &buffer) { - string s = md5bin(sString); - return bin2str((const void *)s.data(), s.length(), ""); + return md5str(buffer.c_str(), buffer.size()); +} + +string TC_MD5::md5str(const char *buffer, size_t length) +{ + vector s = md5bin(buffer, length); + return bin2str((const void *)s.data(), s.size(), ""); } string TC_MD5::bin2str(const void *buf, size_t len, const string &sSep) diff --git a/util/src/tc_mysql.cpp b/util/src/tc_mysql.cpp index 4f0127f..cbb79e3 100644 --- a/util/src/tc_mysql.cpp +++ b/util/src/tc_mysql.cpp @@ -16,7 +16,7 @@ #if TARS_MYSQL #include "util/tc_mysql.h" -#include "mysql.h" +#include "util/tc_common.h" #include "errmsg.h" #include #include @@ -71,6 +71,10 @@ void TC_Mysql::init(const TC_DBConf& tcDBConf) _dbConf = tcDBConf; } +TC_DBConf TC_Mysql::getDBConf() +{ + return _dbConf; +} void TC_Mysql::connect() { disconnect(); @@ -108,10 +112,6 @@ void TC_Mysql::disconnect() string TC_Mysql::escapeString(const string& sFrom) { - if(!_bConnected) - { - connect(); - } string sTo; string::size_type iLen = sFrom.length() * 2 + 1; @@ -119,7 +119,7 @@ string TC_Mysql::escapeString(const string& sFrom) memset(pTo, 0x00, iLen); - mysql_real_escape_string(_pstMql, pTo, sFrom.c_str(), sFrom.length()); + mysql_escape_string(pTo, sFrom.c_str(), sFrom.length()); sTo = pTo; @@ -128,12 +128,26 @@ string TC_Mysql::escapeString(const string& sFrom) return sTo; } -MYSQL *TC_Mysql::getMysql(void) +string TC_Mysql::buildInsertSQLNoSafe(const string &sTableName, const RECORD_DATA &mpColumns) { - return _pstMql; + return buildSQLNoSafe(sTableName, "insert", mpColumns); } -string TC_Mysql::buildInsertSQL(const string &sTableName, const RECORD_DATA &mpColumns) +string TC_Mysql::buildInsertSQLNoSafe(const string &sTableName, const map>> &mpColumns) +{ + return buildBatchSQLNoSafe(sTableName, "insert", mpColumns); +} + +string TC_Mysql::buildReplaceSQLNoSafe(const string &sTableName, const RECORD_DATA &mpColumns) +{ + return buildSQLNoSafe(sTableName, "replace", mpColumns); +} + +string TC_Mysql::buildReplaceSQLNoSafe(const string &sTableName, const map>> &mpColumns) +{ + return buildBatchSQLNoSafe(sTableName, "replace", mpColumns); +} +string TC_Mysql::buildSQLNoSafe(const string &sTableName, const string &command, const map > &mpColumns) { ostringstream sColumnNames; ostringstream sColumnValues; @@ -169,50 +183,66 @@ string TC_Mysql::buildInsertSQL(const string &sTableName, const RECORD_DATA &mpC } ostringstream os; - os << "insert into " << sTableName << " (" << sColumnNames.str() << ") values (" << sColumnValues.str() << ")"; + os << command << " into " << sTableName << " (" << sColumnNames.str() << ") values (" << sColumnValues.str() << ")"; return os.str(); } -string TC_Mysql::buildReplaceSQL(const string &sTableName, const RECORD_DATA &mpColumns) +string TC_Mysql::buildBatchSQLNoSafe(const string &sTableName, const string &command, const map >> &mpColumns) { + if(mpColumns.empty()) + return ""; ostringstream sColumnNames; ostringstream sColumnValues; - map >::const_iterator itEnd = mpColumns.end(); - for(map >::const_iterator it = mpColumns.begin(); it != itEnd; ++it) + size_t count = mpColumns.begin()->second.second.size(); + + auto itEnd = mpColumns.end(); + for(auto it = mpColumns.begin(); it != itEnd; ++it) { if (it == mpColumns.begin()) { sColumnNames << "`" << it->first << "`"; - if(it->second.first == DB_INT) - { - sColumnValues << it->second.second; - } - else - { - sColumnValues << "'" << escapeString(it->second.second) << "'"; - } } else - { + { sColumnNames << ",`" << it->first << "`"; + } + + if(count != it->second.second.size()) + { + throw TC_Mysql_Exception("[TC_Mysql::buildBatchSQLNoSafe]: column count not same!"); + } + } + + for(size_t i = 0; i < count; i++) + { + sColumnValues << "("; + auto itEnd = mpColumns.end(); + for(auto it = mpColumns.begin(); it != itEnd; ++it) + { + if(it != mpColumns.begin()) + sColumnValues << ","; + if(it->second.first == DB_INT) { - sColumnValues << "," + it->second.second; + sColumnValues << it->second.second[i]; } else { - sColumnValues << ",'" << escapeString(it->second.second) << "'"; + sColumnValues << "'" << escapeString(it->second.second[i]) << "'"; } } + sColumnValues << ")"; + if(i != count - 1) + sColumnValues << ","; } ostringstream os; - os << "replace into " << sTableName << " (" << sColumnNames.str() << ") values (" << sColumnValues.str() << ")"; + os << command << " into `" << sTableName << "` (" << sColumnNames.str() << ") values " << sColumnValues.str(); return os.str(); } -string TC_Mysql::buildUpdateSQL(const string &sTableName,const RECORD_DATA &mpColumns, const string &sWhereFilter) +string TC_Mysql::buildUpdateSQLNoSafe(const string &sTableName,const RECORD_DATA &mpColumns, const string &sWhereFilter) { ostringstream sColumnNameValueSet; @@ -241,6 +271,152 @@ string TC_Mysql::buildUpdateSQL(const string &sTableName,const RECORD_DATA &mpCo ostringstream os; os << "update " << sTableName << " set " << sColumnNameValueSet.str() << " " << sWhereFilter; + return os.str(); +} +string TC_Mysql::realEscapeString(const string& sFrom) +{ + if(!_bConnected) + { + connect(); + } + string sTo; + string::size_type iLen = sFrom.length() * 2 + 1; + char *pTo = (char *)malloc(iLen); + memset(pTo, 0x00, iLen); + mysql_real_escape_string(_pstMql, pTo, sFrom.c_str(), sFrom.length()); + sTo = pTo; + free(pTo); + return sTo; +} +MYSQL *TC_Mysql::getMysql(void) +{ + return _pstMql; +} +string TC_Mysql::buildInsertSQL(const string &sTableName, const RECORD_DATA &mpColumns) +{ + return buildSQL(sTableName, "insert", mpColumns); +} +string TC_Mysql::buildInsertSQL(const string &sTableName, const map >> &mpColumns) +{ + return buildBatchSQL(sTableName, "insert", mpColumns); +} +string TC_Mysql::buildReplaceSQL(const string &sTableName, const RECORD_DATA &mpColumns) +{ + return buildSQL(sTableName, "replace", mpColumns); +} +string TC_Mysql::buildReplaceSQL(const string &sTableName, const map>> &mpColumns) +{ + return buildBatchSQL(sTableName, "replace", mpColumns); +} +string TC_Mysql::buildSQL(const string &sTableName, const string &command, const map > &mpColumns) +{ + ostringstream sColumnNames; + ostringstream sColumnValues; + map >::const_iterator itEnd = mpColumns.end(); + for(map >::const_iterator it = mpColumns.begin(); it != itEnd; ++it) + { + if (it == mpColumns.begin()) + { + sColumnNames << "`" << it->first << "`"; + if(it->second.first == DB_INT) + { + sColumnValues << it->second.second; + } + else + { + sColumnValues << "'" << realEscapeString(it->second.second) << "'"; + } + } + else + { + sColumnNames << ",`" << it->first << "`"; + if(it->second.first == DB_INT) + { + sColumnValues << "," + it->second.second; + } + else + { + sColumnValues << ",'" << realEscapeString(it->second.second) << "'"; + } + } + } + ostringstream os; + os << command << " into `" << sTableName << "` (" << sColumnNames.str() << ") values (" << sColumnValues.str() << ")"; + return os.str(); +} +string TC_Mysql::buildBatchSQL(const string &sTableName, const string &command, const map >> &mpColumns) +{ + if(mpColumns.empty()) + return ""; + ostringstream sColumnNames; + ostringstream sColumnValues; + size_t count = mpColumns.begin()->second.second.size(); + auto itEnd = mpColumns.end(); + for(auto it = mpColumns.begin(); it != itEnd; ++it) + { + if(it == mpColumns.begin()) + { + sColumnNames << "`" << it->first << "`"; + } + else + { + sColumnNames << ",`" << it->first << "`"; + } + if(count != it->second.second.size()) + { + throw TC_Mysql_Exception("[TC_Mysql::buildBatchSQL]: column count not same!" + TC_Common::tostr(count) + " !=" + TC_Common::tostr(it->second.second.size())); + } + } + for(size_t i = 0; i < count; i++) + { + sColumnValues << "("; + auto itEnd = mpColumns.end(); + for(auto it = mpColumns.begin(); it != itEnd; ++it) + { + if(it != mpColumns.begin()) + sColumnValues << ","; + if(it->second.first == DB_INT) + { + sColumnValues << it->second.second[i]; + } + else + { + sColumnValues << "'" << realEscapeString(it->second.second[i]) << "'"; + } + } + sColumnValues << ")"; + if(i != count - 1) + sColumnValues << ","; + } + ostringstream os; + os << command << " into `" << sTableName << "` (" << sColumnNames.str() << ") values " << sColumnValues.str(); + return os.str(); +} +string TC_Mysql::buildUpdateSQL(const string &sTableName,const RECORD_DATA &mpColumns, const string &sWhereFilter) +{ + ostringstream sColumnNameValueSet; + map >::const_iterator itEnd = mpColumns.end(); + for(map >::const_iterator it = mpColumns.begin(); it != itEnd; ++it) + { + if (it == mpColumns.begin()) + { + sColumnNameValueSet << "`" << it->first << "`"; + } + else + { + sColumnNameValueSet << ",`" << it->first << "`"; + } + if(it->second.first == DB_INT) + { + sColumnNameValueSet << "= " << it->second.second; + } + else + { + sColumnNameValueSet << "= '" << realEscapeString(it->second.second) << "'"; + } + } + ostringstream os; + os << "update `" << sTableName << "` set " << sColumnNameValueSet.str() << " " << sWhereFilter; return os.str(); } @@ -369,6 +545,61 @@ TC_Mysql::MysqlData TC_Mysql::queryRecord(const string& sSql) return data; } +size_t TC_Mysql::travelRecord(const string& sSql, const std::function &)> & pdatafunc) +{ + size_t count = 0; + if (!_bConnected) + { + connect(); + } + _sLastSql = sSql; + int iRet = mysql_real_query(_pstMql, sSql.c_str(), sSql.length()); + if (iRet != 0) + { + int iErrno = mysql_errno(_pstMql); + if (iErrno == 2013 || iErrno == 2006) + { + connect(); + iRet = mysql_real_query(_pstMql, sSql.c_str(), sSql.length()); + } + } + if (iRet != 0) + { + throw TC_Mysql_Exception("[TC_Mysql::execute]: mysql_query: [ " + sSql + " ] :" + string(mysql_error(_pstMql))); + } + MYSQL_RES *pstRes = mysql_store_result(_pstMql); + if (pstRes == NULL) + { + throw TC_Mysql_Exception("[TC_Mysql::queryRecord]: mysql_store_result: " + sSql + " : " + string(mysql_error(_pstMql))); + } + vector vtFields; + MYSQL_FIELD *field; + while ((field = mysql_fetch_field(pstRes))) + { + vtFields.push_back(field->name); + } + MYSQL_ROW stRow; + while ((stRow = mysql_fetch_row(pstRes)) != (MYSQL_ROW)NULL) + { + map mpRow; + unsigned long * lengths = mysql_fetch_lengths(pstRes); + for (size_t i = 0; i < vtFields.size(); i++) + { + if (stRow[i]) + { + mpRow[vtFields[i]] = string(stRow[i], lengths[i]); + } + else + { + mpRow[vtFields[i]] = ""; + } + } + pdatafunc(mpRow); + count++; + } + mysql_free_result(pstRes); + return count; +} size_t TC_Mysql::updateRecord(const string &sTableName, const RECORD_DATA &mpColumns, const string &sCondition) { string sSql = buildUpdateSQL(sTableName, mpColumns, sCondition); @@ -385,7 +616,19 @@ size_t TC_Mysql::insertRecord(const string &sTableName, const RECORD_DATA &mpCol return mysql_affected_rows(_pstMql); } +size_t TC_Mysql::insertRecord(const string &sTableName, const map >> &mpColumns) +{ + string sSql = buildInsertSQL(sTableName, mpColumns); + execute(sSql); + return mysql_affected_rows(_pstMql); +} size_t TC_Mysql::replaceRecord(const string &sTableName, const RECORD_DATA &mpColumns) +{ + string sSql = buildReplaceSQL(sTableName, mpColumns); + execute(sSql); + return mysql_affected_rows(_pstMql); +} +size_t TC_Mysql::replaceRecord(const string &sTableName, const map>> &mpColumns) { string sSql = buildReplaceSQL(sTableName, mpColumns); execute(sSql); diff --git a/util/src/tc_option.cpp b/util/src/tc_option.cpp index 3cae2a1..1415911 100644 --- a/util/src/tc_option.cpp +++ b/util/src/tc_option.cpp @@ -29,6 +29,24 @@ void TC_Option::decode(int argc, char *argv[]) { v.push_back(argv[i]); } + for(size_t i = 0; i < v.size(); i++) + { + if(v[i].length() > 2 && v[i].substr(0,2) == "--") + { + parse(v[i]); + } + else + { + _vSingle.push_back(v[i]); + } + } +} +void TC_Option::decode(const char *command) +{ + _mParam.clear(); + if(command == NULL) + return; + vector v = TC_Common::sepstr(command, " \t"); for(size_t i = 0; i < v.size(); i++) { diff --git a/util/src/tc_sem_mutex.cpp b/util/src/tc_sem_mutex.cpp index 10438ad..946b228 100644 --- a/util/src/tc_sem_mutex.cpp +++ b/util/src/tc_sem_mutex.cpp @@ -32,6 +32,9 @@ TC_SemMutex::TC_SemMutex(key_t iKey) init(iKey); } +TC_SemMutex::~TC_SemMutex() +{ +} void TC_SemMutex::init(key_t iKey) { #if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) @@ -60,7 +63,8 @@ void TC_SemMutex::init(key_t iKey) //将所有信号量的值设置为0 if ( semctl( iSemID, 0, SETALL, arg ) == -1 ) { - throw TC_SemMutex_Exception("[TC_SemMutex::init] semctl error:" + string(strerror(errno))); + TARS_THROW_EXCEPTION_SYSCODE(TC_SemMutex_Exception, "[TC_SemMutex::init] semctl error"); + // throw TC_SemMutex_Exception("[TC_SemMutex::init] semctl error", TC_Exception::getSystemCode()); } } else @@ -68,13 +72,15 @@ void TC_SemMutex::init(key_t iKey) //信号量已经存在 if ( errno != EEXIST ) { - throw TC_SemMutex_Exception("[TC_SemMutex::init] sem has exist error:" + string(strerror(errno))); + TARS_THROW_EXCEPTION_SYSCODE(TC_SemMutex_Exception, "[TC_SemMutex::init] sem has exist error"); + // throw TC_SemMutex_Exception("[TC_SemMutex::init] sem has exist error", TC_Exception::getSystemCode()); } //连接信号量 if ( (iSemID = semget( iKey, 2, 0666 )) == -1 ) { - throw TC_SemMutex_Exception("[TC_SemMutex::init] connect sem error:" + string(strerror(errno))); + TARS_THROW_EXCEPTION_SYSCODE(TC_SemMutex_Exception, "[TC_SemMutex::init] connect sem error"); + // throw TC_SemMutex_Exception("[TC_SemMutex::init] connect sem error", TC_Exception::getSystemCode()); } } @@ -82,7 +88,7 @@ void TC_SemMutex::init(key_t iKey) _semID = iSemID; } -int TC_SemMutex::rlock() const +void TC_SemMutex::rlock() const { //进入共享锁, 第二个信号量的值表示当前使用信号量的进程个数 //等待第一个信号量变为0(排他锁没有使用) @@ -97,12 +103,12 @@ int TC_SemMutex::rlock() const } while ((ret == -1) &&(errno==EINTR)); - return ret; + // return ret; //return semop( _semID, &sops[0], nsops); } -int TC_SemMutex::unrlock( ) const +void TC_SemMutex::unrlock( ) const { //解除共享锁, 有进程使用过第二个信号量 //等到第二个信号量可以使用(第二个信号量的值>=1) @@ -117,7 +123,7 @@ int TC_SemMutex::unrlock( ) const } while ((ret == -1) &&(errno==EINTR)); - return ret; + // return ret; //return semop( _semID, &sops[0], nsops); } @@ -137,13 +143,14 @@ bool TC_SemMutex::tryrlock() const } else { - throw TC_SemMutex_Exception("[TC_SemMutex::tryrlock] semop error : " + string(strerror(errno))); + TARS_THROW_EXCEPTION_SYSCODE(TC_SemMutex_Exception, "[TC_SemMutex::tryrlock] semop error"); + // throw TC_SemMutex_Exception("[TC_SemMutex::tryrlock] semop error", TC_Exception::getSystemCode()); } } return true; } -int TC_SemMutex::wlock() const +void TC_SemMutex::wlock() const { //进入排他锁, 第一个信号量和第二个信号都没有被使用过(即, 两个锁都没有被使用) //等待第一个信号量变为0 @@ -160,11 +167,11 @@ int TC_SemMutex::wlock() const } while ((ret == -1) &&(errno==EINTR)); - return ret; + // return ret; //return semop( _semID, &sops[0], nsops); } -int TC_SemMutex::unwlock() const +void TC_SemMutex::unwlock() const { //解除排他锁, 有进程使用过第一个信号量 //等待第一个信号量(信号量值>=1) @@ -179,7 +186,7 @@ int TC_SemMutex::unwlock() const } while ((ret == -1) &&(errno==EINTR)); - return ret; + // return ret; //return semop( _semID, &sops[0], nsops); @@ -200,14 +207,222 @@ bool TC_SemMutex::trywlock() const } else { - throw TC_SemMutex_Exception("[TC_SemMutex::trywlock] semop error : " + string(strerror(errno))); + TARS_THROW_EXCEPTION_SYSCODE(TC_SemMutex_Exception, "[TC_SemMutex::trywlock] semop error"); + // throw TC_SemMutex_Exception("[TC_SemMutex::trywlock] semop error", TC_Exception::getSystemCode()); } } return true; } +#else +TC_SemMutex::TC_SemMutex():_readers(0), _writersWaiting(0), _writers(0) +{ } +TC_SemMutex::TC_SemMutex(key_t iKey) +{ + init(iKey); +} +TC_SemMutex::~TC_SemMutex() +{ + if(_mutex != NULL) + { + CloseHandle(_mutex); + _mutex = NULL; + } + if(_readEvent!= NULL) + { + CloseHandle(_readEvent); + _readEvent = NULL; + } + if(_writeEvent != NULL) + { + CloseHandle(_writeEvent); + _writeEvent = NULL; + } +} +void TC_SemMutex::init(key_t iKey) +{ + string key = "tars-mutex-" + TC_Common::tostr(iKey); + string rkey = "tars-readEvent-" + TC_Common::tostr(iKey); + string wkey = "tars-writeEvent-" + TC_Common::tostr(iKey); + _mutex = CreateMutex(NULL, FALSE, key.c_str()); + if (_mutex == NULL) + { + TARS_THROW_EXCEPTION_SYSCODE(TC_SemMutex_Exception, "[TC_SemMutex::init] CreateMutex error"); + } + _readEvent = CreateEvent(NULL, TRUE, TRUE, rkey.c_str()); + if (_readEvent == NULL) + { + CloseHandle(_mutex); + _mutex = NULL; + TARS_THROW_EXCEPTION_SYSCODE(TC_SemMutex_Exception, "[TC_SemMutex::init] CreateEvent error"); + } + _writeEvent = CreateEvent(NULL, TRUE, TRUE, wkey.c_str()); + if (_writeEvent == NULL) + { + CloseHandle(_mutex); + _mutex = NULL; + CloseHandle(_readEvent); + _readEvent = NULL; + TARS_THROW_EXCEPTION_SYSCODE(TC_SemMutex_Exception, "[TC_SemMutex::init] CreateEvent error"); + } + _semKey = iKey; +} +void TC_SemMutex::addWriter() const +{ + switch (WaitForSingleObject(_mutex, INFINITE)) + { + case WAIT_OBJECT_0: + if (++_writersWaiting == 1) + ResetEvent(_readEvent); + ReleaseMutex(_mutex); + break; + default: + TARS_THROW_EXCEPTION_SYSCODE(TC_SemMutex_Exception, "[TC_SemMutex::addWriter] WaitForSingleObject error"); + } +} +void TC_SemMutex::removeWriter() const +{ + switch (WaitForSingleObject(_mutex, INFINITE)) + { + case WAIT_OBJECT_0: + if (--_writersWaiting == 0 && _writers == 0) + SetEvent(_readEvent); + ReleaseMutex(_mutex); + break; + default: + TARS_THROW_EXCEPTION_SYSCODE(TC_SemMutex_Exception, "[TC_SemMutex::removeWriter] WaitForSingleObject error"); + } +} +void TC_SemMutex::rlock() const +{ + HANDLE h[2]; + h[0] = _mutex; + h[1] = _readEvent; + switch (WaitForMultipleObjects(2, h, TRUE, INFINITE)) + { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + ++_readers; + ResetEvent(_writeEvent); + ReleaseMutex(_mutex); + assert(_writers == 0); + break; + default: + TARS_THROW_EXCEPTION_SYSCODE(TC_SemMutex_Exception, "[TC_SemMutex::rlock] WaitForSingleObject error"); + } +} +void TC_SemMutex::unrlock( ) const +{ + unlockImp(); +} +bool TC_SemMutex::tryrlock() const +{ + for (;;) + { + if (_writers != 0 || _writersWaiting != 0) + return false; + DWORD result = tryReadLockOnce(); + switch (result) + { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + return true; + case WAIT_TIMEOUT: + continue; + default: + TARS_THROW_EXCEPTION_SYSCODE(TC_SemMutex_Exception, "[TC_SemMutex::tryrlock] WaitForSingleObject error"); + } + } +} +void TC_SemMutex::wlock() const +{ + addWriter(); + HANDLE h[2]; + h[0] = _mutex; + h[1] = _writeEvent; + switch (WaitForMultipleObjects(2, h, TRUE, INFINITE)) + { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + --_writersWaiting; + ++_readers; + ++_writers; + ResetEvent(_readEvent); + ResetEvent(_writeEvent); + ReleaseMutex(_mutex); + assert(_writers == 1); + break; + default: + removeWriter(); + TARS_THROW_EXCEPTION_SYSCODE(TC_SemMutex_Exception, "[TC_SemMutex::wlock] WaitForSingleObject error"); + } +} +void TC_SemMutex::unwlock() const +{ + unlockImp(); +} +bool TC_SemMutex::trywlock() const +{ + addWriter(); + HANDLE h[2]; + h[0] = _mutex; + h[1] = _writeEvent; + switch (WaitForMultipleObjects(2, h, TRUE, 1)) + { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + --_writersWaiting; + ++_readers; + ++_writers; + ResetEvent(_readEvent); + ResetEvent(_writeEvent); + ReleaseMutex(_mutex); + assert(_writers == 1); + return true; + case WAIT_TIMEOUT: + default: + removeWriter(); + } + return false; +} +void TC_SemMutex::unlockImp() const +{ + switch (WaitForSingleObject(_mutex, INFINITE)) + { + case WAIT_OBJECT_0: + _writers = 0; + if (_writersWaiting == 0) SetEvent(_readEvent); + if (--_readers == 0) SetEvent(_writeEvent); + ReleaseMutex(_mutex); + break; + default: + TARS_THROW_EXCEPTION_SYSCODE(TC_SemMutex_Exception, "[TC_SemMutex::unlockImp] WaitForSingleObject error"); + } +} +DWORD TC_SemMutex::tryReadLockOnce() const +{ + HANDLE h[2]; + h[0] = _mutex; + h[1] = _readEvent; + DWORD result = WaitForMultipleObjects(2, h, TRUE, 1); + switch (result) + { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + ++_readers; + ResetEvent(_writeEvent); + ReleaseMutex(_mutex); + assert(_writers == 0); + return result; + case WAIT_TIMEOUT: + default: + ; + } + return result; +} #endif +} diff --git a/util/src/tc_socket.cpp b/util/src/tc_socket.cpp index 02f72a6..7578995 100755 --- a/util/src/tc_socket.cpp +++ b/util/src/tc_socket.cpp @@ -83,14 +83,14 @@ void TC_Socket::createSocket(int iSocketType, int iDomain) TARS_THROW_EXCEPTION_SYSCODE(TC_Socket_Exception, "[TC_Socket::createSocket] create socket error"); // throw TC_Socket_Exception("[TC_Socket::createSocket] create socket error! :" + string(strerror(errno))); } - else - { + else + { ignoreSigPipe(); } } -void TC_Socket::getPeerName(string &sPeerAddress, uint16_t &iPeerPort) +void TC_Socket::getPeerName(string &sPeerAddress, uint16_t &iPeerPort) const { assert(_iDomain == AF_INET || _iDomain == AF_INET6); @@ -115,9 +115,8 @@ void TC_Socket::getPeerName(string &sPathName) const struct sockaddr_un stSock; bzero(&stSock, sizeof(struct sockaddr_un)); - socklen_t iSockLen = sizeof(stSock); + SOCKET_LEN_TYPE iSockLen = sizeof(stSock); getPeerName((struct sockaddr *)&stSock, iSockLen); - sPathName = stSock.sun_path; } @@ -127,7 +126,7 @@ void TC_Socket::getSockName(string &sPathName) const struct sockaddr_un stSock; bzero(&stSock, sizeof(struct sockaddr_un)); - socklen_t iSockLen = sizeof(stSock); + SOCKET_LEN_TYPE iSockLen = sizeof(stSock); getSockName((struct sockaddr *)&stSock, iSockLen); sPathName = stSock.sun_path; @@ -140,7 +139,7 @@ void TC_Socket::bind(const char *sPathName) unlink(sPathName); struct sockaddr_un stBindAddr; - bzero(&stBindAddr, sizeof(struct sockaddr_un)); + memset(&stBindAddr, 0x00, sizeof(stBindAddr)); stBindAddr.sun_family = _iDomain; strncpy(stBindAddr.sun_path, sPathName, sizeof(stBindAddr.sun_path)); @@ -161,7 +160,7 @@ int TC_Socket::connectNoThrow(const char *sPathName) assert(_iDomain == AF_LOCAL); struct sockaddr_un stServerAddr; - bzero(&stServerAddr, sizeof(struct sockaddr_un)); + memset(&stServerAddr, 0x00, sizeof(stServerAddr)); stServerAddr.sun_family = _iDomain; strncpy(stServerAddr.sun_path, sPathName, sizeof(stServerAddr.sun_path)); @@ -170,7 +169,7 @@ int TC_Socket::connectNoThrow(const char *sPathName) #endif -void TC_Socket::getPeerName(struct sockaddr *pstPeerAddr, socklen_t &iPeerLen) const +void TC_Socket::getPeerName(struct sockaddr *pstPeerAddr, SOCKET_LEN_TYPE &iPeerLen) const { if(getpeername(_sock, pstPeerAddr, &iPeerLen) < 0) { @@ -195,7 +194,8 @@ void TC_Socket::getSockName(string &sSockAddress, uint16_t &iSockPort) const iSockPort = (AF_INET6 == _iDomain) ? ntohs(in6.sin6_port) : ntohs(in4.sin_port); } -void TC_Socket::getSockName(struct sockaddr *pstSockAddr, socklen_t &iSockLen) const + +void TC_Socket::getSockName(struct sockaddr *pstSockAddr, SOCKET_LEN_TYPE &iSockLen) const { if(getsockname(_sock, pstSockAddr, &iSockLen) < 0) { @@ -203,11 +203,11 @@ void TC_Socket::getSockName(struct sockaddr *pstSockAddr, socklen_t &iSockLen) c } } -int TC_Socket::accept(TC_Socket &tcSock, struct sockaddr *pstSockAddr, socklen_t &iSockLen) +SOCKET_TYPE TC_Socket::accept(TC_Socket &tcSock, struct sockaddr *pstSockAddr, SOCKET_LEN_TYPE &iSockLen) { assert(tcSock._sock == INVALID_SOCKET); - int ifd; + SOCKET_TYPE ifd; while ((ifd = ::accept(_sock, pstSockAddr, &iSockLen)) < 0 && errno == EINTR); @@ -371,12 +371,12 @@ void TC_Socket::bind(const string &sServerAddr, int port) bind(bindAddr, len); } -void TC_Socket::bind(struct sockaddr *pstBindAddr, socklen_t iAddrLen) + +void TC_Socket::bind(const struct sockaddr *pstBindAddr, SOCKET_LEN_TYPE iAddrLen) { //如果服务器终止后,服务器可以第二次快速启动而不用等待一段时间 int iReuseAddr = 1; - //设置 setSockOpt(SO_REUSEADDR, (const void *)&iReuseAddr, sizeof(int), SOL_SOCKET); if(::bind(_sock, pstBindAddr, iAddrLen) < 0) @@ -444,8 +444,7 @@ void TC_Socket::connect(const string &sServerAddr, uint16_t port) } } - -int TC_Socket::connect(const struct sockaddr *pstServerAddr, socklen_t serverLen) +int TC_Socket::connect(const struct sockaddr *pstServerAddr, SOCKET_LEN_TYPE serverLen) { return ::connect(_sock, pstServerAddr, serverLen); @@ -461,12 +460,12 @@ void TC_Socket::listen(int iConnBackLog) int TC_Socket::recv(void *pvBuf, size_t iLen, int iFlag) { - return ::recv(_sock, (char*)pvBuf, iLen, iFlag); + return ::recv(_sock, (char*)pvBuf, (int)iLen, iFlag); } int TC_Socket::send(const void *pvBuf, size_t iLen, int iFlag) { - return ::send(_sock, (const char*)pvBuf, iLen, iFlag); + return ::send(_sock, (char*)pvBuf, (int)iLen, iFlag); } int TC_Socket::recvfrom(void *pvBuf, size_t iLen, string &sFromAddr, uint16_t &iFromPort, int iFlags) @@ -489,9 +488,9 @@ int TC_Socket::recvfrom(void *pvBuf, size_t iLen, string &sFromAddr, uint16_t &i return iBytes; } -int TC_Socket::recvfrom(void *pvBuf, size_t iLen, struct sockaddr *pstFromAddr, socklen_t &iFromLen, int iFlags) +int TC_Socket::recvfrom(void *pvBuf, size_t iLen, struct sockaddr *pstFromAddr, SOCKET_LEN_TYPE &iFromLen, int iFlags) { - return ::recvfrom(_sock, (char*)pvBuf, iLen, iFlags, pstFromAddr, &iFromLen); + return ::recvfrom(_sock, (char*)pvBuf, (int)iLen, iFlags, pstFromAddr, &iFromLen); } int TC_Socket::sendto(const void *pvBuf, size_t iLen, const string &sToAddr, uint16_t port, int iFlags) @@ -535,9 +534,9 @@ int TC_Socket::sendto(const void *pvBuf, size_t iLen, const string &sToAddr, uin return sendto(pvBuf, iLen, toAddr, len, iFlags); } -int TC_Socket::sendto(const void *pvBuf, size_t iLen, struct sockaddr *pstToAddr, socklen_t iToLen, int iFlags) +int TC_Socket::sendto(const void *pvBuf, size_t iLen, struct sockaddr *pstToAddr, SOCKET_LEN_TYPE iToLen, int iFlags) { - return ::sendto(_sock, (const char *)pvBuf, iLen, iFlags, pstToAddr, iToLen); + return ::sendto(_sock, (char*)pvBuf, (int)iLen, iFlags, pstToAddr, iToLen); } void TC_Socket::shutdown(int iHow) @@ -555,12 +554,12 @@ void TC_Socket::setblock(bool bBlock) setblock(_sock, bBlock); } -int TC_Socket::setSockOpt(int opt, const void *pvOptVal, socklen_t optLen, int level) +int TC_Socket::setSockOpt(int opt, const void *pvOptVal, SOCKET_LEN_TYPE optLen, int level) { return setsockopt(_sock, level, opt, (const char*)pvOptVal, optLen); } -int TC_Socket::getSockOpt(int opt, void *pvOptVal, socklen_t &optLen, int level) +int TC_Socket::getSockOpt(int opt, void *pvOptVal, SOCKET_LEN_TYPE &optLen, int level) const { return getsockopt(_sock, level, opt, (char*)pvOptVal, &optLen); } @@ -585,7 +584,9 @@ void TC_Socket::setCloseWait(int delay) if(setSockOpt(SO_LINGER, (const void *)&stLinger, sizeof(linger), SOL_SOCKET) == -1) { - throw TC_Socket_Exception("[TC_Socket::setCloseWait] error", errno); + TARS_THROW_EXCEPTION_SYSCODE(TC_Socket_Exception, "[TC_Socket::setCloseWait] error"); + + // throw TC_Socket_Exception("[TC_Socket::setCloseWait] error", TC_Exception::getSystemCode()); } } @@ -628,11 +629,11 @@ void TC_Socket::setSendBufferSize(int sz) } } -int TC_Socket::getSendBufferSize() +int TC_Socket::getSendBufferSize() const { int sz; - socklen_t len = sizeof(sz); - if(getSockOpt(SO_SNDBUF, (void*)&sz, len, SOL_SOCKET) == -1 || len != sizeof(sz)) + SOCKET_LEN_TYPE len = sizeof(sz); + if (getSockOpt(SO_SNDBUF, (void*)&sz, len, SOL_SOCKET) == -1 || len != sizeof(sz)) { TARS_THROW_EXCEPTION_SYSCODE(TC_Socket_Exception, "[TC_Socket::getSendBufferSize] error"); } @@ -648,11 +649,11 @@ void TC_Socket::setRecvBufferSize(int sz) } } -int TC_Socket::getRecvBufferSize() +int TC_Socket::getRecvBufferSize() const { int sz; - socklen_t len = sizeof(sz); - if(getSockOpt(SO_RCVBUF, (void*)&sz, len, SOL_SOCKET) == -1 || len != sizeof(sz)) + SOCKET_LEN_TYPE len = sizeof(sz); + if (getSockOpt(SO_RCVBUF, (void*)&sz, len, SOL_SOCKET) == -1 || len != sizeof(sz)) { TARS_THROW_EXCEPTION_SYSCODE(TC_Socket_Exception, "[TC_Socket::getRecvBufferSize] error"); } @@ -672,7 +673,7 @@ void TC_Socket::ignoreSigPipe() { #endif } -void TC_Socket::setblock(int fd, bool bBlock) +void TC_Socket::setblock(SOCKET_TYPE fd, bool bBlock) { #if TARGET_PLATFORM_LINUX||TARGET_PLATFORM_IOS diff --git a/util/src/tc_thread.cpp b/util/src/tc_thread.cpp index c7bda6a..791e056 100644 --- a/util/src/tc_thread.cpp +++ b/util/src/tc_thread.cpp @@ -64,6 +64,7 @@ TC_Thread::TC_Thread() : _running(false), _th(NULL) TC_Thread::~TC_Thread() { + if(_th != NULL) { //如果资源没有被detach或者被join,则自己释放 diff --git a/util/src/tc_thread_cond.cpp b/util/src/tc_thread_cond.cpp index 399fed8..cf1250b 100644 --- a/util/src/tc_thread_cond.cpp +++ b/util/src/tc_thread_cond.cpp @@ -26,79 +26,6 @@ using namespace std; namespace tars { -// TC_ThreadCond::TC_ThreadCond() -// { -// int rc; - -// pthread_condattr_t attr; - -// rc = pthread_condattr_init(&attr); -// if(rc != 0) -// { -// throw TC_ThreadCond_Exception("[TC_ThreadCond::TC_ThreadCond] pthread_condattr_init error", errno); -// } - -// rc = pthread_cond_init(&_cond, &attr); -// if(rc != 0) -// { -// throw TC_ThreadCond_Exception("[TC_ThreadCond::TC_ThreadCond] pthread_cond_init error", errno); -// } - -// rc = pthread_condattr_destroy(&attr); -// if(rc != 0) -// { -// throw TC_ThreadCond_Exception("[TC_ThreadCond::TC_ThreadCond] pthread_condattr_destroy error", errno); -// } -// } - -// TC_ThreadCond::~TC_ThreadCond() -// { -// int rc = 0; -// rc = pthread_cond_destroy(&_cond); -// if(rc != 0) -// { -// cerr << "[TC_ThreadCond::~TC_ThreadCond] pthread_cond_destroy error:" << string(strerror(rc)) << endl; -// } -// // assert(rc == 0); -// } - -// void TC_ThreadCond::signal() -// { -// int rc = pthread_cond_signal(&_cond); -// if(rc != 0) -// { -// throw TC_ThreadCond_Exception("[TC_ThreadCond::signal] pthread_cond_signal error", errno); -// } -// } - -// void TC_ThreadCond::broadcast() -// { -// int rc = pthread_cond_broadcast(&_cond); -// if(rc != 0) -// { -// throw TC_ThreadCond_Exception("[TC_ThreadCond::broadcast] pthread_cond_broadcast error", errno); -// } -// } - -// timespec TC_ThreadCond::abstime( int millsecond) const -// { -// struct timeval tv; - -// //gettimeofday(&tv, 0); -// TC_TimeProvider::getInstance()->getNow(&tv); - -// int64_t it = tv.tv_sec * (int64_t)1000000 + tv.tv_usec + (int64_t)millsecond * 1000; - -// tv.tv_sec = it / (int64_t)1000000; -// tv.tv_usec = it % (int64_t)1000000; - -// timespec ts; -// ts.tv_sec = tv.tv_sec; -// ts.tv_nsec = tv.tv_usec * 1000; - -// return ts; -// } - TC_ThreadCond::TC_ThreadCond() { } diff --git a/util/src/tc_thread_mutex.cpp b/util/src/tc_thread_mutex.cpp index b346173..6fd50cf 100644 --- a/util/src/tc_thread_mutex.cpp +++ b/util/src/tc_thread_mutex.cpp @@ -15,6 +15,7 @@ */ #include "util/tc_thread_mutex.h" +#include "util/tc_common.h" #include #include #include @@ -68,202 +69,6 @@ bool TC_ThreadRecMutex::tryLock() const { return _mutex.try_lock(); } -// TC_ThreadMutex::TC_ThreadMutex() -// { -// int rc; -// pthread_mutexattr_t attr; -// rc = pthread_mutexattr_init(&attr); -// assert(rc == 0); - -// rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); -// assert(rc == 0); - -// rc = pthread_mutex_init(&_mutex, &attr); -// assert(rc == 0); - -// rc = pthread_mutexattr_destroy(&attr); -// assert(rc == 0); - -// if(rc != 0) -// { -// throw TC_ThreadMutex_Exception("[TC_ThreadMutex::TC_ThreadMutex] pthread_mutexattr_init error", rc); -// } -// } - -// TC_ThreadMutex::~TC_ThreadMutex() -// { -// int rc = 0; -// rc = pthread_mutex_destroy(&_mutex); -// if(rc != 0) -// { -// cerr << "[TC_ThreadMutex::~TC_ThreadMutex] pthread_mutex_destroy error:" << string(strerror(rc)) << endl; -// } -// // assert(rc == 0); -// } - -// void TC_ThreadMutex::lock() const -// { -// int rc = pthread_mutex_lock(&_mutex); -// if(rc != 0) -// { -// if(rc == EDEADLK) -// { -// throw TC_ThreadMutex_Exception("[TC_ThreadMutex::lock] pthread_mutex_lock dead lock error", rc); -// } -// else -// { -// throw TC_ThreadMutex_Exception("[TC_ThreadMutex::lock] pthread_mutex_lock error", rc); -// } -// } -// } - -// bool TC_ThreadMutex::tryLock() const -// { -// int rc = pthread_mutex_trylock(&_mutex); -// if(rc != 0 && rc != EBUSY) -// { -// if(rc == EDEADLK) -// { -// throw TC_ThreadMutex_Exception("[TC_ThreadMutex::tryLock] pthread_mutex_trylock dead lock error", rc); -// } -// else -// { -// throw TC_ThreadMutex_Exception("[TC_ThreadMutex::tryLock] pthread_mutex_trylock error", rc); -// } -// } -// return (rc == 0); -// } - -// void TC_ThreadMutex::unlock() const -// { -// int rc = pthread_mutex_unlock(&_mutex); -// if(rc != 0) -// { -// throw TC_ThreadMutex_Exception("[TC_ThreadMutex::unlock] pthread_mutex_unlock error", rc); -// } -// } - -// int TC_ThreadMutex::count() const -// { -// return 0; -// } - -// void TC_ThreadMutex::count(int c) const -// { -// } - -// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// TC_ThreadRecMutex::TC_ThreadRecMutex() -// : _count(0) -// { -// int rc; - -// pthread_mutexattr_t attr; -// rc = pthread_mutexattr_init(&attr); -// if(rc != 0) -// { -// throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutexattr_init error", rc); -// } -// rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); -// if(rc != 0) -// { -// throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutexattr_settype error", rc); -// } - -// rc = pthread_mutex_init(&_mutex, &attr); -// if(rc != 0) -// { -// throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutex_init error", rc); -// } - -// rc = pthread_mutexattr_destroy(&attr); -// if(rc != 0) -// { -// throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::TC_ThreadRecMutex] pthread_mutexattr_destroy error", rc); -// } -// } - -// TC_ThreadRecMutex::~TC_ThreadRecMutex() -// { -// while (_count) -// { -// unlock(); -// } - -// int rc = 0; -// rc = pthread_mutex_destroy(&_mutex); -// if(rc != 0) -// { -// cerr << "[TC_ThreadRecMutex::~TC_ThreadRecMutex] pthread_mutex_destroy error:" << string(strerror(rc)) << endl; -// } -// // assert(rc == 0); -// } - -// int TC_ThreadRecMutex::lock() const -// { -// int rc = pthread_mutex_lock(&_mutex); -// if(rc != 0) -// { -// throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::lock] pthread_mutex_lock error", rc); -// } - -// if(++_count > 1) -// { -// rc = pthread_mutex_unlock(&_mutex); -// assert(rc == 0); -// } - -// return rc; -// } - -// int TC_ThreadRecMutex::unlock() const -// { -// if(--_count == 0) -// { -// int rc = 0; -// rc = pthread_mutex_unlock(&_mutex); -// return rc; -// } -// return 0; -// } - -// bool TC_ThreadRecMutex::tryLock() const -// { -// int rc = pthread_mutex_trylock(&_mutex); -// if(rc != 0 ) -// { -// if(rc != EBUSY) -// { -// throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::tryLock] pthread_mutex_trylock error", rc); -// } -// } -// else if(++_count > 1) -// { -// rc = pthread_mutex_unlock(&_mutex); -// if(rc != 0) -// { -// throw TC_ThreadMutex_Exception("[TC_ThreadRecMutex::tryLock] pthread_mutex_unlock error", rc); -// } -// } -// return (rc == 0); -// } - -// bool TC_ThreadRecMutex::willUnlock() const -// { -// return _count == 1; -// } - -// int TC_ThreadRecMutex::count() const -// { -// int c = _count; -// _count = 0; -// return c; -// } - -// void TC_ThreadRecMutex::count(int c) const -// { -// _count = c; -// } } diff --git a/util/src/tc_thread_rwlock.cpp b/util/src/tc_thread_rwlock.cpp index 9fc1ba5..608c329 100644 --- a/util/src/tc_thread_rwlock.cpp +++ b/util/src/tc_thread_rwlock.cpp @@ -62,105 +62,6 @@ void TC_ThreadRWLocker::unWriteLock() const _mutex.unWriteLock(); } -// TC_ThreadRWLocker::TC_ThreadRWLocker() -// { -// int ret = ::pthread_rwlock_init(&m_sect, NULL); -// assert(ret == 0); - -// if(ret != 0) -// { -// throw TC_ThreadRW_Exception("[TC_ThreadRWLocker::TC_ThreadRWLocker] pthread_rwlock_init error", ret); -// } -// } - -// TC_ThreadRWLocker::~TC_ThreadRWLocker() -// { -// int ret = ::pthread_rwlock_destroy(&m_sect); -// if(ret != 0) -// { -// cerr<<"[TC_ThreadRWLocker::~TC_ThreadRWLocker] pthread_rwlock_destroy error:"<= 1000000) { tt.tv_usec -= 1000000; tt.tv_sec++;} } -// TC_ThreadLock TC_TimeProvider::g_tl; -// TC_TimeProviderPtr TC_TimeProvider::g_tp = NULL; - -// TC_TimeProvider* TC_TimeProvider::getInstance() -// { -// if(!g_tp) -// { -// TC_ThreadLock::Lock lock(g_tl); - -// if(!g_tp) -// { -// g_tp = new TC_TimeProvider(); - -// g_tp->start(); -// } -// } -// return g_tp.get(); -// } - -// TC_TimeProvider::~TC_TimeProvider() -// { -// { -// TC_ThreadLock::Lock lock(g_tl); -// _terminate = true; -// g_tl.notify(); -// } - -// getThreadControl().join(); -// } - -// void TC_TimeProvider::getNow(timeval *tv) -// { -// int idx = _buf_idx; -// *tv = _t[idx]; - -// if(_cpu_cycle != 0 && _use_tsc) //cpu-cycle在两个interval周期后采集完成 -// { -// addTimeOffset(*tv,idx); -// } -// else -// { -// ::gettimeofday(tv, NULL); -// } -// } - -// int64_t TC_TimeProvider::getNowMs() -// { -// struct timeval tv; -// getNow(&tv); -// return tv.tv_sec * (int64_t)1000 + tv.tv_usec/1000; -// } - -// void TC_TimeProvider::run() -// { -// while(!_terminate) -// { -// timeval& tt = _t[!_buf_idx]; - -// ::gettimeofday(&tt, NULL); - -// setTsc(tt); - -// _buf_idx = !_buf_idx; - -// TC_ThreadLock::Lock lock(g_tl); - -// g_tl.timedWait(800); //修改800时 需对应修改addTimeOffset中offset判读值 - -// } -// } - -// float TC_TimeProvider::cpuMHz() -// { -// if(_cpu_cycle != 0) -// return 1.0/_cpu_cycle; - -// return 0; -// } - -// void TC_TimeProvider::setTsc(timeval& tt) -// { -// uint32_t low = 0; -// uint32_t high = 0; -// rdtsc(low,high); -// uint64_t current_tsc = ((uint64_t)high << 32) | low; - -// uint64_t& last_tsc = _tsc[!_buf_idx]; -// timeval& last_tt = _t[_buf_idx]; - -// if(_tsc[_buf_idx] == 0 || _tsc[!_buf_idx] == 0 ) -// { -// _cpu_cycle = 0; -// last_tsc = current_tsc; -// } -// else -// { -// time_t sptime = (tt.tv_sec - last_tt.tv_sec)*1000*1000 + (tt.tv_usec - last_tt.tv_usec); -// _cpu_cycle = (float)sptime/(current_tsc - _tsc[_buf_idx]); //us -// last_tsc = current_tsc; -// } -// } - -// void TC_TimeProvider::addTimeOffset(timeval& tt,const int &idx) -// { -// uint32_t low = 0; -// uint32_t high = 0; -// rdtsc(low,high); -// uint64_t current_tsc = ((uint64_t)high << 32) | low; -// int64_t t = (int64_t)(current_tsc - _tsc[idx]); -// time_t offset = (time_t)(t*_cpu_cycle); -// if(t < -1000 || offset > 1000000)//毫秒级别 -// { -// //cerr<< "TC_TimeProvider add_time_offset error,correct it by use gettimeofday. current_tsc|"<= 1000000) { tt.tv_usec -= 1000000; tt.tv_sec++;} -// } - - } diff --git a/util/src/tc_timer.cpp b/util/src/tc_timer.cpp new file mode 100644 index 0000000..c7b4c4d --- /dev/null +++ b/util/src/tc_timer.cpp @@ -0,0 +1,150 @@ + +#include "util/tc_timer.h" + + +namespace tars +{ + +TC_Timer::~TC_Timer() +{ + stopTimer(); +} + +void TC_Timer::startTimer(int numThread) +{ + if (numThread <= 0) + numThread = 1; + + _tpool.init(numThread + 1); + _tpool.start(); + _tpool.exec(std::bind(&TC_Timer::run, this)); +} + +void TC_Timer::stopTimer() +{ + { + std::unique_lock lck(_mutex); + _terminate = true; + _cond.notify_all(); + } + + _tpool.stop(); +} + +void TC_Timer::erase(int64_t uniqId) +{ + std::lock_guard lock(_mutex); + + auto it = _mapEvent.find(uniqId); + + if (it != _mapEvent.end()) { + auto itEvent = _mapTimer.find(it->second->_fireMillseconds); + + if (itEvent != _mapTimer.end()) { + itEvent->second.erase(uniqId); + + if (itEvent->second.empty()) { + _mapTimer.erase(itEvent); + } + } + _mapEvent.erase(it); + } +} + +int64_t TC_Timer::post(const shared_ptr & event) +{ + std::unique_lock lock(_mutex); + + int64_t uniqId = (int64_t)event.get(); + + if(_mapEvent.find(uniqId) == _mapEvent.end()) { + _mapEvent[uniqId] = event; + } + //cout << "post event! fire time:" << TC_Common::tm2str(event->_fireMillseconds/1000, "%Y-%m-%d %H:%M:%S")<_fireMillseconds].insert(uniqId); + _cond.notify_one(); + return uniqId; +} + +void TC_Timer::fireEvent(const EVENT_SET & el) +{ + auto itList = el.begin(); + + while (itList != el.end()) { + shared_ptr func ; + + { + std::lock_guard lock(_mutex); + + auto it = _mapEvent.find(*itList); + + if (it != _mapEvent.end()) { + + func = it->second; + + _mapEvent.erase(it); + } + } + + if(func) { + //执行具体事件对象 + _tpool.exec(func->_func); + } + + ++itList; + } +} + +void TC_Timer::run() +{ + while (!_terminate) + { + try + { + EVENT_SET el; + + { + std::unique_lock lock(_mutex); + + auto it = _mapTimer.begin(); + + if (it != _mapTimer.end()) + { + uint64_t ms = TC_TimeProvider::getInstance()->getNowMs(); + + //cout << "now ms:" << TC_Common::tm2str(ms / 1000, "%Y-%m-%d %H:%M:%S") << "| it first:" << TC_Common::tm2str(it->first / 1000, "%Y-%m-%d %H:%M:%S") << endl; + if (it->first <= ms) + { + //时间过了, 有事件需要触发了 + el.swap(it->second); + _mapTimer.erase(it); + } + else + { + //时间还没到 + ms = it->first - ms; + _cond.wait_for(lock, std::chrono::milliseconds(ms)); + } + } + else + { + //没有任何事件, 等待一下 + _cond.wait_for(lock, std::chrono::milliseconds(1000)); + } + } + + if (!el.empty()) + { + //触发相关所有事件 + fireEvent(el); + } + + } + catch (exception & ex) { + cerr << ex.what() << endl; + } + } +} +} + +