cfg_encoder.c 5 KB
Newer Older
1
/*
Moritz Grimm's avatar
Moritz Grimm committed
2
 * Copyright (c) 2015, 2020 Moritz Grimm <mgrimm@mrsserver.net>
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */

#include <sys/queue.h>

#include <assert.h>
#include <string.h>

#include "cfg_private.h"
#include "cfg_encoder.h"
#include "xalloc.h"

struct cfg_encoder {
	TAILQ_ENTRY(cfg_encoder) entry;
	char			*name;
	enum cfg_stream_format	 format;
	char			*program;
};

37
TAILQ_HEAD(cfg_encoder_list, cfg_encoder);
38

39
40
struct cfg_encoder_list *
cfg_encoder_list_create(void)
41
{
42
43
44
45
46
47
	struct cfg_encoder_list *el;

	el = xcalloc(1UL, sizeof(*el));
	TAILQ_INIT(el);

	return (el);
48
49
50
}

void
51
cfg_encoder_list_destroy(struct cfg_encoder_list **el_p)
52
{
53
	struct cfg_encoder_list *el = *el_p;
54
55
	struct cfg_encoder	*e;

56
57
58
	if (!el)
		return;

59
60
	while (NULL != (e = TAILQ_FIRST(el)))
		cfg_encoder_list_remove(el, &e);
61
62
63

	xfree(el);
	*el_p = NULL;
64
65
}

66
67
68
69
70
71
72
73
74
75
76
77
78
unsigned int
cfg_encoder_list_nentries(struct cfg_encoder_list *el)
{
	struct cfg_encoder	*e;
	unsigned int		 n = 0;

	TAILQ_FOREACH(e, el, entry) {
		n++;
	}

	return (n);
}

79
struct cfg_encoder *
80
cfg_encoder_list_find(struct cfg_encoder_list *el, const char *name)
81
82
83
{
	struct cfg_encoder	*e;

84
	TAILQ_FOREACH(e, el, entry) {
85
86
87
88
		if (0 == strcasecmp(e->name, name))
			return (e);
	}

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
	return (NULL);
}

struct cfg_encoder *
cfg_encoder_list_get(struct cfg_encoder_list *el, const char *name)
{
	struct cfg_encoder	*e;

	e = cfg_encoder_list_find(el, name);
	if (e)
		return (e);
	e = cfg_encoder_create(name);
	if (!e)
		return (NULL);

	TAILQ_INSERT_TAIL(el, e, entry);

	return (e);
}

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
void
cfg_encoder_list_foreach(struct cfg_encoder_list *el,
    void (*cb)(cfg_encoder_t, void *), void *cb_arg)
{
	struct cfg_encoder	*e;

	TAILQ_FOREACH(e, el, entry) {
		cb(e, cb_arg);
	}
}

void
cfg_encoder_list_remove(struct cfg_encoder_list *el, struct cfg_encoder **e_p)
{
	TAILQ_REMOVE(el, *e_p, entry);
	cfg_encoder_destroy(e_p);
}

127
128
129
130
131
132
133
134
struct cfg_encoder *
cfg_encoder_create(const char *name)
{
	struct cfg_encoder	*e;

	if (!name || !name[0])
		return (NULL);

135
136
137
138
139
140
	e = xcalloc(1UL, sizeof(*e));
	e->name = xstrdup(name);

	return (e);
}

141
142
143
144
145
146
147
148
149
150
151
void
cfg_encoder_destroy(struct cfg_encoder **e_p)
{
	struct cfg_encoder	*e = *e_p;

	xfree(e->name);
	xfree(e->program);
	xfree(e);
	*e_p = NULL;
}

152
int
153
154
155
156
157
158
159
160
161
162
cfg_encoder_set_format(struct cfg_encoder *e, enum cfg_stream_format fmt)
{
	assert(CFG_STREAM_MIN <= fmt && CFG_STREAM_MAX >= fmt);
	e->format = fmt;
	return (0);
}

int
cfg_encoder_set_name(struct cfg_encoder *e, struct cfg_encoder_list *el,
    const char *name, const char **errstrp)
163
{
164
165
	struct cfg_encoder	*e2;

166
167
168
169
170
171
	if (!name || !name[0]) {
		if (errstrp)
			*errstrp = "empty";
		return (-1);
	}

172
173
174
175
176
177
	e2 = cfg_encoder_list_find(el, name);
	if (e2 && e2 != e) {
		if (errstrp)
			*errstrp = "already exists";
		return (-1);
	}
178

179
	SET_XSTRDUP(e->name, name, errstrp);
180
181
182
183
184

	return (0);
}

int
185
186
cfg_encoder_set_format_str(struct cfg_encoder *e,
    struct cfg_encoder_list *not_used, const char *fmt_str,
187
188
189
190
    const char **errstrp)
{
	enum cfg_stream_format	fmt;

191
192
	(void)not_used;

Moritz Grimm's avatar
Moritz Grimm committed
193
	if (!fmt_str || !fmt_str[0]) {
194
195
196
197
198
199
200
201
202
203
204
		if (errstrp)
			*errstrp = "empty";
		return (-1);
	}

	if (0 > cfg_stream_str2fmt(fmt_str, &fmt)) {
		if (errstrp)
			*errstrp = "unsupported stream format";
		return (-1);
	}

205
	cfg_encoder_set_format(e, fmt);
206
207
208
209
210

	return (0);
}

int
211
212
cfg_encoder_set_program(struct cfg_encoder *e,
    struct cfg_encoder_list *not_used, const char *program,
213
    const char **errstrp)
214
{
215
216
	(void)not_used;

217
218
219
220
221
	if (!program || !program[0]) {
		if (errstrp)
			*errstrp = "empty";
		return (-1);
	}
222

223
224
	xfree(e->program);
	e->program = xstrdup(program);
225
226
227
228
229
230
231
232
233
234
235
236
237

	return (0);
}

int
cfg_encoder_validate(struct cfg_encoder *e, const char **errstrp)
{
	if (CFG_STREAM_INVALID == e->format) {
		if (errstrp)
			*errstrp = "format not set";
		return (-1);
	}

238
239
240
241
242
	if (!e->program) {
		if (errstrp)
			*errstrp = "program not set";
		return (-1);
	}
243

244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
	CHECKPH_PROHIBITED(e->program, PLACEHOLDER_TRACK);
	CHECKPH_PROHIBITED(e->program, PLACEHOLDER_STRING);
	CHECKPH_DUPLICATE(e->program, PLACEHOLDER_METADATA);
	CHECKPH_DUPLICATE(e->program, PLACEHOLDER_ARTIST);
	CHECKPH_DUPLICATE(e->program, PLACEHOLDER_TITLE);

	return (0);
}

const char *
cfg_encoder_get_name(struct cfg_encoder *e)
{
	return (e->name);
}

enum cfg_stream_format
cfg_encoder_get_format(struct cfg_encoder *e)
{
	return (e->format);
}

const char *
cfg_encoder_get_program(struct cfg_encoder *e)
{
	return (e->program);
}