output/httpd: add constructor, destructor, Configure()

This commit is contained in:
Max Kellermann 2013-01-30 13:29:21 +01:00
parent ad5eb2f8d6
commit 6d79a1cdfc
2 changed files with 66 additions and 50 deletions

View File

@ -34,8 +34,8 @@
#include <forward_list> #include <forward_list>
#include <stdbool.h> struct config_param;
class EventLoop;
class ServerSocket; class ServerSocket;
class HttpdClient; class HttpdClient;
@ -124,6 +124,11 @@ struct HttpdOutput {
*/ */
guint clients_max, clients_cnt; guint clients_max, clients_cnt;
HttpdOutput(EventLoop &_loop);
~HttpdOutput();
bool Configure(const config_param *param, GError **error_r);
bool Bind(GError **error_r); bool Bind(GError **error_r);
void Unbind(); void Unbind();

View File

@ -58,6 +58,26 @@ static void
httpd_listen_in_event(int fd, const struct sockaddr *address, httpd_listen_in_event(int fd, const struct sockaddr *address,
size_t address_length, int uid, void *ctx); size_t address_length, int uid, void *ctx);
inline
HttpdOutput::HttpdOutput(EventLoop &_loop)
:encoder(nullptr), unflushed_input(0),
server_socket(new ServerSocket(_loop, httpd_listen_in_event, this)),
metadata(nullptr)
{
}
HttpdOutput::~HttpdOutput()
{
if (metadata != nullptr)
metadata->Unref();
if (encoder != nullptr)
encoder_finish(encoder);
delete server_socket;
}
inline bool inline bool
HttpdOutput::Bind(GError **error_r) HttpdOutput::Bind(GError **error_r)
{ {
@ -76,23 +96,14 @@ HttpdOutput::Unbind()
server_socket->Close(); server_socket->Close();
} }
static struct audio_output * inline bool
httpd_output_init(const struct config_param *param, HttpdOutput::Configure(const config_param *param, GError **error_r)
GError **error)
{ {
HttpdOutput *httpd = new HttpdOutput();
if (!ao_base_init(&httpd->base, &httpd_output_plugin, param, error)) {
g_free(httpd);
return NULL;
}
/* read configuration */ /* read configuration */
httpd->name = name = config_get_block_string(param, "name", "Set name in config");
config_get_block_string(param, "name", "Set name in config"); genre = config_get_block_string(param, "genre", "Set genre in config");
httpd->genre = website = config_get_block_string(param, "website",
config_get_block_string(param, "genre", "Set genre in config"); "Set website in config");
httpd->website =
config_get_block_string(param, "website", "Set website in config");
guint port = config_get_block_unsigned(param, "port", 8000); guint port = config_get_block_unsigned(param, "port", 8000);
@ -101,49 +112,54 @@ httpd_output_init(const struct config_param *param,
const struct encoder_plugin *encoder_plugin = const struct encoder_plugin *encoder_plugin =
encoder_plugin_get(encoder_name); encoder_plugin_get(encoder_name);
if (encoder_plugin == NULL) { if (encoder_plugin == NULL) {
g_set_error(error, httpd_output_quark(), 0, g_set_error(error_r, httpd_output_quark(), 0,
"No such encoder: %s", encoder_name); "No such encoder: %s", encoder_name);
ao_base_finish(&httpd->base); return false;
g_free(httpd);
return NULL;
} }
httpd->clients_max = config_get_block_unsigned(param,"max_clients", 0); clients_max = config_get_block_unsigned(param,"max_clients", 0);
/* set up bind_to_address */ /* set up bind_to_address */
httpd->server_socket = new ServerSocket(*main_loop,
httpd_listen_in_event, httpd);
const char *bind_to_address = const char *bind_to_address =
config_get_block_string(param, "bind_to_address", NULL); config_get_block_string(param, "bind_to_address", NULL);
bool success = bind_to_address != NULL && bool success = bind_to_address != NULL &&
strcmp(bind_to_address, "any") != 0 strcmp(bind_to_address, "any") != 0
? httpd->server_socket->AddHost(bind_to_address, port, error) ? server_socket->AddHost(bind_to_address, port, error_r)
: httpd->server_socket->AddPort(port, error); : server_socket->AddPort(port, error_r);
if (!success) { if (!success)
ao_base_finish(&httpd->base); return false;
g_free(httpd);
return NULL;
}
/* initialize metadata */
httpd->metadata = NULL;
httpd->unflushed_input = 0;
/* initialize encoder */ /* initialize encoder */
httpd->encoder = encoder_init(encoder_plugin, param, error); encoder = encoder_init(encoder_plugin, param, error_r);
if (httpd->encoder == NULL) { if (encoder == nullptr)
ao_base_finish(&httpd->base); return false;
g_free(httpd);
return NULL;
}
/* determine content type */ /* determine content type */
httpd->content_type = encoder_get_mime_type(httpd->encoder); content_type = encoder_get_mime_type(encoder);
if (httpd->content_type == NULL) { if (content_type == nullptr)
httpd->content_type = "application/octet-stream"; content_type = "application/octet-stream";
return true;
}
static struct audio_output *
httpd_output_init(const struct config_param *param,
GError **error_r)
{
HttpdOutput *httpd = new HttpdOutput(*main_loop);
if (!ao_base_init(&httpd->base, &httpd_output_plugin, param,
error_r)) {
delete httpd;
return nullptr;
}
if (!httpd->Configure(param, error_r)) {
ao_base_finish(&httpd->base);
delete httpd;
return nullptr;
} }
return &httpd->base; return &httpd->base;
@ -154,11 +170,6 @@ httpd_output_finish(struct audio_output *ao)
{ {
HttpdOutput *httpd = (HttpdOutput *)ao; HttpdOutput *httpd = (HttpdOutput *)ao;
if (httpd->metadata)
httpd->metadata->Unref();
encoder_finish(httpd->encoder);
delete httpd->server_socket;
ao_base_finish(&httpd->base); ao_base_finish(&httpd->base);
delete httpd; delete httpd;
} }