2002-09-02 Marcus Brinkmann <marcus@g10code.de>
[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 <ctype.h>
27 #include "gpgme.h"
28 #include "util.h"
29
30
31 int
32 _gpgme_hextobyte (const byte *str)
33 {
34   int val = 0;
35   int i;
36
37   for (i = 0; i < 2; i++)
38     {
39       if (*str >= '0' && *str <= '9')
40         val += *str - '0';
41       else if (*str >= 'A' && *str <= 'F')
42         val += 10 + *str - 'A';
43       else if (*str >= 'a' && *str <= 'f')
44         val += 10 + *str - 'a';
45       else
46         return -1;
47       val *= 16;
48       str++;
49     }
50   return val;
51 }
52
53
54 GpgmeError
55 _gpgme_decode_c_string (const char *src, char **destp)
56 {
57   char *dest;
58
59   /* We can malloc a buffer of the same length, because the converted
60      string will never be larger.  */
61   dest = xtrymalloc (strlen (src) + 1);
62   if (!dest)
63     return mk_error (Out_Of_Core);
64
65   while (*src)
66     {
67       if (*src != '\\')
68         *(dest++) = *(src++);
69       else if (src[1] == '\\')
70         {
71           src++;
72           *(dest++) = *(src++); 
73         }
74       else if (src[1] == 'n')
75         {
76           src += 2;
77           *(dest++) = '\n'; 
78         }
79       else if (src[1] == 'r')
80         {
81           src += 2;
82           *(dest++) = '\r'; 
83         }
84       else if (src[1] == 'v')
85         {
86           src += 2;
87           *(dest++) = '\v'; 
88         }
89       else if (src[1] == 'b')
90         {
91           src += 2;
92           *(dest++) = '\b'; 
93         }
94       else if (src[1] == '0')
95         {
96           /* Hmmm: no way to express this */
97           src += 2;
98           *(dest++) = '\\';
99           *(dest++) = '\0'; 
100         }
101       else if (src[1] == 'x' && isxdigit (src[2]) && isxdigit (src[3]))
102         {
103           int val = _gpgme_hextobyte (&src[2]);
104           if (val == -1)
105             {
106               /* Should not happen.  */
107               *(dest++) = *(src++);
108               *(dest++) = *(src++);
109               *(dest++) = *(src++);
110               *(dest++) = *(src++);
111             }
112           else
113             {
114               if (!val)
115                 {
116                   *(dest++) = '\\';
117                   *(dest++) = '\0'; 
118                 }
119               else 
120                 *(byte*)dest++ = val;
121               src += 4;
122             }
123         }
124       else
125         {
126           /* should not happen */
127           src++;
128           *(dest++) = '\\'; 
129           *(dest++) = *(src++);
130         } 
131     }
132   *(dest++) = 0;
133   *destp = dest;
134
135   return 0;
136 }