From 86f8526302b42e76908fa50c43c1419b6d42c570 Mon Sep 17 00:00:00 2001 From: Yang Gu Date: Fri, 20 Nov 2009 16:53:20 +0800 Subject: [PATCH 1/2] Framework to support non-standard terminator --- gatchat/gatchat.c | 68 +++++++++++++++++++++++++++++++++++++++++----------- gatchat/gatchat.h | 3 ++ 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/gatchat/gatchat.c b/gatchat/gatchat.c index 320150a..17f9118 100644 --- a/gatchat/gatchat.c +++ b/gatchat/gatchat.c @@ -88,6 +88,13 @@ struct _GAtChat { GTimer *wakeup_timer; /* Keep track of elapsed time */ GAtSyntax *syntax; gboolean destroyed; /* Re-entrancy guard */ + GSList *terminator_list; /* Non-standard terminator */ +}; + +struct terminator_info { + const char *terminator; + int len; + gboolean success; }; static gint at_notify_node_compare_by_id(gconstpointer a, gconstpointer b) @@ -204,6 +211,14 @@ static void at_command_destroy(struct at_command *cmd) g_free(cmd); } +static void free_terminator(struct terminator_info *ti) +{ + g_free((char *)ti->terminator); + ti->terminator = NULL; + g_free(ti); + ti = NULL; +} + static void g_at_chat_cleanup(GAtChat *chat) { struct at_command *c; @@ -251,6 +266,13 @@ static void g_at_chat_cleanup(GAtChat *chat) chat->syntax = NULL; chat->channel = NULL; + + if (chat->terminator_list) { + g_slist_foreach(chat->terminator_list, + (GFunc)free_terminator, NULL); + g_slist_free(chat->terminator_list); + chat->terminator_list = NULL; + } } static void read_watcher_destroy_notify(GAtChat *chat) @@ -359,12 +381,6 @@ static void g_at_chat_finish_command(GAtChat *p, gboolean ok, at_command_destroy(cmd); } -struct terminator_info { - const char *terminator; - int len; - gboolean success; -}; - static struct terminator_info terminator_table[] = { { "OK", -1, TRUE }, { "ERROR", -1, FALSE }, @@ -378,6 +394,32 @@ static struct terminator_info terminator_table[] = { { "+EXT ERROR:", 11, FALSE } }; +void g_at_chat_add_terminator(GAtChat *chat, const char *terminator, + int len, gboolean success) +{ + struct terminator_info *ti = g_new0(struct terminator_info, 1); + ti->terminator = strdup(terminator); + ti->len = len; + ti->success = success; + chat->terminator_list = g_slist_prepend(chat->terminator_list, ti); +} + +static gboolean meet_terminator(GAtChat *chat, + struct terminator_info *info, char *line) +{ + if (info->len == -1 && !strcmp(line, info->terminator)) { + g_at_chat_finish_command(chat, info->success, line); + return TRUE; + } + + if (info->len > 0 && !strncmp(line, info->terminator, info->len)) { + g_at_chat_finish_command(chat, info->success, line); + return TRUE; + } + + return FALSE; +} + static gboolean g_at_chat_handle_command_response(GAtChat *p, struct at_command *cmd, char *line) @@ -385,20 +427,16 @@ static gboolean g_at_chat_handle_command_response(GAtChat *p, int i; int size = sizeof(terminator_table) / sizeof(struct terminator_info); int hint; + GSList *l; for (i = 0; i < size; i++) { - struct terminator_info *info = &terminator_table[i]; - - if (info->len == -1 && !strcmp(line, info->terminator)) { - g_at_chat_finish_command(p, info->success, line); + if (meet_terminator(p, &terminator_table[i], line)) return TRUE; - } + } - if (info->len > 0 && - !strncmp(line, info->terminator, info->len)) { - g_at_chat_finish_command(p, info->success, line); + for (l = p->terminator_list; l; l = l->next) { + if (meet_terminator(p, l->data, line)) return TRUE; - } } if (cmd->prefixes) { diff --git a/gatchat/gatchat.h b/gatchat/gatchat.h index fe5b97b..b191f1b 100644 --- a/gatchat/gatchat.h +++ b/gatchat/gatchat.h @@ -128,6 +128,9 @@ gboolean g_at_chat_unregister(GAtChat *chat, guint id); gboolean g_at_chat_set_wakeup_command(GAtChat *chat, const char *cmd, guint timeout, guint msec); +void g_at_chat_add_terminator(GAtChat *chat, const char *terminator, + int len, gboolean success); + #ifdef __cplusplus } -- 1.6.5.2