Correct eol-style property.
[shibboleth/cpp-xmltooling.git] / xmltooling / exceptions.cpp
index 170f9d9..8304297 100644 (file)
-/*\r
- *  Copyright 2001-2009 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * exceptions.cpp\r
- * \r
- * Exception classes\r
- */\r
\r
-#include "internal.h"\r
-#include "exceptions.h"\r
-#include "XMLToolingConfig.h"\r
-#include "util/URLEncoder.h"\r
-#include "util/XMLConstants.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <stdarg.h>\r
-#include <memory>\r
-#include <sstream>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-\r
-using namespace xmltooling;\r
-using namespace xercesc;\r
-using namespace std;\r
-using xmlconstants::XMLTOOLING_NS;\r
-\r
-params::params(int count,...)\r
-{\r
-    va_list args;\r
-    va_start(args,count);\r
-    while (count--)\r
-        v.push_back(va_arg(args,char*));\r
-    va_end(args);\r
-}\r
-\r
-namedparams::namedparams(int count,...)\r
-{\r
-    count*=2;\r
-    va_list args;\r
-    va_start(args,count);\r
-    while (count--)\r
-        v.push_back(va_arg(args,char*));\r
-    va_end(args);\r
-}\r
-\r
-XMLToolingException::ExceptionFactoryMap XMLToolingException::m_factoryMap;\r
-\r
-XMLToolingException* XMLToolingException::getInstance(const char* exceptionClass)\r
-{\r
-    if (exceptionClass) {\r
-        ExceptionFactoryMap::const_iterator i=m_factoryMap.find(exceptionClass);\r
-        if (i!=m_factoryMap.end())\r
-            return (i->second)();\r
-    }\r
-    return new XMLToolingException();\r
-}\r
-\r
-XMLToolingException::XMLToolingException(const char* msg, const params& p)\r
-{\r
-    if (msg)\r
-        m_msg=msg;\r
-    addProperties(p);\r
-}\r
-\r
-XMLToolingException::XMLToolingException(const char* msg, const namedparams& p)\r
-{\r
-    if (msg)\r
-        m_msg=msg;\r
-    addProperties(p);\r
-}\r
-\r
-XMLToolingException::XMLToolingException(const std::string& msg, const params& p) : m_msg(msg)\r
-{\r
-    addProperties(p);\r
-}\r
-\r
-XMLToolingException::XMLToolingException(const std::string& msg, const namedparams& p) : m_msg(msg)\r
-{\r
-    addProperties(p);\r
-}\r
-\r
-void XMLToolingException::setMessage(const char* msg)\r
-{\r
-    if (msg)\r
-        m_msg=msg;\r
-    else\r
-        m_msg.erase();\r
-    m_processedmsg.erase();\r
-}\r
-\r
-inline const char* get_digit_character()\r
-{\r
-    static const char  s_characters[19] = \r
-    {\r
-            '9'\r
-        ,   '8'\r
-        ,   '7'\r
-        ,   '6'\r
-        ,   '5'\r
-        ,   '4'\r
-        ,   '3'\r
-        ,   '2'\r
-        ,   '1'\r
-        ,   '0'\r
-        ,   '1'\r
-        ,   '2'\r
-        ,   '3'\r
-        ,   '4'\r
-        ,   '5'\r
-        ,   '6'\r
-        ,   '7'\r
-        ,   '8'\r
-        ,   '9'\r
-    };\r
-    static const char  *s_mid  =   s_characters + 9;\r
-\r
-    return s_mid;\r
-}\r
-\r
-inline const char* unsigned_integer_to_string(char* buf, size_t cchBuf, size_t i)\r
-{\r
-    char* psz=buf + cchBuf - 1;     // Set psz to last char\r
-    *psz = 0;                       // Set terminating null\r
-\r
-    do {\r
-        size_t lsd = i % 10;  // Get least significant\r
-                                    // digit\r
-\r
-        i /= 10;                    // Prepare for next most\r
-                                    // significant digit\r
-\r
-        --psz;                      // Move back\r
-\r
-        *psz = get_digit_character()[lsd]; // Place the digit\r
-\r
-    } while(i!=0 && psz>buf);\r
-\r
-    return psz;\r
-}\r
-\r
-void XMLToolingException::addProperties(const params& p)\r
-{\r
-    m_processedmsg.erase();\r
-    map<string,string>::size_type i=m_params.size()+1;\r
-    char buf[20];\r
-    const vector<const char*>& v=p.get();\r
-    for (vector<const char*>::const_iterator ci=v.begin(); ci!=v.end(); ci++) {\r
-        m_params[unsigned_integer_to_string(buf,sizeof(buf),i++)] = *ci;\r
-    }\r
-}\r
-        \r
-void XMLToolingException::addProperties(const namedparams& p)\r
-{\r
-    m_processedmsg.erase();\r
-    const vector<const char*>& v=p.get();\r
-    for (vector<const char*>::const_iterator ci=v.begin(); ci!=v.end(); ci++) {\r
-        m_params.erase(*ci);\r
-        m_params[*ci] = *(ci+1);\r
-        ci++;   // advance past name to value, then loop will advance it again\r
-    }\r
-}\r
-\r
-const char* XMLToolingException::getProperty(unsigned int index) const\r
-{\r
-    char buf[20];\r
-    map<string,string>::const_iterator i=m_params.find(unsigned_integer_to_string(buf,sizeof(buf),index));\r
-    return (i==m_params.end()) ? NULL : i->second.c_str();\r
-}\r
-\r
-const char* XMLToolingException::getProperty(const char* name) const\r
-{\r
-    map<string,string>::const_iterator i=m_params.find(name);\r
-    return (i==m_params.end()) ? NULL : i->second.c_str();\r
-}\r
-\r
-const char* XMLToolingException::getMessage() const\r
-{\r
-    if (!m_processedmsg.empty())\r
-        return m_processedmsg.c_str();\r
-    else if (m_params.empty())\r
-        return m_msg.c_str();\r
-\r
-    static const char* legal="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_";\r
-\r
-    // Replace any parameters in the message.\r
-    string::size_type i=0,start=0;\r
-    while (start!=string::npos && start<m_msg.length() && (i=m_msg.find("$",start))!=string::npos) {\r
-        if (i>start)\r
-            m_processedmsg += m_msg.substr(start,i-start);  // append everything in between\r
-        start=i+1;                                  // move start to the beginning of the token name\r
-        i=m_msg.find_first_not_of(legal,start);     // find token delimiter\r
-        if (i==start) {                             // append a non legal character\r
-           m_processedmsg+=m_msg[start++];\r
-           continue;\r
-        }\r
-        \r
-        // search for token in map\r
-        map<string,string>::const_iterator param=m_params.find(m_msg.substr(start,(i==string::npos) ? i : i-start));\r
-        if (param!=m_params.end()) {\r
-            m_processedmsg+=param->second;\r
-            start=i;\r
-        }\r
-    }\r
-    if (start!=string::npos && start<m_msg.length())\r
-        m_processedmsg += m_msg.substr(start,i);    // append rest of string\r
-    return m_processedmsg.c_str();\r
-}\r
-\r
-void xml_encode(string& s, const char* pre, const char* start, const char* post)\r
-{\r
-    s += pre;\r
-    size_t pos;\r
-    while (start && *start) {\r
-        pos = strcspn(start, "\"<>&");\r
-        if (pos > 0) {\r
-            s.append(start, pos);\r
-            start += pos;\r
-        }\r
-        else {\r
-            switch (*start) {\r
-                case '\'':  s += "&apos;";     break;\r
-                case '<':   s += "&lt;";       break;\r
-                case '>':   s += "&gt;";       break;\r
-                case '&':   s += "&amp;";      break;\r
-                default:    s += *start;\r
-            }\r
-            start++;\r
-        }\r
-    }\r
-    s += post;\r
-}\r
-\r
-string XMLToolingException::toString() const\r
-{\r
-    string xml=string("<exception xmlns='http://www.opensaml.org/xmltooling' type='") + getClassName() + "'>";\r
-    const char* msg=getMessage();\r
-    if (msg)\r
-        xml_encode(xml, "<message>", msg, "</message>");\r
-    const URLEncoder* encoder = XMLToolingConfig::getConfig().getURLEncoder();\r
-    for (map<string,string>::const_iterator i=m_params.begin(); i!=m_params.end(); i++) {\r
-        xml_encode(xml, "<param name='", i->first.c_str(), "'");\r
-        xml_encode(xml, ">", encoder->encode(i->second.c_str()).c_str(), "</param>");\r
-    }\r
-    xml+="</exception>";\r
-    return xml;\r
-}\r
-\r
-string XMLToolingException::toQueryString() const\r
-{\r
-    string q;\r
-    const URLEncoder* enc = XMLToolingConfig::getConfig().getURLEncoder();\r
-    for (map<string,string>::const_iterator i=m_params.begin(); i!=m_params.end(); i++) {\r
-        if (!q.empty())\r
-            q += '&';\r
-        q = q + i->first + '=' + enc->encode(i->second.c_str());\r
-    }\r
-    return q;\r
-}\r
-\r
-XMLToolingException* XMLToolingException::fromStream(std::istream& in)\r
-{\r
-    static const XMLCh exception[] =    UNICODE_LITERAL_9(e,x,c,e,p,t,i,o,n);\r
-    static const XMLCh message[] =      UNICODE_LITERAL_7(m,e,s,s,a,g,e);\r
-    static const XMLCh name[] =         UNICODE_LITERAL_4(n,a,m,e);\r
-    static const XMLCh param[] =        UNICODE_LITERAL_5(p,a,r,a,m);\r
-    static const XMLCh type[] =         UNICODE_LITERAL_4(t,y,p,e);\r
-\r
-    DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);\r
-    \r
-    // Check root element.\r
-    const DOMElement* root=doc->getDocumentElement();\r
-    if (!XMLHelper::isNodeNamed(root,XMLTOOLING_NS,exception)) {\r
-        doc->release();\r
-        throw XMLToolingException("Invalid root element on serialized exception.");\r
-    }\r
-    \r
-    auto_ptr_char classname(root->getAttributeNS(NULL,type));\r
-    auto_ptr<XMLToolingException> excep(XMLToolingException::getInstance(classname.get()));\r
-    \r
-    DOMElement* child=XMLHelper::getFirstChildElement(root,XMLTOOLING_NS,message);\r
-    if (child && child->hasChildNodes()) {\r
-        auto_ptr_char m(child->getFirstChild()->getNodeValue());\r
-        excep->setMessage(m.get());\r
-    }\r
-    \r
-    const URLEncoder* encoder = XMLToolingConfig::getConfig().getURLEncoder();\r
-    child=XMLHelper::getFirstChildElement(root,XMLTOOLING_NS,param);\r
-    while (child && child->hasChildNodes()) {\r
-        auto_ptr_char n(child->getAttributeNS(NULL,name));\r
-        char* encoded = XMLString::transcode(child->getFirstChild()->getNodeValue());\r
-        if (n.get() && encoded) {\r
-            encoder->decode(encoded);\r
-            excep->addProperty(n.get(), encoded);\r
-        }\r
-        XMLString::release(&encoded);\r
-        child=XMLHelper::getNextSiblingElement(child,XMLTOOLING_NS,param);\r
-    }\r
-\r
-    doc->release();\r
-    return excep.release();\r
-}\r
-        \r
-XMLToolingException* XMLToolingException::fromString(const char* s)\r
-{\r
-    istringstream in(s);\r
-    return fromStream(in);\r
-}\r
+/*
+ *  Copyright 2001-2009 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * exceptions.cpp
+ * 
+ * Exception classes
+ */
+#include "internal.h"
+#include "exceptions.h"
+#include "XMLToolingConfig.h"
+#include "util/URLEncoder.h"
+#include "util/XMLConstants.h"
+#include "util/XMLHelper.h"
+
+#include <stdarg.h>
+#include <memory>
+#include <sstream>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+using namespace xmltooling;
+using namespace xercesc;
+using namespace std;
+using xmlconstants::XMLTOOLING_NS;
+
+params::params(int count,...)
+{
+    va_list args;
+    va_start(args,count);
+    while (count--)
+        v.push_back(va_arg(args,char*));
+    va_end(args);
+}
+
+namedparams::namedparams(int count,...)
+{
+    count*=2;
+    va_list args;
+    va_start(args,count);
+    while (count--)
+        v.push_back(va_arg(args,char*));
+    va_end(args);
+}
+
+XMLToolingException::ExceptionFactoryMap XMLToolingException::m_factoryMap;
+
+XMLToolingException* XMLToolingException::getInstance(const char* exceptionClass)
+{
+    if (exceptionClass) {
+        ExceptionFactoryMap::const_iterator i=m_factoryMap.find(exceptionClass);
+        if (i!=m_factoryMap.end())
+            return (i->second)();
+    }
+    return new XMLToolingException();
+}
+
+XMLToolingException::XMLToolingException(const char* msg, const params& p)
+{
+    if (msg)
+        m_msg=msg;
+    addProperties(p);
+}
+
+XMLToolingException::XMLToolingException(const char* msg, const namedparams& p)
+{
+    if (msg)
+        m_msg=msg;
+    addProperties(p);
+}
+
+XMLToolingException::XMLToolingException(const std::string& msg, const params& p) : m_msg(msg)
+{
+    addProperties(p);
+}
+
+XMLToolingException::XMLToolingException(const std::string& msg, const namedparams& p) : m_msg(msg)
+{
+    addProperties(p);
+}
+
+void XMLToolingException::setMessage(const char* msg)
+{
+    if (msg)
+        m_msg=msg;
+    else
+        m_msg.erase();
+    m_processedmsg.erase();
+}
+
+inline const char* get_digit_character()
+{
+    static const char  s_characters[19] = 
+    {
+            '9'
+        ,   '8'
+        ,   '7'
+        ,   '6'
+        ,   '5'
+        ,   '4'
+        ,   '3'
+        ,   '2'
+        ,   '1'
+        ,   '0'
+        ,   '1'
+        ,   '2'
+        ,   '3'
+        ,   '4'
+        ,   '5'
+        ,   '6'
+        ,   '7'
+        ,   '8'
+        ,   '9'
+    };
+    static const char  *s_mid  =   s_characters + 9;
+
+    return s_mid;
+}
+
+inline const char* unsigned_integer_to_string(char* buf, size_t cchBuf, size_t i)
+{
+    char* psz=buf + cchBuf - 1;     // Set psz to last char
+    *psz = 0;                       // Set terminating null
+
+    do {
+        size_t lsd = i % 10;  // Get least significant
+                                    // digit
+
+        i /= 10;                    // Prepare for next most
+                                    // significant digit
+
+        --psz;                      // Move back
+
+        *psz = get_digit_character()[lsd]; // Place the digit
+
+    } while(i!=0 && psz>buf);
+
+    return psz;
+}
+
+void XMLToolingException::addProperties(const params& p)
+{
+    m_processedmsg.erase();
+    map<string,string>::size_type i=m_params.size()+1;
+    char buf[20];
+    const vector<const char*>& v=p.get();
+    for (vector<const char*>::const_iterator ci=v.begin(); ci!=v.end(); ci++) {
+        m_params[unsigned_integer_to_string(buf,sizeof(buf),i++)] = *ci;
+    }
+}
+        
+void XMLToolingException::addProperties(const namedparams& p)
+{
+    m_processedmsg.erase();
+    const vector<const char*>& v=p.get();
+    for (vector<const char*>::const_iterator ci=v.begin(); ci!=v.end(); ci++) {
+        m_params.erase(*ci);
+        m_params[*ci] = *(ci+1);
+        ci++;   // advance past name to value, then loop will advance it again
+    }
+}
+
+const char* XMLToolingException::getProperty(unsigned int index) const
+{
+    char buf[20];
+    map<string,string>::const_iterator i=m_params.find(unsigned_integer_to_string(buf,sizeof(buf),index));
+    return (i==m_params.end()) ? NULL : i->second.c_str();
+}
+
+const char* XMLToolingException::getProperty(const char* name) const
+{
+    map<string,string>::const_iterator i=m_params.find(name);
+    return (i==m_params.end()) ? NULL : i->second.c_str();
+}
+
+const char* XMLToolingException::getMessage() const
+{
+    if (!m_processedmsg.empty())
+        return m_processedmsg.c_str();
+    else if (m_params.empty())
+        return m_msg.c_str();
+
+    static const char* legal="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_";
+
+    // Replace any parameters in the message.
+    string::size_type i=0,start=0;
+    while (start!=string::npos && start<m_msg.length() && (i=m_msg.find("$",start))!=string::npos) {
+        if (i>start)
+            m_processedmsg += m_msg.substr(start,i-start);  // append everything in between
+        start=i+1;                                  // move start to the beginning of the token name
+        i=m_msg.find_first_not_of(legal,start);     // find token delimiter
+        if (i==start) {                             // append a non legal character
+           m_processedmsg+=m_msg[start++];
+           continue;
+        }
+        
+        // search for token in map
+        map<string,string>::const_iterator param=m_params.find(m_msg.substr(start,(i==string::npos) ? i : i-start));
+        if (param!=m_params.end()) {
+            m_processedmsg+=param->second;
+            start=i;
+        }
+    }
+    if (start!=string::npos && start<m_msg.length())
+        m_processedmsg += m_msg.substr(start,i);    // append rest of string
+    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() + "'>";
+    const char* msg=getMessage();
+    if (msg)
+        xml_encode(xml, "<message>", msg, "</message>");
+    const URLEncoder* encoder = XMLToolingConfig::getConfig().getURLEncoder();
+    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, ">", encoder->encode(i->second.c_str()).c_str(), "</param>");
+    }
+    xml+="</exception>";
+    return xml;
+}
+
+string XMLToolingException::toQueryString() const
+{
+    string q;
+    const URLEncoder* enc = XMLToolingConfig::getConfig().getURLEncoder();
+    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[] =    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);
+    
+    // Check root element.
+    const DOMElement* root=doc->getDocumentElement();
+    if (!XMLHelper::isNodeNamed(root,XMLTOOLING_NS,exception)) {
+        doc->release();
+        throw XMLToolingException("Invalid root element on serialized exception.");
+    }
+    
+    auto_ptr_char classname(root->getAttributeNS(NULL,type));
+    auto_ptr<XMLToolingException> excep(XMLToolingException::getInstance(classname.get()));
+    
+    DOMElement* child=XMLHelper::getFirstChildElement(root,XMLTOOLING_NS,message);
+    if (child && child->hasChildNodes()) {
+        auto_ptr_char m(child->getFirstChild()->getNodeValue());
+        excep->setMessage(m.get());
+    }
+    
+    const URLEncoder* encoder = XMLToolingConfig::getConfig().getURLEncoder();
+    child=XMLHelper::getFirstChildElement(root,XMLTOOLING_NS,param);
+    while (child && child->hasChildNodes()) {
+        auto_ptr_char n(child->getAttributeNS(NULL,name));
+        char* encoded = XMLString::transcode(child->getFirstChild()->getNodeValue());
+        if (n.get() && encoded) {
+            encoder->decode(encoded);
+            excep->addProperty(n.get(), encoded);
+        }
+        XMLString::release(&encoded);
+        child=XMLHelper::getNextSiblingElement(child,XMLTOOLING_NS,param);
+    }
+
+    doc->release();
+    return excep.release();
+}
+        
+XMLToolingException* XMLToolingException::fromString(const char* s)
+{
+    istringstream in(s);
+    return fromStream(in);
+}