int ug_uri_part_file_ext (UgUri* uuri, const char** ext) { const char* beg; const char* end; int len; if (uuri->file != -1) { len = ug_uri_part_file (uuri, &beg); end = uuri->uri + uuri->file + len -1; for (; end >= beg; end--) { if (end[0] == '.') { end += 1; // + '.' if (ext) *ext = end; return len - (end - beg); } } } return 0; }
// -------------------------------------------------------- // Convenience Functions for UgUri gchar* ug_uri_get_file (UgUri* upart) { const char* str; char* name; int len; if ((len = ug_uri_part_file (upart, &str)) == 0) return NULL; name = g_uri_unescape_segment (str, str+len, NULL); if (name == NULL) name = g_strndup (str, len); // check encoding if (g_utf8_validate (name, -1, NULL) == FALSE) { str = g_locale_to_utf8 (name, -1, NULL, NULL, NULL); if (str == NULL) { str = g_uri_escape_string (name, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT, FALSE); } g_free (name); return (gchar*) str; } return name; }
int ug_uri_init (UgUri* upart, const char* uri) { const char* cur; const char* tmp; // scheme #if defined _WIN32 || defined _WIN64 cur = strpbrk (uri, ":\\/?#"); // make sure ':' before '/', '?', and '#' #else cur = strpbrk (uri, ":/?#"); // make sure ':' before '/', '?', and '#' #endif if (cur && cur[0] == ':') { if (upart == NULL) return cur - uri; upart->scheme_len = cur - uri; cur++; } else { if (upart == NULL) return 0; upart->scheme_len = 0; cur = uri; } upart->uri = uri; #if defined _WIN32 || defined _WIN64 // Windows Path if (upart->scheme_len == 1) { upart->scheme_len = 0; cur = uri; } #endif // _WIN32 || _WIN64 // authority & path if (upart->scheme_len && cur[0] == '/' && cur[1] == '/') { cur += 2; upart->authority = cur - uri; cur += strcspn (cur, "/"); } else upart->authority = -1; upart->path = cur - uri; // file upart->file = -1; if (cur[0]) { for (; ; ) { #if defined _WIN32 || defined _WIN64 tmp = strpbrk (cur, "\\/?#"); if (tmp == NULL || (tmp[0] != '/' && tmp[0] != '\\')) { #else tmp = strpbrk (cur, "/?#"); if (tmp == NULL || tmp[0] != '/') { #endif // _WIN32 || _WIN64 upart->file = cur - uri; break; } cur = tmp + 1; } } // query if ((tmp = strchr (cur, '?')) == NULL) upart->query = -1; else { cur = tmp + 1; upart->query = cur - uri; } // fragment if ((tmp = strrchr (cur, '#')) == NULL) upart->fragment = -1; else { cur = tmp + 1; upart->fragment = cur - uri; } // host & port upart->port = -1; if (upart->authority == -1) upart->host = -1; else { upart->host = upart->authority; tmp = uri + upart->authority; for (cur = uri + upart->path -1; cur >= tmp; cur--) { if (cur[0] == '@') { upart->host = cur - uri + 1; break; } if (cur[0] == ':') upart->port = cur - uri + 1; } } return upart->scheme_len; } int ug_uri_part_scheme (UgUri* uuri, const char** scheme) { if (scheme && uuri->scheme_len) *scheme = uuri->uri; return uuri->scheme_len; } int ug_uri_part_file (UgUri* uuri, const char** file) { if (uuri->file != -1) { if (file) *file = uuri->uri + uuri->file; if (uuri->query != -1) return uuri->query - uuri->file - 1; // - '?' if (uuri->fragment != -1) return uuri->fragment - uuri->file - 1; // - '#' return strlen (uuri->uri + uuri->file); } return 0; } int ug_uri_part_file_ext (UgUri* uuri, const char** ext) { const char* beg; const char* end; int len; if (uuri->file != -1) { len = ug_uri_part_file (uuri, &beg); end = uuri->uri + uuri->file + len -1; for (; end >= beg; end--) { if (end[0] == '.') { end += 1; // + '.' if (ext) *ext = end; return len - (end - beg); } } } return 0; } int ug_uri_part_query (UgUri* uuri, const char** query) { if (uuri->query != -1) { if (query) *query = uuri->uri + uuri->query; if (uuri->fragment != -1) return uuri->fragment - uuri->query -1; // - '#' return strlen (uuri->uri + uuri->query); } return 0; } int ug_uri_part_fragment (UgUri* uuri, const char** fragment) { if (uuri->fragment != -1) { if (fragment) *fragment = uuri->uri + uuri->fragment; return strlen (uuri->uri + uuri->fragment); } return 0; } int ug_uri_part_referrer (UgUri* uuri, const char** referrer) { if (referrer) *referrer = uuri->uri; if (uuri->file == -1) return uuri->path; return uuri->file; } int ug_uri_part_user (UgUri* uuri, const char** user) { const char* beg; const char* end; if (uuri->authority == uuri->host) return 0; beg = uuri->uri + uuri->authority; end = uuri->uri + uuri->host - 1; // - '@' if (user) *user = beg; for (; beg < end; beg++) { if (beg[0] == ':') break; } return beg - uuri->uri - uuri->authority; } int ug_uri_part_password (UgUri* uuri, const char** password) { const char* tmp; int length; length = ug_uri_part_user (uuri, &tmp); if (length && tmp[length] == ':') { tmp += length + 1; // + ':' if (password) *password = tmp; return uuri->host - (tmp - uuri->uri) - 1; // - '@' } return 0; } int ug_uri_part_host (UgUri* uuri, const char** host) { if (uuri->host != -1) { if (host) *host = uuri->uri + uuri->host; if (uuri->port != -1) return uuri->port - uuri->host - 1; // - ':' else return uuri->path - uuri->host; } return 0; } int ug_uri_part_port (UgUri* uuri, const char** port) { if (uuri->port != -1) { if (port) *port = uuri->uri + uuri->port; return uuri->path - uuri->port; } return 0; } int ug_uri_get_port (UgUri* uuri) { if (uuri->port != -1) return strtol (uuri->uri + uuri->port, NULL, 10); return -1; } char* ug_uri_get_file (UgUri* uuri) { const char* str; char* name; int len; len = ug_uri_part_file (uuri, &str); if (len == 0) return NULL; name = ug_unescape_uri (str, len); if (ug_utf8_get_invalid ((uint8_t*) name, NULL) == -1) return name; ug_free (name); return ug_strndup (str, len); } // ------------------------------------ // match uri functions int ug_uri_match_hosts (UgUri* uuri, char** hosts) { const char* str; const char* end1; const char* end2; int len; int lenHost; int nthHost; len = ug_uri_part_host (uuri, &str); if (len) { for (nthHost = 0; *hosts; hosts++, nthHost++) { lenHost = strlen (*hosts); if (lenHost > len) continue; // compare host from head if (strncasecmp (uuri->uri, *hosts, len) == 0) return nthHost; // compare host from tail end1 = str + len -1; end2 = *hosts + lenHost -1; for (; lenHost > 0; lenHost--, end1--, end2--) { if (end1[0] != end2[0]) break; } if (lenHost == 0) return nthHost; } } return -1; } int ug_uri_match_schemes (UgUri* uuri, char** schemes) { int len; int index; len = ug_uri_part_scheme (uuri, NULL); if (len) { for (index = 0; *schemes; schemes++, index++) { if (strncasecmp (uuri->uri, *schemes, len) == 0) return index; } } return -1; }
void ugtk_download_form_complete_entry (UgtkDownloadForm* dform) { const gchar* text; // gchar* temp; UgUri upart; gboolean completed = FALSE; // URL text = gtk_entry_get_text ((GtkEntry*) dform->uri_entry); ug_uri_init (&upart, text); if (upart.host != -1) { // disable changed flags dform->changed.enable = FALSE; #if 0 // complete file entry text = gtk_entry_get_text ((GtkEntry*) dform->file_entry); if (text[0] == 0 || dform->changed.file == FALSE) { temp = ug_uri_get_file (&upart); gtk_entry_set_text ((GtkEntry*) dform->file_entry, (temp) ? temp : "index.htm"); g_free (temp); } // complete user entry text = gtk_entry_get_text ((GtkEntry*) dform->username_entry); if (text[0] == 0 || dform->changed.user == FALSE) { temp = ug_uri_get_user (&upart); gtk_entry_set_text ((GtkEntry*) dform->username_entry, (temp) ? temp : ""); g_free (temp); } // complete password entry text = gtk_entry_get_text ((GtkEntry*) dform->password_entry); if (text[0] == 0 || dform->changed.password == FALSE) { temp = ug_uri_get_password (&upart); gtk_entry_set_text ((GtkEntry*) dform->password_entry, (temp) ? temp : ""); g_free (temp); } #endif // enable changed flags dform->changed.enable = TRUE; // status completed = TRUE; } #if 1 // check existing for file name else if (ug_uri_part_file (&upart, &text) > 0) { completed = TRUE; } #else // file extension else if (ug_uri_part_file_ext (&upart, &text) > 0) { // torrent or metalink file path if (*text == 'm' || *text == 'M' || *text == 't' || *text == 'T') completed = TRUE; } #endif else if (upart.path > 0 && upart.uri[upart.path] != 0) completed = TRUE; else if (gtk_widget_is_sensitive (dform->uri_entry) == FALSE) completed = TRUE; dform->completed = completed; }