contrib/mul/mmn/mmn_parse_arcs.cxx
Go to the documentation of this file.
00001 
00002 //:
00003 // \file
00004 // \brief Parse in a set of arc definitions using names of nodes
00005 // \author Martin Roberts
00006 
00007 #include "mmn_parse_arcs.h"
00008 #include <mbl/mbl_exception.h>
00009 #include <mbl/mbl_parse_block.h>
00010 #include <vcl_sstream.h>
00011 #include <vcl_map.h>
00012 #include <vcl_iostream.h>
00013 #include <vcl_iterator.h>
00014 #include <vcl_algorithm.h>
00015 
00016 
00017 void  mmn_parse_arcs(vcl_istream& is,
00018                      const vcl_vector<vcl_string>& node_names,
00019                      vcl_vector<mmn_arc>& arcs)
00020 {
00021     //First convert node_names to numbers
00022     vcl_map<vcl_string,unsigned> nodeMap;
00023     vcl_vector<vcl_string>::const_iterator nodeIter=node_names.begin();
00024     vcl_vector<vcl_string>::const_iterator nodeIterEnd=node_names.end();
00025     unsigned id=0;
00026     while(nodeIter != nodeIterEnd)
00027     {
00028         nodeMap[*nodeIter++]=id++;
00029     }
00030 
00031     vcl_string s = mbl_parse_block(is);
00032     vcl_istringstream ss(s);
00033     char c;
00034     ss>>c;  // Remove opening brace
00035     if (c!='{')
00036     {
00037         throw mbl_exception_parse_error("Expected '{' in mmn_parse_arcs");
00038     }
00039   
00040     arcs.clear();
00041     vcl_string arcLabel("arc:");
00042     //Loop over each arc in the stream
00043     while (!ss.eof())
00044     {
00045         //Locate the next "arc:" keyword
00046         if(vcl_find(vcl_istream_iterator<vcl_string>(ss),
00047                     vcl_istream_iterator<vcl_string>(),arcLabel) == 
00048            vcl_istream_iterator<vcl_string>())
00049         {
00050             //No more arc: labels to be processed
00051             break;
00052         }
00053         if(ss.bad())
00054         {
00055             vcl_string error_msg = "Stream error parsing arcs block\n";
00056             throw mbl_exception_parse_error(error_msg);
00057         }
00058 
00059         //we have read to just past the next "arc:" label
00060         vcl_string strNodePair=mbl_parse_block(ss);
00061         vcl_istringstream ssArc(strNodePair); //stream for just this arc
00062 
00063         //Now reduce this line/block into 4 tokens for { name1 name2 }
00064         //Note this assumes white space separators
00065         vcl_vector<vcl_string> tokens;
00066         vcl_copy(vcl_istream_iterator<vcl_string>(ssArc),
00067                  vcl_istream_iterator<vcl_string>(),
00068                  vcl_back_inserter(tokens));
00069         if(ssArc.bad())
00070         {
00071             vcl_string error_msg = "Stream error processing line "+strNodePair;
00072             throw mbl_exception_parse_error(error_msg);
00073         }
00074         if(tokens.size() != 4)
00075         {
00076             vcl_string error_msg = "Expected format is 4 tokens: { name1 name 2 }\n";
00077             error_msg+= " Got "+strNodePair;
00078             throw mbl_exception_parse_error(error_msg);
00079         }
00080         if(tokens[0] != "{" || tokens[3] != "}")
00081         {
00082             vcl_string error_msg = "Expected format is 4 tokens : { name1 name2 }\n";
00083             error_msg+= " Missing a (separated?) curly bracket in  "+strNodePair;
00084             throw mbl_exception_parse_error(error_msg);
00085         }
00086 
00087         //Seems to validate
00088         vcl_string node1=tokens[1];
00089         vcl_string node2=tokens[2];
00090 
00091         //Find the numeric IDs of these nodes
00092         vcl_map<vcl_string,unsigned>::const_iterator nodeIter1=nodeMap.find(node1);
00093         if(nodeIter1 == nodeMap.end())
00094         {
00095             vcl_string error_msg = "Node name "+node1+" is not in the list of nodes for arc\n";
00096             error_msg+= strNodePair;
00097             throw mbl_exception_parse_error(error_msg);
00098         }
00099 
00100         vcl_map<vcl_string,unsigned>::const_iterator nodeIter2=nodeMap.find(node2);
00101         if(nodeIter2 == nodeMap.end())
00102         {
00103             vcl_string error_msg = "Node name "+node2+" is not in the list of nodes for arc\n";
00104             error_msg+= strNodePair;
00105             throw mbl_exception_parse_error(error_msg);
00106         }
00107         
00108         //Finally add the arc
00109         arcs.push_back(mmn_arc(nodeIter1->second,nodeIter2->second));
00110 
00111     }
00112 }