78 #define BIT(i) ((int64_t) 1 << (i))
159 static pthread_mutex_t
mutex = PTHREAD_MUTEX_INITIALIZER;
176 fprintf (stderr,
"Unknown tuple field name \"%s\".\n", name);
185 return tuple_fields[field].
name;
193 return tuple_fields[field].
type;
198 if ((tuple->setmask &
BIT (field)))
200 for (TupleBlock * block = tuple->blocks; block; block = block->next)
204 if (block->fields[i] == field)
208 tuple->setmask &= ~
BIT (field);
209 block->fields[i] = -1;
212 return & block->vals[i];
221 tuple->setmask |=
BIT (field);
223 for (TupleBlock * block = tuple->blocks; block; block = block->next)
227 if (block->fields[i] < 0)
229 block->fields[i] = field;
230 return & block->vals[i];
235 TupleBlock * block = g_slice_new0 (TupleBlock);
238 block->next = tuple->blocks;
239 tuple->blocks = block;
241 block->fields[0] = field;
242 return & block->vals[0];
248 for (TupleBlock * block = tuple->blocks; block; block = next)
254 int field = block->fields[i];
259 memset (block, 0,
sizeof (TupleBlock));
260 g_slice_free (TupleBlock, block);
263 g_free(tuple->subtunes);
265 memset (tuple, 0,
sizeof (Tuple));
266 g_slice_free (Tuple, tuple);
271 Tuple * tuple = g_slice_new0 (Tuple);
278 pthread_mutex_lock (&
mutex);
282 pthread_mutex_unlock (&
mutex);
288 pthread_mutex_lock (&
mutex);
290 if (! -- tuple->refcount)
293 pthread_mutex_unlock (&
mutex);
306 const char * base, * ext, * sub;
309 uri_parse (filename, & base, & ext, & sub, & isub);
311 char path[base - filename + 1];
315 char name[ext - base + 1];
321 char extbuf[sub - ext];
338 pthread_mutex_lock (&
mutex);
351 newval->
x = oldval->
x;
355 new->nsubtunes = old->nsubtunes;
358 new->subtunes = g_memdup (old->subtunes, sizeof (
int) * old->nsubtunes);
360 pthread_mutex_unlock (&
mutex);
380 EXPORT
void tuple_set_int (Tuple * tuple,
int nfield,
const char * field,
int x)
387 pthread_mutex_lock (&
mutex);
392 pthread_mutex_unlock (&
mutex);
395 EXPORT
void tuple_set_str (Tuple * tuple,
int nfield,
const char * field,
const char * str)
403 if (! g_utf8_validate (str, -1,
NULL))
405 fprintf (stderr,
"Invalid UTF-8: %s\n", str);
414 pthread_mutex_lock (&
mutex);
421 pthread_mutex_unlock (&
mutex);
424 EXPORT
void tuple_unset (Tuple * tuple,
int nfield,
const char * field)
431 pthread_mutex_lock (&
mutex);
445 pthread_mutex_unlock (&
mutex);
465 pthread_mutex_lock (&
mutex);
471 type = tuple_fields[nfield].
type;
473 pthread_mutex_unlock (&
mutex);
477 EXPORT
char *
tuple_get_str (
const Tuple * tuple,
int nfield,
const char * field)
484 pthread_mutex_lock (&
mutex);
492 pthread_mutex_unlock (&
mutex);
508 EXPORT
int tuple_get_int (
const Tuple * tuple,
int nfield,
const char * field)
515 pthread_mutex_lock (&
mutex);
523 pthread_mutex_unlock (&
mutex);
527 #define APPEND(b, ...) snprintf (b + strlen (b), sizeof b - strlen (b), \
546 APPEND (buf, dngettext (PACKAGE,
"%d channel",
"%d channels",
554 APPEND (buf,
"%d kHz", rate / 1000);
565 pthread_mutex_lock (&
mutex);
567 g_free (tuple->subtunes);
568 tuple->subtunes =
NULL;
570 tuple->nsubtunes = n_subtunes;
572 tuple->subtunes = g_memdup (subtunes,
sizeof (
int) * n_subtunes);
574 pthread_mutex_unlock (&
mutex);
579 pthread_mutex_lock (&
mutex);
581 int n_subtunes = tuple->nsubtunes;
583 pthread_mutex_unlock (&
mutex);
589 pthread_mutex_lock (&
mutex);
592 if (n >= 0 && n < tuple->nsubtunes)
593 subtune = tuple->subtunes ? tuple->subtunes[n] : 1 + n;
595 pthread_mutex_unlock (&
mutex);
605 for (
int i = 0; i < G_N_ELEMENTS (fallbacks); i ++)
607 if (title && title[0])
614 return title ? title :
str_get (
"");