Moved URLEncoder down to tooling lib, added exception->querystring method.
authorScott Cantor <cantor.2@osu.edu>
Thu, 8 Mar 2007 04:42:01 +0000 (04:42 +0000)
committerScott Cantor <cantor.2@osu.edu>
Thu, 8 Mar 2007 04:42:01 +0000 (04:42 +0000)
xmltooling/Makefile.am
xmltooling/XMLToolingConfig.cpp
xmltooling/XMLToolingConfig.h
xmltooling/exceptions.cpp
xmltooling/exceptions.h
xmltooling/util/URLEncoder.cpp [new file with mode: 0644]
xmltooling/util/URLEncoder.h [new file with mode: 0644]
xmltooling/xmltooling.vcproj

index d1d8467..c3f76e2 100644 (file)
@@ -92,6 +92,7 @@ utilinclude_HEADERS = \
        util/StorageService.h \
        util/TemplateEngine.h \
        util/Threads.h \
+       util/URLEncoder.h \
        util/XMLConstants.h \
        util/XMLHelper.h \
        util/XMLObjectChildrenList.h
@@ -161,6 +162,7 @@ libxmltooling_la_SOURCES = \
        util/ReplayCache.cpp \
        util/StorageService.cpp \
        util/TemplateEngine.cpp \
+       util/URLEncoder.cpp \
        util/XMLConstants.cpp \
        util/XMLHelper.cpp \
        validation/ValidatorSuite.cpp \
index 4a686fe..5b245d2 100644 (file)
@@ -34,6 +34,7 @@
 #include "util/ReplayCache.h"
 #include "util/StorageService.h"
 #include "util/TemplateEngine.h"
+#include "util/URLEncoder.h"
 #include "util/XMLConstants.h"
 #include "validation/ValidatorSuite.h"
 
@@ -176,6 +177,12 @@ void XMLToolingConfig::setTemplateEngine(TemplateEngine* templateEngine)
     m_templateEngine = templateEngine;
 }
 
+void XMLToolingConfig::setURLEncoder(URLEncoder* urlEncoder)
+{
+    delete m_urlEncoder;
+    m_urlEncoder = urlEncoder;
+}
+
 bool XMLToolingInternalConfig::init()
 {
 #ifdef _DEBUG
@@ -226,6 +233,8 @@ bool XMLToolingInternalConfig::init()
         registerKeyInfoClasses();
         registerEncryptionClasses();
         registerSOAPClasses();
+
+        m_urlEncoder = new URLEncoder();
         
         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(XMLParserException,xmltooling);
         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(XMLObjectException,xmltooling);
@@ -297,6 +306,9 @@ void XMLToolingInternalConfig::term()
     delete m_templateEngine;
     m_templateEngine = NULL;
 
+    delete m_urlEncoder;
+    m_urlEncoder = NULL;
+
     for (vector<void*>::reverse_iterator i=m_libhandles.rbegin(); i!=m_libhandles.rend(); i++) {
 #if defined(WIN32)
         FARPROC fn=GetProcAddress(static_cast<HMODULE>(*i),"xmltooling_extension_term");
index 7a333d6..cd04d71 100644 (file)
@@ -48,6 +48,7 @@ namespace xmltooling {
     class XMLTOOL_API SOAPTransport;
     class XMLTOOL_API StorageService;
     class XMLTOOL_API TemplateEngine;
+    class XMLTOOL_API URLEncoder;
 
     /**
      * Singleton object that manages library startup/shutdown.configuration.
@@ -60,13 +61,17 @@ namespace xmltooling {
     {
         MAKE_NONCOPYABLE(XMLToolingConfig);
     protected:
-        XMLToolingConfig() : m_replayCache(NULL), m_templateEngine(NULL), clock_skew_secs(180) {}
+        XMLToolingConfig() : m_replayCache(NULL), m_templateEngine(NULL), m_urlEncoder(NULL), clock_skew_secs(180) {}
         
         /** Global ReplayCache instance. */
         ReplayCache* m_replayCache;
         
         /** Global TemplateEngine instance. */
         TemplateEngine* m_templateEngine;
+
+        /** Global URLEncoder instance for use by URL-related functions. */
+        URLEncoder* m_urlEncoder;
+
     public:
         virtual ~XMLToolingConfig() {}
 
@@ -158,6 +163,24 @@ namespace xmltooling {
         }
 
         /**
+         * Sets the global URLEncoder instance.
+         * This method must be externally synchronized with any code that uses the object.
+         * Any previously set object is destroyed.
+         * 
+         * @param urlEncoder   new URLEncoder instance to store
+         */
+        void setURLEncoder(URLEncoder* urlEncoder);
+        
+        /**
+         * Returns the global URLEncoder instance.
+         * 
+         * @return  global URLEncoder or NULL
+         */
+        const URLEncoder* getURLEncoder() const {
+            return m_urlEncoder;
+        }
+        
+        /**
          * Sets the global TemplateEngine instance.
          * This method must be externally synchronized with any code that uses the object.
          * Any previously set object is destroyed.
index 56ce6d3..3b37262 100644 (file)
@@ -23,6 +23,7 @@
 #include "internal.h"
 #include "exceptions.h"
 #include "XMLToolingConfig.h"
+#include "util/URLEncoder.h"
 #include "util/XMLConstants.h"
 #include "util/XMLHelper.h"
 
@@ -222,13 +223,22 @@ string XMLToolingException::toString() const
     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++) {
+    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;
 }
 
+string XMLToolingException::toQueryString() const
+{
+    const URLEncoder* enc = XMLToolingConfig::getConfig().getURLEncoder();
+    string q("type=");
+    q = q + enc->encode(getClassName()) + "&message=" + enc->encode(what());
+    for (map<string,string>::const_iterator i=m_params.begin(); i!=m_params.end(); i++)
+        q = q + '&' + i->first + '=' + enc->encode(i->second.c_str());
+    return q;
+}
+
 XMLToolingException* XMLToolingException::fromStream(std::istream& in)
 {
     static const XMLCh exception[] = { chLatin_e, chLatin_x, chLatin_c, chLatin_e, chLatin_p, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull };
index ce032e1..643adbe 100644 (file)
@@ -276,6 +276,14 @@ namespace xmltooling {
          */
         std::string toString() const;
 
+        /**
+         * Returns a set of query string name/value pairs, URL-encoded, representing the
+         * exception's type, message, and parameters.
+         *
+         * @return  the query string representation
+         */
+        std::string toQueryString() const;
+
     private:
         std::string m_msg;
         mutable std::string m_processedmsg;
diff --git a/xmltooling/util/URLEncoder.cpp b/xmltooling/util/URLEncoder.cpp
new file mode 100644 (file)
index 0000000..633a6f2
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * URLEncoder.cpp
+ * 
+ * Interface to a URL-encoding mechanism along with a
+ * default implementation. 
+ */
+
+#include "internal.h"
+#include "util/URLEncoder.h"
+
+using namespace xmltooling;
+using namespace std;
+
+static char x2c(char *what)
+{
+    register char digit;
+
+    digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
+    digit *= 16;
+    digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
+    return(digit);
+}
+
+void URLEncoder::decode(char* s) const
+{
+    register int x,y;
+
+    for(x=0,y=0;s[y];++x,++y)
+    {
+        if((s[x] = s[y]) == '%')
+        {
+            s[x] = x2c(&s[y+1]);
+            y+=2;
+        }
+        else if (s[x] == '+')
+        {
+            s[x] = ' ';
+        }
+    }
+    s[x] = '\0';
+}
+
+static inline char hexchar(unsigned short s)
+{
+    return (s<=9) ? ('0' + s) : ('A' + s - 10);
+}
+
+string URLEncoder::encode(const char* s) const
+{
+    string ret;
+    for (; *s; s++) {
+        if (isBad(*s)) {
+            ret+='%';
+            ret+=hexchar((unsigned char)*s >> 4);
+            ret+=hexchar((unsigned char)*s & 0x0F);
+        }
+        else
+            ret+=*s;
+    }
+    return ret;
+}
diff --git a/xmltooling/util/URLEncoder.h b/xmltooling/util/URLEncoder.h
new file mode 100644 (file)
index 0000000..d30f0f1
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file xmltooling/util/URLEncoder.h
+ * 
+ * Interface to a URL-encoding mechanism along with a
+ * default implementation.
+ */
+
+#ifndef __xmltool_urlenc_h__
+#define __xmltool_urlenc_h__
+
+#include <xmltooling/base.h>
+
+namespace xmltooling {
+    /**
+     * Interface to a URL-encoding mechanism along with a default implementation.
+     * 
+     * Since URL-encoding is not canonical, it's important that the same
+     * encoder is used during some library operations and the calling code.
+     * Applications can supply an alternative implementation to the library
+     * if required.
+     */
+    class XMLTOOL_API URLEncoder {
+        MAKE_NONCOPYABLE(URLEncoder);
+    public:
+        URLEncoder() {}
+        virtual ~URLEncoder() {}
+        
+        /**
+         * Produce a URL-safe but equivalent version of the input string.
+         * 
+         * @param s input string to encode
+         * @return a string object containing the result of encoding the input
+         */
+        virtual std::string encode(const char* s) const;
+        
+        /**
+         * Perform an in-place decoding operation on the input string.
+         * The resulting string will be NULL-terminated.
+         * 
+         * @param s input string to decode in a writable buffer
+         */
+        virtual void decode(char* s) const;
+        
+    protected:
+        /**
+         * Returns true iff the input character requires encoding.
+         * 
+         * @param ch    the character to check
+         * @return  true iff the character should be encoded 
+         */
+        virtual bool isBad(char ch) const {
+            static char badchars[]="=&/?:\"\\+<>#%{}|^~[]`;@";
+            return (strchr(badchars,ch) || ch<=0x20 || ch>=0x7F);
+        }
+    };
+};
+
+#endif /* __xmltool_urlenc_h__ */
index e09b176..6846084 100644 (file)
                                        >\r
                                </File>\r
                                <File\r
+                                       RelativePath=".\util\URLEncoder.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
                                        RelativePath=".\util\Win32Threads.cpp"\r
                                        >\r
                                </File>\r
                                        >\r
                                </File>\r
                                <File\r
+                                       RelativePath=".\util\URLEncoder.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
                                        RelativePath=".\util\XMLConstants.h"\r
                                        >\r
                                </File>\r