Line data Source code
1 : /*
2 : * gnome-keyring
3 : *
4 : * Copyright (C) 2008 Stefan Walter
5 : *
6 : * This program is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU Lesser General Public License as
8 : * published by the Free Software Foundation; either version 2.1 of
9 : * the License, or (at your option) any later version.
10 : *
11 : * This program is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * Lesser General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this program; if not, write to the Free Software
18 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 : * MA 02110-1301 USA
20 : *
21 : * Author: Stef Walter <stefw@thewalter.net>
22 : */
23 :
24 : #include "config.h"
25 :
26 : #include "egg-hex.h"
27 :
28 : #include <string.h>
29 :
30 : static const char HEXC_UPPER[] = "0123456789ABCDEF";
31 : static const char HEXC_LOWER[] = "0123456789abcdef";
32 :
33 : gpointer
34 24 : egg_hex_decode (const gchar *data, gssize n_data, gsize *n_decoded)
35 : {
36 24 : return egg_hex_decode_full (data, n_data, 0, 1, n_decoded);
37 : }
38 :
39 : gpointer
40 26 : egg_hex_decode_full (const gchar *data,
41 : gssize n_data,
42 : const gchar *delim,
43 : guint group,
44 : gsize *n_decoded)
45 : {
46 : guchar *result;
47 : guchar *decoded;
48 : gsize n_delim;
49 : gushort j;
50 26 : gint state = 0;
51 26 : gint part = 0;
52 : const gchar* pos;
53 :
54 26 : g_return_val_if_fail (data || !n_data, NULL);
55 26 : g_return_val_if_fail (n_decoded, NULL);
56 26 : g_return_val_if_fail (group >= 1, NULL);
57 :
58 26 : if (n_data == -1)
59 5 : n_data = strlen (data);
60 26 : n_delim = delim ? strlen (delim) : 0;
61 26 : decoded = result = g_malloc0 ((n_data / 2) + 1);
62 26 : *n_decoded = 0;
63 :
64 243 : while (n_data > 0 && state == 0) {
65 :
66 218 : if (decoded != result && delim) {
67 8 : if (n_data < n_delim || memcmp (data, delim, n_delim) != 0) {
68 1 : state = -1;
69 1 : break;
70 : }
71 :
72 7 : data += n_delim;
73 7 : n_data -= n_delim;
74 : }
75 :
76 648 : while (part < group && n_data > 0) {
77 :
78 : /* Find the position */
79 432 : pos = strchr (HEXC_UPPER, g_ascii_toupper (*data));
80 432 : if (pos == 0) {
81 1 : if (n_data > 0)
82 1 : state = -1;
83 1 : break;
84 : }
85 :
86 431 : j = pos - HEXC_UPPER;
87 431 : if(!state) {
88 216 : *decoded = (j & 0xf) << 4;
89 216 : state = 1;
90 : } else {
91 215 : *decoded |= (j & 0xf);
92 215 : (*n_decoded)++;
93 215 : decoded++;
94 215 : state = 0;
95 215 : part++;
96 : }
97 :
98 431 : ++data;
99 431 : --n_data;
100 : }
101 :
102 217 : part = 0;
103 : }
104 :
105 : /* Parsing error */
106 26 : if (state != 0) {
107 3 : g_free (result);
108 3 : result = NULL;
109 : }
110 :
111 26 : return result;
112 : }
113 :
114 : gchar*
115 4 : egg_hex_encode (gconstpointer data, gsize n_data)
116 : {
117 4 : return egg_hex_encode_full (data, n_data, TRUE, NULL, 0);
118 : }
119 :
120 : gchar*
121 16 : egg_hex_encode_full (gconstpointer data,
122 : gsize n_data,
123 : gboolean upper_case,
124 : const gchar *delim,
125 : guint group)
126 : {
127 : GString *result;
128 : const gchar *input;
129 : const char *hexc;
130 : gsize bytes;
131 : guchar j;
132 :
133 16 : g_return_val_if_fail (data || !n_data, NULL);
134 :
135 16 : input = data;
136 16 : hexc = upper_case ? HEXC_UPPER : HEXC_LOWER;
137 :
138 16 : result = g_string_sized_new (n_data * 2 + 1);
139 16 : bytes = 0;
140 :
141 241 : while (n_data > 0) {
142 :
143 225 : if (delim && group && bytes && (bytes % group) == 0)
144 : g_string_append (result, delim);
145 :
146 225 : j = *(input) >> 4 & 0xf;
147 225 : g_string_append_c (result, hexc[j]);
148 :
149 225 : j = *(input++) & 0xf;
150 225 : g_string_append_c (result, hexc[j]);
151 :
152 225 : ++bytes;
153 225 : --n_data;
154 : }
155 :
156 : /* Make sure still null terminated */
157 16 : return g_string_free (result, FALSE);
158 : }
159 :
|