/* ==================================================================== * The Vovida Software License, Version 1.0 * * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The names "VOCAL", "Vovida Open Communication Application Library", * and "Vovida Open Communication Application Library (VOCAL)" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor * may "VOCAL" appear in their name, without prior written * permission of Vovida Networks, Inc. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * ==================================================================== * * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc. For more information on Vovida Networks, Inc., please see * . * */ static const char* const support_cxx_Version = "$Id: support.cxx,v 1.46.24.1 2003/02/27 22:10:46 bko Exp $"; #include "global.h" #include "support.hxx" #include #ifndef WIN32 #include #else #define __STDC__ 1 extern "C" { #include } #include #endif #include "debug.h" #include #include "cpLog.h" /********************************************************************** Support functions for the MGCP library. **********************************************************************/ bool isIn(char ch, const string& charlist) { string::size_type pos = charlist.find_first_of(ch); if (pos != string::npos) { return true; } else { return false; } } substring paren_match(const string& inputText) { // create a substring from inputText and call it substring subInputText(&inputText, 0, inputText.length()); return paren_match(subInputText); } substring paren_match(const substring& inputText) { string::size_type position = 0, firstParenLocation = string::npos; bool foundFirstParen = false; int parenCount = 0; while ( position < inputText.length() && !(foundFirstParen && (parenCount == 0)) ) { // scan for the first paren char currentChar = const_cast < substring& > (inputText)[position]; if (currentChar == '(') { if (!foundFirstParen) { foundFirstParen = true; firstParenLocation = position; } parenCount++; } else if (currentChar == ')') { if (foundFirstParen) { parenCount--; } } position++; } if (foundFirstParen && (parenCount == 0)) { // in this case, create a substring based on this one ODEBUG(DEBUG_LOWLEVEL, 2, cout << ":" << inputText.str().substr(firstParenLocation + 1, (position - firstParenLocation - 2)) << ":\n"; ); substring retVal(inputText, firstParenLocation + 1, position - firstParenLocation - 2); return retVal; } else { // in this case, it is an error cerr << "could not match the string" << endl; if (firstParenLocation != string::npos) { substring errVal(inputText, firstParenLocation, inputText.length() - firstParenLocation); cerr << "string: " << errVal << endl; } return substring(); } return substring(); } string str_paren_match(const string& inputText) { // create a substring from inputText and call it substring subInputText(&inputText, 0, inputText.length()); string matched = (paren_match(subInputText)).str(); return( matched ); } sub_split_t sub_split_paren_match(const string& inputText, const string& characters) { string::size_type position = 0, oldPosition = 0; sub_split_t splitted; unsigned int length = inputText.length(); while (position < length) { // the code must loop through the entire text to make sure it // matches parentheses int parenCount = 0; while ((position < length) && !(isIn(inputText[position], characters) && (parenCount == 0)) ) { char currentChar = inputText[position]; if (currentChar == '(') { parenCount++; } if (currentChar == ')') { parenCount--; } position++; } if (position == string::npos) position = inputText.length(); if (parenCount != 0) { // we reached the end without balanced parentheses -- mark as an // error and continue cerr << "this is an error" << endl; } ODEBUG(DEBUG_LOWLEVEL, 2, cout << inputText.substr(oldPosition, (position - oldPosition)); ); ODEBUG(DEBUG_LOWLEVEL, 2, cout << ":\n"; ); (splitted).push_back( substring( &inputText, oldPosition, (position - oldPosition)) ); oldPosition = inputText.find_first_not_of(characters, position); if (oldPosition == string::npos) oldPosition = inputText.length(); position = oldPosition; } ODEBUG(DEBUG_LOWLEVEL, 2, cout << "number of lines: " << splitted.size() << endl; ); return splitted; } split_t split_paren_match(const string& inputText, const string& characters) { string::size_type position = 0, oldPosition = 0; split_t splitted; unsigned int length = inputText.length(); while (position < length) { // the code must loop through the entire text to make sure it // matches parentheses int parenCount = 0; while ((position < length) && !(isIn(inputText[position], characters) && (parenCount == 0)) ) { char currentChar = inputText[position]; if (currentChar == '(') { parenCount++; } if (currentChar == ')') { parenCount--; } position++; } if (position == string::npos) position = inputText.length(); if (parenCount != 0) { // we reached the end without balanced parentheses -- mark as an // error and continue cerr << "this is an error" << endl; } ODEBUG(DEBUG_LOWLEVEL, 2, cout << inputText.substr(oldPosition, (position - oldPosition)); ); ODEBUG(DEBUG_LOWLEVEL, 2, cout << ":\n"; ); if((position != oldPosition) && (oldPosition < position)) { (splitted).push_back( inputText.substr( oldPosition, (position - oldPosition))); } oldPosition = inputText.find_first_not_of(characters, position); if (oldPosition == string::npos) oldPosition = inputText.length(); position = oldPosition; } ODEBUG(DEBUG_LOWLEVEL, 2, cout << "number of lines: " << splitted.size() << endl; ); return splitted; } sub_split_t sub_split(const string& inputText, const string& characters) { string::size_type position = 0, oldPosition = 0; sub_split_t splitted; unsigned int length = inputText.length(); while (position < length) { position = inputText.find_first_of(characters, oldPosition); // advance forward and eat all characters of type characters if (position == string::npos) position = inputText.length(); ODEBUG(DEBUG_LOWLEVEL, 2, cout << inputText.substr(oldPosition, (position - oldPosition)); ); ODEBUG(DEBUG_LOWLEVEL, 2, cout << ":\n"; ); (splitted).push_back( substring( &inputText, oldPosition, (position - oldPosition)) ); oldPosition = inputText.find_first_not_of(characters, position); if (oldPosition == string::npos) oldPosition = inputText.length(); position = oldPosition; } ODEBUG(DEBUG_LOWLEVEL, 2, cout << "number of lines: " << splitted.size() << endl; ); return splitted; } split_t split(const string& inputText, const string& characters) { // this is the original split definition, which I think may be inefficient // I will instead try a more efficient way of doing things. string::size_type position = 0, oldPosition = 0; split_t splitted; unsigned int length = inputText.length(); while (position < length) { position = inputText.find_first_of(characters, oldPosition); if (position == string::npos) position = inputText.length(); ODEBUG(DEBUG_LOWLEVEL, 2, cout << inputText.substr(oldPosition, (position - oldPosition)); ); ODEBUG(DEBUG_LOWLEVEL, 2, cout << ":\n"; ); if((position != oldPosition) && (oldPosition < position)) { (splitted).push_back( inputText.substr(oldPosition, (position - oldPosition))); } oldPosition = position + 1; } return splitted; } vector < string > new_split(const string& inputText, const string& characters) { vector < string > splitted; #if 0 // this is the original split definition, which I think may be inefficient // I will instead try a more efficient way of doing things. string::size_type position = 0, oldPosition = 0; vector < string > splitted; unsigned int length = inputText.length(); while (position < length) { position = inputText.find_first_of(characters, oldPosition); if (position == string::npos) position = inputText.length(); ODEBUG(DEBUG_LOWLEVEL, 2, cout << inputText.substr(oldPosition, (position - oldPosition)); ); ODEBUG(DEBUG_LOWLEVEL, 2, cout << ":\n"; ); (splitted).push_back( inputText.substr(oldPosition, (position - oldPosition))); oldPosition = position + 1; } return splitted; // this is the new way // build a set set < char > charSet; string::size_type charPos = 0; string::size_type charLen = characters.length(); while (charPos < charLen) { charSet.insert(characters[charPos]); charPos++; } string::size_type position = 0; string::size_type length = inputText.length(); vector < string > splitted; bool inDividingChar = true; while (position < length) { if (!inDividingChar) { if (charSet.find(inputText[position]) != charSet.end()) { inDividingChar = true; } } if (charSet.find(inputText[position]) == charSet.end()) { if (inDividingChar) { splitted.push_back(string("", 20)); } inDividingChar = false; splitted.back() += inputText[position]; } position++; } return splitted; #endif return splitted; } void chop(string* input) { string::iterator p = input->end(); if (p != input->begin()) --p; input->erase(p); } void chomp(string* input) { size_t i; i = input->length() - 1; if (i >= 0) { if ( ((*input)[i] == '\n' ) || ((*input)[i] == '\r')) { input->erase(i, 1); } } } string str2lower(string str) { unsigned int i = 0; unsigned int size = str.size(); while (i < size) { str[i] = tolower(str[i]); i++; } return str; } string c2lower_s(const char* cstr) { string str; // unsigned int i = 0; while (cstr && *cstr) { str += tolower(*cstr); cstr++; } return str; } int matchString(string a, string regex) { regex_t re; int status; if ((status = regcomp( &re, regex.c_str(), REG_EXTENDED)) != 0) return (status); status = regexec( &re, a.c_str(), 0, NULL, 0); regfree(&re); return (status); } bool stringToInt ( const string& s, int *num) { /// skipping spaces in the front // string::size_type position = 0; // position = s.find_first_not_of(string(" "), 0); int position = 0; int i, j; for (i = 0, j = s.length(); i < j; i++) { if (s[i] != ' ') { position = i; break; } } /// convert the string to integer char ch; int value = 0; for (i = position, j = s.length(); i < j; i++) { ch = s[i]; if ( (ch >= '0') && (ch <= '9') ) value = atoi(&ch) + value * 10; else if ( ch == ' ' ) break; /// a whole number is read else return (false); /// illegal char, not a digit or space } *num = value; return (true); } bool getRange( const string& s, int* start, int* end, bool* isRange) { /// initialize all possible returns *start = 0; *end = 0; *isRange = false; /// split the range into two integers, assuming the numbers /// are separeted by '-'. // deque test_1_vector; //sub_split_t test_1_vector; split_t test_1_vector; // string myStr(s.str()); //test_1_vector = sub_split(myStr, "-"); test_1_vector = split( s, "-"); /// read in the first integer if any if (test_1_vector.size() >= 1 ) { if (!stringToInt( test_1_vector[0], start)) // if (true), a valid integer is read into start variable return (false); // first number is not a valid integer } else return (false); // no data in the input string at all /// read in the second integer if any if (test_1_vector.size() >= 2 ) { if (stringToInt( test_1_vector[1], end)) // if (true), a valid second integer is read into end variable { if (*start <= *end ) *isRange = true; // got a valid range else return (false); // range is not valid, larger number went first } else return (false); // second number after '-' is not valid, ignore the range } return (true); // success in getting one or two valid integers from string } // Data convertToHex(const unsigned char* src, int len) { Data data; unsigned char temp; //convert to hex. int i; //int j = 0; for (i = 0; i < len; i++) { temp = src[i]; int hi = (temp & 0xf0) / 16; int low = (temp & 0xf); char buf[5]; buf[0] = '\0'; assert(hi >= 0); assert(hi < 16); assert(low >= 0); assert(low < 16); sprintf(buf, "%1.1x%1.1x", hi, low); data += buf; } #if 0 //Change to 1 if needed for debugging cpLog(LOG_DEBUG, "convertToHex, value is: %s", data.logData()); #endif return data; } int convertToUnsigned(const Data& data, unsigned char* dest) { int len = data.length(); data.getData(reinterpret_cast(dest), len+1); dest[len] = '\0'; //convert and return the length of dest. cpLog(LOG_DEBUG, "orig value string: %s", data.logData()); cpLog(LOG_DEBUG, "orig value hex: %s", convertToHex(dest, len).logData()); cpLog(LOG_DEBUG, "convertToUnsigned, length is %d, value is : %s", len, dest); return len; }