|
Packit |
b00eeb |
/*
|
|
Packit |
b00eeb |
* gnome-keyring
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* Copyright (C) 2008 Stefan Walter
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
b00eeb |
* it under the terms of the GNU Lesser General Public License as
|
|
Packit |
b00eeb |
* published by the Free Software Foundation; either version 2.1 of
|
|
Packit |
b00eeb |
* the License, or (at your option) any later version.
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* This program is distributed in the hope that it will be useful, but
|
|
Packit |
b00eeb |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
b00eeb |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
b00eeb |
* Lesser General Public License for more details.
|
|
Packit |
b00eeb |
*
|
|
Packit |
b00eeb |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
b00eeb |
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
b00eeb |
*/
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
#include "config.h"
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
#include "egg-hex.h"
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
#include <string.h>
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
static const char HEXC_UPPER[] = "0123456789ABCDEF";
|
|
Packit |
b00eeb |
static const char HEXC_LOWER[] = "0123456789abcdef";
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
gpointer
|
|
Packit |
b00eeb |
egg_hex_decode (const gchar *data, gssize n_data, gsize *n_decoded)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
return egg_hex_decode_full (data, n_data, 0, 1, n_decoded);
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
gpointer
|
|
Packit |
b00eeb |
egg_hex_decode_full (const gchar *data,
|
|
Packit |
b00eeb |
gssize n_data,
|
|
Packit |
b00eeb |
const gchar *delim,
|
|
Packit |
b00eeb |
guint group,
|
|
Packit |
b00eeb |
gsize *n_decoded)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
guchar *result;
|
|
Packit |
b00eeb |
guchar *decoded;
|
|
Packit |
b00eeb |
gsize n_delim;
|
|
Packit |
b00eeb |
gushort j;
|
|
Packit |
b00eeb |
gint state = 0;
|
|
Packit |
b00eeb |
gint part = 0;
|
|
Packit |
b00eeb |
const gchar* pos;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
g_return_val_if_fail (data || !n_data, NULL);
|
|
Packit |
b00eeb |
g_return_val_if_fail (n_decoded, NULL);
|
|
Packit |
b00eeb |
g_return_val_if_fail (group >= 1, NULL);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
if (n_data == -1)
|
|
Packit |
b00eeb |
n_data = strlen (data);
|
|
Packit |
b00eeb |
n_delim = delim ? strlen (delim) : 0;
|
|
Packit |
b00eeb |
decoded = result = g_malloc0 ((n_data / 2) + 1);
|
|
Packit |
b00eeb |
*n_decoded = 0;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
while (n_data > 0 && state == 0) {
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
if (decoded != result && delim) {
|
|
Packit |
b00eeb |
if (n_data < n_delim || memcmp (data, delim, n_delim) != 0) {
|
|
Packit |
b00eeb |
state = -1;
|
|
Packit |
b00eeb |
break;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
data += n_delim;
|
|
Packit |
b00eeb |
n_data -= n_delim;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
while (part < group && n_data > 0) {
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
/* Find the position */
|
|
Packit |
b00eeb |
pos = strchr (HEXC_UPPER, g_ascii_toupper (*data));
|
|
Packit |
b00eeb |
if (pos == 0) {
|
|
Packit |
b00eeb |
if (n_data > 0)
|
|
Packit |
b00eeb |
state = -1;
|
|
Packit |
b00eeb |
break;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
j = pos - HEXC_UPPER;
|
|
Packit |
b00eeb |
if(!state) {
|
|
Packit |
b00eeb |
*decoded = (j & 0xf) << 4;
|
|
Packit |
b00eeb |
state = 1;
|
|
Packit |
b00eeb |
} else {
|
|
Packit |
b00eeb |
*decoded |= (j & 0xf);
|
|
Packit |
b00eeb |
(*n_decoded)++;
|
|
Packit |
b00eeb |
decoded++;
|
|
Packit |
b00eeb |
state = 0;
|
|
Packit |
b00eeb |
part++;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
++data;
|
|
Packit |
b00eeb |
--n_data;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
part = 0;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
/* Parsing error */
|
|
Packit |
b00eeb |
if (state != 0) {
|
|
Packit |
b00eeb |
g_free (result);
|
|
Packit |
b00eeb |
result = NULL;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
return result;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
gchar*
|
|
Packit |
b00eeb |
egg_hex_encode (gconstpointer data, gsize n_data)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
return egg_hex_encode_full (data, n_data, TRUE, NULL, 0);
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
gchar*
|
|
Packit |
b00eeb |
egg_hex_encode_full (gconstpointer data,
|
|
Packit |
b00eeb |
gsize n_data,
|
|
Packit |
b00eeb |
gboolean upper_case,
|
|
Packit |
b00eeb |
const gchar *delim,
|
|
Packit |
b00eeb |
guint group)
|
|
Packit |
b00eeb |
{
|
|
Packit |
b00eeb |
GString *result;
|
|
Packit |
b00eeb |
const gchar *input;
|
|
Packit |
b00eeb |
const char *hexc;
|
|
Packit |
b00eeb |
gsize bytes;
|
|
Packit |
b00eeb |
guchar j;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
g_return_val_if_fail (data || !n_data, NULL);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
input = data;
|
|
Packit |
b00eeb |
hexc = upper_case ? HEXC_UPPER : HEXC_LOWER;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
result = g_string_sized_new (n_data * 2 + 1);
|
|
Packit |
b00eeb |
bytes = 0;
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
while (n_data > 0) {
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
if (delim && group && bytes && (bytes % group) == 0)
|
|
Packit |
b00eeb |
g_string_append (result, delim);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
j = *(input) >> 4 & 0xf;
|
|
Packit |
b00eeb |
g_string_append_c (result, hexc[j]);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
j = *(input++) & 0xf;
|
|
Packit |
b00eeb |
g_string_append_c (result, hexc[j]);
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
++bytes;
|
|
Packit |
b00eeb |
--n_data;
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|
|
Packit |
b00eeb |
/* Make sure still null terminated */
|
|
Packit |
b00eeb |
return g_string_free (result, FALSE);
|
|
Packit |
b00eeb |
}
|
|
Packit |
b00eeb |
|