[libgdata] Fixed colour parsing from hexadecimal



commit 599e39034bd5abdbd2a3b20399193457c2192282
Author: Philip Withnall <philip tecnocode co uk>
Date:   Thu Apr 23 21:03:08 2009 +0100

    Fixed colour parsing from hexadecimal
    
    Fixed gdata_color_from_hexadecimal to parse colours properly with needing
    any memory allocations. Added a test case for it.
---
 gdata/gdata-types.c   |   46 ++++++++++++++++++++++++++++++++--------------
 gdata/tests/general.c |   25 +++++++++++++++++++++++++
 2 files changed, 57 insertions(+), 14 deletions(-)

diff --git a/gdata/gdata-types.c b/gdata/gdata-types.c
index 6274834..8edc06f 100644
--- a/gdata/gdata-types.c
+++ b/gdata/gdata-types.c
@@ -91,27 +91,45 @@ gdata_color_get_type (void)
 gboolean
 gdata_color_from_hexadecimal (const gchar *hexadecimal, GDataColor *color)
 {
-	gchar *hex;
+	gint temp;
 
 	g_return_val_if_fail (hexadecimal != NULL, FALSE);
 	g_return_val_if_fail (color != NULL, FALSE);
 
-	hex = g_strdup (hexadecimal);
-	if (*hex == '#')
-		hex++;
-	if (strlen (hex) != 6) {
-		g_free (hex);
+	if (*hexadecimal == '#')
+		hexadecimal++;
+	if (strlen (hexadecimal) != 6)
 		return FALSE;
-	}
 
-	/* This is horrible and hacky, but should work */
-	color->blue = strtoul (hex + 4, NULL, 16);
-	*(hex + 4) = '\0';
-	color->green = strtoul (hex + 2, NULL, 16);
-	*(hex + 2) = '\0';
-	color->red = strtoul (hex, NULL, 16);
+	/* Red */
+	temp = g_ascii_xdigit_value (*(hexadecimal++)) * 16;
+	if (temp < 0)
+		return FALSE;
+	color->red = temp;
+	temp = g_ascii_xdigit_value (*(hexadecimal++));
+	if (temp < 0)
+		return FALSE;
+	color->red += temp;
+
+	/* Green */
+	temp = g_ascii_xdigit_value (*(hexadecimal++)) * 16;
+	if (temp < 0)
+		return FALSE;
+	color->green = temp;
+	temp = g_ascii_xdigit_value (*(hexadecimal++));
+	if (temp < 0)
+		return FALSE;
+	color->green += temp;
 
-	g_free (hex);
+	/* Blue */
+	temp = g_ascii_xdigit_value (*(hexadecimal++)) * 16;
+	if (temp < 0)
+		return FALSE;
+	color->blue = temp;
+	temp = g_ascii_xdigit_value (*(hexadecimal++));
+	if (temp < 0)
+		return FALSE;
+	color->blue += temp;
 
 	return TRUE;
 }
diff --git a/gdata/tests/general.c b/gdata/tests/general.c
index bcf5f38..b47e930 100644
--- a/gdata/tests/general.c
+++ b/gdata/tests/general.c
@@ -188,6 +188,30 @@ test_query_categories (void)
 	g_object_unref (query);
 }
 
+static void
+test_color_parsing (void)
+{
+	GDataColor color;
+
+	/* With hash */
+	g_assert (gdata_color_from_hexadecimal ("#F99Ff0", &color) == TRUE);
+	g_assert_cmpuint (color.red, ==, 249);
+	g_assert_cmpuint (color.green, ==, 159);
+	g_assert_cmpuint (color.blue, ==, 240);
+
+	/* Without hash */
+	g_assert (gdata_color_from_hexadecimal ("F99Ff0", &color) == TRUE);
+	g_assert_cmpuint (color.red, ==, 249);
+	g_assert_cmpuint (color.green, ==, 159);
+	g_assert_cmpuint (color.blue, ==, 240);
+
+	/* Invalid, but correct length */
+	g_assert (gdata_color_from_hexadecimal ("foobar", &color) == FALSE);
+
+	/* Wildly invalid */
+	g_assert (gdata_color_from_hexadecimal ("this is not a real colour!", &color) == FALSE);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -198,6 +222,7 @@ main (int argc, char *argv[])
 	g_test_add_func ("/entry/get_xml", test_entry_get_xml);
 	g_test_add_func ("/entry/parse_xml", test_entry_parse_xml);
 	g_test_add_func ("/query/categories", test_query_categories);
+	g_test_add_func ("/color/parsing", test_color_parsing);
 
 	return g_test_run ();
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]