summaryrefslogtreecommitdiff
path: root/src/libwebvi/libwebvi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libwebvi/libwebvi.c')
-rw-r--r--src/libwebvi/libwebvi.c338
1 files changed, 338 insertions, 0 deletions
diff --git a/src/libwebvi/libwebvi.c b/src/libwebvi/libwebvi.c
new file mode 100644
index 0000000..b3d030a
--- /dev/null
+++ b/src/libwebvi/libwebvi.c
@@ -0,0 +1,338 @@
+/*
+ * libwebvi.c
+ *
+ * Copyright (c) 2010-2013 Antti Ajanki <antti.ajanki@iki.fi>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+#include <string.h>
+#include <libxml/xmlversion.h>
+#include "libwebvi.h"
+#include "webvicontext.h"
+#include "request.h"
+#include "version.h"
+
+static const char *VERSION = "libwebvi/" LIBWEBVI_VERSION;
+
+struct WebviErrorMessage {
+ WebviResult code;
+ const char *message;
+};
+
+int webvi_global_init() {
+ LIBXML_TEST_VERSION
+ return 0;
+}
+
+void webvi_cleanup() {
+ webvi_context_cleanup_all();
+}
+
+WebviCtx webvi_initialize_context(void) {
+ return webvi_context_initialize();
+}
+
+void webvi_cleanup_context(WebviCtx ctxhandle) {
+ webvi_context_cleanup(ctxhandle);
+}
+
+const char* webvi_version(void) {
+ return VERSION;
+}
+
+const char* webvi_strerror(WebviResult err) {
+ static struct WebviErrorMessage error_messages[] =
+ {{WEBVIERR_OK, "Succeeded"},
+ {WEBVIERR_INVALID_HANDLE, "Invalid handle"},
+ {WEBVIERR_INVALID_PARAMETER, "Invalid parameter"},
+ {WEBVIERR_UNKNOWN_ERROR, "Internal error"}};
+
+ for (int i=0; i<(sizeof(error_messages)/sizeof(error_messages[0])); i++) {
+ if (err == error_messages[i].code) {
+ return error_messages[i].message;
+ }
+ }
+
+ return "Internal error";
+}
+
+WebviResult webvi_set_config(WebviCtx ctxhandle, WebviConfig conf, ...) {
+ va_list argptr;
+ const char *p;
+ WebviResult res = WEBVIERR_OK;
+
+ WebviContext *ctx = get_context_by_handle(ctxhandle);
+ if (!ctx)
+ return WEBVIERR_INVALID_HANDLE;
+
+ va_start(argptr, conf);
+
+ switch (conf) {
+ case WEBVI_CONFIG_TEMPLATE_PATH:
+ p = va_arg(argptr, char *);
+ webvi_context_set_template_path(ctx, p);
+ break;
+ case WEBVI_CONFIG_DEBUG:
+ p = va_arg(argptr, char *);
+ webvi_context_set_debug(ctx, strcmp(p, "0") != 0);
+ break;
+ case WEBVI_CONFIG_TIMEOUT_CALLBACK:
+ // FIXME
+ // va_arg(argptr, long)
+ break;
+ case WEBVI_CONFIG_TIMEOUT_DATA:
+ // FIXME
+ // va_arg(argptr, long)
+ break;
+ default:
+ res = WEBVIERR_INVALID_PARAMETER;
+ };
+
+ va_end(argptr);
+
+ return res;
+}
+
+WebviHandle webvi_new_request(WebviCtx ctxhandle, const char *href) {
+ WebviContext *ctx = get_context_by_handle(ctxhandle);
+ if (!ctx)
+ return WEBVI_INVALID_HANDLE;
+
+ WebviRequest *req = request_create(href, ctx);
+ return webvi_context_add_request(ctx, req);
+}
+
+WebviResult webvi_start_request(WebviCtx ctxhandle, WebviHandle h) {
+ WebviContext *ctx = get_context_by_handle(ctxhandle);
+ if (!ctx)
+ return WEBVIERR_INVALID_HANDLE;
+
+ WebviRequest *req = webvi_context_get_request(ctx, h);
+ if (!req)
+ return WEBVIERR_INVALID_HANDLE;
+
+ request_start(req);
+
+ return WEBVIERR_OK;
+}
+
+WebviResult webvi_stop_request(WebviCtx ctxhandle, WebviHandle h) {
+ WebviContext *ctx = get_context_by_handle(ctxhandle);
+ if (!ctx)
+ return WEBVIERR_INVALID_HANDLE;
+
+ WebviRequest *req = webvi_context_get_request(ctx, h);
+ if (!req)
+ return WEBVIERR_INVALID_HANDLE;
+
+ request_stop(req);
+
+ return WEBVIERR_OK;
+}
+
+WebviResult webvi_delete_request(WebviCtx ctxhandle, WebviHandle h) {
+ WebviContext *ctx = get_context_by_handle(ctxhandle);
+ if (!ctx)
+ return WEBVIERR_INVALID_HANDLE;
+
+ WebviResult res = webvi_stop_request(ctxhandle, h);
+ if (res != WEBVIERR_OK)
+ return res;
+
+ webvi_context_remove_request(ctx, h);
+
+ return WEBVIERR_OK;
+}
+
+WebviResult webvi_set_opt(WebviCtx ctxhandle, WebviHandle h, WebviOption opt, ...) {
+ WebviContext *ctx = get_context_by_handle(ctxhandle);
+ if (!ctx)
+ return WEBVIERR_INVALID_HANDLE;
+
+ WebviRequest *req = webvi_context_get_request(ctx, h);
+ if (!req)
+ return WEBVIERR_INVALID_HANDLE;
+
+ va_list argptr;
+ WebviResult res = WEBVIERR_OK;
+
+ va_start(argptr, opt);
+
+ switch (opt) {
+ case WEBVIOPT_WRITEFUNC:
+ request_set_write_callback(req, va_arg(argptr, webvi_callback));
+ break;
+ case WEBVIOPT_READFUNC:
+ request_set_read_callback(req, va_arg(argptr, webvi_callback));
+ break;
+ case WEBVIOPT_WRITEDATA:
+ request_set_write_data(req, va_arg(argptr, void *));
+ break;
+ case WEBVIOPT_READDATA:
+ request_set_read_data(req, va_arg(argptr, void *));
+ break;
+ default:
+ res = WEBVIERR_INVALID_PARAMETER;
+ };
+
+ va_end(argptr);
+
+ return res;
+}
+
+WebviResult webvi_get_info(WebviCtx ctxhandle, WebviHandle h, WebviInfo info, ...) {
+ WebviContext *ctx = get_context_by_handle(ctxhandle);
+ if (!ctx)
+ return WEBVIERR_INVALID_HANDLE;
+
+ WebviRequest *req = webvi_context_get_request(ctx, h);
+ if (!req)
+ return WEBVIERR_INVALID_HANDLE;
+
+ va_list argptr;
+ WebviResult res = WEBVIERR_OK;
+
+ va_start(argptr, info);
+
+ switch (info) {
+ case WEBVIINFO_URL:
+ {
+ char **output = va_arg(argptr, char **);
+ if (output) {
+ *output = NULL;
+
+ const char *url = request_get_url(req);
+ if (url) {
+ *output = malloc(strlen(url)+1);
+ if (*output) {
+ strcpy(*output, url);
+ }
+ }
+ }
+ break;
+ }
+
+ case WEBVIINFO_CONTENT_LENGTH:
+ {
+ // FIXME
+ long *content_length = va_arg(argptr, long *);
+ if (content_length)
+ *content_length = -1;
+ break;
+ }
+
+ case WEBVIINFO_CONTENT_TYPE:
+ {
+ // FIXME
+ char **output = va_arg(argptr, char **);
+ if (output) {
+ *output = malloc(1);
+ **output = '\0';
+ }
+ break;
+ }
+
+ case WEBVIINFO_STREAM_TITLE:
+ {
+ // FIXME
+ char **output = va_arg(argptr, char **);
+ if (output) {
+ *output = malloc(1);
+ **output = '\0';
+ }
+ break;
+ }
+
+ default:
+ res = WEBVIERR_INVALID_PARAMETER;
+ };
+
+ va_end(argptr);
+
+ return res;
+}
+
+WebviResult webvi_fdset(WebviCtx ctxhandle, fd_set *readfd, fd_set *writefd,
+ fd_set *excfd, int *max_fd) {
+ WebviContext *ctx = get_context_by_handle(ctxhandle);
+ if (!ctx)
+ return WEBVIERR_INVALID_HANDLE;
+
+ return webvi_context_fdset(ctx, readfd, writefd, excfd, max_fd);
+}
+
+WebviResult webvi_perform(WebviCtx ctxhandle, int sockfd, int ev_bitmask,
+ long *running_handles) {
+ WebviContext *ctx = get_context_by_handle(ctxhandle);
+ if (!ctx)
+ return WEBVIERR_INVALID_HANDLE;
+
+ webvi_context_handle_socket_action(ctx, sockfd, ev_bitmask, running_handles);
+
+ return WEBVIERR_OK;
+}
+
+WebviMsg *webvi_get_message(WebviCtx ctxhandle, int *remaining_messages) {
+ WebviContext *ctx = get_context_by_handle(ctxhandle);
+ if (!ctx)
+ return NULL;
+
+ return webvi_context_next_message(ctx, remaining_messages);
+}
+
+int webvi_process_some(WebviCtx ctx, int timeout_seconds) {
+ fd_set readfds;
+ fd_set writefds;
+ fd_set excfds;
+ int maxfd;
+ int s;
+ WebviResult res;
+ struct timeval timeout;
+ long running_handles;
+
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_ZERO(&excfds);
+ res = webvi_fdset(ctx, &readfds, &writefds, &excfds, &maxfd);
+ if (res != WEBVIERR_OK) {
+ return -1;
+ }
+
+ timeout.tv_sec = timeout_seconds;
+ timeout.tv_usec = 0;
+ s = select(maxfd+1, &readfds, &writefds, NULL, &timeout);
+
+ if (s == -1) {
+ // error
+ return -1;
+ } else if (s == 0) {
+ // timeout
+ webvi_perform(ctx, WEBVI_SELECT_TIMEOUT, WEBVI_SELECT_CHECK, &running_handles);
+ } else {
+ // handle one fd
+ for (int fd=0; fd<=maxfd; fd++) {
+ if (FD_ISSET(fd, &readfds)) {
+ webvi_perform(ctx, fd, WEBVI_SELECT_READ, &running_handles);
+ } else if (FD_ISSET(fd, &writefds)) {
+ webvi_perform(ctx, fd, WEBVI_SELECT_WRITE, &running_handles);
+ } else if (FD_ISSET(fd, &excfds)) {
+ webvi_perform(ctx, fd, WEBVI_SELECT_EXCEPTION, &running_handles);
+ }
+ }
+ }
+
+ return running_handles;
+}