关键词搜索

源码搜索 ×
×

tars源码分析之8

发布2022-07-03浏览469次

详情内容

在做软件开发时,配置可少不了,我不建议你再写了,直接看如下的代码吧:

  1. #include <errno.h>
  2. #include <fstream>
  3. #include "util/tc_config.h"
  4. #include "util/tc_common.h"
  5. namespace tars
  6. {
  7. TC_ConfigDomain::TC_ConfigDomain(const string &sLine)
  8. {
  9. _name = TC_Common::trim(sLine);
  10. }
  11. TC_ConfigDomain::~TC_ConfigDomain()
  12. {
  13. destroy();
  14. }
  15. TC_ConfigDomain::TC_ConfigDomain(const TC_ConfigDomain &tcd)
  16. {
  17. (*this) = tcd;
  18. }
  19. TC_ConfigDomain& TC_ConfigDomain::operator=(const TC_ConfigDomain &tcd)
  20. {
  21. if(this != &tcd)
  22. {
  23. destroy();
  24. _name = tcd._name;
  25. _param = tcd._param;
  26. _key = tcd._key;
  27. _domain= tcd._domain;
  28. _line = tcd._line;
  29. const map<string, TC_ConfigDomain*> & m = tcd.getDomainMap();
  30. map<string, TC_ConfigDomain*>::const_iterator it = m.begin();
  31. while(it != m.end())
  32. {
  33. _subdomain[it->first] = it->second->clone();
  34. ++it;
  35. }
  36. }
  37. return *this;
  38. }
  39. TC_ConfigDomain::DomainPath TC_ConfigDomain::parseDomainName(const string& path, bool bWithParam)
  40. {
  41. TC_ConfigDomain::DomainPath dp;
  42. if(bWithParam)
  43. {
  44. string::size_type pos1 = path.find_first_of(TC_CONFIG_PARAM_BEGIN);
  45. if(pos1 == string::npos)
  46. {
  47. throw TC_Config_Exception("[TC_Config::parseDomainName] : param path '" + path + "' is invalid!" );
  48. }
  49. if(path[0] != TC_CONFIG_DOMAIN_SEP)
  50. {
  51. throw TC_Config_Exception("[TC_Config::parseDomainName] : param path '" + path + "' must start with '/'!" );
  52. }
  53. string::size_type pos2 = path.find_first_of(TC_CONFIG_PARAM_END);
  54. if(pos2 == string::npos)
  55. {
  56. throw TC_Config_Exception("[TC_Config::parseDomainName] : param path '" + path + "' is invalid!" );
  57. }
  58. dp._domains = TC_Common::sepstr<string>(path.substr(1, pos1-1), TC_Common::tostr(TC_CONFIG_DOMAIN_SEP));
  59. dp._param = path.substr(pos1+1, pos2 - pos1 - 1);
  60. }
  61. else
  62. {
  63. // if(path.length() <= 1 || path[0] != TC_CONFIG_DOMAIN_SEP)
  64. if(path[0] != TC_CONFIG_DOMAIN_SEP)
  65. {
  66. throw TC_Config_Exception("[TC_Config::parseDomainName] : param path '" + path + "' must start with '/'!" );
  67. }
  68. dp._domains = TC_Common::sepstr<string>(path.substr(1), TC_Common::tostr(TC_CONFIG_DOMAIN_SEP));
  69. }
  70. return dp;
  71. }
  72. TC_ConfigDomain* TC_ConfigDomain::addSubDomain(const string& name)
  73. {
  74. if(_subdomain.find(name) == _subdomain.end())
  75. {
  76. _domain.push_back(name);
  77. _subdomain[name] = new TC_ConfigDomain(name);
  78. }
  79. return _subdomain[name];
  80. }
  81. string TC_ConfigDomain::getParamValue(const string &name) const
  82. {
  83. map<string, string>::const_iterator it = _param.find(name);
  84. if( it == _param.end())
  85. {
  86. throw TC_ConfigNoParam_Exception("[TC_ConfigDomain::getParamValue] param '" + name + "' not exits!");
  87. }
  88. return it->second;
  89. }
  90. TC_ConfigDomain *TC_ConfigDomain::getSubTcConfigDomain(vector<string>::const_iterator itBegin, vector<string>::const_iterator itEnd)
  91. {
  92. if(itBegin == itEnd)
  93. {
  94. return this;
  95. }
  96. map<string, TC_ConfigDomain*>::const_iterator it = _subdomain.find(*itBegin);
  97. //根据匹配规则找不到匹配的子域
  98. if(it == _subdomain.end())
  99. {
  100. return NULL;
  101. }
  102. //继续在子域下搜索
  103. return it->second->getSubTcConfigDomain(itBegin + 1, itEnd);
  104. }
  105. const TC_ConfigDomain *TC_ConfigDomain::getSubTcConfigDomain(vector<string>::const_iterator itBegin, vector<string>::const_iterator itEnd) const
  106. {
  107. if(itBegin == itEnd)
  108. {
  109. return this;
  110. }
  111. map<string, TC_ConfigDomain*>::const_iterator it = _subdomain.find(*itBegin);
  112. //根据匹配规则找不到匹配的子域
  113. if(it == _subdomain.end())
  114. {
  115. return NULL;
  116. }
  117. //继续在子域下搜索
  118. return it->second->getSubTcConfigDomain(itBegin + 1, itEnd);
  119. }
  120. void TC_ConfigDomain::insertParamValue(const map<string, string> &m)
  121. {
  122. _param.insert(m.begin(), m.end());
  123. map<string, string>::const_iterator it = m.begin();
  124. while(it != m.end())
  125. {
  126. size_t i = 0;
  127. for(; i < _key.size(); i++)
  128. {
  129. if(_key[i] == it->first)
  130. {
  131. break;
  132. }
  133. }
  134. //没有该key, 则添加到最后
  135. if(i == _key.size())
  136. {
  137. _key.push_back(it->first);
  138. }
  139. ++it;
  140. }
  141. }
  142. void TC_ConfigDomain::setParamValue(const string &name, const string &value)
  143. {
  144. _param[name] = value;
  145. //如果key已经存在,则删除
  146. for(vector<string>::iterator it = _key.begin(); it != _key.end(); ++it)
  147. {
  148. if(*it == name)
  149. {
  150. _key.erase(it);
  151. break;
  152. }
  153. }
  154. _key.push_back(name);
  155. }
  156. void TC_ConfigDomain::setParamValue(const string &line)
  157. {
  158. if(line.empty())
  159. {
  160. return;
  161. }
  162. _line.push_back(line);
  163. string::size_type pos = 0;
  164. for(; pos <= line.length() - 1; pos++)
  165. {
  166. if (line[pos] == '=')
  167. {
  168. if(pos > 0 && line[pos-1] == '\\')
  169. {
  170. continue;
  171. }
  172. string name = parse(TC_Common::trim(line.substr(0, pos), " \r\n\t"));
  173. string value;
  174. if(pos < line.length() - 1)
  175. {
  176. value = parse(TC_Common::trim(line.substr(pos + 1), " \r\n\t"));
  177. }
  178. setParamValue(name, value);
  179. return;
  180. }
  181. }
  182. setParamValue(line, "");
  183. }
  184. string TC_ConfigDomain::parse(const string& s)
  185. {
  186. if(s.empty())
  187. {
  188. return "";
  189. }
  190. string param;
  191. string::size_type pos = 0;
  192. for(; pos <= s.length() - 1; pos++)
  193. {
  194. char c;
  195. if(s[pos] == '\\' && pos < s.length() - 1)
  196. {
  197. switch (s[pos+1])
  198. {
  199. case '\\':
  200. c = '\\';
  201. pos++;
  202. break;
  203. case 'r':
  204. c = '\r';
  205. pos++;
  206. break;
  207. case 'n':
  208. c = '\n';
  209. pos++;
  210. break;
  211. case 't':
  212. c = '\t';
  213. pos++;
  214. break;
  215. case '=':
  216. c = '=';
  217. pos++;
  218. break;
  219. default:
  220. throw TC_Config_Exception("[TC_ConfigDomain::parse] '" + s + "' is invalid, '" + TC_Common::tostr(s[pos]) + TC_Common::tostr(s[pos+1]) + "' couldn't be parse!" );
  221. }
  222. param += c;
  223. }
  224. else if (s[pos] == '\\')
  225. {
  226. throw TC_Config_Exception("[TC_ConfigDomain::parse] '" + s + "' is invalid, '" + TC_Common::tostr(s[pos]) + "' couldn't be parse!" );
  227. }
  228. else
  229. {
  230. param += s[pos];
  231. }
  232. }
  233. return param;
  234. }
  235. string TC_ConfigDomain::reverse_parse(const string &s)
  236. {
  237. if(s.empty())
  238. {
  239. return "";
  240. }
  241. string param;
  242. string::size_type pos = 0;
  243. for(; pos <= s.length() - 1; pos++)
  244. {
  245. string c;
  246. switch (s[pos])
  247. {
  248. case '\\':
  249. param += "\\\\";
  250. break;
  251. case '\r':
  252. param += "\\r";
  253. break;
  254. case '\n':
  255. param += "\\n";
  256. break;
  257. case '\t':
  258. param += "\\t";
  259. break;
  260. break;
  261. case '=':
  262. param += "\\=";
  263. break;
  264. case '<':
  265. case '>':
  266. throw TC_Config_Exception("[TC_ConfigDomain::reverse_parse] '" + s + "' is invalid, couldn't be parse!" );
  267. default:
  268. param += s[pos];
  269. }
  270. }
  271. return param;
  272. }
  273. string TC_ConfigDomain::getName() const
  274. {
  275. return _name;
  276. }
  277. void TC_ConfigDomain::setName(const string& name)
  278. {
  279. _name = name;
  280. }
  281. vector<string> TC_ConfigDomain::getKey() const
  282. {
  283. return _key;
  284. }
  285. vector<string> TC_ConfigDomain::getLine() const
  286. {
  287. return _line;
  288. }
  289. vector<string> TC_ConfigDomain::getSubDomain() const
  290. {
  291. return _domain;
  292. }
  293. void TC_ConfigDomain::destroy()
  294. {
  295. _param.clear();
  296. _key.clear();
  297. _line.clear();
  298. _domain.clear();
  299. map<string, TC_ConfigDomain*>::iterator it = _subdomain.begin();
  300. while(it != _subdomain.end())
  301. {
  302. delete it->second;
  303. ++it;
  304. }
  305. _subdomain.clear();
  306. }
  307. string TC_ConfigDomain::tostr(int i) const
  308. {
  309. string sTab;
  310. for(int k = 0; k < i; ++k)
  311. {
  312. sTab += "\t";
  313. }
  314. ostringstream buf;
  315. buf << sTab << "<" << reverse_parse(_name) << ">" << endl;;
  316. for(size_t n = 0; n < _key.size(); n++)
  317. {
  318. map<string, string>::const_iterator it = _param.find(_key[n]);
  319. assert(it != _param.end());
  320. //值为空, 则不打印出=
  321. if(it->second.empty())
  322. {
  323. buf << "\t" << sTab << reverse_parse(_key[n]) << endl;
  324. }
  325. else
  326. {
  327. buf << "\t" << sTab << reverse_parse(_key[n]) << "=" << reverse_parse(it->second) << endl;
  328. }
  329. }
  330. ++i;
  331. for(size_t n = 0; n < _domain.size(); n++)
  332. {
  333. map<string, TC_ConfigDomain*>::const_iterator itm = _subdomain.find(_domain[n]);
  334. assert(itm != _subdomain.end());
  335. buf << itm->second->tostr(i);
  336. }
  337. buf << sTab << "</" << reverse_parse(_name) << ">" << endl;
  338. return buf.str();
  339. }
  340. /********************************************************************/
  341. /* TC_Config implement */
  342. /********************************************************************/
  343. TC_Config::TC_Config() : _root("")
  344. {
  345. }
  346. TC_Config::TC_Config(const TC_Config &tc)
  347. : _root(tc._root)
  348. {
  349. }
  350. TC_Config& TC_Config::operator=(const TC_Config &tc)
  351. {
  352. if(this != &tc)
  353. {
  354. _root = tc._root;
  355. }
  356. return *this;
  357. }
  358. void TC_Config::parse(istream &is)
  359. {
  360. _root.destroy();
  361. stack<TC_ConfigDomain*> stkTcCnfDomain;
  362. stkTcCnfDomain.push(&_root);
  363. string line;
  364. while(getline(is, line))
  365. {
  366. line = TC_Common::trim(line, " \r\n\t");
  367. if(line.length() == 0)
  368. {
  369. continue;
  370. }
  371. if(line[0] == '#')
  372. {
  373. continue;
  374. }
  375. else if(line[0] == '<')
  376. {
  377. string::size_type posl = line.find_first_of('>');
  378. if(posl == string::npos)
  379. {
  380. throw TC_Config_Exception("[TC_Config::parse]:parse error! line : " + line);
  381. }
  382. if(line[1] == '/')
  383. {
  384. string sName(line.substr(2, (posl - 2)));
  385. if(stkTcCnfDomain.size() <= 0)
  386. {
  387. throw TC_Config_Exception("[TC_Config::parse]:parse error! <" + sName + "> hasn't matched domain.");
  388. }
  389. if(stkTcCnfDomain.top()->getName() != sName)
  390. {
  391. throw TC_Config_Exception("[TC_Config::parse]:parse error! <" + stkTcCnfDomain.top()->getName() + "> hasn't match <" + sName +">.");
  392. }
  393. //弹出
  394. stkTcCnfDomain.pop();
  395. }
  396. else
  397. {
  398. string name(line.substr(1, posl - 1));
  399. stkTcCnfDomain.push(stkTcCnfDomain.top()->addSubDomain(name));
  400. }
  401. }
  402. else
  403. {
  404. stkTcCnfDomain.top()->setParamValue(line);
  405. }
  406. }
  407. if(stkTcCnfDomain.size() != 1)
  408. {
  409. throw TC_Config_Exception("[TC_Config::parse]:parse error : hasn't match");
  410. }
  411. }
  412. void TC_Config::parseFile(const string &sFileName)
  413. {
  414. if(sFileName.length() == 0)
  415. {
  416. throw TC_Config_Exception("[TC_Config::parseFile]:file name is empty");
  417. }
  418. ifstream ff;
  419. ff.open(sFileName.c_str());
  420. if (!ff)
  421. {
  422. throw TC_Config_Exception("[TC_Config::parseFile]:fopen fail: " + sFileName, errno);
  423. }
  424. parse(ff);
  425. }
  426. void TC_Config::parseString(const string& buffer)
  427. {
  428. istringstream iss;
  429. iss.str(buffer);
  430. parse(iss);
  431. }
  432. string TC_Config::operator[](const string &path)
  433. {
  434. TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(path, true);
  435. TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains);
  436. if(pTcConfigDomain == NULL)
  437. {
  438. throw TC_ConfigNoParam_Exception("[TC_Config::operator[]] path '" + path + "' not exits!");
  439. }
  440. return pTcConfigDomain->getParamValue(dp._param);
  441. }
  442. string TC_Config::get(const string &sName, const string &sDefault) const
  443. {
  444. try
  445. {
  446. TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(sName, true);
  447. const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains);
  448. if(pTcConfigDomain == NULL)
  449. {
  450. throw TC_ConfigNoParam_Exception("[TC_Config::get] path '" + sName + "' not exits!");
  451. }
  452. return pTcConfigDomain->getParamValue(dp._param);
  453. }
  454. catch ( TC_ConfigNoParam_Exception &ex )
  455. {
  456. return sDefault;
  457. }
  458. }
  459. bool TC_Config::getDomainMap(const string &path, map<string, string> &m) const
  460. {
  461. TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(path, false);
  462. const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains);
  463. if(pTcConfigDomain == NULL)
  464. {
  465. return false;
  466. }
  467. m = pTcConfigDomain->getParamMap();
  468. return true;
  469. }
  470. map<string, string> TC_Config::getDomainMap(const string &path) const
  471. {
  472. map<string, string> m;
  473. TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(path, false);
  474. const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains);
  475. if(pTcConfigDomain != NULL)
  476. {
  477. m = pTcConfigDomain->getParamMap();
  478. }
  479. return m;
  480. }
  481. vector<string> TC_Config::getDomainKey(const string &path) const
  482. {
  483. vector<string> v;
  484. TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(path, false);
  485. const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains);
  486. if(pTcConfigDomain != NULL)
  487. {
  488. v = pTcConfigDomain->getKey();
  489. }
  490. return v;
  491. }
  492. vector<string> TC_Config::getDomainLine(const string &path) const
  493. {
  494. vector<string> v;
  495. TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(path, false);
  496. const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains);
  497. if(pTcConfigDomain != NULL)
  498. {
  499. v = pTcConfigDomain->getLine();
  500. }
  501. return v;
  502. }
  503. bool TC_Config::getDomainVector(const string &path, vector<string> &vtDomains) const
  504. {
  505. TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(path, false);
  506. //根域, 特殊处理
  507. if(dp._domains.empty())
  508. {
  509. vtDomains = _root.getSubDomain();
  510. return !vtDomains.empty();
  511. }
  512. const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains);
  513. if(pTcConfigDomain == NULL)
  514. {
  515. return false;
  516. }
  517. vtDomains = pTcConfigDomain->getSubDomain();
  518. return true;
  519. }
  520. vector<string> TC_Config::getDomainVector(const string &path) const
  521. {
  522. TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(path, false);
  523. //根域, 特殊处理
  524. if(dp._domains.empty())
  525. {
  526. return _root.getSubDomain();
  527. }
  528. const TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains);
  529. if(pTcConfigDomain == NULL)
  530. {
  531. return vector<string>();
  532. }
  533. return pTcConfigDomain->getSubDomain();
  534. }
  535. TC_ConfigDomain *TC_Config::newTcConfigDomain(const string &sName)
  536. {
  537. return new TC_ConfigDomain(sName);
  538. }
  539. TC_ConfigDomain *TC_Config::searchTcConfigDomain(const vector<string>& domains)
  540. {
  541. return _root.getSubTcConfigDomain(domains.begin(), domains.end());
  542. }
  543. const TC_ConfigDomain *TC_Config::searchTcConfigDomain(const vector<string>& domains) const
  544. {
  545. return _root.getSubTcConfigDomain(domains.begin(), domains.end());
  546. }
  547. int TC_Config::insertDomain(const string &sCurDomain, const string &sAddDomain, bool bCreate)
  548. {
  549. TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(sCurDomain, false);
  550. TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains);
  551. if(pTcConfigDomain == NULL)
  552. {
  553. if(bCreate)
  554. {
  555. pTcConfigDomain = &_root;
  556. for(size_t i = 0; i < dp._domains.size(); i++)
  557. {
  558. pTcConfigDomain = pTcConfigDomain->addSubDomain(dp._domains[i]);
  559. }
  560. }
  561. else
  562. {
  563. return -1;
  564. }
  565. }
  566. pTcConfigDomain->addSubDomain(sAddDomain);
  567. return 0;
  568. }
  569. int TC_Config::insertDomainParam(const string &sCurDomain, const map<string, string> &m, bool bCreate)
  570. {
  571. TC_ConfigDomain::DomainPath dp = TC_ConfigDomain::parseDomainName(sCurDomain, false);
  572. TC_ConfigDomain *pTcConfigDomain = searchTcConfigDomain(dp._domains);
  573. if(pTcConfigDomain == NULL)
  574. {
  575. if(bCreate)
  576. {
  577. pTcConfigDomain = &_root;
  578. for(size_t i = 0; i < dp._domains.size(); i++)
  579. {
  580. pTcConfigDomain = pTcConfigDomain->addSubDomain(dp._domains[i]);
  581. }
  582. }
  583. else
  584. {
  585. return -1;
  586. }
  587. }
  588. pTcConfigDomain->insertParamValue(m);
  589. return 0;
  590. }
  591. string TC_Config::tostr() const
  592. {
  593. string buffer;
  594. map<string, TC_ConfigDomain*> msd = _root.getDomainMap();
  595. map<string, TC_ConfigDomain*>::const_iterator it = msd.begin();
  596. while (it != msd.end())
  597. {
  598. buffer += it->second->tostr(0);
  599. ++it;
  600. }
  601. return buffer;
  602. }
  603. void TC_Config::joinConfig(const TC_Config &cf, bool bUpdate)
  604. {
  605. string buffer;
  606. if(bUpdate)
  607. {
  608. buffer = tostr() + cf.tostr();
  609. }
  610. else
  611. {
  612. buffer = cf.tostr() + tostr();
  613. }
  614. parseString(buffer);
  615. }
  616. }

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载