ad85a8a932dafdede105d687a81f5ecd91036f99
[gpgme.git] / gpgme / conversion.c
1 /* conversion.c - String conversion helper functions.
2  *      Copyright (C) 2000 Werner Koch (dd9jn)
3  *      Copyright (C) 2001, 2002 g10 Code GmbH
4  *
5  * This file is part of GPGME.
6  *
7  * GPGME is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GPGME is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #if HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <string.h>
27 #include <ctype.h>
28 #include "gpgme.h"
29 #include "util.h"
30
31
32 int
33 _gpgme_hextobyte (const byte *str)
34 {
35   int val = 0;
36   int i;
37
38 #define NROFHEXDIGITS 2
39   for (i = 0; i < NROFHEXDIGITS; i++)
40     {
41       if (*str >= '0' && *str <= '9')
42         val += *str - '0';
43       else if (*str >= 'A' && *str <= 'F')
44         val += 10 + *str - 'A';
45       else if (*str >= 'a' && *str <= 'f')
46         val += 10 + *str - 'a';
47       else
48         return -1;
49       if (i < NROFHEXDIGITS - 1)
50         val *= 16;
51       str++;
52     }
53   return val;
54 }
55
56
57 GpgmeError
58 _gpgme_decode_c_string (const char *src, char **destp)
59 {
60   char *dest;
61
62   /* We can malloc a buffer of the same length, because the converted
63      string will never be larger.  */
64   dest = xtrymalloc (strlen (src) + 1);
65   if (!dest)
66     return mk_error (Out_Of_Core);
67
68   *destp = dest;
69
70   while (*src)
71     {
72       if (*src != '\\')
73         *(dest++) = *(src++);
74       else if (src[1] == '\\')
75         {
76           src++;
77           *(dest++) = *(src++); 
78         }
79       else if (src[1] == 'n')
80         {
81           src += 2;
82           *(dest++) = '\n'; 
83         }
84       else if (src[1] == 'r')
85         {
86           src += 2;
87           *(dest++) = '\r'; 
88         }
89       else if (src[1] == 'v')
90         {
91           src += 2;
92           *(dest++) = '\v'; 
93         }
94       else if (src[1] == 'b')
95         {
96           src += 2;
97           *(dest++) = '\b'; 
98         }
99       else if (src[1] == '0')
100         {
101           /* Hmmm: no way to express this */
102           src += 2;
103           *(dest++) = '\\';
104           *(dest++) = '\0'; 
105         }
106       else if (src[1] == 'x' && isxdigit (src[2]) && isxdigit (src[3]))
107         {
108           int val = _gpgme_hextobyte (&src[2]);
109           if (val == -1)
110             {
111               /* Should not happen.  */
112               *(dest++) = *(src++);
113               *(dest++) = *(src++);
114               *(dest++) = *(src++);
115               *(dest++) = *(src++);
116             }
117           else
118             {
119               if (!val)
120                 {
121                   *(dest++) = '\\';
122                   *(dest++) = '\0'; 
123                 }
124               else 
125                 *(byte*)dest++ = val;
126               src += 4;
127             }
128         }
129       else
130         {
131           /* should not happen */
132           src++;
133           *(dest++) = '\\'; 
134           *(dest++) = *(src++);
135         } 
136     }
137   *(dest++) = 0;
138
139   return 0;
140 }