static const char HEXC_UPPER[] = "0123456789ABCDEF";
static const char HEXC_LOWER[] = "0123456789abcdef";
-guchar*
+gpointer
egg_hex_decode (const gchar *data, gssize n_data, gsize *n_decoded)
{
+ return egg_hex_decode_full (data, n_data, 0, 1, n_decoded);
+}
+
+gpointer
+egg_hex_decode_full (const gchar *data, gssize n_data,
+ gchar delim, guint group, gsize *n_decoded)
+{
guchar *result;
guchar *decoded;
gushort j;
gint state = 0;
+ gint part = 0;
const gchar* pos;
g_return_val_if_fail (data || !n_data, NULL);
g_return_val_if_fail (n_decoded, NULL);
+ g_return_val_if_fail (group >= 1, NULL);
if (n_data == -1)
n_data = strlen (data);
decoded = result = g_malloc0 ((n_data / 2) + 1);
*n_decoded = 0;
- while (n_data > 0) {
- if (!g_ascii_isspace (*data)) {
+ while (n_data > 0 && state == 0) {
- /* Find the position */
+ if (decoded != result && delim) {
+ if (*data != delim) {
+ state = -1;
+ break;
+ }
+
+ ++data;
+ --n_data;
+ }
+
+ while (part < group && n_data > 0) {
+
+ /* Find the position */
pos = strchr (HEXC_UPPER, g_ascii_toupper (*data));
- if (pos == 0)
+ if (pos == 0) {
+ if (n_data > 0)
+ state = -1;
break;
+ }
j = pos - HEXC_UPPER;
if(!state) {
(*n_decoded)++;
decoded++;
state = 0;
+ part++;
}
- }
- ++data;
- --n_data;
+ ++data;
+ --n_data;
+ }
+
+ part = 0;
}
/* Parsing error */
}
gchar*
-egg_hex_encode (const guchar *data, gsize n_data)
+egg_hex_encode (gconstpointer data, gsize n_data)
{
return egg_hex_encode_full (data, n_data, TRUE, '\0', 0);
}
gchar*
-egg_hex_encode_full (const guchar *data, gsize n_data,
+egg_hex_encode_full (gconstpointer data, gsize n_data,
gboolean upper_case, gchar delim, guint group)
{
GString *result;
+ const gchar *input;
const char *hexc;
gsize bytes;
guchar j;
g_return_val_if_fail (data || !n_data, NULL);
+ input = data;
hexc = upper_case ? HEXC_UPPER : HEXC_LOWER;
result = g_string_sized_new (n_data * 2 + 1);
if (group && bytes && (bytes % group) == 0)
g_string_append_c (result, delim);
- j = *(data) >> 4 & 0xf;
+ j = *(input) >> 4 & 0xf;
g_string_append_c (result, hexc[j]);
- j = *(data++) & 0xf;
+ j = *(input++) & 0xf;
g_string_append_c (result, hexc[j]);
++bytes;
#include <glib.h>
-guchar* egg_hex_decode (const gchar *data,
+gpointer egg_hex_decode (const gchar *data,
gssize n_data,
gsize *n_decoded);
-gchar* egg_hex_encode (const guchar *data,
+gpointer egg_hex_decode_full (const gchar *data,
+ gssize n_data,
+ gchar delim,
+ guint group,
+ gsize *n_decoded);
+
+gchar* egg_hex_encode (gconstpointer data,
gsize n_data);
-gchar* egg_hex_encode_full (const guchar *data,
+gchar* egg_hex_encode_full (gconstpointer data,
gsize n_data,
gboolean upper_case,
gchar delim,
static const guchar TEST_DATA[] = { 0x05, 0xD6, 0x95, 0x96, 0x10, 0x12, 0xAE, 0x35 };
static const gchar *TEST_HEX = "05D695961012AE35";
static const gchar *TEST_HEX_DELIM = "05 D6 95 96 10 12 AE 35";
-static const gchar *TEST_HEX_SPACE = "\n05 D695 \r961012AE35\n\n";
DEFINE_TEST(hex_encode)
{
g_assert (data);
g_assert (n_data == sizeof (TEST_DATA));
g_assert (memcmp (data, TEST_DATA, n_data) == 0);
+ g_free (data);
- /* Spaces should be ignored */
- data = egg_hex_decode (TEST_HEX_SPACE, -1, &n_data);
+ /* Nothing in, empty out */
+ data = egg_hex_decode ("AB", 0, &n_data);
+ g_assert (data);
+ g_assert (n_data == 0);
+ g_free (data);
+
+ /* Delimited*/
+ data = egg_hex_decode_full (TEST_HEX_DELIM, -1, ' ', 1, &n_data);
g_assert (data);
g_assert (n_data == sizeof (TEST_DATA));
g_assert (memcmp (data, TEST_DATA, n_data) == 0);
+ g_free (data);
+}
+
+DEFINE_TEST(hex_decode_fail)
+{
+ guchar *data;
+ gsize n_data;
/* Invalid input, null out */
data = egg_hex_decode ("AB", 1, &n_data);
g_assert (!data);
- /* Nothing in, empty out */
- data = egg_hex_decode ("AB", 0, &n_data);
- g_assert (data);
- g_assert (n_data == 0);
+ /* Bad characters, null out */
+ data = egg_hex_decode ("ABXX", -1, &n_data);
+ g_assert (!data);
+
+ /* Not Delimited, null out*/
+ data = egg_hex_decode_full ("ABABAB", -1, ':', 1, &n_data);
+ g_assert (!data);
}