/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * soup-misc.c: Miscellaneous functions * Copyright (C) 2000-2003, Ximian, Inc. */ #ifdef HAVE_CONFIG_H #include #endif #include #include "soup-misc.h" #include "soup-misc-private.h" /** * SECTION:soup-misc * @short_description: Miscellaneous functions * **/ const gboolean soup_ssl_supported = TRUE; /** * soup_str_case_hash: * @key: ASCII string to hash * * Hashes @key in a case-insensitive manner. * * Return value: the hash code. **/ guint soup_str_case_hash (gconstpointer key) { const char *p = key; guint h = g_ascii_toupper(*p); if (h) for (p += 1; *p != '\0'; p++) h = (h << 5) - h + g_ascii_toupper(*p); return h; } /** * soup_str_case_equal: * @v1: an ASCII string * @v2: another ASCII string * * Compares @v1 and @v2 in a case-insensitive manner * * Return value: %TRUE if they are equal (modulo case) **/ gboolean soup_str_case_equal (gconstpointer v1, gconstpointer v2) { const char *string1 = v1; const char *string2 = v2; return g_ascii_strcasecmp (string1, string2) == 0; } /** * soup_add_io_watch: (skip) * @async_context: (allow-none): the #GMainContext to dispatch the I/O * watch in, or %NULL for the default context * @chan: the #GIOChannel to watch * @condition: the condition to watch for * @function: the callback to invoke when @condition occurs * @data: user data to pass to @function * * Adds an I/O watch as with g_io_add_watch(), but using the given * @async_context. * * Return value: a #GSource, which can be removed from @async_context * with g_source_destroy(). **/ GSource * soup_add_io_watch (GMainContext *async_context, GIOChannel *chan, GIOCondition condition, GIOFunc function, gpointer data) { GSource *watch = g_io_create_watch (chan, condition); g_source_set_callback (watch, (GSourceFunc) function, data, NULL); g_source_attach (watch, async_context); g_source_unref (watch); return watch; } /** * soup_add_idle: (skip) * @async_context: (allow-none): the #GMainContext to dispatch the I/O * watch in, or %NULL for the default context * @function: the callback to invoke at idle time * @data: user data to pass to @function * * Adds an idle event as with g_idle_add(), but using the given * @async_context. * * If you want @function to run "right away", use * soup_add_completion(), since that sets a higher priority on the * #GSource than soup_add_idle() does. * * Return value: a #GSource, which can be removed from @async_context * with g_source_destroy(). **/ GSource * soup_add_idle (GMainContext *async_context, GSourceFunc function, gpointer data) { GSource *source = g_idle_source_new (); g_source_set_callback (source, function, data, NULL); g_source_attach (source, async_context); g_source_unref (source); return source; } GSource * soup_add_completion_reffed (GMainContext *async_context, GSourceFunc function, gpointer data, GDestroyNotify dnotify) { GSource *source = g_idle_source_new (); g_source_set_priority (source, G_PRIORITY_DEFAULT); g_source_set_callback (source, function, data, dnotify); g_source_attach (source, async_context); return source; } /** * soup_add_completion: (skip) * @async_context: (allow-none): the #GMainContext to dispatch the I/O * watch in, or %NULL for the default context * @function: the callback to invoke * @data: user data to pass to @function * * Adds @function to be executed from inside @async_context with the * default priority. Use this when you want to complete an action in * @async_context's main loop, as soon as possible. * * Return value: a #GSource, which can be removed from @async_context * with g_source_destroy(). * * Since: 2.24 **/ GSource * soup_add_completion (GMainContext *async_context, GSourceFunc function, gpointer data) { GSource *source; source = soup_add_completion_reffed (async_context, function, data, NULL); g_source_unref (source); return source; } /** * soup_add_timeout: (skip) * @async_context: (allow-none): the #GMainContext to dispatch the I/O * watch in, or %NULL for the default context * @interval: the timeout interval, in milliseconds * @function: the callback to invoke at timeout time * @data: user data to pass to @function * * Adds a timeout as with g_timeout_add(), but using the given * @async_context. * * Return value: a #GSource, which can be removed from @async_context * with g_source_destroy(). **/ GSource * soup_add_timeout (GMainContext *async_context, guint interval, GSourceFunc function, gpointer data) { GSource *source = g_timeout_source_new (interval); g_source_set_callback (source, function, data, NULL); g_source_attach (source, async_context); g_source_unref (source); return source; } /* 00 URI_UNRESERVED * 01 URI_PCT_ENCODED * 02 URI_GEN_DELIMS * 04 URI_SUB_DELIMS * 08 HTTP_SEPARATOR * 10 HTTP_CTL */ const char soup_char_attributes[] = { /* 0x00 - 0x07 */ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /* 0x08 - 0x0f */ 0x11, 0x19, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /* 0x10 - 0x17 */ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /* 0x18 - 0x1f */ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /* !"#$%&' */ 0x09, 0x04, 0x09, 0x02, 0x04, 0x01, 0x04, 0x04, /* ()*+,-./ */ 0x0c, 0x0c, 0x04, 0x04, 0x0c, 0x00, 0x00, 0x0a, /* 01234567 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 89:;<=>? */ 0x00, 0x00, 0x0a, 0x0c, 0x09, 0x0a, 0x09, 0x0a, /* @ABCDEFG */ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* HIJKLMNO */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* PQRSTUVW */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* XYZ[\]^_ */ 0x00, 0x00, 0x00, 0x0a, 0x09, 0x0a, 0x01, 0x00, /* `abcdefg */ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* hijklmno */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* pqrstuvw */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* xyz{|}~ */ 0x00, 0x00, 0x00, 0x09, 0x01, 0x09, 0x00, 0x11, /* 0x80 - 0xFF */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; /** * soup_host_matches_host * @host: a URI * @compare_with: a URI * * Checks if the @host and @compare_with exactly match or prefixed with a dot. * * Return value: %TRUE if the hosts match, %FALSE otherwise * * Since: 2.54 **/ gboolean soup_host_matches_host (const gchar *host, const gchar *compare_with) { char *match; int dlen; g_return_val_if_fail (host != NULL, FALSE); g_return_val_if_fail (compare_with != NULL, FALSE); if (!g_ascii_strcasecmp (host, compare_with)) return TRUE; if (*host != '.') return FALSE; if (!g_ascii_strcasecmp (host + 1, compare_with)) return TRUE; dlen = strlen (host); while ((match = strstr (compare_with, host))) { if (!match[dlen]) return TRUE; compare_with = match + 1; } return FALSE; }