From fe5ae89555ead1863420c1a9c389553e75e4527c Mon Sep 17 00:00:00 2001 From: "N.N." Date: Tue, 30 Mar 2004 02:59:55 +0000 Subject: New in PiDiP 0.12.13 svn path=/trunk/externals/pidip/; revision=1509 --- include/pdp_mp4configset.h | 532 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 532 insertions(+) create mode 100644 include/pdp_mp4configset.h (limited to 'include/pdp_mp4configset.h') diff --git a/include/pdp_mp4configset.h b/include/pdp_mp4configset.h new file mode 100644 index 0000000..a20d260 --- /dev/null +++ b/include/pdp_mp4configset.h @@ -0,0 +1,532 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is MPEG4IP. + * + * The Initial Developer of the Original Code is Cisco Systems Inc. + * Portions created by Cisco Systems Inc. are + * Copyright (C) Cisco Systems Inc. 2000, 2001. All Rights Reserved. + * + * Contributor(s): + * Dave Mackie dmackie@cisco.com + * Bill May wmay@cisco.com + * + * Adapted for PD/PDP by Yves Degoyon (ydegoyon@free.fr) + */ + +#ifndef __CONFIG_SET_H__ +#define __CONFIG_SET_H__ + +#include + +#ifndef CONFIG_SAFETY +#define CONFIG_SAFETY 1 +#endif + +typedef u_int32_t config_integer_t; + +typedef u_int16_t config_index_t; + + +enum ConfigException { + CONFIG_ERR_INAME, + CONFIG_ERR_TYPE, + CONFIG_ERR_MEMORY, +}; + +// TBD type specific exception info and printing utility +class CConfigException { +public: + CConfigException(ConfigException e) { + type = e; + fprintf( stderr, "pdp_mp4configset : exception : type : %d\n", e ); + } + ConfigException type; +}; + +#define CONFIG_MAX_STRLEN 255 + +// TBD weld this in, and throw exception +inline char* stralloc(const char* src) { + char* dst = (char*)malloc(strlen(src)+1); + if (dst) { + strcpy(dst, src); + } + return dst; +} + +enum ConfigType { + CONFIG_TYPE_UNDEFINED, + CONFIG_TYPE_INTEGER, + CONFIG_TYPE_BOOL, + CONFIG_TYPE_STRING, + CONFIG_TYPE_FLOAT +}; + +union UConfigValue { + UConfigValue(void) { + m_svalue = NULL; + } + UConfigValue(config_integer_t ivalue) { + m_ivalue = ivalue; + } + UConfigValue(bool bvalue) { + m_bvalue = bvalue; + } + UConfigValue(char* svalue) { + m_svalue = svalue; + } + UConfigValue(float fvalue) { + m_fvalue = fvalue; + } + + config_integer_t m_ivalue; + bool m_bvalue; + char* m_svalue; + float m_fvalue; +}; + +struct SConfigVariable { + config_index_t *m_iName; + const char* m_sName; + ConfigType m_type; + UConfigValue m_defaultValue; + UConfigValue m_value; + + const char* ToAscii() { + static char sBuf[CONFIG_MAX_STRLEN+3]; + switch (m_type) { + case CONFIG_TYPE_INTEGER: + sprintf(sBuf, "%d", m_value.m_ivalue); + return sBuf; + case CONFIG_TYPE_BOOL: + sprintf(sBuf, "%d", m_value.m_bvalue); + return sBuf; + case CONFIG_TYPE_STRING: + if (strchr(m_value.m_svalue, ' ')) { + sBuf[0] = '"'; + strncpy(&sBuf[1], m_value.m_svalue, CONFIG_MAX_STRLEN); + strcpy(&sBuf[ + MIN(strlen(m_value.m_svalue), CONFIG_MAX_STRLEN)+1], "\""); + } + return m_value.m_svalue; + case CONFIG_TYPE_FLOAT: + sprintf(sBuf, "%f", m_value.m_fvalue); + return sBuf; + default: + return ""; + } + } + + bool FromAscii(const char* s) { + switch (m_type) { + case CONFIG_TYPE_INTEGER: + return (sscanf(s, " %i ", &m_value.m_ivalue) == 1); + case CONFIG_TYPE_BOOL: + // OPTION could add "yes/no", "true/false" + if (sscanf(s, " %u ", &m_value.m_ivalue) != 1) { + return false; + } + m_value.m_bvalue = m_value.m_ivalue ? true : false; + return true; + case CONFIG_TYPE_STRING: + // N.B. assuming m_svalue has been alloc'ed + { + size_t len = strlen(s); + free(m_value.m_svalue); + if (*s == '"' && s[len] == '"') { + m_value.m_svalue = strdup(s + 1); + m_value.m_svalue[len - 1] = '\0'; + } else { + m_value.m_svalue = strdup(s); + } + if (m_value.m_svalue == NULL) { + throw new CConfigException(CONFIG_ERR_MEMORY); + } + return true; + } + case CONFIG_TYPE_FLOAT: + return (sscanf(s, " %f ", &m_value.m_fvalue) == 1); + default: + return false; + } + } + + void SetToDefault(void) { + switch (m_type) { + case CONFIG_TYPE_INTEGER: + m_value.m_ivalue = m_defaultValue.m_ivalue; + break; + case CONFIG_TYPE_BOOL: + m_value.m_bvalue = m_defaultValue.m_bvalue; + break; + case CONFIG_TYPE_STRING: + // free(m_value.m_svalue); + m_value.m_svalue = stralloc(m_defaultValue.m_svalue); + if (m_value.m_svalue == NULL) { + throw new CConfigException(CONFIG_ERR_MEMORY); + } + break; + case CONFIG_TYPE_FLOAT: + m_value.m_fvalue = m_defaultValue.m_fvalue; + break; + default: + break; + } + } + + bool IsValueDefault(void) { + switch (m_type) { + case CONFIG_TYPE_INTEGER: + return m_value.m_ivalue == m_defaultValue.m_ivalue; + case CONFIG_TYPE_BOOL: + return m_value.m_bvalue == m_defaultValue.m_bvalue; + case CONFIG_TYPE_STRING: + return (strcmp(m_value.m_svalue, m_defaultValue.m_svalue) == 0); + case CONFIG_TYPE_FLOAT: + return m_value.m_fvalue == m_defaultValue.m_fvalue; + default: + return false; + } + } + void CleanUpConfig(void) { + if (m_type == CONFIG_TYPE_STRING) { + CHECK_AND_FREE(m_value.m_svalue); + } + } +}; + +struct SUnknownConfigVariable { + struct SUnknownConfigVariable *next; + char *value; +}; + +class CConfigSet { +public: + CConfigSet(SConfigVariable* variables, + config_index_t numVariables, + const char* defaultFileName) { + uint32_t size; + m_fileName = NULL; + m_debug = false; + m_variables = variables; + m_numVariables = numVariables; + size = sizeof(SConfigVariable) * numVariables; + m_variables = + (SConfigVariable*)malloc(size); + + memcpy(m_variables, variables, size); + m_defaultFileName = strdup(defaultFileName); + SetToDefaults(); + m_unknown_head = NULL; + }; + + ~CConfigSet() { + free(m_fileName); + for (config_index_t i = 0; i < m_numVariables; i++) { + m_variables[i].CleanUpConfig(); + } + free(m_variables); + m_variables = NULL; + SUnknownConfigVariable *ptr = m_unknown_head; + while (ptr != NULL) { + m_unknown_head = ptr->next; + free(ptr->value); + free(ptr); + ptr = m_unknown_head; + } + CHECK_AND_FREE(m_defaultFileName); + } + + void InitializeIndexes(void) { + for (config_index_t ix = 0; ix < m_numVariables; ix++) { + *m_variables[ix].m_iName = ix; + } + } + + void AddConfigVariables (SConfigVariable* vars, + config_index_t numVariables) { + config_index_t start = m_numVariables; + uint32_t size = sizeof(SConfigVariable) * + (m_numVariables + numVariables); + m_variables = (SConfigVariable*)realloc(m_variables, size); + memcpy(&m_variables[m_numVariables], vars, + numVariables * sizeof(SConfigVariable)); + m_numVariables += numVariables; + SetToDefaults(start); + } + + const char* GetFileName() { + return m_fileName; + } + + inline void CheckIName(config_index_t iName) { + if (iName >= m_numVariables) { + throw new CConfigException(CONFIG_ERR_INAME); + } + if (*m_variables[iName].m_iName != iName) { + throw new CConfigException(CONFIG_ERR_INAME); + } + } + + inline void CheckIntegerType(config_index_t iName) { + if (m_variables[iName].m_type != CONFIG_TYPE_INTEGER) { + throw new CConfigException(CONFIG_ERR_TYPE); + } + } + + inline void CheckBoolType(config_index_t iName) { + if (m_variables[iName].m_type != CONFIG_TYPE_BOOL) { + throw new CConfigException(CONFIG_ERR_TYPE); + } + } + + inline void CheckStringType(config_index_t iName) { + if (m_variables[iName].m_type != CONFIG_TYPE_STRING) { + throw new CConfigException(CONFIG_ERR_TYPE); + } + } + + inline void CheckFloatType(config_index_t iName) { + if (m_variables[iName].m_type != CONFIG_TYPE_FLOAT) { + throw new CConfigException(CONFIG_ERR_TYPE); + } + } + + inline bool IsDefault (const config_index_t iName) { +#if CONFIG_SAFETY + CheckIName(iName); + CheckIntegerType(iName); +#endif + return m_variables[iName].IsValueDefault(); + }; + + inline config_integer_t GetIntegerValue(const config_index_t iName) { +#if CONFIG_SAFETY + CheckIName(iName); + CheckIntegerType(iName); +#endif + return m_variables[iName].m_value.m_ivalue; + } + + inline void SetIntegerValue(const config_index_t iName, + config_integer_t ivalue) { +#if CONFIG_SAFETY + CheckIName(iName); + CheckIntegerType(iName); +#endif + m_variables[iName].m_value.m_ivalue = ivalue; + } + + inline bool GetBoolValue(const config_index_t iName) { +#if CONFIG_SAFETY + CheckIName(iName); + CheckBoolType(iName); +#endif + return m_variables[iName].m_value.m_bvalue;; + } + + inline void SetBoolValue(const config_index_t iName, bool bvalue) { +#if CONFIG_SAFETY + CheckIName(iName); + CheckBoolType(iName); +#endif + m_variables[iName].m_value.m_bvalue = bvalue; + } + + inline char* GetStringValue(const config_index_t iName) { +#if CONFIG_SAFETY + CheckIName(iName); + CheckStringType(iName); +#endif + return m_variables[iName].m_value.m_svalue; + } + + inline void SetStringValue(const config_index_t iName, const char* svalue) { + printf ( "setting variable : %d to : %s\n", iName, svalue ); +#if CONFIG_SAFETY + CheckIName(iName); + CheckStringType(iName); +#endif + if (svalue == m_variables[iName].m_value.m_svalue) { + return; + } + // free(m_variables[iName].m_value.m_svalue); + m_variables[iName].m_value.m_svalue = stralloc(svalue); + if (m_variables[iName].m_value.m_svalue == NULL) { + throw new CConfigException(CONFIG_ERR_MEMORY); + } + } + + inline float GetFloatValue(const config_index_t iName) { +#if CONFIG_SAFETY + CheckIName(iName); + CheckFloatType(iName); +#endif + return m_variables[iName].m_value.m_fvalue; + } + + inline void SetFloatValue(const config_index_t iName, float fvalue) { +#if CONFIG_SAFETY + CheckIName(iName); + CheckFloatType(iName); +#endif + m_variables[iName].m_value.m_fvalue = fvalue; + } + + void SetToDefaults(int start = 0) { + for (config_index_t i = start; i < m_numVariables; i++) { + m_variables[i].SetToDefault(); + } + } + + void SetToDefault(const config_index_t iName) { + m_variables[iName].SetToDefault(); + } + + void ProcessLine (char *line) { + // comment + if (line[0] == '#') { + return; + } + char* s = line; + while (*s != '\0') s++; + s--; + while (isspace(*s)) { + *s = '\0'; + s--; + } + s = line; + + SConfigVariable* var = FindByName(strsep(&s, "=")); + if (var == NULL || s == NULL) { + if (s != NULL) { + *(s - 1) = '='; // restore seperation character + SUnknownConfigVariable *ptr; + ptr = MALLOC_STRUCTURE(SUnknownConfigVariable); + ptr->next = m_unknown_head; + ptr->value = strdup(line); + m_unknown_head = ptr; + } + if (m_debug) { + fprintf(stderr, "bad config line %s\n", s); + } + return; + } + if (!var->FromAscii(s)) { + if (m_debug) { + fprintf(stderr, "bad config value in line %s\n", s); + } + } + } + + bool ReadFromFile(const char* fileName) { + free(m_fileName); + m_fileName = stralloc(fileName); + FILE* pFile = fopen(fileName, "r"); + if (pFile == NULL) { + if (m_debug) { + fprintf(stderr, "couldn't open file %s\n", fileName); + } + return false; + } + char line[256]; + while (fgets(line, sizeof(line), pFile)) { + ProcessLine(line); + } + fclose(pFile); + return true; + } + + bool WriteToFile(const char* fileName, bool allValues = false) { + FILE* pFile = fopen(fileName, "w"); + config_index_t i; + SConfigVariable *var; + SUnknownConfigVariable *ptr; + + if (pFile == NULL) { + if (m_debug) { + fprintf(stderr, "couldn't open file %s\n", fileName); + } + return false; + } + for (i = 0; i < m_numVariables; i++) { + var = &m_variables[i]; + if (allValues || !var->IsValueDefault()) { + fprintf(pFile, "%s=%s\n", var->m_sName, var->ToAscii()); + } + } + ptr = m_unknown_head; + while (ptr != NULL) { + fprintf(pFile, "%s\n", ptr->value); + ptr = ptr->next; + } + fclose(pFile); + return true; + } + + bool ReadDefaultFile(void) { + return ReadFromFile(m_defaultFileName); + } + bool WriteDefaultFile(void) { + return WriteToFile(m_defaultFileName); + } + + void SetDebug(bool debug = true) { + m_debug = debug; + } + +protected: + SConfigVariable* FindByName(const char* sName) { + for (config_index_t i = 0; i < m_numVariables; i++) { + if (!strcasecmp(sName, m_variables[i].m_sName)) { + return &m_variables[i]; + } + } + return NULL; + }; + +protected: + SConfigVariable* m_variables; + config_index_t m_numVariables; + const char* m_defaultFileName; + bool m_debug; + char* m_fileName; + SUnknownConfigVariable *m_unknown_head; +}; + +// To define configuration variables - first DECLARE_CONFIG in a +// .h file. Then in either a C++ or h file, define a static array +// of configuration variables using CONFIG_BOOL, CONFIG_FLOAT, CONFIG_INT +// or CONFIG_STRING. You can include the .h anywhere you use the variable - +// in a .cpp, you must include the .h file with DECLARE_CONFIG_VARIABLES +// defined before the .h file. Note - if you're already including mp4live.h, +// you need to #define the DECLARE_CONFIG_VARIABLES after the include. +// +// Note - you want to add the config variables BEFORE the ReadFromFile +// call +#ifdef DECLARE_CONFIG_VARIABLES +#define DECLARE_CONFIG(a) config_index_t (a); +#else +#define DECLARE_CONFIG(a) extern config_index_t (a); +#endif + +#define CONFIG_BOOL(var, name, defval) \ + { &(var), (name), CONFIG_TYPE_BOOL, (defval), } +#define CONFIG_FLOAT(var, name, defval) \ + { &(var), (name), CONFIG_TYPE_FLOAT,(float) (defval), } +#define CONFIG_INT(var, name, defval) \ + { &(var), (name), CONFIG_TYPE_INTEGER,(config_integer_t) (defval), } +#define CONFIG_STRING(var, name, defval) \ + { &(var), (name), CONFIG_TYPE_STRING, (defval), } + + +#endif /* __CONFIG_SET_H__ */ -- cgit v1.2.1