Hi,

This patch adds a bunch of tests related to efreet_uri, and enabled
parsing of usernames/passwords/ports along with the rest of the uri
scheme. the encode itself has also been updated to support all of this. 

I wasn't exactly sure why efreet_uri_encode didn't even return the
hostname. if a program can't handle such a valid uri, it's a program
bug, thus it shouldn't be a limit of the library.
Index: src/lib/efreet_uri.h
===================================================================
--- src/lib/efreet_uri.h	(revision 40539)
+++ src/lib/efreet_uri.h	(working copy)
@@ -24,7 +24,11 @@ struct Efreet_Uri
 {
     const char *protocol;   /**< The protocol used (usually 'file')*/
     const char *hostname;   /**< The name of the host if any, or NULL */
+    const char *username;   /**< The username, or NULL */
+    const char *password;   /**< The password, or NULL */
     const char *path;       /**< The full file path whitout protocol nor host*/
+
+    int         port;       /**< The port, or 0 */
 };
 
 
Index: src/lib/efreet_uri.c
===================================================================
--- src/lib/efreet_uri.c	(revision 40539)
+++ src/lib/efreet_uri.c	(working copy)
@@ -6,6 +6,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 #include <ctype.h>
 #include <limits.h>
 
@@ -17,6 +18,8 @@
 # include <Evil.h>
 #endif
 
+#include <Ecore_Str.h>
+
 #include "Efreet.h"
 #include "efreet_private.h"
 
@@ -33,15 +36,20 @@ efreet_uri_decode(const char *full_uri)
 {
     Efreet_Uri *uri;
     const char *p;
-    char protocol[64], hostname[_POSIX_HOST_NAME_MAX], path[PATH_MAX];
-    int i = 0;
+    char protocol[64], hostname[_POSIX_HOST_NAME_MAX], path[PATH_MAX], buf[PATH_MAX],
+         username[_POSIX_HOST_NAME_MAX], password[_POSIX_HOST_NAME_MAX], port[6];
+    int i = 0, auth_limit = _POSIX_HOST_NAME_MAX * 3;
 
-    /* An uri should be in the form <protocol>://<hostname>/<path> */
+    /* An uri should be in the form <protocol>://<authority>/<path> */
     if (!strstr(full_uri, "://")) return NULL;
 
     memset(protocol, 0, 64);
+    memset(username, 0, _POSIX_HOST_NAME_MAX);
+    memset(password, 0, _POSIX_HOST_NAME_MAX);
     memset(hostname, 0, _POSIX_HOST_NAME_MAX);
+    memset(port, 0, 6);
     memset(path, 0, PATH_MAX);
+    memset(buf, 0, PATH_MAX);
 
     /* parse protocol */
     p = full_uri;
@@ -49,13 +57,41 @@ efreet_uri_decode(const char *full_uri)
          protocol[i] = *p;
     protocol[i] = '\0';
 
-    /* parse hostname */
+    /* parse authority */
     p += 3;
     if (*p != '/')
     {
-        for (i = 0; *p != '/' && *p != '\0' && i < _POSIX_HOST_NAME_MAX; p++, i++)
-            hostname[i] = *p;
-        hostname[i] = '\0';
+        for (i = 0; *p != '/' && *p != '\0' && i < auth_limit; p++, i++)
+        {
+            if (*p == ':')
+            {
+                memcpy(hostname, buf, _POSIX_HOST_NAME_MAX);
+                memset(buf, 0, PATH_MAX);
+                i = -1;
+            }
+            else if (*p == '@')
+            {
+                /* the previous segment is the password */
+                if (hostname[0] != '\0')
+                {
+                    memcpy(username, hostname, _POSIX_HOST_NAME_MAX);
+                    memcpy(password, buf, _POSIX_HOST_NAME_MAX);
+                    memset(hostname, 0, _POSIX_HOST_NAME_MAX);
+                }
+                else
+                    memcpy(username, buf, _POSIX_HOST_NAME_MAX);
+                memset(buf, 0, PATH_MAX);
+                i = -1;
+            }
+            else
+                buf[i] = *p;
+        }
+        buf[i] = '\0';
+        /* the previous segment is the port */
+        if (hostname[0] != '\0')
+            memcpy(port, buf, 6);
+        else
+            memcpy(hostname, buf, _POSIX_HOST_NAME_MAX);
     }
     else
         hostname[0] = '\0';
@@ -79,7 +115,10 @@ efreet_uri_decode(const char *full_uri)
     if (!uri) return NULL;
 
     uri->protocol = eina_stringshare_add(protocol);
+    uri->username = eina_stringshare_add(username);
+    uri->password = eina_stringshare_add(password);
     uri->hostname = eina_stringshare_add(hostname);
+    uri->port = atoi(port);
     uri->path = eina_stringshare_add(path);
 
     return uri;
@@ -91,23 +130,46 @@ efreet_uri_decode(const char *full_uri)
  * @brief Get the string rapresentation of the given uri struct escaping
  * illegal caracters. Remember to free the string with eina_stringshare_del()
  * when you don't need it anymore.
- * @note The resulting string will contain the protocol and the path but not
- * the hostname, as many apps doesn't handle it.
  */
 EAPI const char *
 efreet_uri_encode(Efreet_Uri *uri)
 {
     char dest[PATH_MAX * 3 + 4];
+    int full_size = PATH_MAX * 3 + 4;
     const char *p;
     int i;
 
     if (!uri || !uri->path || !uri->protocol) return NULL;
-    memset(dest, 0, PATH_MAX * 3 + 4);
+    memset(dest, 0, full_size);
     snprintf(dest, strlen(uri->protocol) + 4, "%s://", uri->protocol);
 
-    /* Most app doesn't handle the hostname in the uri so it's put to NULL */
-    for (i = strlen(uri->protocol) + 3, p = uri->path; *p != '\0'; p++, i++)
+    if (*uri->username != '\0')
     {
+        ecore_strlcat(dest, uri->username, full_size);
+        if (*uri->password != '\0')
+        {
+            const char *buf[_POSIX_HOST_NAME_MAX];
+
+            snprintf(buf, sizeof(buf), ":%s", uri->password);
+            ecore_strlcat(dest, buf, full_size);
+        }
+        ecore_strlcat(dest, "@", full_size);
+    }
+
+    if (*uri->hostname != '\0')
+    {
+        ecore_strlcat(dest, uri->hostname, full_size);
+        if (uri->port)
+        {
+            const char *buf[_POSIX_HOST_NAME_MAX];
+
+            snprintf(buf, sizeof(buf), ":%d", uri->port);
+            ecore_strlcat(dest, buf, full_size);
+        }
+    }
+
+    for (i = strlen(dest), p = uri->path; *p != '\0'; p++, i++)
+    {
         if (isalnum(*p) || strchr("/$-_.+!*'()", *p))
             dest[i] = *p;
         else
@@ -129,7 +191,9 @@ efreet_uri_free(Efreet_Uri *uri)
 {
     if (!uri) return;
     IF_RELEASE(uri->protocol);
+    IF_RELEASE(uri->username);
+    IF_RELEASE(uri->password);
+    IF_RELEASE(uri->hostname);
     IF_RELEASE(uri->path);
-    IF_RELEASE(uri->hostname);
     FREE(uri);
 }
Index: src/bin/ef_uri.c
===================================================================
--- src/bin/ef_uri.c	(revision 0)
+++ src/bin/ef_uri.c	(revision 0)
@@ -0,0 +1,334 @@
+/* vim: set sw=4 ts=4 sts=4 et: */
+#include "Efreet.h"
+#include "efreet_private.h"
+#include <stdio.h>
+
+#define ERR(...) EINA_ERROR_PERR(__VA_ARGS__)
+
+int
+ef_cb_uri_decode(void)
+{
+    Efreet_Uri *uri;
+    const char *full_uri = "file:///tmp/foo/bar";
+
+    printf("\n");
+
+    uri = efreet_uri_decode(full_uri);
+
+    if (!uri->protocol || *uri->protocol == '\0')
+    {
+        ERR("No protocol obtained from uri: %s\n", full_uri);
+        return 0;
+    }
+
+    if (strcmp(uri->protocol, "file"))
+    {
+        ERR("Protocol mismatch, expected 'file', got '%s'\n", uri->protocol);
+        return 0;
+    }
+
+    if (!uri->path || *uri->path == '\0')
+    {
+        ERR("No path obtained from uri: %s\n", full_uri);
+        return 0;
+    }
+
+    if (strcmp(uri->path, "/tmp/foo/bar"))
+    {
+        ERR("Path mismatch, expected '/tmp/foo/bar', got '%s'\n", uri->path);
+        return 0;
+    }
+
+    if (uri->hostname && *uri->hostname != '\0')
+    {
+        ERR("Hostname '%s', obtained from uri: %s\n", uri->hostname, full_uri);
+        return 0;
+    }
+
+    if (uri->username && *uri->username != '\0')
+    {
+        ERR("Username '%s' obtained from uri: %s\n", uri->username, full_uri);
+        return 0;
+    }
+
+    if (uri->password && *uri->password != '\0')
+    {
+        ERR("Password '%s' obtained from uri: %s\n", uri->password, full_uri);
+        return 0;
+    }
+
+    if (uri->port)
+    {
+        ERR("Port '%d' obtained from uri: %s\n", uri->port, full_uri);
+        return 0;
+    }
+
+    efreet_uri_free(uri);
+
+    uri = efreet_uri_decode("ftp://foo:[email protected]:123/alpha/beta";);
+
+    if (strcmp(uri->protocol, "ftp"))
+    {
+        ERR("Protocol mismatch, expected 'ftp', got '%s'\n", uri->protocol);
+        return 0;
+    }
+
+    if (strcmp(uri->username, "foo"))
+    {
+        ERR("Username mismatch, expected 'foo', got '%s'\n", uri->username);
+        return 0;
+    }
+
+    if (strcmp(uri->password, "bar"))
+    {
+        ERR("Password mismatch, expected 'bar', got '%s'\n", uri->password);
+        return 0;
+    }
+
+    if (strcmp(uri->hostname, "example.com"))
+    {
+        ERR("Hostname mismatch, expected 'example.com', got '%s'\n", uri->hostname);
+        return 0;
+    }
+
+    if (uri->port != 123)
+    {
+        ERR("Port mismatch, expected '123', got '%d'\n", uri->port);
+        return 0;
+    }
+
+    if (strcmp(uri->path, "/alpha/beta"))
+    {
+        ERR("Path mismatch, expected '/alpha/beta', got '%s'\n", uri->path);
+        return 0;
+    }
+
+
+    efreet_uri_free(uri);
+
+    uri = efreet_uri_decode("ftp://[email protected]:123";);
+
+    if (strcmp(uri->protocol, "ftp"))
+    {
+        ERR("Protocol mismatch, expected 'ftp', got '%s'\n", uri->protocol);
+        return 0;
+    }
+
+    if (strcmp(uri->username, "foo"))
+    {
+        ERR("Username mismatch, expected 'foo', got '%s'\n", uri->username);
+        return 0;
+    }
+
+    if (*uri->password != '\0')
+    {
+        ERR("Password mismatch, expected '', got '%s'\n", uri->password);
+        return 0;
+    }
+
+    if (strcmp(uri->hostname, "example.com"))
+    {
+        ERR("Hostname mismatch, expected 'example.com', got '%s'\n", uri->hostname);
+        return 0;
+    }
+
+    if (uri->port != 123)
+    {
+        ERR("Port mismatch, expected '123', got '%d'\n", uri->port);
+        return 0;
+    }
+
+    if (*uri->path != '\0')
+    {
+        ERR("Path mismatch, expected '', got '%s'\n", uri->path);
+        return 0;
+    }
+
+    uri = efreet_uri_decode("ftp://[email protected]";);
+
+    if (strcmp(uri->protocol, "ftp"))
+    {
+        ERR("Protocol mismatch, expected 'ftp', got '%s'\n", uri->protocol);
+        return 0;
+    }
+
+    if (strcmp(uri->username, "foo"))
+    {
+        ERR("Username mismatch, expected 'foo', got '%s'\n", uri->username);
+        return 0;
+    }
+
+    if (*uri->password != '\0')
+    {
+        ERR("Password mismatch, expected '', got '%s'\n", uri->password);
+        return 0;
+    }
+
+    if (strcmp(uri->hostname, "example.com"))
+    {
+        ERR("Hostname mismatch, expected 'example.com', got '%s'\n", uri->hostname);
+        return 0;
+    }
+
+    if (uri->port)
+    {
+        ERR("Port mismatch, expected '0', got '%d'\n", uri->port);
+        return 0;
+    }
+
+    if (*uri->path != '\0')
+    {
+        ERR("Path mismatch, expected '', got '%s'\n", uri->path);
+        return 0;
+    }
+
+    efreet_uri_free(uri);
+
+    uri = efreet_uri_decode("ftp://example.com:123";);
+
+    if (strcmp(uri->protocol, "ftp"))
+    {
+        ERR("Protocol mismatch, expected 'ftp', got '%s'\n", uri->protocol);
+        return 0;
+    }
+
+    if (*uri->username != '\0')
+    {
+        ERR("Username mismatch, expected '', got '%s'\n", uri->username);
+        return 0;
+    }
+
+    if (*uri->password != '\0')
+    {
+        ERR("Password mismatch, expected '', got '%s'\n", uri->password);
+        return 0;
+    }
+
+    if (strcmp(uri->hostname, "example.com"))
+    {
+        ERR("Hostname mismatch, expected 'example.com', got '%s'\n", uri->hostname);
+        return 0;
+    }
+
+    if (uri->port != 123)
+    {
+        ERR("Port mismatch, expected '123', got '%d'\n", uri->port);
+        return 0;
+    }
+
+    if (*uri->path != '\0')
+    {
+        ERR("Path mismatch, expected '', got '%s'\n", uri->path);
+        return 0;
+    }
+
+    efreet_uri_free(uri);
+
+    uri = efreet_uri_decode("ftp://example.com";);
+
+    if (strcmp(uri->protocol, "ftp"))
+    {
+        ERR("Protocol mismatch, expected 'ftp', got '%s'\n", uri->protocol);
+        return 0;
+    }
+
+    if (*uri->username != '\0')
+    {
+        ERR("Username mismatch, expected '', got '%s'\n", uri->username);
+        return 0;
+    }
+
+    if (*uri->password != '\0')
+    {
+        ERR("Password mismatch, expected '', got '%s'\n", uri->password);
+        return 0;
+    }
+
+    if (strcmp(uri->hostname, "example.com"))
+    {
+        ERR("Hostname mismatch, expected 'example.com', got '%s'\n", uri->hostname);
+        return 0;
+    }
+
+    if (uri->port)
+    {
+        ERR("Port mismatch, expected '0', got '%d'\n", uri->port);
+        return 0;
+    }
+
+    if (*uri->path != '\0')
+    {
+        ERR("Path mismatch, expected '', got '%s'\n", uri->path);
+        return 0;
+    }
+
+    efreet_uri_free(uri);
+
+    return 1;
+}
+
+int
+ef_cb_uri_encode(void)
+{
+    Efreet_Uri *uri;
+    const char *full_uri1 = "ftp://foo:[email protected]:123/alpha/beta";,
+          *full_uri2 = "ftp://[email protected]:123/alpha/beta";,
+          *full_uri3 = "ftp://[email protected]/alpha/beta";,
+          *full_uri4 = "ftp://example.com";,
+          *full_uri5 = "ftp://example.com:123/alpha";,
+          *test;
+
+    printf("\n");
+
+    uri = efreet_uri_decode(full_uri1);
+    test = efreet_uri_encode(uri);
+    if (strcmp(full_uri1, test))
+    {
+        ERR("Decode mismatch, expected '%s', got '%s'\n", full_uri1, test);
+        return 0;
+    }
+    eina_stringshare_del(test);
+    efreet_uri_free(uri);
+
+    uri = efreet_uri_decode(full_uri2);
+    test = efreet_uri_encode(uri);
+    if (strcmp(full_uri2, test))
+    {
+        ERR("Decode mismatch, expected '%s', got '%s'\n", full_uri2, test);
+        return 0;
+    }
+    eina_stringshare_del(test);
+    efreet_uri_free(uri);
+
+    uri = efreet_uri_decode(full_uri3);
+    test = efreet_uri_encode(uri);
+    if (strcmp(full_uri3, test))
+    {
+        ERR("Decode mismatch, expected '%s', got '%s'\n", full_uri3, test);
+        return 0;
+    }
+    eina_stringshare_del(test);
+    efreet_uri_free(uri);
+
+    uri = efreet_uri_decode(full_uri4);
+    test = efreet_uri_encode(uri);
+    if (strcmp(full_uri4, test))
+    {
+        ERR("Decode mismatch, expected '%s', got '%s'\n", full_uri4, test);
+        return 0;
+    }
+    eina_stringshare_del(test);
+    efreet_uri_free(uri);
+
+    uri = efreet_uri_decode(full_uri5);
+    test = efreet_uri_encode(uri);
+    if (strcmp(full_uri5, test))
+    {
+        ERR("Decode mismatch, expected '%s', got '%s'\n", full_uri5, test);
+        return 0;
+    }
+    eina_stringshare_del(test);
+    efreet_uri_free(uri);
+
+    return 1;
+}
Index: src/bin/main.c
===================================================================
--- src/bin/main.c	(revision 40539)
+++ src/bin/main.c	(working copy)
@@ -34,6 +34,8 @@ int ef_cb_menu_save(void);
 int ef_cb_menu_edit(void);
 #endif
 int ef_cb_utils(void);
+int ef_cb_uri_decode(void);
+int ef_cb_uri_encode(void);
 int ef_mime_cb_get(void);
 
 typedef struct Efreet_Test Efreet_Test;
@@ -72,6 +74,8 @@ static Efreet_Test tests[] = {
     {"Menu Edit", ef_cb_menu_edit},
 #endif
     {"Utils", ef_cb_utils},
+    {"Uri Decode", ef_cb_uri_decode},
+    {"Uri Encode", ef_cb_uri_encode},
     {"Mime", ef_mime_cb_get},
     {NULL, NULL}
 };
Index: src/bin/Makefile.am
===================================================================
--- src/bin/Makefile.am	(revision 40539)
+++ src/bin/Makefile.am	(working copy)
@@ -27,6 +27,7 @@ ef_utils.c \
 ef_desktop.c \
 ef_menu.c \
 ef_mime.c \
+ef_uri.c \
 main.c
 
 if DEFAULT_VISIBILITY
------------------------------------------------------------------------------
The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
production scanning environment may not be a perfect world - but thanks to
Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700
Series Scanner you'll get full speed at 300 dpi even with all image 
processing features enabled. http://p.sf.net/sfu/kodak-com
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to