Reducing header overuse, non-inlining selected methods (CPPOST-35).
[shibboleth/cpp-xmltooling.git] / xmltooling / util / TemplateEngine.cpp
index 22881e3..4062fca 100644 (file)
  */
 
 #include "internal.h"
+#include "io/GenericRequest.h"
 #include "util/TemplateEngine.h"
 
 using namespace xmltooling;
 using namespace std;
 
+namespace {
+    static const pair<const string,string> emptyPair;
+}
+
+const char* TemplateEngine::TemplateParameters::getParameter(const char* name) const
+{
+    map<string,string>::const_iterator i=m_map.find(name);
+    return (i!=m_map.end() ? i->second.c_str() : (m_request ? m_request->getParameter(name) : NULL));
+}
+
+const multimap<string,string>* TemplateEngine::TemplateParameters::getLoopCollection(const char* name) const
+{
+    map< string,multimap<string,string> >::const_iterator i=m_collectionMap.find(name);
+    return (i!=m_collectionMap.end() ? &(i->second) : NULL);
+}
+
 void TemplateEngine::setTagPrefix(const char* tagPrefix)
 {
     keytag = string("<") + tagPrefix + " ";
@@ -94,6 +111,7 @@ void TemplateEngine::process(
     const char*& lastpos,
     ostream& os,
     const TemplateParameters& parameters,
+    const std::pair<const std::string,std::string>& loopentry,
     const XMLToolingException* e
     ) const
 {
@@ -120,11 +138,17 @@ void TemplateEngine::process(
                 string key = buf.substr(lastpos-line, thispos-lastpos);
                 trimspace(key);
 
-                const char* p = parameters.getParameter(key.c_str());
-                if (!p && e)
-                    p = e->getProperty(key.c_str());
-                if (p)
-                    html_encode(os,p);
+                if (key == "$name" && !loopentry.first.empty())
+                    html_encode(os,loopentry.first.c_str());
+                else if (key == "$value" && !loopentry.second.empty())
+                    html_encode(os,loopentry.second.c_str());
+                else {
+                    const char* p = parameters.getParameter(key.c_str());
+                    if (!p && e)
+                        p = e->getProperty(key.c_str());
+                    if (p)
+                        html_encode(os,p);
+                }
                 lastpos = thispos + 2; // strlen("/>")
             }
         }
@@ -145,7 +169,7 @@ void TemplateEngine::process(
                 if (visible)
                     cond = parameters.getParameter(key.c_str()) || (e && e->getProperty(key.c_str()));
                 lastpos = thispos + 1; // strlen(">")
-                process(cond, buf, lastpos, os, parameters, e);
+                process(cond, buf, lastpos, os, parameters, loopentry, e);
             }
         }
 #ifdef HAVE_STRCASECMP
@@ -175,7 +199,7 @@ void TemplateEngine::process(
                 if (visible)
                     cond = !(parameters.getParameter(key.c_str()) || (e && e->getProperty(key.c_str())));
                 lastpos = thispos + 1; // strlen(">")
-                process(cond, buf, lastpos, os, parameters, e);
+                process(cond, buf, lastpos, os, parameters, loopentry, e);
             }
         }
 #ifdef HAVE_STRCASECMP
@@ -206,22 +230,18 @@ void TemplateEngine::process(
                 trimspace(key);
                 lastpos = thispos + 1; // strlen(">")
             }
-            const vector<xmltooling::TemplateEngine::TemplateParameters> forParams = parameters.getParameterCollection(key.c_str());
 
-            unsigned int forend = forParams.size();
-            if (forend==0) {  // have to go through at least once to match end tags
-               cond = false;
-               forend = 1;
+            const multimap<string,string>* forParams = parameters.getLoopCollection(key.c_str());
+            if (!forParams || forParams->size() == 0) {
+                process(false, buf, lastpos, os, parameters, emptyPair, e);
             }
-
-            const char *savlastpos = lastpos;
-            for (unsigned int i=0; i<forend; i++ ) {
-                const TemplateParameters nullp;
-                const TemplateParameters* tp = forParams.size()>0? static_cast<const TemplateParameters*>(&forParams[i]): &nullp;
-                lastpos = savlastpos;
-                process(cond, buf, lastpos, os, *tp, e);
+            else {
+                const char* savlastpos = lastpos;
+                for (multimap<string,string>::const_iterator i=forParams->begin(); i!=forParams->end(); ++i) {
+                    lastpos = savlastpos;
+                    process(cond, buf, lastpos, os, parameters, *i, e);
+                }
             }
-
         }
 
 #ifdef HAVE_STRCASECMP
@@ -253,5 +273,5 @@ void TemplateEngine::run(istream& is, ostream& os, const TemplateParameters& par
         buf += line + '\n';
 
     const char* pos=buf.c_str();
-    process(true, buf, pos, os, parameters, e);
+    process(true, buf, pos, os, parameters, emptyPair, e);
 }