18#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
61 mConfigValues.insert(ConfigValuesMap::value_type(it->first, it->second));
68 int startingArgForNameValuePairs = 1 + skipCount;
69 char *firstArg = argv[startingArgForNameValuePairs];
72 if(argc >= (startingArgForNameValuePairs + 1) && firstArg[0] !=
'-' && firstArg[0] !=
'/')
74 if(argc >= (startingArgForNameValuePairs + 1) && firstArg[0] !=
'-')
78 startingArgForNameValuePairs++;
82 for(
int i = startingArgForNameValuePairs; i < argc; i++)
84 Data argData(argv[i]);
93 throw Exception(
"Help text requested - process stopping", __FILE__, __LINE__);
95 else if(argData.
at(0) ==
'-' || argData.
at(0) ==
'/')
104 const char * anchor = pb.
position();
108 pb.
data(name, anchor);
112 pb.
data(value, anchor);
119 cerr <<
"Invalid command line parameters:" << endl;
120 cerr <<
" Name/Value pairs must contain an = or a : between the name and the value" << endl;
121 cerr <<
" Bad argument: " << argData << endl;
122 Data exceptionString(
"Name/Value pairs must contain an = or a : between the name and the value (Bad argument: " + argData +
")");
123 throw Exception(exceptionString, __FILE__, __LINE__);
128 cerr <<
"Invalid command line parameters:" << endl;
129 cerr <<
" Exception parsing Name/Value pairs: " << ex << endl;
130 cerr <<
" Bad argument: " << argData << endl;
136 cerr <<
"Invalid command line parameters:" << endl;
137 cerr <<
" Name/Value pairs must be prefixed with either a -, --, or a /" << endl;
138 cerr <<
" Bad argument: " << argData << endl;
139 Data exceptionString(
"Name/Value pairs must be prefixed with either a -, --, or a / (Bad argument: " + argData +
")");
140 throw Exception(exceptionString, __FILE__, __LINE__);
150 const char* anchor = pb.
start();
158 ifstream configFile(filename.
c_str());
162 Data exceptionString(
"Error opening/reading configuration file: " + filename);
163 throw Exception(exceptionString, __FILE__, __LINE__);
167 while(getline(configFile, sline))
175 if(pb.
eof() || *anchor ==
'#')
continue;
179 pb.
data(name,anchor);
190 pb.
data(value, anchor);
193 Data lowerName(name);
195 if(lowerName ==
"include")
210 Data indexNameLower(indexName);
215 const Data& keyName = it->first;
216 if(keyName.
prefix(indexNameLower) && keyName.
size() > numPos
217 && isdigit(
static_cast< unsigned char >(keyName[numPos])))
220 while(i < keyName.
size() && isdigit(
static_cast< unsigned char >(keyName[i])))
225 if(keys.find(indexFullName) == keys.end())
227 keys.insert(indexFullName);
250 Data ret(defaultValue);
265 if(it->second ==
"1" ||
273 else if(it->second ==
"0" ||
281 cerr <<
"Invalid boolean setting: " << name <<
" = " << it->second <<
": Valid values are: 1,true,on,enable,0,false,off or disable" << endl;
291 bool ret = defaultValue;
303 value = it->second.convertUnsignedLong();
313 unsigned long ret = defaultValue;
325 value = it->second.convertInt();
336 int ret = defaultValue;
348 value = it->second.convertInt();
359 int ret = defaultValue;
368 std::pair<ConfigValuesMap::const_iterator,ConfigValuesMap::const_iterator> valuesIts =
mConfigValues.equal_range(lowerName);
370 for (ConfigValuesMap::const_iterator it=valuesIts.first; it!=valuesIts.second; ++it)
375 while(!it->second.empty() && !pb.
eof())
380 pb.
data(item, start);
381 value.push_back(item);
395 std::vector<Data> _value;
403 value.push_back(v.convertInt());
413 std::pair<ConfigValuesMap::const_iterator,ConfigValuesMap::const_iterator> valuesIts =
mConfigValues.equal_range(lowerName);
415 for (ConfigValuesMap::const_iterator it=valuesIts.first; it!=valuesIts.second; ++it)
420 while(!it->second.empty() && !pb.
eof())
425 pb.
data(item, start);
442 Data mapsPrefixLower(mapsPrefix);
447 const Data& keyName = it->first;
448 if(keyName.
prefix(mapsPrefixLower) && keyName.
size() > numPos
449 && isdigit(
static_cast< unsigned char >(keyName[numPos])))
452 while(i < keyName.
size() && isdigit(
static_cast< unsigned char >(keyName[i])))
456 if(keyName.
size() - i < 1)
458 stringstream err_text;
459 err_text <<
"Configuration key " << keyName <<
" missing subkey name";
460 Data err_data(err_text.str());
461 throw Exception(err_data, __FILE__, __LINE__);
463 Data index = keyName.
substr(numPos, i - numPos);
477 if(configValues.find(lowerName) != configValues.end())
479 stringstream err_text;
480 err_text <<
"Duplicate configuration key " << name <<
" while parsing " << source;
481 Data err_data(err_text.str());
482 throw Exception(err_data, __FILE__, __LINE__);
484 configValues.insert(ConfigValuesMap::value_type(lowerName, value));
504 pb.
data(filenameOnly, anchor);
511 if(!filename.
empty())
531 std::multimap<Data, Data> sortedMap;
532 ConfigParse::ConfigValuesMap::const_iterator it = config.
mConfigValues.begin();
535 sortedMap.insert(std::multimap<Data, Data>::value_type(it->first, it->second));
537 std::multimap<Data, Data>::const_iterator it2 = sortedMap.begin();
538 for(; it2 != sortedMap.end(); it2++)
540 strm << it2->first <<
" = " << it2->second << endl;
The abstract base-class for all exceptions thrown by resip code.
unsigned short getConfigUnsignedShort(const resip::Data &name, int defaultValue) const
ConfigValuesMap mConfigValues
bool AddBasePathIfRequired(Data &filename) const
virtual void parseConfig(int argc, char **argv, const resip::Data &defaultConfigFilename)
void insertConfigValue(const resip::Data &name, const resip::Data &value)
HashMultiMap< resip::Data, resip::Data > ConfigValuesMap
resip::Data mConfigBasePath
ConfigValuesMap mCmdLineConfigValues
virtual void printHelpText(int argc, char **argv)=0
virtual void parseCommandLine(int argc, char **argv, int skipCount=0)
int getConfigInt(const resip::Data &name, int defaultValue) const
virtual void parseConfigFile(const resip::Data &filename)
NestedConfigMap getConfigNested(const resip::Data &mapsPrefix) const
resip::Data removePath(const resip::Data &fileAndPath) const
void getConfigIndexKeys(const resip::Data &indexName, std::set< resip::Data > &keys) const
resip::Data getConfigData(const resip::Data &name, const resip::Data &defaultValue, bool useDefaultIfEmpty=false) const
resip::Data mCmdLineConfigFilename
HashMap< int, NestedConfigParse > NestedConfigMap
bool getConfigValue(const resip::Data &name, resip::Data &value) const
unsigned long getConfigUnsignedLong(const resip::Data &name, unsigned long defaultValue) const
ConfigValuesMap mFileConfigValues
bool getConfigBool(const resip::Data &name, bool defaultValue) const
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
const char * c_str() const
Returns a null-terminated string representing.
char & at(size_type p)
Returns the character at the specified position.
bool prefix(const Data &pre) const noexcept
Returns true if this Data starts with the bytes indicated by the passed-in Data.
Data substr(size_type first, size_type count=Data::npos) const
Copies a portion of this Data into a new Data.
bool empty() const noexcept
Checks whether the Data is empty.
Data & lowercase()
Converts this Data to lowercase.
size_type size() const noexcept
Returns the number of bytes in this Data.
size_type find(const Data &match, size_type start=0) const
Finds a specified sequence of bytes in this Data.
const char * begin() const noexcept
Returns a pointer to the beginning of the buffer used by the Data.
int convertInt() const
Takes the contents of the Data and converts them to an integer.
static std::bitset< 256 > toBitset(const resip::Data &chars)
Creates a bitset reflecting the contents of this data (as a set) ie.
Provides string-parsing functionality with protection from buffer overflow.
CurrentPosition skipToEnd()
CurrentPosition skipWhitespace()
CurrentPosition skipToChar(char c)
CurrentPosition position() const
CurrentPosition skipChars(const char *cs)
CurrentPosition skipToOneOf(const char *cs)
CurrentPosition skipChar()
void data(Data &data, const char *start) const
make the passed in data share memory with the buffer (uses Data::Share)
const char * skipBackToOneOf(const char *cs)
static const char * Whitespace
dcm! – add UnusedChecking(_enum) below;
bool isEqualNoCase(const Data &left, const Data &right)
EncodeStream & operator<<(EncodeStream &strm, const BaseException &e)