config_file.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #include <string>
  2. #include <fstream>
  3. #include <iterator>
  4. #include <log.h>
  5. #include <config_file.h>
  6. static void trim(char*b,char*e)
  7. {
  8. char*e1=e;
  9. for(;e1>b;--e1)
  10. {
  11. if(!std::isspace(e1[-1]))
  12. break;
  13. }
  14. char*b1=b;
  15. for(;b1<e1;++b1)
  16. {
  17. if(!std::isspace(*b1))
  18. break;
  19. }
  20. memmove(b,b1,e1-b1);
  21. b[e1-b1]=0;
  22. }
  23. int config_file::open(const char*fname)
  24. {
  25. _buf.reserve(1<<10);
  26. std::ifstream f(fname,std::ios_base::binary);
  27. if(!f)
  28. {
  29. log_errno("can't open the inifile:%s",fname);
  30. return -1;
  31. }
  32. f.unsetf(std::ios::skipws);
  33. std::copy(std::istream_iterator<char>(f),std::istream_iterator<char>(), std::back_inserter(_buf));
  34. _buf.push_back('\n');
  35. _buf.push_back('0');
  36. char*s=&_buf[0];
  37. char*e=&_buf.back();
  38. for(;s<e;)
  39. {
  40. char*p=strchr(s,'\n');
  41. if(p==0)
  42. break;
  43. *p=0;
  44. if(p==s)
  45. {
  46. s=p+1;
  47. continue;
  48. }
  49. char*v=strchr(s,'=');
  50. if(v==0)
  51. {
  52. s=p+1;
  53. continue;
  54. }
  55. char*r=v;
  56. for(;r;)
  57. {
  58. r=strchr(r+1,'#');
  59. if(r && (*(r-1)==' ' ||*(r-1)=='\t'))
  60. {
  61. *r=0;
  62. break;
  63. }
  64. }
  65. if(r==0) r=p;
  66. char*k=s;
  67. *p=0;
  68. *v=0;
  69. trim(k,v);
  70. v++;
  71. trim(v,r);
  72. _map.insert(std::make_pair(k,v));
  73. s=p+1;
  74. }
  75. return 0;
  76. }
  77. int config_file::get(const char*key,int default_v)const
  78. {
  79. auto it=_map.find(key);
  80. return it==_map.end()
  81. ? (log_info("config param: %s=%d(default)",key,default_v),default_v)
  82. : (log_info("config param: %s=%s",key,it->second), atoi(it->second));
  83. }
  84. int config_file::get(const char*sec,const char*key,int default_v)const
  85. {
  86. char k[512];
  87. sprintf(k,"%s.%s",sec,key);
  88. return get(k,default_v);
  89. }
  90. double config_file::get(const char*key,double default_v)const
  91. {
  92. auto it=_map.find(key);
  93. return it==_map.end()
  94. ? (log_info("config param: %s=%lf(default)",key,default_v),default_v)
  95. : (log_info("config param: %s=%s",key,it->second), atof(it->second));
  96. }
  97. double config_file::get(const char*sec,const char*key,double default_v)const
  98. {
  99. char k[512];
  100. sprintf(k,"%s.%s",sec,key);
  101. return get(k,default_v);
  102. }
  103. const char* config_file::get(const char*sec,const char*key,const char*v)const
  104. {
  105. char k[512];
  106. sprintf(k,"%s.%s",sec,key);
  107. return get(k,v);
  108. #if 0
  109. auto it=_map.find(k);
  110. return it==_map.end()
  111. ? get(k,v)
  112. : (log_info("config param: %s=%s",k,it->second),it->second);
  113. #endif
  114. }
  115. const char* config_file::get(const char*key,const char*defv)const
  116. {
  117. auto it=_map.find(key);
  118. return it==_map.end()
  119. ? (log_info("config param: %s=%s(default)",key,defv),defv)
  120. : (log_info("config param: %s=%s",key,it->second), it->second);
  121. }
  122. std::set<const char*> config_file::keys()const
  123. {
  124. std::set<const char*> ret;
  125. for(auto it:_map)
  126. ret.insert(it.first);
  127. return std::move(ret);
  128. }
  129. bool config_file::contains(const char*k)const
  130. {
  131. return _map.find(k)!=_map.end();
  132. }
  133. bool config_file::contains(const char*sec,const char*k)const
  134. {
  135. char key[512];
  136. snprintf(key,255,"%s.%s",sec,k);
  137. return contains(key);
  138. }
  139. void config_file::print(std::ostream&o)
  140. {
  141. for(auto &m:_map)
  142. o<<m.first<<"="<<m.second<<"\n";
  143. o<<std::ends;
  144. }