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   *destp = dest;
66
67   while (*src)
68     {
69       if (*src != '\\')
70         *(dest++) = *(src++);
71       else if (src[1] == '\\')
72         {
73           src++;
74           *(dest++) = *(src++); 
75         }
76       else if (src[1] == 'n')
77         {
78           src += 2;
79           *(dest++) = '\n'; 
80         }
81       else if (src[1] == 'r')
82         {
83           src += 2;
84           *(dest++) = '\r'; 
85         }
86       else if (src[1] == 'v')
87         {
88           src += 2;
89           *(dest++) = '\v'; 
90         }
91       else if (src[1] == 'b')
92         {
93           src += 2;
94           *(dest++) = '\b'; 
95         }
96       else if (src[1] == '0')
97         {
98           /* Hmmm: no way to express this */
99           src += 2;
100           *(dest++) = '\\';
101           *(dest++) = '\0'; 
102         }
103       else if (src[1] == 'x' && isxdigit (src[2]) && isxdigit (src[3]))
104         {
105           int val = _gpgme_hextobyte (&src[2]);
106           if (val == -1)
107             {
108               /* Should not happen.  */
109               *(dest++) = *(src++);
110               *(dest++) = *(src++);
111               *(dest++) = *(src++);
112               *(dest++) = *(src++);
113             }
114           else
115             {
116               if (!val)
117                 {
118                   *(dest++) = '\\';
119                   *(dest++) = '\0'; 
120                 }
121               else 
122                 *(byte*)dest++ = val;
123               src += 4;
124             }
125         }
126       else
127         {
128           /* should not happen */
129           src++;
130           *(dest++) = '\\'; 
131           *(dest++) = *(src++);
132         } 
133     }
134   *(dest++) = 0;
135
136   return 0;
137 }