2 * Copyright (c) 2006-2011 Ed Schouten <ed@80386.nl>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * @brief General utility functions
35 #ifdef BUILD_SCROBBLER
37 * @brief Convert a numerical value to a hexadecimal character.
45 return (val
- 10 + 'a');
49 hex_encode(unsigned char *bin
, char *hex
, size_t len
)
52 *hex
++ = toxdigit(*bin
>> 4);
53 *hex
++ = toxdigit(*bin
++ & 0x0f);
56 #endif /* BUILD_SCROBBLER */
59 http_escape(const char *str
, const char *prepend
)
62 const char allowed
[] = "-_.!~*'()/";
68 /* Argument may be empty */
70 return g_strdup(prepend
);
72 ret
= g_string_new(prepend
);
74 for (c
= str
; *c
!= '\0'; c
++) {
76 g_string_append_c(ret
, '+');
77 else if (g_ascii_isalnum(*c
) || strchr(allowed
, *c
) != NULL
)
78 /* Character is allowed */
79 g_string_append_c(ret
, *c
);
81 /* Reserved or unwise character */
82 g_string_append_printf(ret
, "%%%02hhx",
83 (const unsigned char)*c
);
86 return g_string_free(ret
, FALSE
);
91 * @brief Unescape a string according to HTTP/1.1. The conversion will
92 * be performed in place. The arguments point to the read and
93 * write offsets. In almost all cases, they must point to the
97 http_unescape(char *r
, char *w
)
99 for (; *r
!= '\0'; r
++, w
++) {
101 g_ascii_isxdigit(r
[1]) && g_ascii_isxdigit(r
[2])) {
102 /* Character needs to be unescaped */
103 *w
= g_ascii_xdigit_value(r
[1]) << 4;
104 *w
|= g_ascii_xdigit_value(r
[2]);
105 /* Move two bytes more */
107 } else if (*r
== '+') {
108 /* Convert + back to space */
111 /* Ordinary character */
116 /* Null terminate the output */
121 url_escape(const char *str
)
123 if (strstr(str
, "://") == NULL
) {
124 return http_escape(str
, "file://");
126 return g_strdup(str
);
131 url_unescape(char *str
)
133 if (strncmp(str
, "file://", 7) == 0) {
134 http_unescape(str
+ 7, str
);
135 /* XXX: slash conversion */
140 #endif /* BUILD_XSPF */