blob: 9dc5f9799b8985fbd942928f0bdc776f36855d55 [file]
/*
* history.c - History functions for Speech Dispatcher
*
* Copyright (C) 2001, 2002, 2003 Brailcom, o.p.s.
*
* This 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 2, or (at your option)
* any later version.
*
* This software 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 <https://www.gnu.org/licenses/>.
*
* $Id: history.c,v 1.24 2008-02-08 10:01:09 hanke Exp $
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "speechd.h"
#include "msg.h"
#include "set.h"
#include "server.h"
#include "history.h"
/* List of messages in history */
static GList *message_history;
/* Compares TSpeechDMessage data structure elements
with given ID */
gint message_compare_id(gconstpointer element, gconstpointer value)
{
gint ret;
ret = ((TSpeechDMessage *) element)->id - *((int *)value);
return ret;
}
gint(*p_msg_comp_id) (gconstpointer element, gconstpointer value) = message_compare_id;
char *history_get_client_list()
{
TFDSetElement *client;
GString *clist;
int i;
clist = g_string_new("");
for (i = 1; i <= SpeechdStatus.max_uid; i++) {
MSG(4, "Getting settings for client %d of %d", i,
SpeechdStatus.max_uid - 1);
client = get_client_settings_by_uid(i);
assert(client != NULL);
g_string_append_printf(clist, C_OK_CLIENTS "-");
g_string_append_printf(clist, "%d ", client->uid);
g_string_append(clist, client->client_name);
g_string_append_printf(clist, " %d", client->active);
g_string_append(clist, "\r\n");
}
g_string_append_printf(clist, OK_CLIENT_LIST_SENT);
return g_string_free(clist, FALSE);
}
char *history_get_client_id(int fd)
{
GString *cid;
int uid;
uid = get_client_uid_by_fd(fd);
if (uid == 0)
return g_strdup(ERR_INTERNAL);
cid = g_string_new("");
g_string_append_printf(cid, C_OK_CLIENT_ID "-%d\r\n", uid);
g_string_append_printf(cid, OK_CLIENT_ID_SENT);
return g_string_free(cid, FALSE);
}
char *history_get_message(int uid)
{
/* TODO: Rework. */
#if 0
GString *mtext;
GList *gl;
TSpeechDMessage *msg;
int i, pos;
char c;
char helper[1024];
mtext = g_string_new("");
gl = g_list_find_custom(message_history, &uid, compare_message_uid);
if (gl == NULL)
return g_strdup(ERR_ID_NOT_EXIST);
if (gl->data == NULL)
return g_strdup(ERR_INTERNAL);
msg = (TSpeechDMessage *) gl->data;
i = 0;
pos = 0;
while (c = msg->buf[i]) {
helper[pos] = msg->buf[i];
pos++;
i++;
if (c == '\n') {
helper[pos - 2] = 0;
g_string_append_printf(mtext, C_OK_MSG_TEXT "-%s\r\n",
helper);
pos = 0;
}
}
helper[pos] = 0;
g_string_append_printf(mtext, C_OK_MSG_TEXT "-%s\r\n", helper);
g_string_append_printf(mtext, OK_MSG_TEXT_SENT);
#endif
return g_strdup(ERR_NOT_IMPLEMENTED);
}
char *history_get_message_list(guint client_id, int from, int num)
{
TSpeechDMessage *message;
GString *mlist;
GList *gl;
TFDSetElement *client_settings;
GList *client_msgs;
int i;
MSG(4, "message_list: from %d num %d, client %d\n", from, num,
client_id);
client_settings = get_client_settings_by_uid(client_id);
if (client_settings == NULL)
return g_strdup(ERR_NO_SUCH_CLIENT);
mlist = g_string_new("");
client_msgs = get_messages_by_client(client_id);
for (i = from; i <= from + num - 1; i++) {
gl = g_list_nth(client_msgs, i);
if (gl == NULL) {
g_string_append_printf(mlist, OK_MSGS_LIST_SENT);
return g_string_free(mlist, FALSE);
}
message = gl->data;
if (message == NULL) {
if (SPEECHD_DEBUG)
FATAL("Internal error.\n");
g_string_free(mlist, TRUE);
return g_strdup(ERR_INTERNAL);
}
g_string_append_printf(mlist, C_OK_MSGS "-");
g_string_append_printf(mlist, "%d %s\r\n", message->id,
client_settings->client_name);
}
g_string_append_printf(mlist, OK_MSGS_LIST_SENT);
return g_string_free(mlist, FALSE);
}
char *history_get_last(int fd)
{
TSpeechDMessage *message;
GString *lastm;
GList *gl;
gl = g_list_last(message_history);
if (gl == NULL)
return g_strdup(ERR_NO_MESSAGE);
message = gl->data;
lastm = g_string_new("");
g_string_append_printf(lastm, C_OK_LAST_MSG "-%d\r\n", message->id);
g_string_append_printf(lastm, OK_LAST_MSG);
return g_string_free(lastm, FALSE);
}
char *history_cursor_set_last(int fd, guint client_id)
{
GList *client_msgs;
TFDSetElement *settings;
settings = get_client_settings_by_fd(fd);
if (settings == NULL)
FATAL("Couldn't find settings for active client");
client_msgs = get_messages_by_client(client_id);
settings->hist_cur_pos = g_list_length(client_msgs) - 1;
settings->hist_cur_uid = client_id;
return g_strdup(OK_CUR_SET_LAST);
}
char *history_cursor_set_first(int fd, guint client_id)
{
TFDSetElement *settings;
settings = get_client_settings_by_fd(fd);
if (settings == NULL)
FATAL("Couldn't find settings for active client");
settings->hist_cur_pos = 0;
settings->hist_cur_uid = client_id;
return g_strdup(OK_CUR_SET_FIRST);
}
char *history_cursor_set_pos(int fd, guint client_id, int pos)
{
TFDSetElement *settings;
GList *client_msgs;
if (pos < 0)
return g_strdup(ERR_POS_LOW);
client_msgs = get_messages_by_client(client_id);
if (pos > g_list_length(client_msgs) - 1)
return g_strdup(ERR_POS_HIGH);
settings = get_client_settings_by_fd(fd);
if (settings == NULL)
FATAL("Couldn't find settings for active client");
settings->hist_cur_pos = pos;
settings->hist_cur_uid = client_id;
MSG(4, "cursor pos:%d\n", settings->hist_cur_pos);
return g_strdup(OK_CUR_SET_POS);
}
char *history_cursor_forward(int fd)
{
TFDSetElement *settings;
GList *client_msgs;
settings = get_client_settings_by_fd(fd);
if (settings == NULL)
FATAL("Couldn't find settings for active client");
client_msgs = get_messages_by_client(settings->hist_cur_uid);
if ((settings->hist_cur_pos + 1) > g_list_length(client_msgs) - 1)
return g_strdup(ERR_POS_HIGH);
settings->hist_cur_pos++;
return g_strdup(OK_CUR_MOV_FOR);
}
char *history_cursor_backward(int fd)
{
TFDSetElement *settings;
settings = get_client_settings_by_fd(fd);
if (settings == NULL)
FATAL("Couldn't find settings for active client");
if ((settings->hist_cur_pos - 1) < 0)
return g_strdup(ERR_POS_LOW);
settings->hist_cur_pos--;
return g_strdup(OK_CUR_MOV_BACK);
}
char *history_cursor_get(int fd)
{
TFDSetElement *settings;
TSpeechDMessage *new;
GString *reply;
GList *gl, *client_msgs;
settings = get_client_settings_by_fd(fd);
if (settings == NULL)
FATAL("Couldn't find settings for active client");
client_msgs = get_messages_by_client(settings->hist_cur_uid);
gl = g_list_nth(client_msgs, (int)settings->hist_cur_pos);
if (gl == NULL)
return g_strdup(ERR_NO_MESSAGE);
new = gl->data;
reply = g_string_new("");
g_string_printf(reply, C_OK_CUR_POS "-%d\r\n" OK_CUR_POS_RET, new->id);
return g_string_free(reply, FALSE);
}
char *history_say_id(int fd, int id)
{
TSpeechDMessage *msg;
GList *gl;
gl = g_list_find_custom(message_history, &id, p_msg_comp_id);
if (gl == NULL)
return g_strdup(ERR_ID_NOT_EXIST);
msg = gl->data;
if (msg == NULL)
return g_strdup(ERR_INTERNAL);
MSG(4, "putting history message into queue\n");
// new = (TSpeechDMessage *) spd_message_copy(msg);
// queue_message(new, fd, 0, 0);
return g_strdup(OK_MESSAGE_QUEUED);
}
int history_add_message(TSpeechDMessage * msg)
{
TSpeechDMessage *hist_msg;
/* We will make an exact copy of the message for inclusion into history. */
hist_msg = (TSpeechDMessage *) spd_message_copy(msg);
if (hist_msg == NULL) {
if (SPEECHD_DEBUG)
FATAL("Can't include message into history\n");
return -1;
}
/* Do the necessary expiration of old messages */
if (g_list_length(message_history) >=
SpeechdOptions.max_history_messages) {
GList *gl;
MSG(5, "Discarding older history message, limit reached");
gl = g_list_first(message_history);
if (gl != NULL) {
message_history =
g_list_remove_link(message_history, gl);
if (gl->data != NULL)
mem_free_message(gl->data);
}
}
/* Save the message into history */
message_history = g_list_append(message_history, hist_msg);
return 0;
}
GList *get_messages_by_client(int uid)
{
GList *list = NULL;
GList *gl;
TSpeechDMessage *msg;
guint i;
guint history_length = g_list_length(message_history);
for (i = 0; i < history_length; i++) {
gl = g_list_nth(message_history, i);
assert(gl != NULL);
msg = gl->data;
if (msg->settings.uid == uid) {
list = g_list_append(list, msg);
}
}
return list;
}