#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "share/grabbag.h"
#include "share/compat.h"
#include "FLAC/assert.h"
#include <stdlib.h>
#include <string.h>
FLAC__bool grabbag__seektable_convert_specification_to_template(const char *spec, FLAC__bool only_explicit_placeholders, FLAC__uint64 total_samples_to_encode, uint32_t sample_rate, FLAC__StreamMetadata *seektable_template, FLAC__bool *spec_has_real_points)
{
uint32_t i;
const char *pt;
FLAC__ASSERT(0 != spec);
FLAC__ASSERT(0 != seektable_template);
FLAC__ASSERT(seektable_template->type == FLAC__METADATA_TYPE_SEEKTABLE);
if(0 != spec_has_real_points)
*spec_has_real_points = false;
for(pt = spec, i = 0; pt && *pt; i++) {
const char *q = strchr(pt, ';');
FLAC__ASSERT(0 != q);
if(q > pt) {
if(0 == strncmp(pt, "X;", 2)) {
if(!FLAC__metadata_object_seektable_template_append_placeholders(seektable_template, 1))
return false;
}
else if(q[-1] == 'x') {
if(total_samples_to_encode > 0) {
if(0 != spec_has_real_points)
*spec_has_real_points = true;
if(!only_explicit_placeholders) {
const int n = (uint32_t)atoi(pt);
if(n > 0)
if(!FLAC__metadata_object_seektable_template_append_spaced_points(seektable_template, (uint32_t)n, total_samples_to_encode))
return false;
}
}
}
else if(q[-1] == 's') {
if(total_samples_to_encode > 0 && sample_rate > 0) {
if(0 != spec_has_real_points)
*spec_has_real_points = true;
if(!only_explicit_placeholders) {
const double sec = atof(pt);
if(sec > 0.0) {
uint32_t samples = (uint32_t)(sec * (double)sample_rate);
samples = samples < sample_rate / 2 ? sample_rate / 2 : samples;
if(samples > 0) {
if(!FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(seektable_template, samples, total_samples_to_encode))
return false;
}
}
}
}
}
else {
if(0 != spec_has_real_points)
*spec_has_real_points = true;
if(!only_explicit_placeholders) {
char *endptr;
const FLAC__int64 n = (FLAC__int64)strtoll(pt, &endptr, 10);
if(
(n > 0 || (endptr > pt && *endptr == ';')) &&
(total_samples_to_encode == 0 || (FLAC__uint64)n < total_samples_to_encode)
)
if(!FLAC__metadata_object_seektable_template_append_point(seektable_template, (FLAC__uint64)n))
return false;
}
}
}
pt = ++q;
}
if(!FLAC__metadata_object_seektable_template_sort(seektable_template, true))
return false;
return true;
}