]> git.sesse.net Git - vlc/blob - src/misc/strings.c
cefe5f48b4d789a42d8a8bd3b1a8ade93e7c1bf8
[vlc] / src / misc / strings.c
1 /*****************************************************************************
2  * strings.c: String related functions
3  *****************************************************************************
4  * Copyright (C) 2006 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Antoine Cellerier <dionoea at videolan dot org>
8  *          Daniel Stranger <vlc at schmaller dot de>
9  *          RĂ©mi Denis-Courmont <rem # videolan org>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include <vlc/vlc.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <assert.h>
34
35 #include "vlc_strings.h"
36
37 /**
38  * Decode URI encoded string
39  * \return decoded duplicated string
40  */
41 char *decode_encoded_URI_duplicate( const char *psz )
42 {
43     char *psz_dup = strdup( psz );
44     decode_encoded_URI( psz_dup );
45     return psz_dup;
46 }
47
48 /**
49  * Decode URI encoded string
50  * \return nothing
51  */
52 void decode_encoded_URI( char *psz )
53 {
54     unsigned char *in = (unsigned char *)psz, *out = in, c;
55
56     while( ( c = *in++ ) != '\0' )
57     {
58         switch( c )
59         {
60             case '%':
61             {
62                 char val[5], *pval = val;
63                 unsigned long cp;
64
65                 switch( c = *in++ )
66                 {
67                     case '\0':
68                         return;
69
70                     case 'u':
71                     case 'U':
72                         if( ( *pval++ = *in++ ) == '\0' )
73                             return;
74                         if( ( *pval++ = *in++ ) == '\0' )
75                             return;
76                         c = *in++;
77
78                     default:
79                         *pval++ = c;
80                         if( ( *pval++ = *in++ ) == '\0' )
81                             return;
82                         *pval = '\0';
83                 }
84
85                 cp = strtoul( val, NULL, 0x10 );
86                 if( cp < 0x80 )
87                     *out++ = cp;
88                 else
89                 if( cp < 0x800 )
90                 {
91                     *out++ = (( cp >>  6)         | 0xc0);
92                     *out++ = (( cp        & 0x3f) | 0x80);
93                 }
94                 else
95                 {
96                     assert( cp < 0x10000 );
97                     *out++ = (( cp >> 12)         | 0xe0);
98                     *out++ = (((cp >>  6) & 0x3f) | 0x80);
99                     *out++ = (( cp        & 0x3f) | 0x80);
100                 }
101                 break;
102             }
103
104             case '+':
105                 *out++ = ' ';
106                 break;
107
108             default:
109                 /* Inserting non-ASCII or non-printable characters is unsafe,
110                  * and no sane browser will send these unencoded */
111                 if( ( c < 32 ) || ( c > 127 ) )
112                     *out++ = '?';
113                 else
114                     *out++ = c;
115         }
116     }
117     *out = '\0';
118 }
119
120 /**
121  * Converts "&lt;", "&gt;" and "&amp;" to "<", ">" and "&"
122  * \param string to convert
123  */
124 void resolve_xml_special_chars( char *psz_value )
125 {
126     char *p_pos = psz_value;
127
128     while ( *psz_value )
129     {
130         if( !strncmp( psz_value, "&lt;", 4 ) )
131         {
132             *p_pos = '<';
133             psz_value += 4;
134         }
135         else if( !strncmp( psz_value, "&gt;", 4 ) )
136         {
137             *p_pos = '>';
138             psz_value += 4;
139         }
140         else if( !strncmp( psz_value, "&amp;", 5 ) )
141         {
142             *p_pos = '&';
143             psz_value += 5;
144         }
145         else if( !strncmp( psz_value, "&quot;", 6 ) )
146         {
147             *p_pos = '\"';
148             psz_value += 6;
149         }
150         else if( !strncmp( psz_value, "&#039;", 6 ) )
151         {
152             *p_pos = '\'';
153             psz_value += 6;
154         }
155         else
156         {
157             *p_pos = *psz_value;
158             psz_value++;
159         }
160
161         p_pos++;
162     }
163
164     *p_pos = '\0';
165 }
166
167 /**
168  * Converts '<', '>', '\"', '\'' and '&' to their html entities
169  * \param psz_content simple element content that is to be converted
170  */
171 char *convert_xml_special_chars( const char *psz_content )
172 {
173     char *psz_temp = malloc( 6 * strlen( psz_content ) + 1 );
174     const char *p_from = psz_content;
175     char *p_to   = psz_temp;
176
177     while ( *p_from )
178     {
179         if ( *p_from == '<' )
180         {
181             strcpy( p_to, "&lt;" );
182             p_to += 4;
183         }
184         else if ( *p_from == '>' )
185         {
186             strcpy( p_to, "&gt;" );
187             p_to += 4;
188         }
189         else if ( *p_from == '&' )
190         {
191             strcpy( p_to, "&amp;" );
192             p_to += 5;
193         }
194         else if( *p_from == '\"' )
195         {
196             strcpy( p_to, "&quot;" );
197             p_to += 6;
198         }
199         else if( *p_from == '\'' )
200         {
201             strcpy( p_to, "&#039;" );
202             p_to += 6;
203         }
204         else
205         {
206             *p_to = *p_from;
207             p_to++;
208         }
209         p_from++;
210     }
211     *p_to = '\0';
212
213     return psz_temp;
214 }