mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-02-02 15:07:36 -05:00
commit
00e1cf91c8
@ -51,6 +51,7 @@ noinst_HEADERS = \
|
||||
format_ogg.h \
|
||||
format_mp3.h \
|
||||
format_ebml.h \
|
||||
format_text.h \
|
||||
format_vorbis.h \
|
||||
format_theora.h \
|
||||
format_flac.h \
|
||||
@ -100,6 +101,7 @@ icecast_SOURCES = \
|
||||
format_midi.c \
|
||||
format_flac.c \
|
||||
format_ebml.c \
|
||||
format_text.c \
|
||||
format_kate.c \
|
||||
format_skeleton.c \
|
||||
format_opus.c \
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "format_ogg.h"
|
||||
#include "format_mp3.h"
|
||||
#include "format_ebml.h"
|
||||
#include "format_text.h"
|
||||
|
||||
#include "logging.h"
|
||||
#include "stats.h"
|
||||
@ -71,6 +72,8 @@ format_type_t format_get_type (const char *contenttype)
|
||||
return FORMAT_TYPE_EBML;
|
||||
else if(strcmp(contenttype, "video/x-matroska-3d") == 0)
|
||||
return FORMAT_TYPE_EBML;
|
||||
else if(strcmp(contenttype, "text/plain") == 0)
|
||||
return FORMAT_TYPE_TEXT;
|
||||
else
|
||||
/* We default to the Generic format handler, which
|
||||
can handle many more formats than just mp3.
|
||||
@ -90,6 +93,9 @@ int format_get_plugin(format_type_t type, source_t *source)
|
||||
case FORMAT_TYPE_EBML:
|
||||
ret = format_ebml_get_plugin(source);
|
||||
break;
|
||||
case FORMAT_TYPE_TEXT:
|
||||
ret = format_text_get_plugin(source);
|
||||
break;
|
||||
case FORMAT_TYPE_GENERIC:
|
||||
ret = format_mp3_get_plugin(source);
|
||||
break;
|
||||
|
@ -32,6 +32,7 @@ typedef enum _format_type_tag
|
||||
FORMAT_ERROR, /* No format, source not processable */
|
||||
FORMAT_TYPE_OGG,
|
||||
FORMAT_TYPE_EBML,
|
||||
FORMAT_TYPE_TEXT,
|
||||
FORMAT_TYPE_GENERIC
|
||||
} format_type_t;
|
||||
|
||||
|
135
src/format_text.c
Normal file
135
src/format_text.c
Normal file
@ -0,0 +1,135 @@
|
||||
/* Icecast
|
||||
*
|
||||
* This program is distributed under the GNU General Public License,
|
||||
* version 2. A copy of this license is included with this source.
|
||||
* At your option, this specific source file can also be distributed
|
||||
* under the GNU GPL version 3.
|
||||
*
|
||||
* Copyright 2021, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "source.h"
|
||||
#include "format.h"
|
||||
#include "format_text.h"
|
||||
|
||||
#define CATMODULE "format-text"
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
typedef struct {
|
||||
bool skipchar;
|
||||
char skipchar_char;
|
||||
} text_state_t;
|
||||
|
||||
static void text_free_plugin(format_plugin_t *plugin)
|
||||
{
|
||||
free(plugin->_state);
|
||||
free(plugin);
|
||||
}
|
||||
|
||||
static size_t skipchar(char *text, char skip, size_t len)
|
||||
{
|
||||
char *inp = text;
|
||||
char *outp = text;
|
||||
size_t ret = 0;
|
||||
|
||||
// skip prefix.
|
||||
for (; len && *inp != skip; inp++, outp++, len--, ret++);
|
||||
|
||||
for (; len; inp++, len--) {
|
||||
if (*inp != skip) {
|
||||
*outp = *inp;
|
||||
outp++;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static refbuf_t *text_get_buffer(source_t *source)
|
||||
{
|
||||
format_plugin_t *format = source->format;
|
||||
text_state_t *state = format->_state;
|
||||
refbuf_t *refbuf = refbuf_new(1024);
|
||||
ssize_t bytes;
|
||||
|
||||
bytes = client_body_read(source->client, refbuf->data, refbuf->len);
|
||||
if (bytes < 0) {
|
||||
/* Why do we do this here (not source.c)? -- ph3-der-loewe, 2018-04-17 */
|
||||
if (client_body_eof(source->client)) {
|
||||
refbuf_release (refbuf);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (state->skipchar)
|
||||
bytes = skipchar(refbuf->data, state->skipchar_char, bytes);
|
||||
|
||||
refbuf->len = bytes;
|
||||
refbuf->sync_point = 1;
|
||||
format->read_bytes += bytes;
|
||||
|
||||
ICECAST_LOG_DDEBUG("Got buffer for source %p with %zi bytes", source, bytes);
|
||||
|
||||
return refbuf;
|
||||
}
|
||||
|
||||
int format_text_get_plugin(source_t *source)
|
||||
{
|
||||
format_plugin_t *plugin = calloc(1, sizeof(format_plugin_t));
|
||||
text_state_t *state = calloc(1, sizeof(text_state_t));
|
||||
const char *skip;
|
||||
|
||||
ICECAST_LOG_DEBUG("Opening text format for source %p", source);
|
||||
|
||||
plugin->get_buffer = text_get_buffer;
|
||||
plugin->write_buf_to_client = format_generic_write_to_client;
|
||||
plugin->create_client_data = NULL;
|
||||
plugin->free_plugin = text_free_plugin;
|
||||
plugin->write_buf_to_file = NULL;
|
||||
plugin->set_tag = NULL;
|
||||
plugin->apply_settings = NULL;
|
||||
|
||||
plugin->contenttype = httpp_getvar(source->parser, "content-type");
|
||||
|
||||
skip = httpp_getvar(source->parser, "x-icecast-text-skip-char");
|
||||
if (skip) {
|
||||
ICECAST_LOG_WARN("Source %p on mount %#H uses experimental X-Icecast-Text-Skip-Char:-header", source, source->mount);
|
||||
}
|
||||
if (skip && strlen(skip) == 3 && skip[0] == '%') {
|
||||
bool valid = true;
|
||||
size_t i;
|
||||
|
||||
for (i = 1; i < 3; i++) {
|
||||
const char c = skip[i];
|
||||
|
||||
state->skipchar_char <<= 4;
|
||||
if (c >= '0' && c <= '9') {
|
||||
state->skipchar_char += c - '0';
|
||||
} else if (c >= 'a' && c <= 'f') {
|
||||
state->skipchar_char += c - 'a' + 10;
|
||||
} else if (c >= 'A' && c <= 'F') {
|
||||
state->skipchar_char += c - 'A' + 10;
|
||||
} else {
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
state->skipchar = valid;
|
||||
}
|
||||
|
||||
plugin->_state = state;
|
||||
vorbis_comment_init(&plugin->vc);
|
||||
source->format = plugin;
|
||||
|
||||
return 0;
|
||||
}
|
16
src/format_text.h
Normal file
16
src/format_text.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* Icecast
|
||||
*
|
||||
* This program is distributed under the GNU General Public License, version 2.
|
||||
* A copy of this license is included with this source.
|
||||
*
|
||||
* Copyright 2021, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
|
||||
*/
|
||||
|
||||
#ifndef __FORMAT_TEXT_H__
|
||||
#define __FORMAT_TEXT_H__
|
||||
|
||||
#include "format.h"
|
||||
|
||||
int format_text_get_plugin(source_t *source);
|
||||
|
||||
#endif /* __FORMAT_TEXT_H__ */
|
Loading…
x
Reference in New Issue
Block a user