1
/*
2
 * Copyright 2008-2011 Various Authors
3
 * Copyright 2004 Timo Hirvonen
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License as
7
 * published by the Free Software Foundation; either version 2 of the
8
 * License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
#ifndef _UTILS_H
20
#define _UTILS_H
21
22
#ifdef HAVE_CONFIG
23
#include "config/utils.h"
24
#endif
25
26
#include <stdlib.h>
27
#include <string.h>
28
#include <sys/types.h>
29
#include <sys/stat.h>
30
#include <unistd.h>
31
#include <time.h>
32
#include <stdint.h>
33
#ifdef HAVE_BYTESWAP_H
34
#include <byteswap.h>
35
#endif
36
37
#define N_ELEMENTS(array) (sizeof(array) / sizeof((array)[0]))
38
39
#define STRINGIZE_HELPER(x) #x
40
#define STRINGIZE(x) STRINGIZE_HELPER(x)
41
42
#define getentry(ptr, offset, type) (*((type *) ((char *) (ptr) + (offset))))
43
44
static inline int min(int a, int b)
45
{
46
	return a < b ? a : b;
47
}
48
49
static inline int max(int a, int b)
50
{
51
	return a > b ? a : b;
52
}
53
54
static inline int clamp(int val, int minval, int maxval)
55
{
56
	if (val < minval)
57
		return minval;
58
	if (val > maxval)
59
		return maxval;
60
	return val;
61
}
62
63
static inline int scale_from_percentage(int val, int max_val)
64
{
65
	if (val < 0)
66
		return (val * max_val - 50) / 100;
67
	return (val * max_val + 50) / 100;
68
}
69
70
static inline int scale_to_percentage(int val, int max_val)
71
{
72
	int half = max_val / 2;
73
74
	if (max_val <= 0)
75
		return 100;
76
77
	if (val < 0)
78
		return (val * 100 - half) / max_val;
79
	return (val * 100 + half) / max_val;
80
}
81
82
static inline int str_to_int(const char *str, long int *val)
83
{
84
	char *end;
85
86
	*val = strtol(str, &end, 10);
87
	if (*str == 0 || *end != 0)
88
		return -1;
89
	return 0;
90
}
91
92
static inline int strcmp0(const char *str1, const char *str2)
93
{
94
	if (!str1)
95
		return str2 ? -1 : 0;
96
	if (!str2)
97
		return 1;
98
99
	return strcmp(str1, str2);
100
}
101
102
static inline uint32_t hash_str(const char *s)
103
{
104
	const unsigned char *p = (const unsigned char *)s;
105
	uint32_t h = 5381;
106
107
	while (*p) {
108
		h *= 33;
109
		h ^= *p++;
110
	}
111
112
	return h ^ (h >> 16);
113
}
114
115
static inline time_t file_get_mtime(const char *filename)
116
{
117
	struct stat s;
118
119
	/* stat follows symlinks, lstat does not */
120
	if (stat(filename, &s) == -1)
121
		return -1;
122
	return s.st_mtime;
123
}
124
125
static inline void ns_sleep(int ns)
126
{
127
	struct timespec req;
128
129
	req.tv_sec = 0;
130
	req.tv_nsec = ns;
131
	nanosleep(&req, NULL);
132
}
133
134
static inline void us_sleep(int us)
135
{
136
	ns_sleep(us * 1e3);
137
}
138
139
static inline void ms_sleep(int ms)
140
{
141
	ns_sleep(ms * 1e6);
142
}
143
144
static inline int is_http_url(const char *name)
145
{
146
	return strncmp(name, "http://", 7) == 0;
147
}
148
149
static inline int is_cdda_url(const char *name)
150
{
151
	return strncmp(name, "cdda://", 7) == 0;
152
}
153
154
static inline int is_cue_url(const char *name)
155
{
156
	return strncmp(name, "cue://", 6) == 0;
157
}
158
159
static inline int is_url(const char *name)
160
{
161
	return is_http_url(name) || is_cdda_url(name) || is_cue_url(name);
162
}
163
164
static inline int is_freeform_true(const char *c)
165
{
166
	return	c[0] == '1' ||
167
		c[0] == 'y' || c[0] == 'Y' ||
168
		c[0] == 't' || c[0] == 'T';
169
}
170
171
/* e.g. NetBSD */
172
#if defined(bswap16)
173
/* GNU libc */
174
#elif defined(bswap_16)
175
# define bswap16 bswap_16
176
/* e.g. OpenBSD */
177
#elif defined(swap16)
178
# define bswap16 swap16
179
#else
180
# define bswap16(x) \
181
	((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
182
#endif
183
184
static inline uint16_t swap_uint16(uint16_t x)
185
{
186
	return bswap16(x);
187
}
188
189
/* e.g. NetBSD */
190
#if defined(bswap32)
191
/* GNU libc */
192
#elif defined(bswap_32)
193
# define bswap32 bswap_32
194
/* e.g. OpenBSD */
195
#elif defined(swap32)
196
# define bswap32 swap32
197
#else
198
# define bswap32(x) \
199
	((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |	\
200
	 (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
201
#endif
202
203
static inline uint32_t swap_uint32(uint32_t x)
204
{
205
	return bswap32(x);
206
}
207
208
static inline uint32_t read_le32(const char *buf)
209
{
210
	const unsigned char *b = (const unsigned char *)buf;
211
212
	return b[0] | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
213
}
214
215
static inline uint16_t read_le16(const char *buf)
216
{
217
	const unsigned char *b = (const unsigned char *)buf;
218
219
	return b[0] | (b[1] << 8);
220
}
221
222
#endif