00001 // Copyright 2009-2015 Sandia Corporation. Under the terms 00002 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. 00003 // Government retains certain rights in this software. 00004 // 00005 // Copyright (c) 2009-2015, Sandia Corporation 00006 // All rights reserved. 00007 // 00008 // This file is part of the SST software package. For license 00009 // information, see the LICENSE file in the top level directory of the 00010 // distribution. 00011 00012 #ifndef SST_CORE_LINKMAP_H 00013 #define SST_CORE_LINKMAP_H 00014 00015 #include <sst/core/sst_types.h> 00016 #include <sst/core/serialization.h> 00017 00018 #include <string> 00019 #include <map> 00020 00021 #include <sst/core/component.h> 00022 #include <sst/core/link.h> 00023 00024 namespace SST { 00025 00026 /** 00027 * Maps port names to the Links that are connected to it 00028 */ 00029 class LinkMap { 00030 00031 private: 00032 std::map<std::string,Link*> linkMap; 00033 const std::vector<std::string> * allowedPorts; 00034 std::vector<std::string> selfPorts; 00035 00036 // bool checkPort(const char *def, const char *offered) const 00037 // { 00038 // const char * x = def; 00039 // const char * y = offered; 00040 00041 // /* Special case. Name of '*' matches everything */ 00042 // if ( *x == '*' && *(x+1) == '\0' ) return true; 00043 00044 // do { 00045 // if ( *x == '%' && (*(x+1) == '(' || *(x+1) == 'd') ) { 00046 // // We have a %d or %(var)d to eat 00047 // x++; 00048 // if ( *x == '(' ) { 00049 // while ( *x && (*x != ')') ) x++; 00050 // x++; /* *x should now == 'd' */ 00051 // } 00052 // if ( *x != 'd') /* Malformed string. Fail all the things */ 00053 // return false; 00054 // x++; /* Finish eating the variable */ 00055 // /* Now, eat the corresponding digits of y */ 00056 // while ( *y && isdigit(*y) ) y++; 00057 // } 00058 // if ( *x != *y ) return false; 00059 // if ( *x == '\0' ) return true; 00060 // x++; 00061 // y++; 00062 // } while ( *x && *y ); 00063 // if ( *x != *y ) return false; // aka, both NULL 00064 // return true; 00065 // } 00066 00067 // bool checkPort(const std::string &name) const 00068 // { 00069 // // First check to see if this is a self port 00070 // for ( std::vector<std::string>::const_iterator i = selfPorts.begin() ; i != selfPorts.end() ; ++i ) { 00071 // /* Compare name with stored name, which may have wildcards */ 00072 // // if ( checkPort(i->c_str(), x) ) { 00073 // if ( name == *i ) { 00074 // return true; 00075 // } 00076 // } 00077 00078 // // If no a self port, check against info in library manifest 00079 // Component::isValidPortForComponent( 00080 // const char *x = name.c_str(); 00081 // bool found = false; 00082 // if ( NULL != allowedPorts ) { 00083 // for ( std::vector<std::string>::const_iterator i = allowedPorts->begin() ; i != allowedPorts->end() ; ++i ) { 00084 // /* Compare name with stored name, which may have wildcards */ 00085 // if ( checkPort(i->c_str(), x) ) { 00086 // found = true; 00087 // break; 00088 // } 00089 // } 00090 // } 00091 // return found; 00092 // } 00093 00094 // bool checkPort(const std::string &name) const 00095 // { 00096 // const char *x = name.c_str(); 00097 // bool found = false; 00098 // if ( NULL != allowedPorts ) { 00099 // for ( std::vector<std::string>::const_iterator i = allowedPorts->begin() ; i != allowedPorts->end() ; ++i ) { 00100 // /* Compare name with stored name, which may have wildcards */ 00101 // if ( checkPort(i->c_str(), x) ) { 00102 // found = true; 00103 // break; 00104 // } 00105 // } 00106 // } 00107 00108 // if ( !found ) { // Check self ports 00109 // for ( std::vector<std::string>::const_iterator i = selfPorts.begin() ; i != selfPorts.end() ; ++i ) { 00110 // /* Compare name with stored name, which may have wildcards */ 00111 // // if ( checkPort(i->c_str(), x) ) { 00112 // if ( name == *i ) { 00113 // found = true; 00114 // break; 00115 // } 00116 // } 00117 // } 00118 00119 // return found; 00120 // } 00121 00122 public: 00123 LinkMap() : allowedPorts(NULL) {} 00124 ~LinkMap() { 00125 // Delete all the links in the map 00126 for ( std::map<std::string,Link*>::iterator it = linkMap.begin(); it != linkMap.end(); ++it ) { 00127 delete it->second; 00128 } 00129 linkMap.clear(); 00130 } 00131 00132 /** 00133 * Set the list of allowed port names from the ElementInfoPort 00134 */ 00135 void setAllowedPorts(const std::vector<std::string> *p) 00136 { 00137 allowedPorts = p; 00138 } 00139 00140 /** 00141 * Add a port name to the list of allowed ports. 00142 * Used by SelfLinks, as these are undocumented. 00143 */ 00144 void addSelfPort(std::string& name) 00145 { 00146 selfPorts.push_back(name); 00147 } 00148 00149 bool isSelfPort(const std::string& name) const { 00150 for ( std::vector<std::string>::const_iterator i = selfPorts.begin() ; i != selfPorts.end() ; ++i ) { 00151 /* Compare name with stored name, which may have wildcards */ 00152 // if ( checkPort(i->c_str(), x) ) { 00153 if ( name == *i ) { 00154 return true; 00155 } 00156 } 00157 return false; 00158 } 00159 00160 /** Inserts a new pair of name and link into the map */ 00161 void insertLink(std::string name, Link* link) { 00162 linkMap.insert(std::pair<std::string,Link*>(name,link)); 00163 } 00164 00165 /** Returns a Link pointer for a given name */ 00166 Link* getLink(std::string name) { 00167 // if ( !checkPort(name) ) { 00168 // #ifdef USE_PARAM_WARNINGS 00169 // std::cerr << "Warning: Using undocumented port '" << name << "'." << std::endl; 00170 // #endif 00171 // } 00172 std::map<std::string,Link*>::iterator it = linkMap.find(name); 00173 if ( it == linkMap.end() ) return NULL; 00174 else return it->second; 00175 } 00176 00177 /** 00178 Checks to see if LinkMap is empty. 00179 @return True if Link map is empty, false otherwise 00180 */ 00181 bool empty() { 00182 return linkMap.empty(); 00183 } 00184 00185 // FIXME: Cludge for now, fix later. Need to make LinkMap look 00186 // like a regular map instead. 00187 /** Return a reference to the internal map */ 00188 std::map<std::string,Link*>& getLinkMap() { 00189 return linkMap; 00190 } 00191 00192 friend class boost::serialization::access; 00193 /** Serialize LinkMap */ 00194 template<class Archive> 00195 void serialize(Archive & ar, const unsigned int version ) 00196 { 00197 ar & BOOST_SERIALIZATION_NVP(linkMap); 00198 } 00199 }; 00200 00201 } // namespace SST 00202 00203 BOOST_CLASS_EXPORT_KEY(SST::LinkMap) 00204 00205 #endif // SST_CORE_LINKMAP_H