-/*
- * Copyright 2001-2007 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/XMLConstants.h"
-#include "util/XMLHelper.h"
-
-#include <stdarg.h>
-#include <sstream>
-#include <xercesc/util/XMLUniDefs.hpp>
-
-using namespace xmltooling;
-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, int i)
-{
- char* psz=buf + cchBuf - 1; // Set psz to last char
- *psz = 0; // Set terminating null
-
- do {
- unsigned int 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();
- int 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();
-}
-
-string XMLToolingException::toString() const
-{
- 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+="</exception>";
- return xml;
-}
-
-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 };
-
- 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());
- }
-
- child=XMLHelper::getFirstChildElement(root,XMLTOOLING_NS,param);
- while (child && child->hasChildNodes()) {
- auto_ptr_char n(child->getAttributeNS(NULL,name));
- 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);
- }
-
- doc->release();
- return excep.release();
-}
-
-XMLToolingException* XMLToolingException::fromString(const char* s)
-{
- istringstream in(s);
- return fromStream(in);
-}
+/*\r
+ * Copyright 2001-2007 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 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, int i)\r
+{\r
+ char* psz=buf + cchBuf - 1; // Set psz to last char\r
+ *psz = 0; // Set terminating null\r
+\r
+ do {\r
+ unsigned int 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
+ int 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 += "'"; break;\r
+ case '<': s += "<"; break;\r
+ case '>': s += ">"; break;\r
+ case '&': s += "&"; 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
+ 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, ">", i->second.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
+ child=XMLHelper::getFirstChildElement(root,XMLTOOLING_NS,param);\r
+ while (child && child->hasChildNodes()) {\r
+ auto_ptr_char n(child->getAttributeNS(NULL,name));\r
+ char* v=toUTF8(child->getFirstChild()->getNodeValue());\r
+ if (n.get() && v)\r
+ excep->addProperty(n.get(), v);\r
+ delete[] v;\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