Add xsi:nil support to objects.
[shibboleth/xmltooling.git] / xmltooling / exceptions.cpp
index 3b37262..4b15451 100644 (file)
@@ -217,35 +217,63 @@ const char* XMLToolingException::getMessage() const
     return m_processedmsg.c_str();
 }
 
+void xml_encode(string& s, const char* pre, const char* start, const char* post)
+{
+    s += pre;
+    size_t pos;
+    while (start && *start) {
+        pos = strcspn(start, "\"<>&");
+        if (pos > 0) {
+            s.append(start, pos);
+            start += pos;
+        }
+        else {
+            switch (*start) {
+                case '\'':  s += "&apos;";     break;
+                case '<':   s += "&lt;";       break;
+                case '>':   s += "&gt;";       break;
+                case '&':   s += "&amp;";      break;
+                default:    s += *start;
+            }
+            start++;
+        }
+    }
+    s += post;
+}
+
 string XMLToolingException::toString() const
 {
-    string xml=string("<exception xmlns=\"http://www.opensaml.org/xmltooling\" type=\"") + getClassName() + "\">";
+    string xml=string("<exception xmlns='http://www.opensaml.org/xmltooling' type='") + getClassName() + "'>";
     const char* msg=getMessage();
     if (msg)
-        xml=xml + "<message>" + msg + "</message>";
-    for (map<string,string>::const_iterator i=m_params.begin(); i!=m_params.end(); i++)
-        xml=xml + "<param name=\"" + i->first + "\">" + i->second + "</param>";
+        xml_encode(xml, "<message>", msg, "</message>");
+    for (map<string,string>::const_iterator i=m_params.begin(); i!=m_params.end(); i++) {
+        xml_encode(xml, "<param name='", i->first.c_str(), "'");
+        xml_encode(xml, ">", i->second.c_str(), "</param>");
+    }
     xml+="</exception>";
     return xml;
 }
 
 string XMLToolingException::toQueryString() const
 {
+    string q;
     const URLEncoder* enc = XMLToolingConfig::getConfig().getURLEncoder();
-    string q("type=");
-    q = q + enc->encode(getClassName()) + "&message=" + enc->encode(what());
-    for (map<string,string>::const_iterator i=m_params.begin(); i!=m_params.end(); i++)
-        q = q + '&' + i->first + '=' + enc->encode(i->second.c_str());
+    for (map<string,string>::const_iterator i=m_params.begin(); i!=m_params.end(); i++) {
+        if (!q.empty())
+            q += '&';
+        q = q + i->first + '=' + enc->encode(i->second.c_str());
+    }
     return q;
 }
 
 XMLToolingException* XMLToolingException::fromStream(std::istream& in)
 {
-    static const XMLCh exception[] = { chLatin_e, chLatin_x, chLatin_c, chLatin_e, chLatin_p, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull };
-    static const XMLCh message[] = { chLatin_m, chLatin_e, chLatin_s, chLatin_s, chLatin_a, chLatin_g, chLatin_e, chNull };
-    static const XMLCh name[] = { chLatin_n, chLatin_a, chLatin_m, chLatin_e, chNull };
-    static const XMLCh param[] = { chLatin_p, chLatin_a, chLatin_r, chLatin_a, chLatin_m, chNull };
-    static const XMLCh type[] = { chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull };
+    static const XMLCh exception[] =    UNICODE_LITERAL_9(e,x,c,e,p,t,i,o,n);
+    static const XMLCh message[] =      UNICODE_LITERAL_7(m,e,s,s,a,g,e);
+    static const XMLCh name[] =         UNICODE_LITERAL_4(n,a,m,e);
+    static const XMLCh param[] =        UNICODE_LITERAL_5(p,a,r,a,m);
+    static const XMLCh type[] =         UNICODE_LITERAL_4(t,y,p,e);
 
     DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);
     
@@ -271,8 +299,8 @@ XMLToolingException* XMLToolingException::fromStream(std::istream& in)
         char* v=toUTF8(child->getFirstChild()->getNodeValue());
         if (n.get() && v)
             excep->addProperty(n.get(), v);
-        XMLString::release(&v);
-        child=XMLHelper::getNextSiblingElement(root,XMLTOOLING_NS,param);
+        delete[] v;
+        child=XMLHelper::getNextSiblingElement(child,XMLTOOLING_NS,param);
     }
 
     doc->release();