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

流媒体/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 ParsePair_cxx_Version =
  51.     "$Id: ParsePair.cxx,v 1.10 2001/05/24 04:03:48 icahoon Exp $";
  52. #include "ParsePair.hxx"
  53. #include <cstdio>
  54. #include <cassert>
  55. #include <cstring>
  56. #include <fstream>
  57. #include <strstream>
  58. #include <cctype>
  59. using Vocal::Configuration::ParsePair;
  60. using Vocal::Configuration::Value;
  61. using Vocal::Configuration::NameValueMap;
  62. using Vocal::ReturnCode;
  63. using Vocal::SUCCESS;
  64. using std::string;
  65. using std::ifstream;
  66. using std::istrstream;
  67. const size_t ParsePair::MAX_LINE_LENGTH = 1024;
  68. const size_t ParsePair::MAX_NAME_LENGTH  = 96;
  69. const size_t ParsePair::MAX_VALUE_LENGTH = MAX_LINE_LENGTH - MAX_NAME_LENGTH;
  70. const string ParsePair::SEPARATORS(":= t");
  71. const string ParsePair::COMMENT_CHARS("#!;");
  72. ParsePair::ParsePair()
  73.     :   myTagName("data")
  74. {
  75. }
  76. ParsePair::~ParsePair()
  77. {
  78. }
  79. void
  80. ParsePair::tagName(const string & tag_name)
  81. {
  82.     myTagName = tag_name;
  83. }
  84. ReturnCode              
  85. ParsePair::parse(Type type, const string & s)
  86. {
  87.     ReturnCode rc = !SUCCESS;
  88.     switch ( type )
  89.     {
  90.         case CFG_XML_FILE:
  91.         {
  92.             myFileName = s;
  93.             return ( parseXMLFile() );
  94.         }
  95.         case CFG_XML_STRING:
  96.         {
  97.             return ( parseXMLString(s) );
  98.         }
  99.         case CFG_STRING:
  100.         {
  101.             istrstream  str(s.c_str(), s.size());
  102.             return ( parseStream(str) );
  103.         }
  104.         case CFG_FILE:
  105.         default:
  106.         {
  107.             myFileName = s;
  108.             
  109.             string  xml(".xml");
  110.             size_t  file_name_size = myFileName.size();
  111.             size_t  xml_size = xml.size();
  112.             if (    file_name_size > 4 
  113.                 &&  myFileName.substr(file_name_size - xml_size) == xml
  114.                 )
  115.             {
  116.                 rc = parseXMLFile();
  117.             }
  118.             else
  119.             {
  120.                 rc = parseFile();
  121.             }
  122.         }
  123.     }
  124.     return ( rc );
  125. }
  126. const NameValueMap &
  127. ParsePair::pairs() const
  128. {
  129.     return ( myPairs );
  130. }
  131. ReturnCode          
  132. ParsePair::parseFile()
  133. {
  134.     ifstream     file(myFileName.c_str());
  135.     
  136.     if ( !file.is_open() )
  137.     {
  138.         return ( !SUCCESS );
  139.     }
  140.     ReturnCode rc = parseStream(file);
  141.     file.close();
  142.     
  143.     return ( rc );
  144. }
  145. ReturnCode
  146. ParsePair::parseStream(istream & s)
  147. {
  148.     char    buffer[MAX_LINE_LENGTH];
  149.     memset(buffer, 0, MAX_LINE_LENGTH);
  150.     
  151.     while ( !s.getline(buffer, MAX_LINE_LENGTH).eof() )
  152.     {
  153.         string  line = buffer;
  154.         memset(buffer, 0, MAX_LINE_LENGTH);
  155.         removeWS(line);
  156.         
  157.         if  (   COMMENT_CHARS.find(line[0]) != string::npos
  158.             ||  line.size() == 0 
  159.             )
  160.         {
  161.             continue;
  162.         }
  163.         string newName;
  164.         string newValue;
  165.         size_t  position;
  166.         position = line.find_first_of(SEPARATORS);
  167.         
  168.         if ( position == string::npos )
  169.         {
  170.             Value & val = myPairs[line];
  171.             ++val.count;
  172.             val.type = NO_VALUE;
  173.             continue;
  174.         }
  175.         
  176.         newName = line.substr(0, position);
  177.         line = line.substr(position);
  178.         position = line.find_first_not_of(SEPARATORS);
  179.         
  180.         if ( position == string::npos )
  181.         {
  182.             Value & val = myPairs[newName];
  183.             ++val.count;
  184.             val.type = NO_VALUE;
  185.             continue;
  186.         }
  187.         
  188.         newValue = line.substr(position);
  189.         position = newValue.find_first_of(COMMENT_CHARS);
  190.         
  191.         if ( position != string::npos )
  192.         {
  193.             newValue.erase(position);
  194.             removeTrailingWS(newValue);
  195.         }
  196.         
  197.         Value & val = myPairs[newName];
  198.         ++val.count;
  199.         val.type = VALUE_PRESENT;
  200.         val.value.push_back(newValue);
  201.     }
  202.     
  203.     return ( SUCCESS );
  204. }
  205. ReturnCode          
  206. ParsePair::parseXMLFile()
  207. {
  208.     xmlDocPtr doc = 0;
  209.     doc = xmlParseFile(myFileName.c_str());
  210.     if ( !doc )
  211.     {
  212.         return ( !SUCCESS );
  213.     }
  214.     ReturnCode rc = parseXML(doc);
  215.     
  216.     xmlFreeDoc(doc);
  217.     
  218.     return ( rc );
  219. }
  220. ReturnCode
  221. ParsePair::parseXMLString(const string & s)
  222. {
  223.     xmlDocPtr doc = 0;
  224.     
  225.     doc = xmlParseMemory(const_cast<char *>(s.c_str()), s.size());
  226.     
  227.     if ( !doc )
  228.     {
  229.         return ( !SUCCESS );
  230.     }
  231.     
  232.     ReturnCode rc = parseXML(doc);
  233.     
  234.     xmlFreeDoc(doc);
  235.     
  236.     return ( rc );
  237. }
  238. ReturnCode
  239. ParsePair::parseXML(xmlDocPtr & doc)
  240. {
  241.     xmlNodePtr currentNode = xmlDocGetRootElement(doc);
  242.     
  243.     assert( currentNode != 0 );
  244.     string  name(reinterpret_cast<const char *>(currentNode->name));
  245.     
  246.     while ( name != myTagName )
  247.     {
  248.         currentNode = currentNode->next;
  249.         if ( currentNode == 0 )
  250.         {
  251.             return ( !SUCCESS );
  252.         }
  253.         name = reinterpret_cast<const char *>(currentNode->name);
  254.     }
  255.     assert( currentNode != 0 );
  256.     // step into the configuration data
  257.     //
  258.     for (   currentNode = currentNode->children;
  259.             currentNode != 0; 
  260.             currentNode = currentNode->next 
  261.         )
  262.     {
  263.         if ( currentNode->type != XML_ELEMENT_NODE )
  264.         {
  265.             continue;
  266.         }
  267.         
  268.         name = reinterpret_cast<const char *>(currentNode->name);
  269.         
  270.         const char *  pvalue 
  271.             = reinterpret_cast<const char *>(xmlNodeGetContent(currentNode));
  272.         string value;
  273.         
  274.         if ( pvalue == 0 )
  275.         {
  276.             // We have a name only.
  277.             //
  278.             Value & val = myPairs[name];
  279.             ++val.count;
  280.             val.type = NO_VALUE;
  281.             
  282.             continue;
  283.         }
  284.         
  285.         value = pvalue;
  286.         
  287.         removeWS(value);
  288.         if ( value.size() == 0 )
  289.         {
  290.             // We have a name only.
  291.             //
  292.             Value & val = myPairs[name];
  293.             ++val.count;
  294.             val.type = NO_VALUE;
  295.             
  296.             continue;
  297.         }
  298.                 
  299.         Value & val = myPairs[name];
  300.         ++val.count;
  301.         val.type = VALUE_PRESENT;
  302.         val.value.push_back(value);
  303.         
  304.         currentNode = currentNode->next;
  305.     }
  306.     
  307.     return ( SUCCESS );
  308. }
  309. void
  310. ParsePair::removeWS(string & s)
  311. {
  312.     removeLeadingWS(s);
  313.     removeTrailingWS(s);
  314. }
  315. void
  316. ParsePair::removeLeadingWS(string & s)
  317. {
  318.     string  newS(s);
  319.     size_t  size = newS.size();
  320.     size_t  i;
  321.     bool    found = false;
  322.         
  323.     for ( i = 0; i < size; ++i )
  324.     {
  325.         if ( !isspace(newS[i]) )
  326.         {
  327.             break;
  328.         }
  329.         found = true;
  330.     }
  331.     
  332.     if ( found )
  333.     {
  334.         if ( i < size )
  335.         {
  336.             s = newS.substr(i);
  337.         }
  338.         else
  339.         {
  340.             s.erase();
  341.         }
  342.     }
  343. }
  344. void
  345. ParsePair::removeTrailingWS(string & s)
  346. {
  347.     size_t  size = s.size();
  348.     if ( size == 0 )
  349.     {
  350.         return;
  351.     }
  352.     
  353.     size_t i;
  354.     
  355.     bool found = false;
  356.     
  357.     for ( i = size; i > 0; --i )
  358.     {
  359.         if ( !isspace(s[i-1]) )
  360.         {
  361.             break;
  362.         }
  363.         found = true;
  364.     }
  365.     
  366.     if ( found )
  367.     {
  368.         if ( i > 0 )
  369.         {
  370.             s.erase(i);
  371.         }
  372.         else
  373.         {
  374.             s.erase();
  375.         }
  376.     }
  377. }