2008-01-15 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / common / convert.c
blob7aa6354d6af937f9b052e0e97024c629b98e12ee
1 /* convert.c - Hex conversion functions.
2 * Copyright (C) 2006 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include <config.h>
21 #include <stdlib.h>
22 #include <errno.h>
23 #include <ctype.h>
25 #include "util.h"
28 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
31 /* Convert STRING consisting of hex characters into its binary
32 representation and store that at BUFFER. BUFFER needs to be of
33 LENGTH bytes. The function check that the STRING will convert
34 exactly to LENGTH bytes. The string is delimited by either end of
35 string or a white space character. The function returns -1 on
36 error or the length of the parsed string. */
37 int
38 hex2bin (const char *string, void *buffer, size_t length)
40 int i;
41 const char *s = string;
43 for (i=0; i < length; )
45 if (!hexdigitp (s) || !hexdigitp (s+1))
46 return -1; /* Invalid hex digits. */
47 ((unsigned char*)buffer)[i++] = xtoi_2 (s);
48 s += 2;
50 if (*s && (!isascii (*s) || !isspace (*s)) )
51 return -1; /* Not followed by Nul or white space. */
52 if (i != length)
53 return -1; /* Not of expected length. */
54 if (*s)
55 s++; /* Skip the delimiter. */
56 return s - string;
60 /* Convert STRING consisting of hex characters into its binary representation
61 and store that at BUFFER. BUFFER needs to be of LENGTH bytes. The
62 function check that the STRING will convert exactly to LENGTH
63 bytes. Colons inbetween the hex digits are allowed, if one colon
64 has been given a colon is expected very 2 characters. The string
65 is delimited by either end of string or a white space character.
66 The function returns -1 on error or the length of the parsed
67 string. */
68 int
69 hexcolon2bin (const char *string, void *buffer, size_t length)
71 int i;
72 const char *s = string;
73 int need_colon = 0;
75 for (i=0; i < length; )
77 if (i==1 && *s == ':') /* Skip colons between hex digits. */
79 need_colon = 1;
80 s++;
82 else if (need_colon && *s == ':')
83 s++;
84 else if (need_colon)
85 return -1; /* Colon expected. */
86 if (!hexdigitp (s) || !hexdigitp (s+1))
87 return -1; /* Invalid hex digits. */
88 ((unsigned char*)buffer)[i++] = xtoi_2 (s);
89 s += 2;
91 if (*s == ':')
92 return -1; /* Trailing colons are not allowed. */
93 if (*s && (!isascii (*s) || !isspace (*s)) )
94 return -1; /* Not followed by Nul or white space. */
95 if (i != length)
96 return -1; /* Not of expected length. */
97 if (*s)
98 s++; /* Skip the delimiter. */
99 return s - string;
103 static char *
104 do_bin2hex (const void *buffer, size_t length, char *stringbuf, int with_colon)
106 const unsigned char *s;
107 char *p;
109 if (!stringbuf)
111 /* Not really correct for with_colon but we don't care about the
112 one wasted byte. */
113 size_t n = with_colon? 3:2;
114 size_t nbytes = n * length + 1;
115 if (length && (nbytes-1) / n != length)
117 errno = ENOMEM;
118 return NULL;
120 stringbuf = xtrymalloc (nbytes);
121 if (!stringbuf)
122 return NULL;
125 for (s = buffer, p = stringbuf; length; length--, s++)
127 if (with_colon && s != buffer)
128 *p++ = ':';
129 *p++ = tohex ((*s>>4)&15);
130 *p++ = tohex (*s&15);
132 *p = 0;
134 return stringbuf;
138 /* Convert LENGTH bytes of data in BUFFER into hex encoding and store
139 that at the provided STRINGBUF. STRINGBUF must be allocated of at
140 least (2*LENGTH+1) bytes or be NULL so that the function mallocs an
141 appropriate buffer. Returns STRINGBUF or NULL on error (which may
142 only occur if STRINGBUF has been NULL and the internal malloc
143 failed). */
144 char *
145 bin2hex (const void *buffer, size_t length, char *stringbuf)
147 return do_bin2hex (buffer, length, stringbuf, 0);
150 /* Convert LENGTH bytes of data in BUFFER into hex encoding and store
151 that at the provided STRINGBUF. STRINGBUF must be allocated of at
152 least (3*LENGTH+1) bytes or be NULL so that the function mallocs an
153 appropriate buffer. Returns STRINGBUF or NULL on error (which may
154 only occur if STRINGBUF has been NULL and the internal malloc
155 failed). */
156 char *
157 bin2hexcolon (const void *buffer, size_t length, char *stringbuf)
159 return do_bin2hex (buffer, length, stringbuf, 1);