home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 5164 / miletos.7z / uri.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2011-04-02  |  3.6 KB  |  178 lines

  1. #define __MILETOS_URI_CPP__
  2.  
  3. //
  4. // Libmiletos
  5. //
  6. // Copyright (C) Lauris Kaplinski 2007-2009
  7. //
  8.  
  9. #include <stdlib.h>
  10.  
  11. #include <libarikkei/dict.h>
  12.  
  13. #include "zip.h"
  14. #include "xfpk.h"
  15. #include "xpp.h"
  16.  
  17. #include "uri.h"
  18.  
  19. #ifdef WIN32
  20. #define strdup _strdup
  21. #endif
  22.  
  23. namespace Miletos {
  24.  
  25. namespace URI {
  26.  
  27. // Location
  28.  
  29. Location::Location (const char *address)
  30. {
  31.     arikkei_url_setup (this, (const unsigned char *) address, NULL);
  32. }
  33.  
  34. Location::Location (const char *address, const char *defaultprotocol)
  35. {
  36.     arikkei_url_setup (this, (const unsigned char *) address, (const unsigned char *) defaultprotocol);
  37. }
  38.  
  39. Location::~Location (void)
  40. {
  41.     arikkei_url_release (this);
  42. }
  43.  
  44. char *
  45. Location::getParent (int levels)
  46. {
  47.     if (!base) return NULL;
  48.     const unsigned char *p = (const unsigned char *) strrchr ((const char *) base, '/');
  49.     if (!p) return NULL;
  50.     for (int i = 0; i < levels; i++) {
  51.         if (p == base) return NULL;
  52.         p -= 1;
  53.         while ((p > base) && (*p != '/')) p--;
  54.         if (*p != '/') return NULL;
  55.     }
  56.     size_t len = p - base + 1;
  57.     char *parent = (char *) malloc (len + 1);
  58.     memcpy (parent, base, len);
  59.     parent[len] = 0;
  60.     return parent;
  61. }
  62.  
  63. // URLHandler
  64.  
  65. URLHandler::URLHandler (const char *purl)
  66. : refcount(1)
  67. {
  68.     arikkei_url_setup (&url, (const unsigned char *) purl, NULL);
  69. }
  70.  
  71. URLHandler::~URLHandler (void)
  72. {
  73.     arikkei_url_release (&url);
  74. }
  75.  
  76. const unsigned char *
  77. URLHandler::mmapData (const char *name, size_t *size)
  78. {
  79.     if (!name || !*name) return NULL;
  80.     if (strncmp (name, (const char *) url.path, strlen ((const char *) url.path))) return NULL;
  81.     return mmapDataRelative (name + strlen ((const char *) url.path), size);
  82. }
  83.  
  84. // Resolver
  85.  
  86. Resolver::~Resolver (void)
  87. {
  88.     // Free schemes
  89.     for (size_t i = 0; i < schemes.size (); i++) {
  90.         free (schemes[i]);
  91.     }
  92. }
  93.  
  94. // This grabs reference to handler
  95.  
  96. void
  97. Resolver::addURLHandler (const char *scheme, URLHandler * (* constructor) (const char *))
  98. {
  99.     if (!scheme || !*scheme || !constructor) return;
  100.     char *pscheme = strdup (scheme);
  101.     schemes.push_back (pscheme);
  102.     constructors.insert (pscheme, constructor);
  103. }
  104.  
  105. URLHandler *
  106. Resolver::getHandler (const char *url)
  107. {
  108.     if (!url || !*url) return NULL;
  109.     char *purl = strdup (url);
  110.     char *cpos = strchr (purl, ':');
  111.     if (!cpos) {
  112.         // No scheme specified
  113.         free (purl);
  114.         return NULL;
  115.     }
  116.     *cpos = 0;
  117.     URLHandler * (* constructor) (const char *) = constructors.lookup (purl);
  118.     if (!constructor) {
  119.         // No handler for such scheme
  120.         free (purl);
  121.         return NULL;
  122.     }
  123.     free (purl);
  124.     return constructor (url);
  125. }
  126.  
  127. // FileHandler
  128.  
  129. class FileHandler : public URLHandler {
  130. private:
  131.     // URLHandler implementation
  132.     virtual const unsigned char *mmapData (const char *name, size_t *size);
  133.     virtual void munmapData (const unsigned char *data);
  134. public:
  135. };
  136.  
  137. // Global data
  138.  
  139. static Resolver *globalresolver = NULL;
  140.  
  141. // Scheme should be specified without trailing colon
  142.  
  143. static void
  144. init_global_resolver (void)
  145. {
  146.     globalresolver = new Resolver();
  147.     globalresolver->addURLHandler ("file", FileSystem::URLHandler::newURLHandler);
  148.     globalresolver->addURLHandler ("xfpk", Xfpk::URLHandler::newURLHandler);
  149.     globalresolver->addURLHandler ("xpp", Xpp::URLHandler::newURLHandler);
  150.     globalresolver->addURLHandler ("zip", Zip::URLHandler::newURLHandler);
  151. }
  152.  
  153. unsigned int
  154. isRelativeURL (const char *uri)
  155. {
  156.     return !uri || !strchr (uri, ':');
  157. }
  158.  
  159. void
  160. addURLHandler (const char *scheme, URLHandler * (* constructor) (const char *))
  161. {
  162.     if (!globalresolver) init_global_resolver ();
  163.     globalresolver->addURLHandler (scheme, constructor);
  164. }
  165.  
  166. URLHandler *
  167. getHandler (const char *url)
  168. {
  169.     if (!url || !*url) return NULL;
  170.     if (!globalresolver) init_global_resolver ();
  171.     return globalresolver->getHandler (url);
  172. }
  173.  
  174. } // Namespace URI
  175.  
  176. } // Namespace Miletos
  177.  
  178.