support.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:16k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. static const char* const support_cxx_Version =
  51.     "$Id: support.cxx,v 1.43 2001/06/27 01:43:45 bko Exp $";
  52. #include "support.hxx"
  53. #ifdef __FreeBSD__
  54. #include <sys/types.h>
  55. #endif
  56. #ifndef WIN32
  57. #include <regex.h>
  58. #else
  59. #include "StdAfx.h"
  60. #define __STDC__ 1
  61. extern "C" {
  62. #include <regex.h>
  63. }
  64. #include <iostream>
  65. #endif
  66. #include "debug.h"
  67. #include <set>
  68. #include "cpLog.h"
  69. /**********************************************************************
  70.  
  71. Support functions for the MGCP library.
  72.  
  73. **********************************************************************/
  74. bool isIn(char ch, const string& charlist)
  75. {
  76.     string::size_type pos = charlist.find_first_of(ch);
  77.     if (pos != string::npos)
  78.     {
  79.         return true;
  80.     }
  81.     else
  82.     {
  83.         return false;
  84.     }
  85. }
  86. substring
  87. paren_match(const string& inputText)
  88. {
  89.     // create a substring from inputText and call it
  90.     substring subInputText(&inputText, 0, inputText.length());
  91.     return paren_match(subInputText);
  92. }
  93. substring
  94. paren_match(const substring& inputText)
  95. {
  96.     string::size_type position = 0, firstParenLocation = string::npos;
  97.     bool foundFirstParen = false;
  98.     int parenCount = 0;
  99.     while (
  100.         position < inputText.length()
  101.         && !(foundFirstParen && (parenCount == 0))
  102.     )
  103.     {
  104.         // scan for the first paren
  105.         char currentChar = const_cast < substring& > (inputText)[position];
  106.         if (currentChar == '(')
  107.         {
  108.             if (!foundFirstParen)
  109.             {
  110.                 foundFirstParen = true;
  111.                 firstParenLocation = position;
  112.             }
  113.             parenCount++;
  114.         }
  115.         else if (currentChar == ')')
  116.         {
  117.             if (foundFirstParen)
  118.             {
  119.                 parenCount--;
  120.             }
  121.         }
  122.         position++;
  123.     }
  124.     if (foundFirstParen && (parenCount == 0))
  125.     {
  126.         // in this case, create a substring based on this one
  127.         ODEBUG(DEBUG_LOWLEVEL, 2, cout << ":" << inputText.str().substr(firstParenLocation + 1, (position - firstParenLocation - 2)) << ":n"; );
  128.         substring retVal(inputText, firstParenLocation + 1, position - firstParenLocation - 2);
  129.         return retVal;
  130.     }
  131.     else
  132.     {
  133.         // in this case, it is an error
  134.         cerr << "could not match the string" << endl;
  135.         if (firstParenLocation != string::npos)
  136.         {
  137.             substring errVal(inputText, firstParenLocation, inputText.length() - firstParenLocation);
  138.             cerr << "string: " << errVal << endl;
  139.         }
  140.         return substring();
  141.     }
  142.     return substring();
  143. }
  144. string
  145. str_paren_match(const string& inputText)
  146. {
  147.     // create a substring from inputText and call it
  148.     substring subInputText(&inputText, 0, inputText.length());
  149.     string matched = (paren_match(subInputText)).str();
  150.     return( matched );
  151. }
  152. sub_split_t
  153. sub_split_paren_match(const string& inputText, const string& characters)
  154. {
  155.     string::size_type position = 0, oldPosition = 0;
  156.     sub_split_t splitted;
  157.     unsigned int length = inputText.length();
  158.     while (position < length)
  159.     {
  160.         // the code must loop through the entire text to make sure it
  161.         // matches parentheses
  162.         int parenCount = 0;
  163.         while ((position < length)
  164.                 && !(isIn(inputText[position], characters) && (parenCount == 0))
  165.               )
  166.         {
  167.             char currentChar = inputText[position];
  168.             if (currentChar == '(')
  169.             {
  170.                 parenCount++;
  171.             }
  172.             if (currentChar == ')')
  173.             {
  174.                 parenCount--;
  175.             }
  176.             position++;
  177.         }
  178.         if (position == string::npos)
  179.             position = inputText.length();
  180.         if (parenCount != 0)
  181.         {
  182.             // we reached the end without balanced parentheses -- mark as an
  183.             // error and continue
  184.             cerr << "this is an error" << endl;
  185.         }
  186.         ODEBUG(DEBUG_LOWLEVEL, 2, cout << inputText.substr(oldPosition, (position - oldPosition)); );
  187.         ODEBUG(DEBUG_LOWLEVEL, 2, cout << ":n"; );
  188.         (splitted).push_back(
  189.             substring(
  190.                 &inputText, oldPosition, (position - oldPosition))
  191.         );
  192.         oldPosition = inputText.find_first_not_of(characters, position);
  193.         if (oldPosition == string::npos)
  194.             oldPosition = inputText.length();
  195.         position = oldPosition;
  196.     }
  197.     ODEBUG(DEBUG_LOWLEVEL, 2, cout << "number of lines: " << splitted.size() << endl; );
  198.     return splitted;
  199. }
  200. split_t
  201. split_paren_match(const string& inputText, const string& characters)
  202. {
  203.     string::size_type position = 0, oldPosition = 0;
  204.     split_t splitted;
  205.     unsigned int length = inputText.length();
  206.     while (position < length)
  207.     {
  208.         // the code must loop through the entire text to make sure it
  209.         // matches parentheses
  210.         int parenCount = 0;
  211.         while ((position < length)
  212.                 && !(isIn(inputText[position], characters) && (parenCount == 0))
  213.               )
  214.         {
  215.             char currentChar = inputText[position];
  216.             if (currentChar == '(')
  217.             {
  218.                 parenCount++;
  219.             }
  220.             if (currentChar == ')')
  221.             {
  222.                 parenCount--;
  223.             }
  224.             position++;
  225.         }
  226.         if (position == string::npos)
  227.             position = inputText.length();
  228.         if (parenCount != 0)
  229.         {
  230.             // we reached the end without balanced parentheses -- mark as an
  231.             // error and continue
  232.             cerr << "this is an error" << endl;
  233.         }
  234.         ODEBUG(DEBUG_LOWLEVEL, 2, cout << inputText.substr(oldPosition, (position - oldPosition)); );
  235.         ODEBUG(DEBUG_LOWLEVEL, 2, cout << ":n"; );
  236. if((position != oldPosition) && (oldPosition < position))
  237.         {      
  238.     (splitted).push_back(
  239.                 inputText.substr( oldPosition, (position - oldPosition)));
  240. }
  241.         oldPosition = inputText.find_first_not_of(characters, position);
  242.         if (oldPosition == string::npos)
  243.             oldPosition = inputText.length();
  244.         position = oldPosition;
  245.     }
  246.     ODEBUG(DEBUG_LOWLEVEL, 2, cout << "number of lines: " << splitted.size() << endl; );
  247.     return splitted;
  248. }
  249. sub_split_t sub_split(const string& inputText, const string& characters)
  250. {
  251.     string::size_type position = 0, oldPosition = 0;
  252.     sub_split_t splitted;
  253.     unsigned int length = inputText.length();
  254.     while (position < length)
  255.     {
  256.         position = inputText.find_first_of(characters, oldPosition);
  257.         // advance forward and eat all characters of type characters
  258.         if (position == string::npos)
  259.             position = inputText.length();
  260.         ODEBUG(DEBUG_LOWLEVEL, 2, cout << inputText.substr(oldPosition, (position - oldPosition)); );
  261.         ODEBUG(DEBUG_LOWLEVEL, 2, cout << ":n"; );
  262.         (splitted).push_back(
  263.             substring(
  264.                 &inputText, oldPosition, (position - oldPosition))
  265.         );
  266.         oldPosition = inputText.find_first_not_of(characters, position);
  267.         if (oldPosition == string::npos)
  268.             oldPosition = inputText.length();
  269.         position = oldPosition;
  270.     }
  271.     ODEBUG(DEBUG_LOWLEVEL, 2, cout << "number of lines: " << splitted.size() << endl; );
  272.     return splitted;
  273. }
  274. split_t split(const string& inputText, const string& characters)
  275. {
  276.     // this is the original split definition, which I think may be inefficient
  277.     // I will instead try a more efficient way of doing things.
  278.     string::size_type position = 0, oldPosition = 0;
  279.     split_t splitted;
  280.     unsigned int length = inputText.length();
  281.     while (position < length)
  282.     {
  283.         position = inputText.find_first_of(characters, oldPosition);
  284.         if (position == string::npos)
  285.             position = inputText.length();
  286.         ODEBUG(DEBUG_LOWLEVEL, 2, cout << inputText.substr(oldPosition, (position - oldPosition)); );
  287.         ODEBUG(DEBUG_LOWLEVEL, 2, cout << ":n"; );
  288.         if((position != oldPosition) && (oldPosition < position))
  289.         {      
  290.             (splitted).push_back(
  291.                 inputText.substr(oldPosition, (position - oldPosition)));
  292.         }
  293.         oldPosition = position + 1;
  294.     }
  295.     return splitted;
  296. }
  297. vector < string > new_split(const string& inputText, const string& characters)
  298. {
  299.     vector < string > splitted;
  300. #if 0
  301.     // this is the original split definition, which I think may be inefficient
  302.     // I will instead try a more efficient way of doing things.
  303.     string::size_type position = 0, oldPosition = 0;
  304.     vector < string > splitted;
  305.     unsigned int length = inputText.length();
  306.     while (position < length)
  307.     {
  308.         position = inputText.find_first_of(characters, oldPosition);
  309.         if (position == string::npos)
  310.             position = inputText.length();
  311.         ODEBUG(DEBUG_LOWLEVEL, 2, cout << inputText.substr(oldPosition, (position - oldPosition)); );
  312.         ODEBUG(DEBUG_LOWLEVEL, 2, cout << ":n"; );
  313.         (splitted).push_back(
  314.             inputText.substr(oldPosition, (position - oldPosition)));
  315.         oldPosition = position + 1;
  316.     }
  317.     return splitted;
  318.     // this is the new way
  319.     // build a set
  320.     set < char > charSet;
  321.     string::size_type charPos = 0;
  322.     string::size_type charLen = characters.length();
  323.     while (charPos < charLen)
  324.     {
  325.         charSet.insert(characters[charPos]);
  326.         charPos++;
  327.     }
  328.     string::size_type position = 0;
  329.     string::size_type length = inputText.length();
  330.     vector < string > splitted;
  331.     bool inDividingChar = true;
  332.     while (position < length)
  333.     {
  334.         if (!inDividingChar)
  335.         {
  336.             if (charSet.find(inputText[position]) != charSet.end())
  337.             {
  338.                 inDividingChar = true;
  339.             }
  340.         }
  341.         if (charSet.find(inputText[position]) == charSet.end())
  342.         {
  343.             if (inDividingChar)
  344.             {
  345.                 splitted.push_back(string("", 20));
  346.             }
  347.             inDividingChar = false;
  348.             splitted.back() += inputText[position];
  349.         }
  350.         position++;
  351.     }
  352.     return splitted;
  353. #endif 
  354.     return splitted;
  355. }
  356. void chop(string* input)
  357. {
  358.     string::iterator p = input->end();
  359.     if (p != input->begin())
  360.         --p;
  361.     input->erase(p);
  362. }
  363. void chomp(string* input)
  364. {
  365.     size_t i;
  366.     i = input->length() - 1;
  367.     if (i >= 0)
  368.     {
  369.         if ( ((*input)[i] == 'n' ) ||
  370.                 ((*input)[i] == 'r'))
  371.         {
  372.             input->erase(i, 1);
  373.         }
  374.     }
  375. }
  376. string str2lower(string str)
  377. {
  378.     unsigned int i = 0;
  379.     unsigned int size = str.size();
  380.     while (i < size)
  381.     {
  382.         str[i] = tolower(str[i]);
  383.         i++;
  384.     }
  385.     return str;
  386. }
  387. string c2lower_s(const char* cstr)
  388. {
  389.     string str;
  390.     //    unsigned int i = 0;
  391.     while (cstr && *cstr)
  392.     {
  393.         str += tolower(*cstr);
  394.         cstr++;
  395.     }
  396.     return str;
  397. }
  398. int matchString(string a, string regex)
  399. {
  400.     regex_t re;
  401.     int status;
  402.     if ((status = regcomp( &re, regex.c_str(), REG_EXTENDED)) != 0)
  403.         return (status);
  404.     status = regexec( &re, a.c_str(), 0, NULL, 0);
  405.     regfree(&re);
  406.     return (status);
  407. }
  408. bool stringToInt ( const string& s, int *num)
  409. {
  410.     /// skipping spaces in the front
  411.     //   string::size_type position = 0;
  412.     //  position = s.find_first_not_of(string(" "), 0);
  413.     int position = 0;
  414.     for (int i = 0, j = s.length(); i < j; i++)
  415.     {
  416.         if (s[i] != ' ')
  417.         {
  418.             position = i;
  419.             break;
  420.         }
  421.     }
  422.     /// convert the string to integer
  423.     char ch;
  424.     int value = 0;
  425. #ifndef WIN32
  426.     for (int i = position, j = s.length(); i < j; i++)
  427.     {
  428.         ch = s[i];
  429. #else
  430. for (int iIndex = position,  jIndex= s.length(); iIndex < jIndex; iIndex++)
  431. {
  432. ch = s[iIndex];
  433. #endif
  434.         if ( (ch >= '0') && (ch <= '9') )
  435.             value = atoi(&ch) + value * 10;
  436.         else if ( ch == ' ' )
  437.             break;   /// a whole number is read
  438.         else
  439.             return (false);   /// illegal char, not a digit or space
  440.     }
  441.     *num = value;
  442.     return (true);
  443. }
  444. bool getRange( const string& s, int* start, int* end, bool* isRange)
  445. {
  446.     /// initialize all possible returns
  447.     *start = 0;
  448.     *end = 0;
  449.     *isRange = false;
  450.     /// split the range into two integers, assuming the numbers
  451.     /// are separeted by '-'.
  452.     // deque<string> test_1_vector;
  453.     //sub_split_t test_1_vector;
  454.     split_t test_1_vector;
  455.     // string myStr(s.str());
  456.     //test_1_vector = sub_split(myStr, "-");
  457.     test_1_vector = split( s, "-");
  458.     /// read in the first integer if any
  459.     if (test_1_vector.size() >= 1 )
  460.     {
  461.         if (!stringToInt( test_1_vector[0], start))  // if (true), a valid integer is read into start variable
  462.             return (false);  // first number is not a valid integer
  463.     }
  464.     else
  465.         return (false);   // no data in the input string at all
  466.     /// read in the second integer if any
  467.     if (test_1_vector.size() >= 2 )
  468.     {
  469.         if (stringToInt( test_1_vector[1], end))  // if (true), a valid second integer is read into end variable
  470.         {
  471.             if (*start <= *end )
  472.                 *isRange = true;   // got a valid range
  473.             else
  474.                 return (false);   // range is not valid, larger number went first
  475.         }
  476.         else
  477.             return (false);   // second number after '-' is not valid, ignore the range
  478.     }
  479.     return (true);  // success in getting one or two valid integers from string
  480. }
  481. //
  482. Data convertToHex(const unsigned char* src, int len)
  483. {
  484.     Data data;
  485.     unsigned char temp;
  486.     //convert to hex.
  487.     int i;
  488.     //int j = 0;
  489.     for (i = 0; i < len; i++)
  490.     {
  491.         temp = src[i];
  492.         int hi = (temp & 0xf0) / 16;
  493.         int low = (temp & 0xf);
  494.         char buf[4];
  495.         buf[0] = '';
  496.         sprintf(buf, "%x%x", hi, low);
  497.         data += buf;
  498.     }
  499. #if 0  //Change to 1 if needed for debugging
  500.     cpLog(LOG_DEBUG, "convertToHex, value is: %s", data.getData());
  501. #endif
  502.     return data;
  503. }
  504. int convertToUnsigned(const Data& data, unsigned char* dest)
  505. {
  506.     int len = data.length();
  507.     memcpy(dest, data.getData(), len);
  508.     dest[len] = '';
  509.     //convert and return the length of dest.
  510.     cpLog(LOG_DEBUG, "orig value string: %s", data.getData());
  511.     cpLog(LOG_DEBUG, "orig value hex:    %s", convertToHex(dest, len).getData());
  512.     cpLog(LOG_DEBUG, "convertToUnsigned, length is %d, value is : %s", len, dest);
  513.     return len;
  514. }