Unix porting fixes
authorScott Cantor <cantor.2@osu.edu>
Wed, 29 Mar 2006 19:10:13 +0000 (19:10 +0000)
committerScott Cantor <cantor.2@osu.edu>
Wed, 29 Mar 2006 19:10:13 +0000 (19:10 +0000)
xmltooling/AbstractXMLObject.cpp
xmltooling/Makefile.am
xmltooling/base.h
xmltooling/exceptions.cpp
xmltooling/exceptions.h
xmltooling/io/AbstractXMLObjectUnmarshaller.cpp
xmltooling/util/ParserPool.cpp
xmltooling/util/XMLObjectChildrenList.h
xmltoolingtest/Makefile.am

index cdba177..bb40e91 100644 (file)
@@ -1,78 +1,78 @@
-/*\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
- * AbstractXMLObject.cpp\r
- * \r
- * An abstract implementation of XMLObject.\r
- */\r
-\r
-#include "internal.h"\r
-#include "AbstractXMLObject.h"\r
-#include "exceptions.h"\r
-\r
-#include <algorithm>\r
-#include <log4cpp/Category.hh>\r
-\r
-using namespace xmltooling;\r
-\r
-AbstractXMLObject::~AbstractXMLObject() {\r
-    delete m_typeQname;\r
-    std::for_each(m_children.begin(), m_children.end(), cleanup<XMLObject>());\r
-}\r
-\r
-AbstractXMLObject::AbstractXMLObject(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)\r
-    : m_elementQname(nsURI, localName, prefix), m_typeQname(NULL), m_parent(NULL),\r
-        m_log(&log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".XMLObject"))\r
-{\r
-    addNamespace(Namespace(nsURI, prefix));\r
-    if (schemaType) {\r
-        m_typeQname = new QName(*schemaType);\r
-        addNamespace(Namespace(m_typeQname->getNamespaceURI(), m_typeQname->getPrefix()));\r
-    }\r
-}\r
-\r
-AbstractXMLObject::AbstractXMLObject(const AbstractXMLObject& src)\r
-    : m_namespaces(src.m_namespaces), m_log(src.m_log), m_parent(NULL), m_elementQname(src.m_elementQname), m_typeQname(NULL)\r
-{\r
-    if (src.m_typeQname)\r
-        m_typeQname=new QName(*src.m_typeQname);\r
-}\r
-\r
-XMLObject* AbstractXMLObject::prepareForAssignment(XMLObject* oldValue, XMLObject* newValue) {\r
-\r
-    if (newValue && newValue->hasParent())\r
-        throw XMLObjectException("child XMLObject cannot be added - it is already the child of another XMLObject");\r
-\r
-    if (!oldValue) {\r
-        if (newValue) {\r
-            releaseThisandParentDOM();\r
-            newValue->setParent(this);\r
-            return newValue;\r
-        }\r
-        else {\r
-            return NULL;\r
-        }\r
-    }\r
-\r
-    if (oldValue != newValue) {\r
-        delete oldValue;\r
-        releaseThisandParentDOM();\r
-        newValue->setParent(this);\r
-    }\r
-\r
-    return newValue;\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.
+ */
+
+/**
+ * AbstractXMLObject.cpp
+ * 
+ * An abstract implementation of XMLObject.
+ */
+
+#include "internal.h"
+#include "AbstractXMLObject.h"
+#include "exceptions.h"
+
+#include <algorithm>
+#include <log4cpp/Category.hh>
+
+using namespace xmltooling;
+
+AbstractXMLObject::~AbstractXMLObject() {
+    delete m_typeQname;
+    std::for_each(m_children.begin(), m_children.end(), cleanup<XMLObject>());
+}
+
+AbstractXMLObject::AbstractXMLObject(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+    : m_log(&log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".XMLObject")),
+        m_parent(NULL), m_elementQname(nsURI, localName, prefix), m_typeQname(NULL)
+{
+    addNamespace(Namespace(nsURI, prefix));
+    if (schemaType) {
+        m_typeQname = new QName(*schemaType);
+        addNamespace(Namespace(m_typeQname->getNamespaceURI(), m_typeQname->getPrefix()));
+    }
+}
+
+AbstractXMLObject::AbstractXMLObject(const AbstractXMLObject& src)
+    : m_namespaces(src.m_namespaces), m_log(src.m_log), m_parent(NULL), m_elementQname(src.m_elementQname), m_typeQname(NULL)
+{
+    if (src.m_typeQname)
+        m_typeQname=new QName(*src.m_typeQname);
+}
+
+XMLObject* AbstractXMLObject::prepareForAssignment(XMLObject* oldValue, XMLObject* newValue) {
+
+    if (newValue && newValue->hasParent())
+        throw XMLObjectException("child XMLObject cannot be added - it is already the child of another XMLObject");
+
+    if (!oldValue) {
+        if (newValue) {
+            releaseThisandParentDOM();
+            newValue->setParent(this);
+            return newValue;
+        }
+        else {
+            return NULL;
+        }
+    }
+
+    if (oldValue != newValue) {
+        delete oldValue;
+        releaseThisandParentDOM();
+        newValue->setParent(this);
+    }
+
+    return newValue;
+}
index e139979..5b4e2bc 100644 (file)
@@ -18,7 +18,6 @@ libxmltoolinginclude_HEADERS = \
     AbstractAttributeExtensibleXMLObject.h \
     AbstractDOMCachingXMLObject.h \
     AbstractElementProxy.h \
-    AbstractValidatingXMLObject.h \
     AbstractXMLObject.h \
     AttributeExtensibleXMLObject.h \
     base.h \
@@ -29,7 +28,6 @@ libxmltoolinginclude_HEADERS = \
     Namespace.h \
     QName.h \
     unicode.h \
-    ValidatingXMLObject.h \
     version.h \
     XMLObject.h \
     XMLObjectBuilder.h \
@@ -57,6 +55,8 @@ utilinclude_HEADERS = \
     util/XMLObjectChildrenList.h
 
 valinclude_HEADERS = \
+    validation/AbstractValidatingXMLObject.h \
+    validation/ValidatingXMLObject.h \
     validation/Validator.h
 
 noinst_HEADERS = \
@@ -66,7 +66,6 @@ noinst_HEADERS = \
 
 if BUILD_XMLSEC
 xmlsec_sources = \
-    signature/impl/KeyInfoImpl.cpp \
     signature/impl/XMLSecSignatureImpl.cpp
 else
 xmlsec_sources =
@@ -87,6 +86,7 @@ libxmltooling_la_SOURCES = \
     impl/UnknownElement.cpp \
     io/AbstractXMLObjectMarshaller.cpp \
     io/AbstractXMLObjectUnmarshaller.cpp \
+    signature/impl/KeyInfoImpl.cpp \
     util/NDC.cpp \
     util/ParserPool.cpp \
     util/XMLConstants.cpp \
index d2060cb..093152e 100644 (file)
 #define NULL    0
 #endif
 
+#ifdef _MSC_VER
+    #define XMLTOOLING_DOXYGEN(desc) /##** desc */
+#else
+    #define XMLTOOLING_DOXYGEN(desc)
+#endif
+
 /**
  * Blocks copy c'tor and assignment operator for a class.
  */
         cname() {} \
     public: \
         virtual ~cname() {} \
-        /##** Type-specific clone method. */ \
+        XMLTOOLING_DOXYGEN(Type-specific clone method.) \
         virtual cname* clone##cname() const=0; \
-        /##** Element prefix */ \
+        XMLTOOLING_DOXYGEN(Element prefix) \
         static const XMLCh PREFIX[]; \
-        /##** Element local name */ \
+        XMLTOOLING_DOXYGEN(Element local name) \
         static const XMLCh LOCAL_NAME[]
 
 /**
  * @param upcased   the upcased name of the attribute
  */
 #define DECL_XMLOBJECT_ATTRIB(proper,upcased) \
-    /##** proper attribute name */ \
+    XMLTOOLING_DOXYGEN(proper attribute name) \
     static const XMLCh upcased##_ATTRIB_NAME[]; \
-    /##** Returns the proper attribute. */ \
+    XMLTOOLING_DOXYGEN(Returns the proper attribute.) \
     virtual const XMLCh* get##proper() const=0; \
-    /##** Sets the proper attribute. */ \
+    XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
     virtual void set##proper(const XMLCh* proper)=0
 
 /**
  * @param cname the name of the XMLObject specialization
  */
 #define BEGIN_XMLOBJECTBUILDER(cname) \
-    /##** Builder for cname objects. */ \
+    XMLTOOLING_DOXYGEN(Builder for cname objects.) \
     class XMLTOOL_API cname##Builder : public xmltooling::XMLObjectBuilder { \
     public: \
         virtual ~cname##Builder() {} \
-        /##** Default builder. */ \
+        XMLTOOLING_DOXYGEN(Default builder.) \
         virtual cname* buildObject() const=0
 
 /**
index 10e4e39..114e1ad 100644 (file)
-/*\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);
+}
index 6e82e1e..a10db9b 100644 (file)
-/*\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
- * @file exceptions.h\r
- * \r
- * Exception classes\r
- */\r
\r
-#ifndef __xmltooling_exceptions_h__\r
-#define __xmltooling_exceptions_h__\r
-\r
-#include <map>\r
-#include <string>\r
-#include <vector>\r
-#include <iostream>\r
-#include <xmltooling/base.h>\r
-\r
-/**\r
- * Declares a derived exception class\r
- * \r
- * @param name  the exception class\r
- * @param base  the base class\r
- * @param desc\r
- */\r
-#define DECL_XMLTOOLING_EXCEPTION(name,base,desc) \\r
-    /##** desc */ \\r
-    class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) name : public xmltooling::base { \\r
-    public: \\r
-        /##** base##::##base(const char*,const xmltooling::params&) */ \\r
-        name(const char* msg=NULL, const xmltooling::params& p=xmltooling::params()) \\r
-            : xmltooling::base(msg,p) {} \\r
-        /##** base##::##base(const char*,const xmltooling::namedparams&) */ \\r
-        name(const char* msg, const xmltooling::namedparams& p) \\r
-            : xmltooling::base(msg,p) {} \\r
-        /##** base##::##base(const std::string&,const xmltooling::params&) */ \\r
-        name(const std::string& msg, const xmltooling::params& p=xmltooling::params()) \\r
-            : xmltooling::base(msg,p) {} \\r
-        /##** base##::##base(const std::string&,const xmltooling::namedparams&) */ \\r
-        name(const std::string& msg, const xmltooling::namedparams& p) \\r
-            : xmltooling::base(msg,p) {} \\r
-        virtual ~name() {} \\r
-        virtual const char* getClassName() const { return "xmltooling::"#name; } \\r
-        void raise() const {throw *this;} \\r
-    }\r
-\r
-/**\r
- * Declares a factory function for an exception class.\r
- * \r
- * @param name  the exception class name\r
- */\r
-#define DECL_EXCEPTION_FACTORY(name) \\r
-    xmltooling::XMLToolingException* name##Factory() \\r
-    { \\r
-        return new xmltooling::name(); \\r
-    }\r
-\r
-/**\r
- * Registers a factory for an exception class.\r
- * \r
- * @param name  the exception class name\r
- */\r
-#define REGISTER_EXCEPTION_FACTORY(name) XMLToolingException::registerFactory("xmltooling::"#name,name##Factory)\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-    \r
-    /**\r
-     * Wrapper around a variable number of arguments.\r
-     */\r
-    class XMLTOOL_API params\r
-    {\r
-    public:\r
-        /**\r
-         * Initializes with zero parameters.\r
-         */\r
-        params() {}\r
-        \r
-        /**\r
-         * Initializes the parameter set.\r
-         * \r
-         * @param count     the number of parameters that follow\r
-         */\r
-        params(int count,...);\r
-        \r
-        /**\r
-         * Returns an immutable reference to the set of parameters.\r
-         * \r
-         * @return the parameter set\r
-         */\r
-        const std::vector<const char*>& get() const {return v;}\r
-        \r
-    protected:\r
-        /** Contains the parameters being passed. */\r
-        std::vector<const char*> v;\r
-    };\r
-    \r
-    /**\r
-     * Wrapper around a variable number of name/value pairs.\r
-     */\r
-    class XMLTOOL_API namedparams : public params\r
-    {\r
-    public:\r
-        /**\r
-         * Initializes with zero parameters.\r
-         */\r
-        namedparams() {}\r
-\r
-        /**\r
-         * Initializes the named parameter set.\r
-         * \r
-         * @param count     the number of name/value pairs that follow (must be even)\r
-         */\r
-        namedparams(int count,...);\r
-    };\r
-\r
-    class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException;\r
-    \r
-    /** A factory function that returns an empty exception object of a given type. */\r
-    typedef XMLToolingException* ExceptionFactory();\r
-    \r
-    /**\r
-     * Base exception class, supports parametrized messages and XML serialization.\r
-     * Parameters are prefixed with a dollar sign ($) and can be positional ($1)\r
-     * or named ($info).\r
-     */\r
-    class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException\r
-    {\r
-    public:\r
-        virtual ~XMLToolingException() {}\r
-\r
-        /**\r
-         * Constructs an exception using a message and positional parameters.\r
-         * \r
-         * @param msg   error message\r
-         * @param p     an ordered set of positional parameter strings\r
-         */\r
-        XMLToolingException(const char* msg=NULL, const params& p=params());\r
-\r
-        /**\r
-         * Constructs an exception using a message and named parameters.\r
-         * \r
-         * @param msg   error message\r
-         * @param p     a set of named parameter strings\r
-         */\r
-        XMLToolingException(const char* msg, const namedparams& p);\r
-\r
-        /**\r
-         * Constructs an exception using a message and positional parameters.\r
-         * \r
-         * @param msg   error message\r
-         * @param p     an ordered set of positional parameter strings\r
-         */\r
-        XMLToolingException(const std::string& msg, const params& p=params());\r
-\r
-        /**\r
-         * Constructs an exception using a message and named parameters.\r
-         * \r
-         * @param msg   error message\r
-         * @param p     a set of named parameter strings\r
-         */\r
-        XMLToolingException(const std::string& msg, const namedparams& p);\r
-\r
-        /**\r
-         * Returns the error message, after processing any parameter references.\r
-         * \r
-         * @return  the processed message\r
-         */\r
-        const char* getMessage() const;\r
-\r
-        /**\r
-         * Returns the error message, after processing any parameter references.\r
-         * \r
-         * @return  the processed message\r
-         */\r
-        const char* what() const {return getMessage();}\r
-\r
-        /**\r
-         * Sets the error message.\r
-         * \r
-         * @param msg   the error message\r
-         */\r
-        void setMessage(const char* msg);\r
-\r
-        /**\r
-         * Sets the error message.\r
-         * \r
-         * @param msg   the error message\r
-         */\r
-        void setMessage(const std::string& msg) {\r
-            setMessage(msg.c_str());\r
-        }\r
-\r
-        /**\r
-         * Attach a set of positional parameters to the exception.\r
-         * \r
-         * @param p     an ordered set of named parameter strings\r
-         */\r
-        void addProperties(const params& p);\r
-        \r
-        /**\r
-         * Attach a set of named parameters to the exception.\r
-         * \r
-         * @param p     a set of named parameter strings\r
-         */\r
-        void addProperties(const namedparams& p);\r
-\r
-        /**\r
-         * Attach a single positional parameter at the next available position.\r
-         * \r
-         * @param value the parameter value\r
-         */\r
-        void addProperty(const char* value) {\r
-            addProperties(params(1,value));\r
-        }\r
-\r
-        /**\r
-         * Attach a single named parameter.\r
-         * \r
-         * @param name  the parameter name\r
-         * @param value the parameter value\r
-         */\r
-        void addProperty(const char* name, const char* value) {\r
-            addProperties(namedparams(1,name,value));\r
-        }\r
-\r
-        /**\r
-         * Returns the parameter property with the designated position (based from one).\r
-         * \r
-         * @param index     position to access\r
-         * @return  the parameter property or NULL\r
-         */\r
-        const char* getProperty(unsigned int index) const;\r
-\r
-        /**\r
-         * Returns the parameter property with the designated name.\r
-         * \r
-         * @param name     named parameter to access\r
-         * @return  the parameter property or NULL\r
-         */\r
-        const char* getProperty(const char* name) const;\r
-\r
-        /**\r
-         * Raises an exception using itself.\r
-         * Used to raise an exception of a derived type.\r
-         */\r
-        virtual void raise() const {\r
-            throw *this;\r
-        }\r
-\r
-        /**\r
-         * Returns a unique name for the exception class.\r
-         * \r
-         * @return class name\r
-         */\r
-        virtual const char* getClassName() const {\r
-            return "xmltooling::XMLToolingException";\r
-        }\r
-        \r
-        /**\r
-         * Returns a string containing a serialized representation of the exception.\r
-         * \r
-         * @return  the serialization\r
-         */\r
-        std::string toString() const;\r
-\r
-    private:\r
-        std::string m_msg;\r
-        mutable std::string m_processedmsg;\r
-        std::map<std::string,std::string> m_params;\r
-\r
-    public:\r
-        /**\r
-         * Builds an empty exception of the given type.\r
-         * \r
-         * @param exceptionClass    the name of the exception type to build\r
-         * @return an empty exception object\r
-         */\r
-        static XMLToolingException* getInstance(const char* exceptionClass);\r
-\r
-        /**\r
-         * Builds an exception from a serialized input stream.\r
-         * \r
-         * @param in    input stream\r
-         * @return the exception object found in the stream\r
-         */\r
-        static XMLToolingException* fromStream(std::istream& in);\r
-        \r
-        /**\r
-         * Builds an exception from a serialized input buffer.\r
-         * \r
-         * @param s   input buffer\r
-         * @return the exception object found in the buffer\r
-         */\r
-        static XMLToolingException* fromString(const char* s);\r
-                \r
-        /**\r
-         * Registers a factory to create exceptions of a given class name.\r
-         * \r
-         * @param exceptionClass    name of exception type\r
-         * @param factory           factory function to build exceptions with\r
-         */\r
-        static void registerFactory(const char* exceptionClass, ExceptionFactory* factory) {\r
-            m_factoryMap[exceptionClass] = factory;\r
-        }\r
-        \r
-        /**\r
-         * Unregisters the factory for a given class name.\r
-         * \r
-         * @param exceptionClass    name of exception type\r
-         */\r
-        static void deregisterFactory(const char* exceptionClass) {\r
-            m_factoryMap.erase(exceptionClass);\r
-        }\r
-\r
-    private:\r
-        typedef std::map<std::string,ExceptionFactory*> ExceptionFactoryMap;\r
-        static ExceptionFactoryMap m_factoryMap;\r
-    };\r
-\r
-    DECL_XMLTOOLING_EXCEPTION(XMLParserException,XMLToolingException,Exceptions related to XML parsing);\r
-    DECL_XMLTOOLING_EXCEPTION(XMLObjectException,XMLToolingException,Exceptions in basic object usage);\r
-    DECL_XMLTOOLING_EXCEPTION(MarshallingException,XMLToolingException,Exceptions during object marshalling);\r
-    DECL_XMLTOOLING_EXCEPTION(UnmarshallingException,XMLToolingException,Exceptions during object unmarshalling);\r
-    DECL_XMLTOOLING_EXCEPTION(UnknownElementException,XMLToolingException,Exceptions due to processing of unknown element content);\r
-    DECL_XMLTOOLING_EXCEPTION(UnknownAttributeException,XMLToolingException,Exceptions due to processing of unknown attributes);\r
-    DECL_XMLTOOLING_EXCEPTION(ValidationException,XMLToolingException,Exceptions during object validation);\r
-    DECL_XMLTOOLING_EXCEPTION(SignatureException,XMLToolingException,Exceptions in signature processing);\r
-\r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_exceptions_h__ */\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.
+ */
+
+/**
+ * @file exceptions.h
+ * 
+ * Exception classes
+ */
+#ifndef __xmltooling_exceptions_h__
+#define __xmltooling_exceptions_h__
+
+#include <map>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <xmltooling/base.h>
+
+/**
+ * Declares a derived exception class
+ * 
+ * @param name  the exception class
+ * @param base  the base class
+ * @param desc
+ */
+#define DECL_XMLTOOLING_EXCEPTION(name,base,desc) \
+    XMLTOOLING_DOXYGEN(desc) \
+    class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) name : public xmltooling::base { \
+    public: \
+        XMLTOOLING_DOXYGEN(Constructor) \
+        name(const char* msg=NULL, const xmltooling::params& p=xmltooling::params()) \
+            : xmltooling::base(msg,p) {} \
+        XMLTOOLING_DOXYGEN(Constructor) \
+        name(const char* msg, const xmltooling::namedparams& p) \
+            : xmltooling::base(msg,p) {} \
+        XMLTOOLING_DOXYGEN(Constructor) \
+        name(const std::string& msg, const xmltooling::params& p=xmltooling::params()) \
+            : xmltooling::base(msg,p) {} \
+        XMLTOOLING_DOXYGEN(Constructor) \
+        name(const std::string& msg, const xmltooling::namedparams& p) \
+            : xmltooling::base(msg,p) {} \
+        virtual ~name() {} \
+        virtual const char* getClassName() const { return "xmltooling::"#name; } \
+        void raise() const {throw *this;} \
+    }
+
+/**
+ * Declares a factory function for an exception class.
+ * 
+ * @param name  the exception class name
+ */
+#define DECL_EXCEPTION_FACTORY(name) \
+    xmltooling::XMLToolingException* name##Factory() \
+    { \
+        return new xmltooling::name(); \
+    }
+
+/**
+ * Registers a factory for an exception class.
+ * 
+ * @param name  the exception class name
+ */
+#define REGISTER_EXCEPTION_FACTORY(name) XMLToolingException::registerFactory("xmltooling::"#name,name##Factory)
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+    
+    /**
+     * Wrapper around a variable number of arguments.
+     */
+    class XMLTOOL_API params
+    {
+    public:
+        /**
+         * Initializes with zero parameters.
+         */
+        params() {}
+        
+        /**
+         * Initializes the parameter set.
+         * 
+         * @param count     the number of parameters that follow
+         */
+        params(int count,...);
+        
+        /**
+         * Returns an immutable reference to the set of parameters.
+         * 
+         * @return the parameter set
+         */
+        const std::vector<const char*>& get() const {return v;}
+        
+    protected:
+        /** Contains the parameters being passed. */
+        std::vector<const char*> v;
+    };
+    
+    /**
+     * Wrapper around a variable number of name/value pairs.
+     */
+    class XMLTOOL_API namedparams : public params
+    {
+    public:
+        /**
+         * Initializes with zero parameters.
+         */
+        namedparams() {}
+
+        /**
+         * Initializes the named parameter set.
+         * 
+         * @param count     the number of name/value pairs that follow (must be even)
+         */
+        namedparams(int count,...);
+    };
+
+    class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException;
+    
+    /** A factory function that returns an empty exception object of a given type. */
+    typedef XMLToolingException* ExceptionFactory();
+    
+    /**
+     * Base exception class, supports parametrized messages and XML serialization.
+     * Parameters are prefixed with a dollar sign ($) and can be positional ($1)
+     * or named ($info).
+     */
+    class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException
+    {
+    public:
+        virtual ~XMLToolingException() {}
+
+        /**
+         * Constructs an exception using a message and positional parameters.
+         * 
+         * @param msg   error message
+         * @param p     an ordered set of positional parameter strings
+         */
+        XMLToolingException(const char* msg=NULL, const params& p=params());
+
+        /**
+         * Constructs an exception using a message and named parameters.
+         * 
+         * @param msg   error message
+         * @param p     a set of named parameter strings
+         */
+        XMLToolingException(const char* msg, const namedparams& p);
+
+        /**
+         * Constructs an exception using a message and positional parameters.
+         * 
+         * @param msg   error message
+         * @param p     an ordered set of positional parameter strings
+         */
+        XMLToolingException(const std::string& msg, const params& p=params());
+
+        /**
+         * Constructs an exception using a message and named parameters.
+         * 
+         * @param msg   error message
+         * @param p     a set of named parameter strings
+         */
+        XMLToolingException(const std::string& msg, const namedparams& p);
+
+        /**
+         * Returns the error message, after processing any parameter references.
+         * 
+         * @return  the processed message
+         */
+        const char* getMessage() const;
+
+        /**
+         * Returns the error message, after processing any parameter references.
+         * 
+         * @return  the processed message
+         */
+        const char* what() const {return getMessage();}
+
+        /**
+         * Sets the error message.
+         * 
+         * @param msg   the error message
+         */
+        void setMessage(const char* msg);
+
+        /**
+         * Sets the error message.
+         * 
+         * @param msg   the error message
+         */
+        void setMessage(const std::string& msg) {
+            setMessage(msg.c_str());
+        }
+
+        /**
+         * Attach a set of positional parameters to the exception.
+         * 
+         * @param p     an ordered set of named parameter strings
+         */
+        void addProperties(const params& p);
+        
+        /**
+         * Attach a set of named parameters to the exception.
+         * 
+         * @param p     a set of named parameter strings
+         */
+        void addProperties(const namedparams& p);
+
+        /**
+         * Attach a single positional parameter at the next available position.
+         * 
+         * @param value the parameter value
+         */
+        void addProperty(const char* value) {
+            addProperties(params(1,value));
+        }
+
+        /**
+         * Attach a single named parameter.
+         * 
+         * @param name  the parameter name
+         * @param value the parameter value
+         */
+        void addProperty(const char* name, const char* value) {
+            addProperties(namedparams(1,name,value));
+        }
+
+        /**
+         * Returns the parameter property with the designated position (based from one).
+         * 
+         * @param index     position to access
+         * @return  the parameter property or NULL
+         */
+        const char* getProperty(unsigned int index) const;
+
+        /**
+         * Returns the parameter property with the designated name.
+         * 
+         * @param name     named parameter to access
+         * @return  the parameter property or NULL
+         */
+        const char* getProperty(const char* name) const;
+
+        /**
+         * Raises an exception using itself.
+         * Used to raise an exception of a derived type.
+         */
+        virtual void raise() const {
+            throw *this;
+        }
+
+        /**
+         * Returns a unique name for the exception class.
+         * 
+         * @return class name
+         */
+        virtual const char* getClassName() const {
+            return "xmltooling::XMLToolingException";
+        }
+        
+        /**
+         * Returns a string containing a serialized representation of the exception.
+         * 
+         * @return  the serialization
+         */
+        std::string toString() const;
+
+    private:
+        std::string m_msg;
+        mutable std::string m_processedmsg;
+        std::map<std::string,std::string> m_params;
+
+    public:
+        /**
+         * Builds an empty exception of the given type.
+         * 
+         * @param exceptionClass    the name of the exception type to build
+         * @return an empty exception object
+         */
+        static XMLToolingException* getInstance(const char* exceptionClass);
+
+        /**
+         * Builds an exception from a serialized input stream.
+         * 
+         * @param in    input stream
+         * @return the exception object found in the stream
+         */
+        static XMLToolingException* fromStream(std::istream& in);
+        
+        /**
+         * Builds an exception from a serialized input buffer.
+         * 
+         * @param s   input buffer
+         * @return the exception object found in the buffer
+         */
+        static XMLToolingException* fromString(const char* s);
+                
+        /**
+         * Registers a factory to create exceptions of a given class name.
+         * 
+         * @param exceptionClass    name of exception type
+         * @param factory           factory function to build exceptions with
+         */
+        static void registerFactory(const char* exceptionClass, ExceptionFactory* factory) {
+            m_factoryMap[exceptionClass] = factory;
+        }
+        
+        /**
+         * Unregisters the factory for a given class name.
+         * 
+         * @param exceptionClass    name of exception type
+         */
+        static void deregisterFactory(const char* exceptionClass) {
+            m_factoryMap.erase(exceptionClass);
+        }
+
+    private:
+        typedef std::map<std::string,ExceptionFactory*> ExceptionFactoryMap;
+        static ExceptionFactoryMap m_factoryMap;
+    };
+
+    DECL_XMLTOOLING_EXCEPTION(XMLParserException,XMLToolingException,Exceptions related to XML parsing);
+    DECL_XMLTOOLING_EXCEPTION(XMLObjectException,XMLToolingException,Exceptions in basic object usage);
+    DECL_XMLTOOLING_EXCEPTION(MarshallingException,XMLToolingException,Exceptions during object marshalling);
+    DECL_XMLTOOLING_EXCEPTION(UnmarshallingException,XMLToolingException,Exceptions during object unmarshalling);
+    DECL_XMLTOOLING_EXCEPTION(UnknownElementException,XMLToolingException,Exceptions due to processing of unknown element content);
+    DECL_XMLTOOLING_EXCEPTION(UnknownAttributeException,XMLToolingException,Exceptions due to processing of unknown attributes);
+    DECL_XMLTOOLING_EXCEPTION(ValidationException,XMLToolingException,Exceptions during object validation);
+    DECL_XMLTOOLING_EXCEPTION(SignatureException,XMLToolingException,Exceptions in signature processing);
+
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_exceptions_h__ */
index 465b432..fd4c9f5 100644 (file)
-/*\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
- * AbstractXMLObjectUnmarshaller.cpp\r
- * \r
- * A thread-safe abstract unmarshaller.\r
- */\r
-\r
-#include "internal.h"\r
-#include "exceptions.h"\r
-#include "XMLObjectBuilder.h"\r
-#include "io/AbstractXMLObjectUnmarshaller.h"\r
-#include "util/NDC.h"\r
-#include "util/XMLConstants.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-#include <log4cpp/Category.hh>\r
-\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-\r
-#define XT_log (*static_cast<Category*>(m_log))\r
-\r
-XMLObject* AbstractXMLObjectUnmarshaller::unmarshall(DOMElement* element, bool bindDocument)\r
-{\r
-#ifdef _DEBUG\r
-    xmltooling::NDC ndc("unmarshall");\r
-#endif\r
-\r
-    if (getDOM() || hasParent())\r
-        throw UnmarshallingException("Object already contains data, it cannot be unmarshalled at this stage.");\r
-\r
-    if (!XMLString::equals(element->getNamespaceURI(),getElementQName().getNamespaceURI()) ||\r
-        !XMLString::equals(element->getLocalName(),getElementQName().getLocalPart())) {\r
-        throw UnmarshallingException("Unrecognized element supplied to implementation for unmarshalling.");\r
-    }\r
-\r
-    if (XT_log.isDebugEnabled()) {\r
-        auto_ptr_char dname(element->getNodeName());\r
-        XT_log.debug("unmarshalling DOM element (%s)", dname.get());\r
-    }\r
-\r
-    if (element->hasAttributes()) {\r
-        unmarshallAttributes(element);\r
-    }\r
-\r
-    unmarshallChildElements(element);\r
-\r
-    /* TODO: Signing\r
-    if (xmlObject instanceof SignableXMLObject) {\r
-        verifySignature(domElement, xmlObject);\r
-    }\r
-    */\r
-\r
-    setDOM(element,bindDocument);\r
-    return this;\r
-}\r
-\r
-void AbstractXMLObjectUnmarshaller::unmarshallAttributes(const DOMElement* domElement)\r
-{\r
-#ifdef _DEBUG\r
-    xmltooling::NDC ndc("unmarshallAttributes");\r
-#endif\r
-    static const XMLCh type[]={chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull};\r
-\r
-    if (XT_log.isDebugEnabled()) {\r
-        auto_ptr_char dname(domElement->getNodeName());\r
-        XT_log.debug("unmarshalling attributes for DOM element (%s)", dname.get());\r
-    }\r
-\r
-    DOMNamedNodeMap* attributes = domElement->getAttributes();\r
-    if (!attributes) {\r
-        XT_log.debug("no attributes to unmarshall");\r
-        return;\r
-    }\r
-\r
-    DOMNode* childNode;\r
-    DOMAttr* attribute;\r
-    for (XMLSize_t i=0; i<attributes->getLength(); i++) {\r
-        childNode = attributes->item(i);\r
-\r
-        // The child node should always be an attribute, but just in case\r
-        if (childNode->getNodeType() != DOMNode::ATTRIBUTE_NODE) {\r
-            XT_log.debug("encountered child node of type %d in attribute list, ignoring it", childNode->getNodeType());\r
-            continue;\r
-        }\r
-\r
-        attribute = static_cast<DOMAttr*>(childNode);\r
-        \r
-        const XMLCh* nsuri=attribute->getNamespaceURI();\r
-        if (XMLString::equals(nsuri,XMLConstants::XMLNS_NS)) {\r
-            if (XMLString::equals(attribute->getLocalName(),XMLConstants::XMLNS_PREFIX)) {\r
-                XT_log.debug("found default namespace declaration, adding it to the list of namespaces on the XMLObject");\r
-                addNamespace(Namespace(attribute->getValue(), NULL, true));\r
-                continue;\r
-            }\r
-            else {\r
-                XT_log.debug("found namespace declaration, adding it to the list of namespaces on the XMLObject");\r
-                addNamespace(Namespace(attribute->getValue(), attribute->getLocalName(), true));\r
-                continue;\r
-            }\r
-        }\r
-        else if (XMLString::equals(nsuri,XMLConstants::XSI_NS) && XMLString::equals(attribute->getLocalName(),type)) {\r
-            XT_log.debug("skipping xsi:type declaration");\r
-            continue;\r
-        }\r
-        else if (nsuri && !XMLString::equals(nsuri,XMLConstants::XML_NS)) {\r
-            XT_log.debug("found namespace-qualified attribute, adding prefix to the list of namespaces on the XMLObject");\r
-            addNamespace(Namespace(nsuri, attribute->getPrefix()));\r
-        }\r
-\r
-        XT_log.debug("processing generic attribute");\r
-        processAttribute(attribute);\r
-    }\r
-}\r
-\r
-void AbstractXMLObjectUnmarshaller::unmarshallChildElements(const DOMElement* domElement)\r
-{\r
-#ifdef _DEBUG\r
-    xmltooling::NDC ndc("unmarshallChildElements");\r
-#endif\r
-\r
-    if (XT_log.isDebugEnabled()) {\r
-        auto_ptr_char dname(domElement->getNodeName());\r
-        XT_log.debug("unmarshalling child elements of DOM element (%s)", dname.get());\r
-    }\r
-\r
-    DOMNodeList* childNodes = domElement->getChildNodes();\r
-    DOMNode* childNode;\r
-    if (!childNodes || childNodes->getLength()==0) {\r
-        XT_log.debug("element had no children");\r
-        return;\r
-    }\r
-\r
-    XMLToolingConfig& config=XMLToolingConfig::getConfig();\r
-    for (XMLSize_t i = 0; i < childNodes->getLength(); i++) {\r
-        childNode = childNodes->item(i);\r
-        if (childNode->getNodeType() == DOMNode::ELEMENT_NODE) {\r
-            const XMLObjectBuilder* builder = XMLObjectBuilder::getBuilder(static_cast<DOMElement*>(childNode));\r
-            if (!builder) {\r
-                auto_ptr<QName> cname(XMLHelper::getNodeQName(childNode));\r
-                XT_log.error("no default builder installed, found unknown child element (%s)", cname->toString().c_str());\r
-                throw UnmarshallingException("Unmarshaller found unknown child element, but no default builder was found.");\r
-            }\r
-\r
-            if (XT_log.isDebugEnabled()) {\r
-                auto_ptr<QName> cname(XMLHelper::getNodeQName(childNode));\r
-                XT_log.debug("unmarshalling child element (%s)", cname->toString().c_str());\r
-            }\r
-\r
-            // Retain ownership of the unmarshalled child until it's processed by the parent.\r
-            auto_ptr<XMLObject> childObject(builder->buildFromElement(static_cast<DOMElement*>(childNode)));\r
-            processChildElement(childObject.get(), static_cast<DOMElement*>(childNode));\r
-            childObject.release();\r
-        }\r
-        else if (childNode->getNodeType() == DOMNode::TEXT_NODE) {\r
-            XT_log.debug("processing element content");\r
-            processElementContent(childNode->getNodeValue());\r
-        }\r
-    }\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.
+ */
+
+/**
+ * AbstractXMLObjectUnmarshaller.cpp
+ * 
+ * A thread-safe abstract unmarshaller.
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "XMLObjectBuilder.h"
+#include "io/AbstractXMLObjectUnmarshaller.h"
+#include "util/NDC.h"
+#include "util/XMLConstants.h"
+#include "util/XMLHelper.h"
+
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <log4cpp/Category.hh>
+
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+#define XT_log (*static_cast<Category*>(m_log))
+
+XMLObject* AbstractXMLObjectUnmarshaller::unmarshall(DOMElement* element, bool bindDocument)
+{
+#ifdef _DEBUG
+    xmltooling::NDC ndc("unmarshall");
+#endif
+
+    if (getDOM() || hasParent())
+        throw UnmarshallingException("Object already contains data, it cannot be unmarshalled at this stage.");
+
+    if (!XMLString::equals(element->getNamespaceURI(),getElementQName().getNamespaceURI()) ||
+        !XMLString::equals(element->getLocalName(),getElementQName().getLocalPart())) {
+        throw UnmarshallingException("Unrecognized element supplied to implementation for unmarshalling.");
+    }
+
+    if (XT_log.isDebugEnabled()) {
+        auto_ptr_char dname(element->getNodeName());
+        XT_log.debug("unmarshalling DOM element (%s)", dname.get());
+    }
+
+    if (element->hasAttributes()) {
+        unmarshallAttributes(element);
+    }
+
+    unmarshallChildElements(element);
+
+    /* TODO: Signing
+    if (xmlObject instanceof SignableXMLObject) {
+        verifySignature(domElement, xmlObject);
+    }
+    */
+
+    setDOM(element,bindDocument);
+    return this;
+}
+
+void AbstractXMLObjectUnmarshaller::unmarshallAttributes(const DOMElement* domElement)
+{
+#ifdef _DEBUG
+    xmltooling::NDC ndc("unmarshallAttributes");
+#endif
+    static const XMLCh type[]={chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull};
+
+    if (XT_log.isDebugEnabled()) {
+        auto_ptr_char dname(domElement->getNodeName());
+        XT_log.debug("unmarshalling attributes for DOM element (%s)", dname.get());
+    }
+
+    DOMNamedNodeMap* attributes = domElement->getAttributes();
+    if (!attributes) {
+        XT_log.debug("no attributes to unmarshall");
+        return;
+    }
+
+    DOMNode* childNode;
+    DOMAttr* attribute;
+    for (XMLSize_t i=0; i<attributes->getLength(); i++) {
+        childNode = attributes->item(i);
+
+        // The child node should always be an attribute, but just in case
+        if (childNode->getNodeType() != DOMNode::ATTRIBUTE_NODE) {
+            XT_log.debug("encountered child node of type %d in attribute list, ignoring it", childNode->getNodeType());
+            continue;
+        }
+
+        attribute = static_cast<DOMAttr*>(childNode);
+        
+        const XMLCh* nsuri=attribute->getNamespaceURI();
+        if (XMLString::equals(nsuri,XMLConstants::XMLNS_NS)) {
+            if (XMLString::equals(attribute->getLocalName(),XMLConstants::XMLNS_PREFIX)) {
+                XT_log.debug("found default namespace declaration, adding it to the list of namespaces on the XMLObject");
+                addNamespace(Namespace(attribute->getValue(), NULL, true));
+                continue;
+            }
+            else {
+                XT_log.debug("found namespace declaration, adding it to the list of namespaces on the XMLObject");
+                addNamespace(Namespace(attribute->getValue(), attribute->getLocalName(), true));
+                continue;
+            }
+        }
+        else if (XMLString::equals(nsuri,XMLConstants::XSI_NS) && XMLString::equals(attribute->getLocalName(),type)) {
+            XT_log.debug("skipping xsi:type declaration");
+            continue;
+        }
+        else if (nsuri && !XMLString::equals(nsuri,XMLConstants::XML_NS)) {
+            XT_log.debug("found namespace-qualified attribute, adding prefix to the list of namespaces on the XMLObject");
+            addNamespace(Namespace(nsuri, attribute->getPrefix()));
+        }
+
+        XT_log.debug("processing generic attribute");
+        processAttribute(attribute);
+    }
+}
+
+void AbstractXMLObjectUnmarshaller::unmarshallChildElements(const DOMElement* domElement)
+{
+#ifdef _DEBUG
+    xmltooling::NDC ndc("unmarshallChildElements");
+#endif
+
+    if (XT_log.isDebugEnabled()) {
+        auto_ptr_char dname(domElement->getNodeName());
+        XT_log.debug("unmarshalling child elements of DOM element (%s)", dname.get());
+    }
+
+    DOMNodeList* childNodes = domElement->getChildNodes();
+    DOMNode* childNode;
+    if (!childNodes || childNodes->getLength()==0) {
+        XT_log.debug("element had no children");
+        return;
+    }
+
+    for (XMLSize_t i = 0; i < childNodes->getLength(); i++) {
+        childNode = childNodes->item(i);
+        if (childNode->getNodeType() == DOMNode::ELEMENT_NODE) {
+            const XMLObjectBuilder* builder = XMLObjectBuilder::getBuilder(static_cast<DOMElement*>(childNode));
+            if (!builder) {
+                auto_ptr<QName> cname(XMLHelper::getNodeQName(childNode));
+                XT_log.error("no default builder installed, found unknown child element (%s)", cname->toString().c_str());
+                throw UnmarshallingException("Unmarshaller found unknown child element, but no default builder was found.");
+            }
+
+            if (XT_log.isDebugEnabled()) {
+                auto_ptr<QName> cname(XMLHelper::getNodeQName(childNode));
+                XT_log.debug("unmarshalling child element (%s)", cname->toString().c_str());
+            }
+
+            // Retain ownership of the unmarshalled child until it's processed by the parent.
+            auto_ptr<XMLObject> childObject(builder->buildFromElement(static_cast<DOMElement*>(childNode)));
+            processChildElement(childObject.get(), static_cast<DOMElement*>(childNode));
+            childObject.release();
+        }
+        else if (childNode->getNodeType() == DOMNode::TEXT_NODE) {
+            XT_log.debug("processing element content");
+            processElementContent(childNode->getNodeValue());
+        }
+    }
+}
index 5bec638..838c044 100644 (file)
-/*\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
- * ParserPool.cpp\r
- * \r
- * XML parsing\r
- */\r
-\r
-#include "internal.h"\r
-#include "exceptions.h"\r
-#include "util/NDC.h"\r
-#include "util/ParserPool.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <algorithm>\r
-#include <functional>\r
-#include <sys/types.h>\r
-#include <sys/stat.h>\r
-#include <log4cpp/Category.hh>\r
-#include <xercesc/util/PlatformUtils.hpp>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-#include <xercesc/sax/SAXException.hpp>\r
-#include <xercesc/framework/MemBufInputSource.hpp>\r
-#include <xercesc/framework/LocalFileInputSource.hpp>\r
-#include <xercesc/framework/Wrapper4InputSource.hpp>\r
-\r
-using namespace xmltooling;\r
-using namespace std;\r
-using namespace log4cpp;\r
-\r
-ParserPool::ParserPool(bool namespaceAware, bool schemaAware)\r
-    : m_namespaceAware(namespaceAware), m_schemaAware(schemaAware), m_lock(XMLPlatformUtils::makeMutex()) {}\r
-\r
-ParserPool::~ParserPool()\r
-{\r
-    while(!m_pool.empty()) {\r
-        m_pool.top()->release();\r
-        m_pool.pop();\r
-    }\r
-    XMLPlatformUtils::closeMutex(m_lock);\r
-}\r
-\r
-DOMDocument* ParserPool::newDocument()\r
-{\r
-    return DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();\r
-}\r
-\r
-DOMDocument* ParserPool::parse(DOMInputSource& domsrc)\r
-{\r
-    DOMBuilder* parser=checkoutBuilder();\r
-    try {\r
-        DOMDocument* doc=parser->parse(domsrc);\r
-        parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument,true);\r
-        checkinBuilder(parser);\r
-        return doc;\r
-    }\r
-    catch (...) {\r
-        checkinBuilder(parser);\r
-        throw;\r
-    }\r
-}\r
-\r
-DOMDocument* ParserPool::parse(istream& is)\r
-{\r
-    StreamInputSource src(is);\r
-    Wrapper4InputSource domsrc(&src,false);\r
-    return parse(domsrc);\r
-}\r
-\r
-// Functor to double its argument separated by a character and append to a buffer\r
-template <class T> class doubleit\r
-{\r
-public:\r
-    doubleit(T& t, const typename T::value_type& s) : temp(t), sep(s) {}\r
-    void operator() (const pair<T,T>& s) { temp += s.first + sep + s.first + sep; }\r
-    T& temp;\r
-    const typename T::value_type& sep;\r
-};\r
-\r
-bool ParserPool::loadSchema(const XMLCh* nsURI, const XMLCh* pathname)\r
-{\r
-    // Just check the pathname and then directly register the pair into the map.\r
-    \r
-    auto_ptr_char p(pathname);\r
-#ifdef WIN32\r
-    struct _stat stat_buf;\r
-    if (_stat(p.get(), &stat_buf) != 0)\r
-#else\r
-    struct stat stat_buf;\r
-    if (stat(p.get(), &stat_buf) != 0)\r
-#endif\r
-    {\r
-#if _DEBUG\r
-        xmltooling::NDC ndc("loadSchema");\r
-#endif\r
-        Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");\r
-        auto_ptr_char n(nsURI);\r
-        log.error("failed to load schema for (%s), file not found (%s)",n.get(),p.get());\r
-        return false;\r
-    }\r
-\r
-    XMLPlatformUtils::lockMutex(m_lock);\r
-#ifdef HAVE_GOOD_STL\r
-    m_schemaLocMap[nsURI]=pathname;\r
-    m_schemaLocations.erase();\r
-    for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<xstring>(m_schemaLocations,chSpace));\r
-#else\r
-    auto_ptr_char n(nsURI);\r
-    m_schemaLocMap[n.get()]=p.get();\r
-    m_schemaLocations.erase();\r
-    for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<string>(m_schemaLocations,' '));\r
-#endif\r
-    XMLPlatformUtils::unlockMutex(m_lock);\r
-\r
-    return true;\r
-}\r
-\r
-bool ParserPool::loadCatalog(const XMLCh* pathname)\r
-{\r
-#if _DEBUG\r
-    xmltooling::NDC ndc("loadCatalog");\r
-#endif\r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");\r
-\r
-    // XML constants\r
-    static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };\r
-    static const XMLCh catalog[] = { chLatin_c, chLatin_a, chLatin_t, chLatin_a, chLatin_l, chLatin_o, chLatin_g, chNull };\r
-    static const XMLCh uri[] = { chLatin_u, chLatin_r, chLatin_i, chNull };\r
-    static const XMLCh name[] = { chLatin_n, chLatin_a, chLatin_m, chLatin_e, chNull };\r
-    static const XMLCh CATALOG_NS[] = {\r
-        chLatin_u, chLatin_r, chLatin_n, chColon,\r
-        chLatin_o, chLatin_a, chLatin_s, chLatin_i, chLatin_s, chColon,\r
-        chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chColon,\r
-        chLatin_t, chLatin_c, chColon,\r
-        chLatin_e, chLatin_n, chLatin_t, chLatin_i, chLatin_t, chLatin_y, chColon,\r
-        chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chColon,\r
-        chLatin_x, chLatin_m, chLatin_l, chColon,\r
-        chLatin_c, chLatin_a, chLatin_t, chLatin_a, chLatin_l, chLatin_o, chLatin_g, chNull\r
-    };\r
-\r
-    // Parse the catalog with the internal parser pool.\r
-\r
-    if (log.isDebugEnabled()) {\r
-        auto_ptr_char temp(pathname);\r
-        log.debug("loading XML catalog from %s", temp.get());\r
-    }\r
-\r
-    LocalFileInputSource fsrc(NULL,pathname);\r
-    Wrapper4InputSource domsrc(&fsrc,false);\r
-    try {\r
-        DOMDocument* doc=XMLToolingInternalConfig::getInternalConfig().m_parserPool->parse(domsrc);\r
-        \r
-        // Check root element.\r
-        const DOMElement* root=doc->getDocumentElement();\r
-        if (!XMLHelper::isNodeNamed(root,CATALOG_NS,catalog)) {\r
-            auto_ptr_char temp(pathname);\r
-            log.error("unknown root element, failed to load XML catalog from %s", temp.get());\r
-            doc->release();\r
-            return false;\r
-        }\r
-        \r
-        // Fetch all the <uri> elements.\r
-        DOMNodeList* mappings=root->getElementsByTagNameNS(CATALOG_NS,uri);\r
-        XMLPlatformUtils::lockMutex(m_lock);\r
-        for (XMLSize_t i=0; i<mappings->getLength(); i++) {\r
-            root=static_cast<DOMElement*>(mappings->item(i));\r
-            const XMLCh* from=root->getAttributeNS(NULL,name);\r
-            const XMLCh* to=root->getAttributeNS(NULL,uri);\r
-#ifdef HAVE_GOOD_STL\r
-            m_schemaLocMap[from]=to;\r
-#else\r
-            auto_ptr_char f(from);\r
-            auto_ptr_char t(to);\r
-            m_schemaLocMap[f.get()]=t.get();\r
-#endif\r
-        }\r
-        m_schemaLocations.erase();\r
-#ifdef HAVE_GOOD_STL\r
-        for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<xstring>(m_schemaLocations,chSpace));\r
-#else\r
-        for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<string>(m_schemaLocations,' '));\r
-#endif\r
-        XMLPlatformUtils::unlockMutex(m_lock);\r
-        doc->release();\r
-    }\r
-    catch (XMLParserException& e) {\r
-        log.error("catalog loader caught XMLParserException: %s", e.what());\r
-        return false;\r
-    }\r
-\r
-    return true;\r
-}\r
-\r
-DOMInputSource* ParserPool::resolveEntity(const XMLCh* const publicId, const XMLCh* const systemId, const XMLCh* const baseURI)\r
-{\r
-#if _DEBUG\r
-    xmltooling::NDC ndc("resolveEntity");\r
-#endif\r
-    if (!systemId)\r
-        return NULL;\r
-\r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");\r
-    if (log.isDebugEnabled()) {\r
-        auto_ptr_char sysId(systemId);\r
-        auto_ptr_char base(baseURI);\r
-        log.debug("asked to resolve %s with baseURI %s",sysId.get(),base.get() ? base.get() : "(null)");\r
-    }\r
-\r
-    // Find well-known schemas in the specified location.\r
-#ifdef HAVE_GOOD_STL\r
-    map<xstring,xstring>::const_iterator i=m_schemaLocMap.find(systemId);\r
-    if (i!=m_schemaLocMap.end())\r
-        return new Wrapper4InputSource(new LocalFileInputSource(NULL,i->second.c_str()));\r
-#else\r
-    auto_ptr_char temp(systemId);\r
-    map<string,string>::const_iterator i=m_schemaLocMap.find(temp.get());\r
-    auto_ptr_XMLCh temp2(i->second.c_str());\r
-    if (i!=m_schemaLocMap.end())\r
-        return new Wrapper4InputSource(new LocalFileInputSource(NULL,temp2.get()));\r
-#endif    \r
-\r
-    // Shortcircuit the request.\r
-    log.warn("unauthorized entity request, blocking it");\r
-    static const XMLByte nullbuf[] = {0};\r
-    return new Wrapper4InputSource(new MemBufInputSource(nullbuf,0,systemId));\r
-}\r
-\r
-bool ParserPool::handleError(const DOMError& e)\r
-{\r
-#ifdef _DEBUG\r
-    xmltooling::NDC ndc("handleError");\r
-#endif\r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");\r
-    DOMLocator* locator=e.getLocation();\r
-    auto_ptr_char temp(e.getMessage());\r
-\r
-    switch (e.getSeverity()) {\r
-        case DOMError::DOM_SEVERITY_WARNING:\r
-            log.warnStream() << "warning on line " << locator->getLineNumber()\r
-                << ", column " << locator->getColumnNumber()\r
-                << ", message: " << temp.get() << CategoryStream::ENDLINE;\r
-            return true;\r
-\r
-        case DOMError::DOM_SEVERITY_ERROR:\r
-            log.errorStream() << "error on line " << locator->getLineNumber()\r
-                << ", column " << locator->getColumnNumber()\r
-                << ", message: " << temp.get() << CategoryStream::ENDLINE;\r
-            throw XMLParserException(string("error during XML parsing: ") + (temp.get() ? temp.get() : "no message"));\r
-\r
-        case DOMError::DOM_SEVERITY_FATAL_ERROR:\r
-            log.critStream() << "fatal error on line " << locator->getLineNumber()\r
-                << ", column " << locator->getColumnNumber()\r
-                << ", message: " << temp.get() << CategoryStream::ENDLINE;\r
-            throw XMLParserException(string("fatal error during XML parsing: ") + (temp.get() ? temp.get() : "no message"));\r
-    }\r
-    throw XMLParserException(string("unclassified error during XML parsing: ") + (temp.get() ? temp.get() : "no message"));\r
-}\r
-\r
-DOMBuilder* ParserPool::createBuilder()\r
-{\r
-    static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };\r
-    DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(impltype);\r
-    DOMBuilder* parser=static_cast<DOMImplementationLS*>(impl)->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS,0);\r
-    if (m_namespaceAware)\r
-        parser->setFeature(XMLUni::fgDOMNamespaces,true);\r
-    if (m_schemaAware) {\r
-        parser->setFeature(XMLUni::fgXercesSchema,true);\r
-        parser->setFeature(XMLUni::fgDOMValidation,true);\r
-        parser->setFeature(XMLUni::fgXercesCacheGrammarFromParse,true);\r
-        parser->setFeature(XMLUni::fgXercesValidationErrorAsFatal,true);\r
-        \r
-        // We build a "fake" schema location hint that binds each namespace to itself.\r
-        // This ensures the entity resolver will be given the namespace as a systemId it can check. \r
-#ifdef HAVE_GOOD_STL\r
-        parser->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(m_schemaLocations.c_str()));\r
-#else\r
-        auto_ptr_XMLCh temp(m_schemaLocations.c_str());\r
-        parser->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(temp.get()));\r
-#endif\r
-    }\r
-    parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument,true);\r
-    parser->setEntityResolver(this);\r
-    parser->setErrorHandler(this);\r
-    return parser;\r
-}\r
-\r
-DOMBuilder* ParserPool::checkoutBuilder()\r
-{\r
-    XMLPlatformUtils::lockMutex(m_lock);\r
-    try {\r
-        if (m_pool.empty()) {\r
-            DOMBuilder* builder=createBuilder();\r
-            XMLPlatformUtils::unlockMutex(m_lock);\r
-            return builder;\r
-        }\r
-        DOMBuilder* p=m_pool.top();\r
-        m_pool.pop();\r
-        if (m_schemaAware) {\r
-#ifdef HAVE_GOOD_STL\r
-            p->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(m_schemaLocations.c_str()));\r
-#else\r
-            auto_ptr_XMLCh temp2(m_schemaLocations.c_str());\r
-            p->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(temp2.get()));\r
-#endif\r
-        }\r
-        XMLPlatformUtils::unlockMutex(m_lock);\r
-        return p;\r
-    }\r
-    catch(...) {\r
-        XMLPlatformUtils::unlockMutex(m_lock);\r
-        throw;\r
-    }\r
-}\r
-\r
-void ParserPool::checkinBuilder(DOMBuilder* builder)\r
-{\r
-    if (builder) {\r
-        XMLPlatformUtils::lockMutex(m_lock);\r
-        m_pool.push(builder);\r
-        XMLPlatformUtils::unlockMutex(m_lock);\r
-    }\r
-}\r
-\r
-unsigned int StreamInputSource::StreamBinInputStream::readBytes(XMLByte* const toFill, const unsigned int maxToRead)\r
-{\r
-    XMLByte* target=toFill;\r
-    unsigned int bytes_read=0,request=maxToRead;\r
-\r
-    // Fulfill the rest by reading from the stream.\r
-    if (request && !m_is.eof()) {\r
-        try {\r
-            m_is.read(reinterpret_cast<char* const>(target),request);\r
-            m_pos+=m_is.gcount();\r
-            bytes_read+=m_is.gcount();\r
-        }\r
-        catch(...) {\r
-            Category::getInstance(XMLTOOLING_LOGCAT".StreamInputSource").critStream() <<\r
-                "XML::StreamInputSource::StreamBinInputStream::readBytes caught an exception" << CategoryStream::ENDLINE;\r
-            *toFill=0;\r
-            return 0;\r
-        }\r
-    }\r
-    return bytes_read;\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.
+ */
+
+/**
+ * ParserPool.cpp
+ * 
+ * XML parsing
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "util/NDC.h"
+#include "util/ParserPool.h"
+#include "util/XMLHelper.h"
+
+#include <algorithm>
+#include <functional>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <log4cpp/Category.hh>
+#include <xercesc/util/PlatformUtils.hpp>
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <xercesc/sax/SAXException.hpp>
+#include <xercesc/framework/MemBufInputSource.hpp>
+#include <xercesc/framework/LocalFileInputSource.hpp>
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+using namespace xmltooling;
+using namespace std;
+using namespace log4cpp;
+
+ParserPool::ParserPool(bool namespaceAware, bool schemaAware)
+    : m_namespaceAware(namespaceAware), m_schemaAware(schemaAware), m_lock(XMLPlatformUtils::makeMutex()) {}
+
+ParserPool::~ParserPool()
+{
+    while(!m_pool.empty()) {
+        m_pool.top()->release();
+        m_pool.pop();
+    }
+    XMLPlatformUtils::closeMutex(m_lock);
+}
+
+DOMDocument* ParserPool::newDocument()
+{
+    return DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();
+}
+
+DOMDocument* ParserPool::parse(DOMInputSource& domsrc)
+{
+    DOMBuilder* parser=checkoutBuilder();
+    try {
+        DOMDocument* doc=parser->parse(domsrc);
+        parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument,true);
+        checkinBuilder(parser);
+        return doc;
+    }
+    catch (...) {
+        checkinBuilder(parser);
+        throw;
+    }
+}
+
+DOMDocument* ParserPool::parse(istream& is)
+{
+    StreamInputSource src(is);
+    Wrapper4InputSource domsrc(&src,false);
+    return parse(domsrc);
+}
+
+// Functor to double its argument separated by a character and append to a buffer
+template <class T> class doubleit
+{
+public:
+    doubleit(T& t, const typename T::value_type& s) : temp(t), sep(s) {}
+    void operator() (const pair<T,T>& s) { temp += s.first + sep + s.first + sep; }
+    T& temp;
+    const typename T::value_type& sep;
+};
+
+bool ParserPool::loadSchema(const XMLCh* nsURI, const XMLCh* pathname)
+{
+    // Just check the pathname and then directly register the pair into the map.
+    
+    auto_ptr_char p(pathname);
+#ifdef WIN32
+    struct _stat stat_buf;
+    if (_stat(p.get(), &stat_buf) != 0)
+#else
+    struct stat stat_buf;
+    if (stat(p.get(), &stat_buf) != 0)
+#endif
+    {
+#if _DEBUG
+        xmltooling::NDC ndc("loadSchema");
+#endif
+        Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");
+        auto_ptr_char n(nsURI);
+        log.error("failed to load schema for (%s), file not found (%s)",n.get(),p.get());
+        return false;
+    }
+
+    XMLPlatformUtils::lockMutex(m_lock);
+#ifdef HAVE_GOOD_STL
+    m_schemaLocMap[nsURI]=pathname;
+    m_schemaLocations.erase();
+    for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<xstring>(m_schemaLocations,chSpace));
+#else
+    auto_ptr_char n(nsURI);
+    m_schemaLocMap[n.get()]=p.get();
+    m_schemaLocations.erase();
+    for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<string>(m_schemaLocations,' '));
+#endif
+    XMLPlatformUtils::unlockMutex(m_lock);
+
+    return true;
+}
+
+bool ParserPool::loadCatalog(const XMLCh* pathname)
+{
+#if _DEBUG
+    xmltooling::NDC ndc("loadCatalog");
+#endif
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");
+
+    // XML constants
+    static const XMLCh catalog[] = { chLatin_c, chLatin_a, chLatin_t, chLatin_a, chLatin_l, chLatin_o, chLatin_g, chNull };
+    static const XMLCh uri[] = { chLatin_u, chLatin_r, chLatin_i, chNull };
+    static const XMLCh name[] = { chLatin_n, chLatin_a, chLatin_m, chLatin_e, chNull };
+    static const XMLCh CATALOG_NS[] = {
+        chLatin_u, chLatin_r, chLatin_n, chColon,
+        chLatin_o, chLatin_a, chLatin_s, chLatin_i, chLatin_s, chColon,
+        chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chColon,
+        chLatin_t, chLatin_c, chColon,
+        chLatin_e, chLatin_n, chLatin_t, chLatin_i, chLatin_t, chLatin_y, chColon,
+        chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chColon,
+        chLatin_x, chLatin_m, chLatin_l, chColon,
+        chLatin_c, chLatin_a, chLatin_t, chLatin_a, chLatin_l, chLatin_o, chLatin_g, chNull
+    };
+
+    // Parse the catalog with the internal parser pool.
+
+    if (log.isDebugEnabled()) {
+        auto_ptr_char temp(pathname);
+        log.debug("loading XML catalog from %s", temp.get());
+    }
+
+    LocalFileInputSource fsrc(NULL,pathname);
+    Wrapper4InputSource domsrc(&fsrc,false);
+    try {
+        DOMDocument* doc=XMLToolingInternalConfig::getInternalConfig().m_parserPool->parse(domsrc);
+        
+        // Check root element.
+        const DOMElement* root=doc->getDocumentElement();
+        if (!XMLHelper::isNodeNamed(root,CATALOG_NS,catalog)) {
+            auto_ptr_char temp(pathname);
+            log.error("unknown root element, failed to load XML catalog from %s", temp.get());
+            doc->release();
+            return false;
+        }
+        
+        // Fetch all the <uri> elements.
+        DOMNodeList* mappings=root->getElementsByTagNameNS(CATALOG_NS,uri);
+        XMLPlatformUtils::lockMutex(m_lock);
+        for (XMLSize_t i=0; i<mappings->getLength(); i++) {
+            root=static_cast<DOMElement*>(mappings->item(i));
+            const XMLCh* from=root->getAttributeNS(NULL,name);
+            const XMLCh* to=root->getAttributeNS(NULL,uri);
+#ifdef HAVE_GOOD_STL
+            m_schemaLocMap[from]=to;
+#else
+            auto_ptr_char f(from);
+            auto_ptr_char t(to);
+            m_schemaLocMap[f.get()]=t.get();
+#endif
+        }
+        m_schemaLocations.erase();
+#ifdef HAVE_GOOD_STL
+        for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<xstring>(m_schemaLocations,chSpace));
+#else
+        for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<string>(m_schemaLocations,' '));
+#endif
+        XMLPlatformUtils::unlockMutex(m_lock);
+        doc->release();
+    }
+    catch (XMLParserException& e) {
+        log.error("catalog loader caught XMLParserException: %s", e.what());
+        return false;
+    }
+
+    return true;
+}
+
+DOMInputSource* ParserPool::resolveEntity(const XMLCh* const publicId, const XMLCh* const systemId, const XMLCh* const baseURI)
+{
+#if _DEBUG
+    xmltooling::NDC ndc("resolveEntity");
+#endif
+    if (!systemId)
+        return NULL;
+
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");
+    if (log.isDebugEnabled()) {
+        auto_ptr_char sysId(systemId);
+        auto_ptr_char base(baseURI);
+        log.debug("asked to resolve %s with baseURI %s",sysId.get(),base.get() ? base.get() : "(null)");
+    }
+
+    // Find well-known schemas in the specified location.
+#ifdef HAVE_GOOD_STL
+    map<xstring,xstring>::const_iterator i=m_schemaLocMap.find(systemId);
+    if (i!=m_schemaLocMap.end())
+        return new Wrapper4InputSource(new LocalFileInputSource(NULL,i->second.c_str()));
+#else
+    auto_ptr_char temp(systemId);
+    map<string,string>::const_iterator i=m_schemaLocMap.find(temp.get());
+    auto_ptr_XMLCh temp2(i->second.c_str());
+    if (i!=m_schemaLocMap.end())
+        return new Wrapper4InputSource(new LocalFileInputSource(NULL,temp2.get()));
+#endif    
+
+    // Shortcircuit the request.
+    log.warn("unauthorized entity request, blocking it");
+    static const XMLByte nullbuf[] = {0};
+    return new Wrapper4InputSource(new MemBufInputSource(nullbuf,0,systemId));
+}
+
+bool ParserPool::handleError(const DOMError& e)
+{
+#ifdef _DEBUG
+    xmltooling::NDC ndc("handleError");
+#endif
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");
+    DOMLocator* locator=e.getLocation();
+    auto_ptr_char temp(e.getMessage());
+
+    switch (e.getSeverity()) {
+        case DOMError::DOM_SEVERITY_WARNING:
+            log.warnStream() << "warning on line " << locator->getLineNumber()
+                << ", column " << locator->getColumnNumber()
+                << ", message: " << temp.get() << CategoryStream::ENDLINE;
+            return true;
+
+        case DOMError::DOM_SEVERITY_ERROR:
+            log.errorStream() << "error on line " << locator->getLineNumber()
+                << ", column " << locator->getColumnNumber()
+                << ", message: " << temp.get() << CategoryStream::ENDLINE;
+            throw XMLParserException(string("error during XML parsing: ") + (temp.get() ? temp.get() : "no message"));
+
+        case DOMError::DOM_SEVERITY_FATAL_ERROR:
+            log.critStream() << "fatal error on line " << locator->getLineNumber()
+                << ", column " << locator->getColumnNumber()
+                << ", message: " << temp.get() << CategoryStream::ENDLINE;
+            throw XMLParserException(string("fatal error during XML parsing: ") + (temp.get() ? temp.get() : "no message"));
+    }
+    throw XMLParserException(string("unclassified error during XML parsing: ") + (temp.get() ? temp.get() : "no message"));
+}
+
+DOMBuilder* ParserPool::createBuilder()
+{
+    static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };
+    DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(impltype);
+    DOMBuilder* parser=static_cast<DOMImplementationLS*>(impl)->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS,0);
+    if (m_namespaceAware)
+        parser->setFeature(XMLUni::fgDOMNamespaces,true);
+    if (m_schemaAware) {
+        parser->setFeature(XMLUni::fgXercesSchema,true);
+        parser->setFeature(XMLUni::fgDOMValidation,true);
+        parser->setFeature(XMLUni::fgXercesCacheGrammarFromParse,true);
+        parser->setFeature(XMLUni::fgXercesValidationErrorAsFatal,true);
+        
+        // We build a "fake" schema location hint that binds each namespace to itself.
+        // This ensures the entity resolver will be given the namespace as a systemId it can check. 
+#ifdef HAVE_GOOD_STL
+        parser->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(m_schemaLocations.c_str()));
+#else
+        auto_ptr_XMLCh temp(m_schemaLocations.c_str());
+        parser->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(temp.get()));
+#endif
+    }
+    parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument,true);
+    parser->setEntityResolver(this);
+    parser->setErrorHandler(this);
+    return parser;
+}
+
+DOMBuilder* ParserPool::checkoutBuilder()
+{
+    XMLPlatformUtils::lockMutex(m_lock);
+    try {
+        if (m_pool.empty()) {
+            DOMBuilder* builder=createBuilder();
+            XMLPlatformUtils::unlockMutex(m_lock);
+            return builder;
+        }
+        DOMBuilder* p=m_pool.top();
+        m_pool.pop();
+        if (m_schemaAware) {
+#ifdef HAVE_GOOD_STL
+            p->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(m_schemaLocations.c_str()));
+#else
+            auto_ptr_XMLCh temp2(m_schemaLocations.c_str());
+            p->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(temp2.get()));
+#endif
+        }
+        XMLPlatformUtils::unlockMutex(m_lock);
+        return p;
+    }
+    catch(...) {
+        XMLPlatformUtils::unlockMutex(m_lock);
+        throw;
+    }
+}
+
+void ParserPool::checkinBuilder(DOMBuilder* builder)
+{
+    if (builder) {
+        XMLPlatformUtils::lockMutex(m_lock);
+        m_pool.push(builder);
+        XMLPlatformUtils::unlockMutex(m_lock);
+    }
+}
+
+unsigned int StreamInputSource::StreamBinInputStream::readBytes(XMLByte* const toFill, const unsigned int maxToRead)
+{
+    XMLByte* target=toFill;
+    unsigned int bytes_read=0,request=maxToRead;
+
+    // Fulfill the rest by reading from the stream.
+    if (request && !m_is.eof()) {
+        try {
+            m_is.read(reinterpret_cast<char* const>(target),request);
+            m_pos+=m_is.gcount();
+            bytes_read+=m_is.gcount();
+        }
+        catch(...) {
+            Category::getInstance(XMLTOOLING_LOGCAT".StreamInputSource").critStream() <<
+                "XML::StreamInputSource::StreamBinInputStream::readBytes caught an exception" << CategoryStream::ENDLINE;
+            *toFill=0;
+            return 0;
+        }
+    }
+    return bytes_read;
+}
index 32dd9d7..1890f97 100644 (file)
@@ -194,7 +194,7 @@ namespace xmltooling {
             Container& sublist,
             typename std::list<_Ty*>* backing,
             typename std::list<_Ty*>::iterator ins_fence
-            ) : m_parent(parent), m_container(sublist), m_list(backing), m_fence(ins_fence) {
+            ) : m_container(sublist), m_list(backing), m_fence(ins_fence), m_parent(parent) {
         }
 
         /// @cond OFF
index 65044a3..ae00257 100644 (file)
@@ -16,7 +16,7 @@ endif
 
 xmltoolingtest_h = \
     ComplexXMLObjectTest.h \
-    ExceptionText.h \
+    ExceptionTest.h \
     MarshallingTest.h \
     UnmarshallingTest.h \
     xmltoolingtest.h \