Fix whitespace inconsistencies.
[herrie-working.git] / herrie / src / util.c
blobac7885e03edde51249c096aa9a96b8d5f5ab861b
1 /*
2 * Copyright (c) 2006-2011 Ed Schouten <ed@80386.nl>
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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
24 * SUCH DAMAGE.
26 /**
27 * @file util.c
28 * @brief General utility functions
31 #include "stdinc.h"
33 #include "util.h"
35 #ifdef BUILD_SCROBBLER
36 /**
37 * @brief Convert a numerical value to a hexadecimal character.
39 static inline char
40 toxdigit(char val)
42 if (val < 10)
43 return (val + '0');
44 else
45 return (val - 10 + 'a');
48 void
49 hex_encode(unsigned char *bin, char *hex, size_t len)
51 while (len-- > 0) {
52 *hex++ = toxdigit(*bin >> 4);
53 *hex++ = toxdigit(*bin++ & 0x0f);
56 #endif /* BUILD_SCROBBLER */
58 char *
59 http_escape(const char *str, const char *prepend)
61 const char *c;
62 const char allowed[] = "-_.!~*'()/";
63 GString *ret;
65 if (prepend == NULL)
66 prepend = "";
68 /* Argument may be empty */
69 if (str == NULL)
70 return g_strdup(prepend);
72 ret = g_string_new(prepend);
74 for (c = str; *c != '\0'; c++) {
75 if (*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);
80 else
81 /* Reserved or unwise character */
82 g_string_append_printf(ret, "%%%02hhx",
83 (const unsigned char)*c);
86 return g_string_free(ret, FALSE);
89 #ifdef BUILD_XSPF
90 /**
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
94 * same string.
96 static void
97 http_unescape(char *r, char *w)
99 for (; *r != '\0'; r++, w++) {
100 if (r[0] == '%' &&
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 */
106 r += 2;
107 } else if (*r == '+') {
108 /* Convert + back to space */
109 *w = ' ';
110 } else {
111 /* Ordinary character */
112 *w = *r;
116 /* Null terminate the output */
117 *w = '\0';
120 char *
121 url_escape(const char *str)
123 if (strstr(str, "://") == NULL) {
124 return http_escape(str, "file://");
125 } else {
126 return g_strdup(str);
130 char *
131 url_unescape(char *str)
133 if (strncmp(str, "file://", 7) == 0) {
134 http_unescape(str + 7, str);
135 /* XXX: slash conversion */
138 return (str);
140 #endif /* BUILD_XSPF */