]> git.datanom.net - vcard-parser.git/blobdiff - src/vcard.c
Completed initialization
[vcard-parser.git] / src / vcard.c
index 9a09ccaf0bbd961923dfadffc83ad6ee21fa6d56..e9881f91d85aaf526e68a5d8cb3d391f90a801c3 100644 (file)
  * MA 02110-1301, USA.
  */
 
-# include <vcard.h>
+#include <unistd.h>
+#include <errno.h>
+#include <glib/gprintf.h>
+#include <vcard.h>
+#include <vcard-parser.h>
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
 
 struct _VCard {
-       gchar *version;
+       VCardParserResponse     state;
+       VCardVersion            version;
+       GHashTable*                     vcard;
 };
 
-int main() {
-    return 0;
+static char *replaceWord(const char *s, const char *oldW, const char *newW) {
+    char *result;
+    int i, cnt = 0;
+    int newWlen = strlen(newW);
+    int oldWlen = strlen(oldW);
+
+    for (i = 0; s[i] != '\0'; i++) {
+        if (strstr(&s[i], oldW) == &s[i]) {
+            cnt++;
+            i += oldWlen - 1;
+        }
+    }
+
+    result = (char *) malloc(i + cnt * (newWlen - oldWlen) + 1);
+
+    i = 0;
+    while (*s) {
+        if (strstr(s, oldW) == s) {
+            strcpy(&result[i], newW);
+            i += newWlen;
+            s += oldWlen;
+        }
+        else
+            result[i++] = *s++;
+    }
+
+    result[i] = '\0';
+    return result;
+}
+
+static void hash_table_cb(gpointer key, gpointer value, gpointer data) {
+       GSList* list = (GSList*) value;
+       gchar** str = (gchar**) data;
+       gchar* s = NULL;
+
+       if (!list) return;
+
+       while (list) {
+               VCardProperty* vp = (VCardProperty*) list->data;
+               gchar* s0 = replaceWord(vp->value, "\n", "\n ");
+               if (!*str)
+                       s = g_strconcat(vp->name, ":", s0, NULL);
+               else {
+                       s = g_strconcat(*str, "\n", vp->name, ":", s0, NULL);
+                       g_free(*str);
+               }
+               g_free(s0);
+               *str = g_strdup(s);
+               g_free(s);
+               list = list->next;
+       }
+}
+
+static gchar** make_chunks(const gchar* text) {
+       gchar** chunks = NULL;
+       gchar* v_text = g_strdup(text);
+       g_strstrip(v_text);
+
+       gchar** tmp = g_strsplit(v_text, "END:VCARD", 0);
+       g_free(v_text);
+       guint lines = g_strv_length(tmp);
+       if (lines < 2)
+               return tmp;
+
+       if (strlen(tmp[lines-1]) < 1) {
+               chunks = g_new0(gchar*, lines);
+               lines--;
+       } else
+               chunks = g_new0(gchar*, lines + 1);
+
+       for(int i = 0; i < lines; i++) {
+               g_strchug(tmp[i]);
+               chunks[i] = g_strconcat(tmp[i], "END:VCARD", NULL);
+       }
+       g_strfreev(tmp);
+
+       return chunks;
+}
+
+void VCard_free(VCard* object) {
+       if (object == NULL) return;
+
+       if (object->vcard)
+               destroy_hash_table(object->vcard);
+       g_free(object);
+}
+
+void VCard_list_free(GSList* list) {
+       GSList* tmp = list;
+
+       while(tmp) {
+               VCard* object = (VCard*) tmp->data;
+               VCard_free(object);
+               tmp = tmp->next;
+       }
+
+       if(list)
+               g_slist_free(list);
+}
+
+/*
+VCard* VCard_new(VCardVersion version) {
+       VCard* vc = g_new0(VCard, 1);
+       vc->version = version;
+
+       return vc;
+}
+*/
+
+GSList* VCard_new_from_text(const gchar* text, VCardVersion version, gboolean skip_broken) {
+       GSList* list = NULL;
+       VCard* vc = NULL;
+
+       if (!text || strlen(text) < 1) return NULL;
+
+       gchar** chunks = make_chunks(text);
+       for (int i =  0; i < g_strv_length(chunks); i++) {
+               vc = g_new0(VCard, 1);
+               vc->version = version;
+
+               VCardParserResponse r = vcard_parse_text(chunks[i], &vc->version, &vc->vcard);
+               if (r != VCARD_PARSER_OK && skip_broken) {
+                       VCard_free(vc);
+                       continue;
+               }
+               vc->state = r;
+               list = g_slist_prepend(list, vc);
+       }
+       g_strfreev(chunks);
+
+       return list;
+}
+
+GSList* VCard_new_from_file(FILE* file, VCardVersion version, gboolean skip_broken) {
+       GSList* list = NULL;
+       VCard* vc = g_new0(VCard, 1);
+
+       vc->version = version;
+       list = g_slist_prepend(list, vc);
+
+       return list;
+}
+
+void VCard_print_list(GSList* list) {
+       VCard_print_list_fd(list, STDOUT_FILENO);
+}
+
+void VCard_print_list_fd(GSList* list, int fd) {
+       GSList* tmp = list;
+       if (fd > 0) {
+               while(tmp) {
+                       VCard* object = (VCard*) tmp->data;
+                       VCard_print_fd(object, fd);
+                       if (tmp->next) {
+                               ssize_t len = strlen("\n");
+                               if (write(fd, "\n", len) < len)
+                                       g_warning(strerror(errno));
+                       }
+                       tmp = tmp->next;
+               }
+       }
+}
+
+void VCard_print(VCard* object){
+       VCard_print_fd(object, STDOUT_FILENO);
+}
+
+void VCard_print_fd(VCard* object, int fd) {
+       gchar *body = NULL, *s = NULL;
+
+       if (object && object->vcard && fd > 0) {
+               gchar* version = vcard_version_2_str(object->version);
+               s = g_strdup_printf("BEGIN:VCARD\nVERSION:%s", version);
+               g_free(version);
+               g_hash_table_foreach(object->vcard, hash_table_cb, &s);
+               body = g_strdup_printf("%s\nEND:VCARD", s);
+               g_free(s);
+               ssize_t len = strlen(body);
+               if (write(fd, body, len) < len)
+                       g_warning(strerror(errno));
+               g_free(body);
+       }
+}
+
+gchar* VCard_get_state(VCard* object) {
+       gchar* message = NULL;
+
+       if (!object) return NULL;
+
+       switch (object->state) {
+               case VCARD_PARSER_OK:
+                       message = g_strdup("OK");
+                       break;
+               case VCARD_PARSER_VERSION_MISMATCH:
+                       message = g_strdup("Version mismatch");
+                       break;
+               case VCARD_PARSER_ATTRIBUTE_VERSION_MISMATCH:
+                       message = g_strdup("Attribute not supported in this version");
+                       break;
+               case VCARD_PARSER_BAD_FORMAT:
+                       message = g_strdup("Bad input format");
+                       break;
+               case VCARD_PARSER_ERROR:
+                       message = g_strdup("Unknown error");
+                       break;
+               default:
+                       message = g_strdup("Unhandled error");
+                       break;
+       }
+
+       return message;
+}
+
+GSList* VCard_get_property(VCard* object, const gchar* property) {
+       GSList *values = NULL, *tmp;
+       GSList *iter;
+       VCardProperty* vp = NULL;
+
+       if (object && object->vcard && property) {
+               tmp = g_hash_table_lookup(object->vcard, property);
+               for (iter = tmp; iter; iter = g_slist_next(iter)) {
+                       vp = (VCardProperty*) iter->data;
+                       values = g_slist_prepend(values, g_strdup_printf("%s:%s", vp->name, vp->value));
+        }
+       }
+
+       return values;
 }
This page took 0.04549 seconds and 5 git commands to generate.