Branch data 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 : 4 : egg_hex_decode (const gchar *data, gssize n_data, gsize *n_decoded)
35 : : {
36 : 4 : return egg_hex_decode_full (data, n_data, 0, 1, n_decoded);
37 : : }
38 : :
39 : : gpointer
40 : 6 : 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 : 6 : gint state = 0;
51 : 6 : gint part = 0;
52 : : const gchar* pos;
53 : :
54 [ - + - - ]: 6 : g_return_val_if_fail (data || !n_data, NULL);
55 [ - + ]: 6 : g_return_val_if_fail (n_decoded, NULL);
56 [ - + ]: 6 : g_return_val_if_fail (group >= 1, NULL);
57 : :
58 [ + + ]: 6 : if (n_data == -1)
59 : 4 : n_data = strlen (data);
60 [ + + ]: 6 : n_delim = delim ? strlen (delim) : 0;
61 : 6 : decoded = result = g_malloc0 ((n_data / 2) + 1);
62 : 6 : *n_decoded = 0;
63 : :
64 [ + + + + ]: 26 : while (n_data > 0 && state == 0) {
65 : :
66 [ + + + + ]: 21 : 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 [ + + + + ]: 57 : while (part < group && n_data > 0) {
77 : :
78 : : /* Find the position */
79 : 38 : pos = strchr (HEXC_UPPER, g_ascii_toupper (*data));
80 [ + + ]: 38 : if (pos == 0) {
81 [ + - ]: 1 : if (n_data > 0)
82 : 1 : state = -1;
83 : 1 : break;
84 : : }
85 : :
86 : 37 : j = pos - HEXC_UPPER;
87 [ + + ]: 37 : if(!state) {
88 : 19 : *decoded = (j & 0xf) << 4;
89 : 19 : state = 1;
90 : : } else {
91 : 18 : *decoded |= (j & 0xf);
92 : 18 : (*n_decoded)++;
93 : 18 : decoded++;
94 : 18 : state = 0;
95 : 18 : part++;
96 : : }
97 : :
98 : 37 : ++data;
99 : 37 : --n_data;
100 : : }
101 : :
102 : 20 : part = 0;
103 : : }
104 : :
105 : : /* Parsing error */
106 [ + + ]: 6 : if (state != 0) {
107 : 3 : g_free (result);
108 : 3 : result = NULL;
109 : : }
110 : :
111 : 6 : return result;
112 : : }
113 : :
114 : : gchar*
115 : 1 : egg_hex_encode (gconstpointer data, gsize n_data)
116 : : {
117 : 1 : return egg_hex_encode_full (data, n_data, TRUE, NULL, 0);
118 : : }
119 : :
120 : : gchar*
121 : 3 : 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 [ - + - - ]: 3 : g_return_val_if_fail (data || !n_data, NULL);
134 : :
135 : 3 : input = data;
136 [ + - ]: 3 : hexc = upper_case ? HEXC_UPPER : HEXC_LOWER;
137 : :
138 : 3 : result = g_string_sized_new (n_data * 2 + 1);
139 : 3 : bytes = 0;
140 : :
141 [ + + ]: 27 : while (n_data > 0) {
142 : :
143 [ + + + - : 24 : if (delim && group && bytes && (bytes % group) == 0)
+ + + - ]
144 : : g_string_append (result, delim);
145 : :
146 : 24 : j = *(input) >> 4 & 0xf;
147 [ + - ]: 24 : g_string_append_c (result, hexc[j]);
148 : :
149 : 24 : j = *(input++) & 0xf;
150 [ + - ]: 24 : g_string_append_c (result, hexc[j]);
151 : :
152 : 24 : ++bytes;
153 : 24 : --n_data;
154 : : }
155 : :
156 : : /* Make sure still null terminated */
157 : 3 : return g_string_free (result, FALSE);
158 : : }
159 : :
|