inifile.hpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /* Copyright (c) 2014-2019 WinnerHust
  2. * All rights reserved.
  3. * Redistribution and use in source and binary forms, with or without
  4. * modification, are permitted provided that the following conditions are met:
  5. *
  6. * Redistributions of source code must retain the above copyright notice,
  7. * this list of conditions and the following disclaimer.
  8. *
  9. * Redistributions in binary form must reproduce the above copyright notice,
  10. * this list of conditions and the following disclaimer in the documentation
  11. * and/or other materials provided with the distribution.
  12. *
  13. * The names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  18. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  19. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
  20. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  21. * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  22. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  23. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  24. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  25. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  26. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #ifndef INIFILE_HPP_
  29. #define INIFILE_HPP_
  30. #include <vector>
  31. #include <algorithm>
  32. #include <string>
  33. #include <string.h>
  34. using std::string;
  35. using std::vector;
  36. #define RET_OK 0
  37. // 没有找到匹配的]
  38. #define ERR_UNMATCHED_BRACKETS 2
  39. // 段为空
  40. #define ERR_SECTION_EMPTY 3
  41. // 段名已经存在
  42. #define ERR_SECTION_ALREADY_EXISTS 4
  43. // 解析key value失败
  44. #define ERR_PARSE_KEY_VALUE_FAILED 5
  45. // 打开文件失败
  46. #define ERR_OPEN_FILE_FAILED 6
  47. // 内存不足
  48. #define ERR_NO_ENOUGH_MEMORY 7
  49. // 没有找到对应的key
  50. #define ERR_NOT_FOUND_KEY 8
  51. // 没有找到对应的section
  52. #define ERR_NOT_FOUND_SECTION 9
  53. namespace inifile
  54. {
  55. const char delim[] = "\n";
  56. struct IniItem {
  57. string key;
  58. string value;
  59. string comment; // 每个键的注释,都是指该行上方的内容
  60. string rightComment;
  61. };
  62. struct IniSection {
  63. typedef vector<IniItem>::iterator IniItem_it; // 定义一个迭代器,即指向键元素的指针
  64. IniItem_it begin() {
  65. return items.begin(); // 段结构体的begin元素指向items的头指针
  66. }
  67. IniItem_it end() {
  68. return items.end(); // 段结构体的begin元素指向items的尾指针
  69. }
  70. string name;
  71. string comment; // 每个段的注释,都是指该行上方的内容
  72. string rightComment;
  73. vector<IniItem> items; // 键值项数组,一个段可以有多个键值,所有用vector来储存
  74. };
  75. class IniFile
  76. {
  77. public:
  78. IniFile();
  79. ~IniFile() {
  80. release();
  81. }
  82. public:
  83. /* 打开并解析一个名为fname的INI文件 */
  84. int Load(const string &fname);
  85. /* 将内容保存到当前文件 */
  86. int Save();
  87. /* 将内容另存到一个名为fname的文件 */
  88. int SaveAs(const string &fname);
  89. /* 获取section段第一个键为key的string值,成功返回0,否则返回错误码 */
  90. int GetStringValue(const string &section, const string &key, string *value);
  91. /* 获取section段第一个键为key的int值,成功返回0,否则返回错误码 */
  92. int GetIntValue(const string &section, const string &key, int *value);
  93. /* 获取section段第一个键为key的double值,成功返回0,否则返回错误码 */
  94. int GetDoubleValue(const string &section, const string &key, double *value);
  95. /* 获取section段第一个键为key的bool值,成功返回0,否则返回错误码 */
  96. int GetBoolValue(const string &section, const string &key, bool *value);
  97. /* 获取注释,如果key=""则获取段注释 */
  98. int GetComment(const string &section, const string &key, string *comment);
  99. /* 获取行尾注释,如果key=""则获取段的行尾注释 */
  100. int GetRightComment(const string &section, const string &key, string *rightComment);
  101. /* 获取section段第一个键为key的string值,成功返回获取的值,否则返回默认值 */
  102. void GetStringValueOrDefault(const string &section, const string &key, string *value, const string &defaultValue);
  103. /* 获取section段第一个键为key的int值,成功返回获取的值,否则返回默认值 */
  104. void GetIntValueOrDefault(const string &section, const string &key, int *value, int defaultValue);
  105. /* 获取section段第一个键为key的double值,成功返回获取的值,否则返回默认值 */
  106. void GetDoubleValueOrDefault(const string &section, const string &key, double *value, double defaultValue);
  107. /* 获取section段第一个键为key的bool值,成功返回获取的值,否则返回默认值 */
  108. void GetBoolValueOrDefault(const string &section, const string &key, bool *value, bool defaultValue);
  109. /* 获取section段所有键为key的值,并将值赋到values的vector中 */
  110. int GetValues(const string &section, const string &key, vector<string> *values);
  111. /* 获取section列表,并返回section个数 */
  112. int GetSections(vector<string> *sections);
  113. /* 获取section个数,至少存在一个空section */
  114. int GetSectionNum();
  115. /* 是否存在某个section */
  116. bool HasSection(const string &section);
  117. /* 获取指定section的所有ken=value信息 */
  118. IniSection *getSection(const string &section = "");
  119. /* 是否存在某个key */
  120. bool HasKey(const string &section, const string &key);
  121. /* 设置字符串值 */
  122. int SetStringValue(const string &section, const string &key, const string &value);
  123. /* 设置整形值 */
  124. int SetIntValue(const string &section, const string &key, int value);
  125. /* 设置浮点数值 */
  126. int SetDoubleValue(const string &section, const string &key, double value);
  127. /* 设置布尔值 */
  128. int SetBoolValue(const string &section, const string &key, bool value);
  129. /* 设置注释,如果key=""则设置段注释 */
  130. int SetComment(const string &section, const string &key, const string &comment);
  131. /* 设置行尾注释,如果key=""则设置段的行尾注释 */
  132. int SetRightComment(const string &section, const string &key, const string &rightComment);
  133. /* 删除段 */
  134. void DeleteSection(const string &section);
  135. /* 删除特定段的特定参数 */
  136. void DeleteKey(const string &section, const string &key);
  137. /*设置注释分隔符,默认为"#" */
  138. void SetCommentDelimiter(const string &delimiter);
  139. const string &GetErrMsg();
  140. private:
  141. /* 获取section段所有键为key的值,并将值赋到values的vector中,,将注释赋到comments的vector中 */
  142. int GetValues(const string &section, const string &key, vector<string> *value, vector<string> *comments);
  143. /* 同时设置值和注释 */
  144. int setValue(const string &section, const string &key, const string &value, const string &comment = "");
  145. /* 去掉str前面的c字符 */
  146. static void trimleft(string &str, char c = ' ');
  147. /* 去掉str后面的c字符 */
  148. static void trimright(string &str, char c = ' ');
  149. /* 去掉str前面和后面的空格符,Tab符等空白符 */
  150. static void trim(string &str);
  151. /* 将字符串str按分割符delim分割成多个子串 */
  152. private:
  153. int UpdateSection(const string &cleanLine, const string &comment,
  154. const string &rightComment, IniSection **section);
  155. int AddKeyValuePair(const string &cleanLine, const string &comment,
  156. const string &rightComment, IniSection *section);
  157. void release();
  158. bool split(const string &str, const string &sep, string *left, string *right);
  159. bool IsCommentLine(const string &str);
  160. bool parse(const string &content, string *key, string *value);
  161. // for debug
  162. void print();
  163. private:
  164. /* 获取section段第一个键为key的值,并将值赋到value中 */
  165. int getValue(const string &section, const string &key, string *value);
  166. /* 获取section段第一个键为key的值,并将值赋到value中,将注释赋到comment中 */
  167. int getValue(const string &section, const string &key, string *value, string *comment);
  168. bool StringCmpIgnoreCase(const string &str1, const string &str2);
  169. bool StartWith(const string &str, const string &prefix);
  170. private:
  171. typedef vector<IniSection *>::iterator IniSection_it;
  172. vector<IniSection *> sections_vt; // 用于存储段集合的vector容器
  173. string iniFilePath;
  174. string commentDelimiter;
  175. string errMsg; // 保存出错时的错误信息
  176. };
  177. } // endof namespace inifile
  178. using namespace inifile;
  179. #endif // INIFILE_HPP_