config_set.h
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:10k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is MPEG4IP.
  13.  * 
  14.  * The Initial Developer of the Original Code is Cisco Systems Inc.
  15.  * Portions created by Cisco Systems Inc. are
  16.  * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  * Dave Mackie dmackie@cisco.com
  20.  * Bill May  wmay@cisco.com
  21.  */
  22. #ifndef __CONFIG_SET_H__
  23. #define __CONFIG_SET_H__
  24. #include <systems.h>
  25. #ifndef MIN
  26. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  27. #endif
  28. #ifndef MAX
  29. #define MAX(a, b) ((a) > (b) ? (a) : (b))
  30. #endif
  31. #ifndef CONFIG_SAFETY
  32. #define CONFIG_SAFETY 1
  33. #endif
  34. typedef u_int32_t config_integer_t;
  35. typedef u_int16_t config_index_t;
  36. enum ConfigException {
  37. CONFIG_ERR_INAME,
  38. CONFIG_ERR_TYPE,
  39. CONFIG_ERR_MEMORY,
  40. };
  41. // TBD type specific exception info and printing utility
  42. class CConfigException {
  43. public:
  44. CConfigException(ConfigException e) {
  45. type = e;
  46. }
  47. ConfigException type;
  48. };
  49. #define CONFIG_MAX_STRLEN 255
  50. // TBD weld this in, and throw exception
  51. inline char* stralloc(const char* src) {
  52. char* dst = (char*)malloc(strlen(src)+1);
  53. if (dst) {
  54. strcpy(dst, src);
  55. }
  56. return dst;
  57. }
  58. enum ConfigType {
  59. CONFIG_TYPE_UNDEFINED,
  60. CONFIG_TYPE_INTEGER,
  61. CONFIG_TYPE_BOOL,
  62. CONFIG_TYPE_STRING,
  63. CONFIG_TYPE_FLOAT
  64. };
  65. union UConfigValue {
  66. UConfigValue(void) {
  67. m_svalue = NULL;
  68. }
  69. UConfigValue(config_integer_t ivalue) {
  70. m_ivalue = ivalue;
  71. }
  72. UConfigValue(bool bvalue) {
  73. m_bvalue = bvalue;
  74. }
  75. UConfigValue(char* svalue) {
  76. m_svalue = svalue;
  77. }
  78. UConfigValue(float fvalue) {
  79. m_fvalue = fvalue;
  80. }
  81. config_integer_t m_ivalue;
  82. bool m_bvalue;
  83. char* m_svalue;
  84. float m_fvalue;
  85. };
  86. struct SConfigVariable {
  87. const config_index_t m_iName;
  88. const char*  m_sName;
  89. ConfigType m_type;
  90. UConfigValue m_defaultValue;
  91. UConfigValue m_value;
  92. const char* ToAscii() {
  93. static char sBuf[CONFIG_MAX_STRLEN+3];
  94. switch (m_type) {
  95. case CONFIG_TYPE_INTEGER:
  96. sprintf(sBuf, "%d", m_value.m_ivalue);
  97. return sBuf;
  98. case CONFIG_TYPE_BOOL:
  99. sprintf(sBuf, "%d", m_value.m_bvalue);
  100. return sBuf;
  101. case CONFIG_TYPE_STRING:
  102. if (strchr(m_value.m_svalue, ' ')) {
  103. sBuf[0] = '"';
  104. strncpy(&sBuf[1], m_value.m_svalue, CONFIG_MAX_STRLEN);
  105. strcpy(&sBuf[
  106. MIN(strlen(m_value.m_svalue), CONFIG_MAX_STRLEN)+1], """);
  107. }
  108. return m_value.m_svalue;
  109. case CONFIG_TYPE_FLOAT:
  110. sprintf(sBuf, "%f", m_value.m_fvalue);
  111. return sBuf;
  112. default:
  113. return "";
  114. }
  115. }
  116. bool FromAscii(const char* s) {
  117. switch (m_type) {
  118. case CONFIG_TYPE_INTEGER:
  119. return (sscanf(s, " %i ", &m_value.m_ivalue) == 1);
  120. case CONFIG_TYPE_BOOL:
  121. // OPTION could add "yes/no", "true/false"
  122. if (sscanf(s, " %u ", &m_value.m_ivalue) != 1) {
  123. return false;
  124. }
  125. m_value.m_bvalue = m_value.m_ivalue ? true : false;
  126. return true;
  127. case CONFIG_TYPE_STRING:
  128. // N.B. assuming m_svalue has been alloc'ed
  129. free(m_value.m_svalue);
  130. m_value.m_svalue = (char*)malloc(strlen(s)+1);
  131. if (m_value.m_svalue == NULL) {
  132. throw new CConfigException(CONFIG_ERR_MEMORY);
  133. }
  134. m_value.m_svalue[0] = '';
  135. if (s[0] == '"') {
  136. char* end = strchr(&s[1], '"');
  137. if (end == NULL) {
  138. return false;
  139. }
  140. size_t len = end - &s[1];
  141. strncpy(m_value.m_svalue, &s[1], len);
  142. m_value.m_svalue[len] = '';
  143. }
  144. return (sscanf(s, "%s", m_value.m_svalue) == 1);
  145. case CONFIG_TYPE_FLOAT:
  146. return (sscanf(s, " %f ", &m_value.m_fvalue) == 1);
  147. default:
  148. return false;
  149. }
  150. }
  151. void SetToDefault(void) {
  152. switch (m_type) {
  153. case CONFIG_TYPE_INTEGER:
  154. m_value.m_ivalue = m_defaultValue.m_ivalue;
  155. break;
  156. case CONFIG_TYPE_BOOL:
  157. m_value.m_bvalue = m_defaultValue.m_bvalue;
  158. break;
  159. case CONFIG_TYPE_STRING:
  160. free(m_value.m_svalue);
  161. m_value.m_svalue = stralloc(m_defaultValue.m_svalue);
  162. if (m_value.m_svalue == NULL) {
  163. throw new CConfigException(CONFIG_ERR_MEMORY);
  164. }
  165. break;
  166. case CONFIG_TYPE_FLOAT:
  167. m_value.m_fvalue = m_defaultValue.m_fvalue;
  168. break;
  169. default:
  170. break;
  171. }
  172. bool IsValueDefault(void) {
  173. switch (m_type) {
  174. case CONFIG_TYPE_INTEGER:
  175. return m_value.m_ivalue == m_defaultValue.m_ivalue;
  176. case CONFIG_TYPE_BOOL:
  177. return m_value.m_bvalue == m_defaultValue.m_bvalue;
  178. case CONFIG_TYPE_STRING:
  179. return (strcmp(m_value.m_svalue, m_defaultValue.m_svalue) == 0);
  180. case CONFIG_TYPE_FLOAT:
  181. return m_value.m_fvalue == m_defaultValue.m_fvalue;
  182. default:
  183. return false;
  184. }
  185. };
  186. class CConfigSet {
  187. public:
  188. CConfigSet(SConfigVariable* variables, 
  189.   config_index_t numVariables, 
  190.   const char* defaultFileName) {
  191. m_fileName = NULL;
  192. m_debug = false;
  193. m_variables = variables;
  194. m_numVariables = numVariables;
  195. m_defaultFileName = defaultFileName;
  196. SetToDefaults();
  197. };
  198. ~CConfigSet() {
  199. free(m_fileName);
  200. }
  201. const char* GetFileName() {
  202. return m_fileName;
  203. }
  204. inline void CheckIName(config_index_t iName) {
  205. if (iName >= m_numVariables) {
  206. throw new CConfigException(CONFIG_ERR_INAME);
  207. }
  208. if (m_variables[iName].m_iName != iName) {
  209. throw new CConfigException(CONFIG_ERR_INAME);
  210. }
  211. }
  212. inline void CheckIntegerType(config_index_t iName) {
  213. if (m_variables[iName].m_type != CONFIG_TYPE_INTEGER) {
  214. throw new CConfigException(CONFIG_ERR_TYPE);
  215. }
  216. }
  217. inline void CheckBoolType(config_index_t iName) {
  218. if (m_variables[iName].m_type != CONFIG_TYPE_BOOL) {
  219. throw new CConfigException(CONFIG_ERR_TYPE);
  220. }
  221. }
  222. inline void CheckStringType(config_index_t iName) {
  223. if (m_variables[iName].m_type != CONFIG_TYPE_STRING) {
  224. throw new CConfigException(CONFIG_ERR_TYPE);
  225. }
  226. }
  227. inline void CheckFloatType(config_index_t iName) {
  228. if (m_variables[iName].m_type != CONFIG_TYPE_FLOAT) {
  229. throw new CConfigException(CONFIG_ERR_TYPE);
  230. }
  231. }
  232. inline config_integer_t GetIntegerValue(const config_index_t iName) {
  233. #if CONFIG_SAFETY
  234. CheckIName(iName);
  235. CheckIntegerType(iName);
  236. #endif
  237. return m_variables[iName].m_value.m_ivalue;
  238. }
  239. inline void SetIntegerValue(const config_index_t iName, 
  240.   config_integer_t ivalue) {
  241. #if CONFIG_SAFETY
  242. CheckIName(iName);
  243. CheckIntegerType(iName);
  244. #endif
  245. m_variables[iName].m_value.m_ivalue = ivalue;
  246. }
  247. inline bool GetBoolValue(const config_index_t iName) {
  248. #if CONFIG_SAFETY
  249. CheckIName(iName);
  250. CheckBoolType(iName);
  251. #endif
  252. return m_variables[iName].m_value.m_bvalue;;
  253. }
  254. inline void SetBoolValue(const config_index_t iName, bool bvalue) {
  255. #if CONFIG_SAFETY
  256. CheckIName(iName);
  257. CheckBoolType(iName);
  258. #endif
  259. m_variables[iName].m_value.m_bvalue = bvalue;
  260. }
  261. inline char* GetStringValue(const config_index_t iName) {
  262. #if CONFIG_SAFETY
  263. CheckIName(iName);
  264. CheckStringType(iName);
  265. #endif
  266. return m_variables[iName].m_value.m_svalue;
  267. }
  268. inline void SetStringValue(const config_index_t iName, char* svalue) {
  269. #if CONFIG_SAFETY
  270. CheckIName(iName);
  271. CheckStringType(iName);
  272. #endif
  273. if (svalue == m_variables[iName].m_value.m_svalue) {
  274. return;
  275. }
  276. free(m_variables[iName].m_value.m_svalue);
  277. m_variables[iName].m_value.m_svalue = stralloc(svalue);
  278. if (m_variables[iName].m_value.m_svalue == NULL) {
  279. throw new CConfigException(CONFIG_ERR_MEMORY);
  280. }
  281. }
  282. inline float GetFloatValue(const config_index_t iName) {
  283. #if CONFIG_SAFETY
  284. CheckIName(iName);
  285. CheckFloatType(iName);
  286. #endif
  287. return m_variables[iName].m_value.m_fvalue;
  288. }
  289. inline void SetFloatValue(const config_index_t iName, float fvalue) {
  290. #if CONFIG_SAFETY
  291. CheckIName(iName);
  292. CheckFloatType(iName);
  293. #endif
  294. m_variables[iName].m_value.m_fvalue = fvalue;
  295. }
  296. void SetToDefaults(void) {
  297. for (config_index_t i = 0; i < m_numVariables; i++) {
  298. m_variables[i].SetToDefault();
  299. }
  300. }
  301. bool ReadFromFile(const char* fileName) {
  302. free(m_fileName);
  303. m_fileName = stralloc(fileName);
  304. FILE* pFile = fopen(fileName, "r");
  305. if (pFile == NULL) {
  306. if (m_debug) {
  307. fprintf(stderr, "couldn't open file %sn", fileName);
  308. }
  309. return false;
  310. }
  311. char line[256];
  312. while (fgets(line, sizeof(line), pFile)) {
  313. // comment
  314. if (line[0] == '#') {
  315. continue;
  316. }
  317. char* s = line;
  318. SConfigVariable* var = FindByName(strsep(&s, "="));
  319. if (var == NULL || s == NULL) {
  320. if (m_debug) {
  321. fprintf(stderr, "bad config line %sn", s);  
  322. }
  323. continue;
  324. }
  325. if (!var->FromAscii(s)) {
  326. if (m_debug) {
  327. fprintf(stderr, "bad config value in line %sn", s);  
  328. }
  329. }
  330. }
  331. fclose(pFile);
  332. return true;
  333. }
  334. bool WriteToFile(const char* fileName, bool allValues = false) {
  335. FILE* pFile = fopen(fileName, "w");
  336. if (pFile == NULL) {
  337. if (m_debug) {
  338. fprintf(stderr, "couldn't open file %sn", fileName);
  339. }
  340. return false;
  341. }
  342. for (config_index_t i = 0; i < m_numVariables; i++) {
  343. SConfigVariable* var = &m_variables[i];
  344. if (allValues || !var->IsValueDefault()) {
  345. fprintf(pFile, "%s=%sn", var->m_sName, var->ToAscii());
  346. }
  347. }
  348. fclose(pFile);
  349. return true;
  350. }
  351. bool ReadDefaultFile(void) {
  352. return ReadFromFile(m_defaultFileName);
  353. }
  354. bool WriteDefaultFile(void) {
  355. return WriteToFile(m_defaultFileName);
  356. }
  357. void SetDebug(bool debug = true) {
  358. m_debug = debug;
  359. }
  360. protected:
  361. SConfigVariable* FindByName(const char* sName) {
  362. for (config_index_t i = 0; i < m_numVariables; i++) {
  363. if (!strcmp(sName, m_variables[i].m_sName)) {
  364. return &m_variables[i];
  365. }
  366. }
  367. return NULL;
  368. };
  369. protected:
  370. SConfigVariable* m_variables;
  371. config_index_t m_numVariables;
  372. const char* m_defaultFileName;
  373. bool  m_debug;
  374. char* m_fileName;
  375. };
  376. #endif /* __CONFIG_SET_H__ */