include/Network/URLHandler.hpp

Go to the documentation of this file.
00001 #ifndef hpp_CPP_URLHandler_CPP_hpp
00002 #define hpp_CPP_URLHandler_CPP_hpp
00003 
00004 // We need strings
00005 #include "../Strings/Strings.hpp"
00006 
00008 namespace Network
00009 {
00014     class URL
00015     {
00016         // Type used in this class 
00017     public:
00019         typedef Strings::FastString     String;
00020 
00021         // Members
00022     protected:
00024         String  scheme;
00026         String  authority;
00028         String  path;
00030         String  query;
00032         String  fragment;
00033 
00034         // Helpers
00035     private:
00037         bool splitURI(const String & inputURL);
00039         void normalizePath(String & pathToNormalize) const;
00040         
00041         // Interface
00042     public:    
00044         inline bool isValid() { return authority.getLength() > 0; }
00047         inline String asURI(const String & defaultScheme = "") const 
00048         { 
00049             String schemeTmp = scheme.getLength() ? scheme : defaultScheme; 
00050             schemeTmp += "://" + authority + ((path.getLength() && path[0] != '/') ? "/" : "") + path;
00051             if (query.getLength()) schemeTmp += "?" + query;
00052             if (fragment.getLength()) schemeTmp += "#" + fragment;
00053             return schemeTmp;
00054         }
00056         inline URL appendRelativePath(String newPath) const
00057         {
00058             URL ret(scheme, authority, "");
00059             // Check if new path contain a fragment or a query
00060             int fragmentPos = newPath.reverseFind("#", newPath.getLength());
00061             if (fragmentPos != -1)
00062             {
00063                 ret.fragment = newPath.midString(fragmentPos+1, newPath.getLength());
00064                 newPath = newPath.midString(0, fragmentPos);
00065             }
00066             int queryPos = newPath.reverseFind("?", newPath.getLength());
00067             if (queryPos != -1) 
00068             {
00069                 ret.query = newPath.midString(queryPos+1, newPath.getLength());
00070                 newPath = newPath.midString(0, queryPos);
00071             }
00072             // Let's first normalize newPath
00073             // First remove any /./ in path
00074             newPath.findAndReplace("/./", "/", 0);
00075             // If the newPath start by /, just replace it
00076             if (newPath[0] == '/') { ret.path = newPath; normalizePath(ret.path); return ret; } 
00077             
00078             // Check if this path points to a file
00079             int lastSlashInNewPath = newPath.reverseFind('/', newPath.getLength()) + 1;
00080             bool isFile = isFile = newPath.Find('.', lastSlashInNewPath) != -1;
00081 
00082             // Need to first split the current path to trim any remaining filename
00083             String curPath = path;
00084             int lastSlash = curPath.reverseFind('/', curPath.getLength());
00085             if (lastSlash != -1) curPath = curPath.midString(0, lastSlash);
00086  
00087             // Need to count how many '../' this path contains
00088             // For each one, we have to go up one level in the current path
00089             int upPos = newPath.Find("../");
00090             while (upPos != -1)
00091             {
00092                 // Remove one level of the current path
00093                 lastSlash = curPath.reverseFind('/', curPath.getLength());
00094                 if (lastSlash != -1) curPath = curPath.midString(0, lastSlash);
00095                 newPath = newPath.midString(upPos + 3, newPath.getLength());
00096                 upPos = newPath.Find("../");
00097             }
00098 
00099             // Then concatenate
00100             ret.path = curPath + (curPath.getLength() ? "/" : "") + newPath;
00101             ret.path += (!isFile && ret.path[ret.path.getLength() - 1] != '/') ? "/" : "";
00102             if (ret.path[0] != '/') ret.path = "/" + ret.path;
00103             // Normalize any /./ in path
00104             normalizePath(ret.path);
00105             return ret;
00106         }
00108         static String escapedURI(const String & inputURL);
00109 
00111         inline uint16 stripPortFromAuthority(uint16 defaultPortValue) 
00112         {
00113             int portPos = authority.reverseFind(':', authority.getLength());
00114             if (portPos != -1)
00115             {
00116                 String portValue = authority.midString(portPos+1, authority.getLength());
00117                 authority = authority.midString(0, portPos);
00118                 portPos = defaultPortValue;
00119                 portValue.Scan("%d", &portPos);
00120                 if (portPos < 0) portPos = 0;
00121                 if (portPos > 65535) portPos = 65535;
00122                 return (uint16)portPos;
00123             }
00124             return defaultPortValue;
00125         }
00126 
00127 
00128         // Accessor 
00129     public:
00131         inline const String & getAuthority() const { return authority; }
00133         inline const String & getScheme() const { return scheme; }
00135         inline const String & getPath() const { return path; }
00137         inline const String & getQuery() const { return query; }
00139         inline const String & getFragment() const { return fragment; }
00140 
00141 
00142 
00143     public:
00145         URL() {}
00147         URL(const String & inputURL, const String & defaultScheme = "")
00148         {
00149             splitURI(inputURL);
00150             if (!scheme.getLength()) scheme = defaultScheme;
00151         }
00153         URL(const String & _scheme, const String & _authority, const String & _path, const String & _query = "", const String & _fragment = "")
00154             : scheme(_scheme), authority(_authority), path(_path), query(_query), fragment(_fragment) { }
00155     };
00156 }
00157 
00158 #endif

(C) An X-Ryl669 project 2007

This document describes Unlimited Zooming Interface source code. UZI stands for Unlimited Zooming Interface, and source code license is