-/*\r
- * Copyright 2001-2006 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/XMLConstants.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <sstream>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-\r
-using namespace xmltooling;\r
-using namespace std;\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
-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=xml + "<message>" + msg + "</message>";\r
- for (map<string,string>::const_iterator i=m_params.begin(); i!=m_params.end(); i++) {\r
- xml=xml + "<param name=\"" + i->first + "\">" + i->second + "</param>";\r
- }\r
- xml+="</exception>";\r
- return xml;\r
-}\r
-\r
-XMLToolingException* XMLToolingException::fromStream(std::istream& in)\r
-{\r
- static const XMLCh exception[] = { chLatin_e, chLatin_x, chLatin_c, chLatin_e, chLatin_p, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull };\r
- static const XMLCh message[] = { chLatin_m, chLatin_e, chLatin_s, chLatin_s, chLatin_a, chLatin_g, chLatin_e, chNull };\r
- static const XMLCh name[] = { chLatin_n, chLatin_a, chLatin_m, chLatin_e, chNull };\r
- static const XMLCh param[] = { chLatin_p, chLatin_a, chLatin_r, chLatin_a, chLatin_m, chNull };\r
- static const XMLCh type[] = { chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull };\r
-\r
- DOMDocument* doc=XMLToolingInternalConfig::getInternalConfig().m_parserPool->parse(in);\r
- \r
- // Check root element.\r
- const DOMElement* root=doc->getDocumentElement();\r
- if (!XMLHelper::isNodeNamed(root,XMLConstants::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,XMLConstants::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,XMLConstants::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
- XMLString::release(&v);\r
- child=XMLHelper::getNextSiblingElement(root,XMLConstants::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-2006 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;
+
+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=XMLToolingInternalConfig::getInternalConfig().m_parserPool->parse(in);
+
+ // Check root element.
+ const DOMElement* root=doc->getDocumentElement();
+ if (!XMLHelper::isNodeNamed(root,XMLConstants::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,XMLConstants::XMLTOOLING_NS,message);
+ if (child && child->hasChildNodes()) {
+ auto_ptr_char m(child->getFirstChild()->getNodeValue());
+ excep->setMessage(m.get());
+ }
+
+ child=XMLHelper::getFirstChildElement(root,XMLConstants::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,XMLConstants::XMLTOOLING_NS,param);
+ }
+
+ doc->release();
+ return excep.release();
+}
+
+XMLToolingException* XMLToolingException::fromString(const char* s)
+{
+ istringstream in(s);
+ return fromStream(in);
+}