void owr_image_server_add_image_renderer(OwrImageServer *image_server, OwrImageRenderer *image_renderer, const gchar *tag) { OwrImageServerPrivate *priv; g_return_if_fail(OWR_IS_IMAGE_SERVER(image_server)); g_return_if_fail(OWR_IS_IMAGE_RENDERER(image_renderer)); g_return_if_fail(tag && tag[0]); priv = image_server->priv; g_mutex_lock(&priv->image_renderers_mutex); if (!g_hash_table_contains(priv->image_renderers, tag)) { g_hash_table_insert(priv->image_renderers, g_strdup(tag), image_renderer); g_object_ref(image_renderer); } else g_warning("Image renderer not added, an image renderer is already added for this tag"); g_mutex_unlock(&priv->image_renderers_mutex); if (!priv->socket_service_is_started) { g_socket_listener_add_address(G_SOCKET_LISTENER(priv->socket_service), g_inet_socket_address_new(g_inet_address_new_from_string("127.0.0.1"), (guint16)priv->port), G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL, NULL, NULL); g_socket_service_start(priv->socket_service); priv->socket_service_is_started = TRUE; } }
void owr_image_server_remove_image_renderer(OwrImageServer *image_server, const gchar *tag) { OwrImageServerPrivate *priv; g_return_if_fail(OWR_IS_IMAGE_SERVER(image_server)); priv = image_server->priv; g_mutex_lock(&priv->image_renderers_mutex); if (!g_hash_table_remove(priv->image_renderers, tag)) g_warning("Image renderer not removed, no image renderer exists with this tag"); g_mutex_unlock(&priv->image_renderers_mutex); }
static void owr_image_server_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { OwrImageServerPrivate *priv; g_return_if_fail(OWR_IS_IMAGE_SERVER(object)); priv = OWR_IMAGE_SERVER(object)->priv; switch (property_id) { case PROP_PORT: g_value_set_uint(value, priv->port); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; } }
static void owr_image_server_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { OwrImageServerPrivate *priv; g_return_if_fail(OWR_IS_IMAGE_SERVER(object)); priv = OWR_IMAGE_SERVER(object)->priv; switch (property_id) { case PROP_PORT: priv->port = g_value_get_uint(value); break; case PROP_ALLOW_ORIGIN: g_free(priv->allow_origin); priv->allow_origin = g_value_dup_string(value); g_strdelimit(priv->allow_origin, "\r\n", ' '); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; } }
static gboolean on_incoming_connection(GThreadedSocketService *service, GSocketConnection *connection, GObject *source_object, OwrImageServer *image_server) { GOutputStream *bos; GDataInputStream *dis; gchar *error_body, *error_header = NULL, *response_header = NULL; gchar *line, *tag; gsize line_length, i; guint content_length = 0; OwrImageRenderer *image_renderer; GBytes *image; gconstpointer image_data; gsize image_data_size = 0; OWR_UNUSED(service); OWR_UNUSED(source_object); g_return_val_if_fail(OWR_IS_IMAGE_SERVER(image_server), TRUE); bos = g_buffered_output_stream_new(g_io_stream_get_output_stream(G_IO_STREAM(connection))); dis = g_data_input_stream_new(g_io_stream_get_input_stream(G_IO_STREAM(connection))); g_data_input_stream_set_newline_type(dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); error_body = "404 Not Found"; error_header = g_strdup_printf(HTTP_RESPONSE_HEADER_TEMPLATE, 404, "Not Found", "text/plain", (guint)strlen(error_body)); while (TRUE) { line = g_data_input_stream_read_line(dis, &line_length, NULL, NULL); if (!line) break; if (line_length > 6) { tag = g_strdup(line + 7); for (i = 0; i < strlen(tag); i++) { if (tag[i] == '-') { tag[i] = '\0'; break; } } } else tag = NULL; g_free(line); while ((line = g_data_input_stream_read_line(dis, &line_length, NULL, NULL))) { g_free(line); if (!line_length) { /* got all request headers */ break; } } if (!line) break; g_mutex_lock(&image_server->priv->image_renderers_mutex); image_renderer = tag ? g_hash_table_lookup(image_server->priv->image_renderers, tag) : NULL; g_mutex_unlock(&image_server->priv->image_renderers_mutex); image = image_renderer ? _owr_image_renderer_pull_bmp_image(image_renderer) : NULL; if (!image) { g_output_stream_write(bos, error_header, strlen(error_header), NULL, NULL); g_output_stream_write(bos, error_body, strlen(error_body), NULL, NULL); break; } image_data = g_bytes_get_data(image, &image_data_size); if (content_length != image_data_size) { content_length = image_data_size; g_free(response_header); response_header = g_strdup_printf(HTTP_RESPONSE_HEADER_TEMPLATE, 200, "OK", "image/bmp", content_length); g_buffered_output_stream_set_buffer_size(G_BUFFERED_OUTPUT_STREAM(bos), strlen(response_header) + content_length); } g_output_stream_write(bos, response_header, strlen(response_header), NULL, NULL); g_output_stream_write(bos, image_data, image_data_size, NULL, NULL); g_output_stream_flush(bos, NULL, NULL); g_bytes_unref(image); } g_free(response_header); g_free(error_header); g_object_unref(dis); g_object_unref(bos); return FALSE; }