summaryrefslogtreecommitdiffstats
path: root/gatchat/gatresult.c
diff options
context:
space:
mode:
authorDenis Kenzior <denis.kenzior@intel.com>2009-05-06 14:33:17 -0700
committerMarcel Holtmann <marcel.holtmann@intel.com>2009-05-06 14:42:54 -0700
commit64c42764736de15544e58666bdf97de088f7a7b5 (patch)
tree8f496fa6822a15acc593bd8ee66007ed0925efd3 /gatchat/gatresult.c
parent4ea27466bf3a5a3309d5ee689a1470c20c483ef9 (diff)
downloadofono-64c42764736de15544e58666bdf97de088f7a7b5.tar.bz2
Add AT chat library implementation
Diffstat (limited to 'gatchat/gatresult.c')
-rw-r--r--gatchat/gatresult.c377
1 files changed, 377 insertions, 0 deletions
diff --git a/gatchat/gatresult.c b/gatchat/gatresult.c
new file mode 100644
index 00000000..87457f1c
--- /dev/null
+++ b/gatchat/gatresult.c
@@ -0,0 +1,377 @@
+/*
+ *
+ * AT chat library with GLib integration
+ *
+ * Copyright (C) 2008-2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <glib.h>
+
+#include "gatresult.h"
+
+void g_at_result_iter_init(GAtResultIter *iter, GAtResult *result)
+{
+ iter->result = result;
+ iter->pre.next = result->lines;
+ iter->pre.data = NULL;
+ iter->l = &iter->pre;
+ iter->line_pos = 0;
+}
+
+gboolean g_at_result_iter_next(GAtResultIter *iter, const char *prefix)
+{
+ char *line;
+ int prefix_len = prefix ? strlen(prefix) : 0;
+
+ while ((iter->l = iter->l->next)) {
+ line = iter->l->data;
+
+ if (prefix_len == 0) {
+ iter->line_pos = 0;
+ return TRUE;
+ }
+
+ if (g_str_has_prefix(line, prefix) == FALSE)
+ continue;
+
+ iter->line_pos = prefix_len;
+
+ while (iter->line_pos < strlen(line) &&
+ line[iter->line_pos] == ' ')
+ iter->line_pos += 1;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+const char *g_at_result_iter_raw_line(GAtResultIter *iter)
+{
+ const char *line;
+
+ if (!iter)
+ return NULL;
+
+ if (!iter->l)
+ return NULL;
+
+ line = iter->l->data;
+
+ line += iter->line_pos;
+
+ return line;
+}
+
+static inline int skip_to_next_field(const char *line, int pos, int len)
+{
+ if (pos < len && line[pos] == ',')
+ pos += 1;
+
+ while (pos < len && line[pos] == ' ')
+ pos += 1;
+
+ return pos;
+}
+
+gboolean g_at_result_iter_next_string(GAtResultIter *iter, const char **str)
+{
+ unsigned int pos;
+ unsigned int end;
+ unsigned int len;
+ char *line;
+
+ if (!iter)
+ return FALSE;
+
+ if (!iter->l)
+ return FALSE;
+
+ line = iter->l->data;
+ len = strlen(line);
+
+ pos = iter->line_pos;
+
+ /* Omitted string */
+ if (line[pos] == ',') {
+ end = pos;
+ memset(iter->buf, 0, sizeof(iter->buf));
+ goto out;
+ }
+
+ if (line[pos++] != '"')
+ return FALSE;
+
+ end = pos;
+
+ while (end < len && line[end] != '"')
+ end += 1;
+
+ if (line[end] != '"')
+ return FALSE;
+
+ if (end - pos >= sizeof(iter->buf))
+ return FALSE;
+
+ strncpy(iter->buf, line+pos, end-pos);
+ memset(iter->buf + end - pos, 0, sizeof(iter->buf) - end + pos);
+
+ /* Skip " */
+ end += 1;
+
+out:
+ iter->line_pos = skip_to_next_field(line, end, len);
+
+ if (str)
+ *str = iter->buf;
+
+ return TRUE;
+}
+
+gboolean g_at_result_iter_next_number(GAtResultIter *iter, gint *number)
+{
+ int pos;
+ int end;
+ int len;
+ int value = 0;
+ char *line;
+
+ if (!iter)
+ return FALSE;
+
+ if (!iter->l)
+ return FALSE;
+
+ line = iter->l->data;
+ len = strlen(line);
+
+ pos = iter->line_pos;
+ end = pos;
+
+ while (line[end] >= '0' && line[end] <= '9') {
+ value = value * 10 + (int)(line[end] - '0');
+ end += 1;
+ }
+
+ if (pos == end)
+ return FALSE;
+
+ iter->line_pos = skip_to_next_field(line, end, len);
+
+ if (number)
+ *number = value;
+
+ return TRUE;
+}
+
+gboolean g_at_result_iter_next_range(GAtResultIter *iter, gint *min, gint *max)
+{
+ int pos;
+ int end;
+ int len;
+ int low = 0;
+ int high = 0;
+ char *line;
+
+ if (!iter)
+ return FALSE;
+
+ if (!iter->l)
+ return FALSE;
+
+ line = iter->l->data;
+ len = strlen(line);
+
+ pos = iter->line_pos;
+
+ while (pos < len && line[pos] == ' ')
+ pos += 1;
+
+ end = pos;
+
+ while (line[end] >= '0' && line[end] <= '9') {
+ low = low * 10 + (int)(line[end] - '0');
+ end += 1;
+ }
+
+ if (pos == end)
+ return FALSE;
+
+ if (line[end] == ',') {
+ high = low;
+ goto out;
+ }
+
+ if (line[end] == '-')
+ pos = end = end + 1;
+ else
+ return FALSE;
+
+ while (line[end] >= '0' && line[end] <= '9') {
+ high = high * 10 + (int)(line[end] - '0');
+ end += 1;
+ }
+
+ if (pos == end)
+ return FALSE;
+
+out:
+ iter->line_pos = skip_to_next_field(line, end, len);
+
+ if (min)
+ *min = low;
+
+ if (max)
+ *max = high;
+
+ return TRUE;
+}
+
+static gint skip_until(const char *line, int start, const char delim)
+{
+ int len = strlen(line);
+ int i = start;
+
+ while (i < len) {
+ if (line[i] == delim)
+ return i;
+
+ if (line[i] != '(') {
+ i += 1;
+ continue;
+ }
+
+ i = skip_until(line, i+1, ')');
+
+ if (i < len)
+ i += 1;
+ }
+
+ return i;
+}
+
+gboolean g_at_result_iter_skip_next(GAtResultIter *iter)
+{
+ unsigned int skipped_to;
+ char *line;
+
+ if (!iter)
+ return FALSE;
+
+ if (!iter->l)
+ return FALSE;
+
+ line = iter->l->data;
+
+ skipped_to = skip_until(line, iter->line_pos, ',');
+
+ if (skipped_to == iter->line_pos && line[skipped_to] != ',')
+ return FALSE;
+
+ iter->line_pos = skip_to_next_field(line, skipped_to, strlen(line));
+
+ return TRUE;
+}
+
+gboolean g_at_result_iter_open_list(GAtResultIter *iter)
+{
+ char *line;
+ unsigned int len;
+
+ if (!iter)
+ return FALSE;
+
+ if (!iter->l)
+ return FALSE;
+
+ line = iter->l->data;
+ len = strlen(line);
+
+ if (iter->line_pos >= len)
+ return FALSE;
+
+ if (line[iter->line_pos] != '(')
+ return FALSE;
+
+ iter->line_pos += 1;
+
+ while (iter->line_pos < strlen(line) &&
+ line[iter->line_pos] == ' ')
+ iter->line_pos += 1;
+
+ return TRUE;
+}
+
+gboolean g_at_result_iter_close_list(GAtResultIter *iter)
+{
+ char *line;
+ unsigned int len;
+
+ if (!iter)
+ return FALSE;
+
+ if (!iter->l)
+ return FALSE;
+
+ line = iter->l->data;
+ len = strlen(line);
+
+ if (iter->line_pos >= len)
+ return FALSE;
+
+ if (line[iter->line_pos] != ')')
+ return FALSE;
+
+ iter->line_pos += 1;
+
+ iter->line_pos = skip_to_next_field(line, iter->line_pos, len);
+
+ return TRUE;
+}
+
+const char *g_at_result_final_response(GAtResult *result)
+{
+ if (!result)
+ return NULL;
+
+ return result->final_or_pdu;
+}
+
+const char *g_at_result_pdu(GAtResult *result)
+{
+ if (!result)
+ return NULL;
+
+ return result->final_or_pdu;
+}
+
+gint g_at_result_num_response_lines(GAtResult *result)
+{
+ if (!result)
+ return 0;
+
+ if (!result->lines)
+ return 0;
+
+ return g_slist_length(result->lines);
+}