X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=atom%2Fentry.c;h=fd2921e6ed4a37de8d0b9ac4c090a2aab96080d3;hb=f099b7823ba2274326476a095959bfa58f379599;hp=eefb3ed537268bca1d2303e58eddcbede93c343d;hpb=511cf5520ae1f938b7df901b48c521a2bf79c0b4;p=cascardo%2Fatompub.git diff --git a/atom/entry.c b/atom/entry.c index eefb3ed..fd2921e 100644 --- a/atom/entry.c +++ b/atom/entry.c @@ -22,26 +22,42 @@ #include #include #include +#include struct _atom_entry { xmlDocPtr doc; - char *id; + AtomID *id; char *title; - AtomPerson *author; + time_t updated; + GPtrArray *authors; + GPtrArray *categories; char *summary; + AtomContent *content; }; +static void atom_entry_updated_set_from_iso8601 (AtomEntry *, char *); + +void atom_entry_author_add (AtomEntry *, AtomPerson *); +static void atom_entry_authors_delete (AtomEntry *); + +void atom_entry_category_add (AtomEntry *, AtomCategory *); +static void atom_entry_categories_delete (AtomEntry *); + AtomEntry * -atom_entry_new (char *title, AtomPerson *author) +atom_entry_new (char *id, char *title, AtomPerson *author) { AtomEntry *entry; entry = g_slice_new (AtomEntry); entry->doc = NULL; - entry->id = NULL; + entry->id = atom_id_new (id); entry->title = g_strdup (title); - entry->author = author; + entry->updated = time (0); + entry->authors = NULL; + entry->categories = NULL; + atom_entry_author_add (entry, author); entry->summary = NULL; + entry->content = NULL; return entry; } @@ -52,7 +68,8 @@ atom_entry_new_data_len (char *data, size_t len) xmlNodePtr root; xmlNodePtr child; entry = g_slice_new0 (AtomEntry); - entry->doc = xmlReadMemory (data, len, NULL, NULL, XML_PARSE_RECOVER); + entry->doc = xmlReadMemory (data, len, NULL, NULL, + XML_PARSE_RECOVER | XML_PARSE_NOERROR); if (entry->doc == NULL || (root = xmlDocGetRootElement (entry->doc)) == NULL) { @@ -70,15 +87,27 @@ atom_entry_new_data_len (char *data, size_t len) char * content; content = xmlNodeGetContent (child->xmlChildrenNode); if (!xmlStrcmp (child->name, "id")) - entry->id = content; + entry->id = atom_id_new (content); else if (!xmlStrcmp (child->name, "title")) - entry->title = content; + entry->title = g_strdup (content); + else if (!xmlStrcmp (child->name, "updated")) + atom_entry_updated_set_from_iso8601 (entry, content); else if (!xmlStrcmp (child->name, "summary")) - entry->summary = content; + entry->summary = g_strdup (content); else if (!xmlStrcmp (child->name, "author")) - entry->author = atom_person_new_from_xmlnode (child); + atom_entry_author_add (entry, atom_person_new_from_xmlnode (child)); + else if (!xmlStrcmp (child->name, "category")) + atom_entry_category_add (entry, atom_category_new_from_xmlnode (child)); + else if (!xmlStrcmp (child->name, "content")) + entry->content = atom_content_new_from_xmlnode (child); else - xmlFree (content); + xmlFree (content); + } + if (entry->id == NULL || entry->title == NULL || + entry->updated == 0 || entry->authors == NULL) + { + atom_entry_delete (entry); + return NULL; } return entry; } @@ -89,28 +118,32 @@ atom_entry_delete (AtomEntry *entry) if (entry->doc) xmlFreeDoc (entry->doc); if (entry->id) - g_free (entry->id); + atom_id_delete (entry->id); if (entry->title) g_free (entry->title); - if (entry->author) - atom_person_delete (entry->author); + if (entry->authors) + atom_entry_authors_delete (entry); + if (entry->categories) + atom_entry_categories_delete (entry); if (entry->summary) g_free (entry->summary); g_slice_free (AtomEntry, entry); } -char * +AtomID * atom_entry_id (AtomEntry *entry) { return entry->id; } void -atom_entry_id_set (AtomEntry *entry, char *id) +atom_entry_id_set (AtomEntry *entry, AtomID *id) { + if (id == NULL) + return; if (entry->id) - g_free (entry->id); - entry->id = g_strdup (id); + atom_id_delete (entry->id); + entry->id = id; } char * @@ -122,23 +155,100 @@ atom_entry_title (AtomEntry *entry) void atom_entry_title_set (AtomEntry *entry, char *title) { + if (title == NULL) + return; if (entry->title) g_free (title); - entry->title = g_strdup (entry); + entry->title = g_strdup (title); +} + +time_t +atom_entry_updated (AtomEntry *entry) +{ + return entry->updated; +} + +void +atom_entry_updated_set (AtomEntry *entry, time_t updated) +{ + entry->updated = updated; +} + +static void +atom_entry_updated_set_from_iso8601 (AtomEntry *entry, char *updated) +{ + GTimeVal gtv; + g_time_val_from_iso8601 (updated, >v); + entry->updated = gtv.tv_sec; +} + +static char * +atom_entry_updated_to_iso8601 (AtomEntry *entry) +{ + GTimeVal gtv; + gtv.tv_sec = entry->updated; + gtv.tv_usec = 0; + return g_time_val_to_iso8601 (>v); +} + +void +atom_entry_authors (AtomEntry *entry, AtomPerson *** authors, size_t *len) +{ + if (len) + *len = entry->authors->len; + if (authors) + *authors = entry->authors->pdata; +} + +void +atom_entry_author_add (AtomEntry *entry, AtomPerson *author) +{ + if (entry->authors == NULL) + { + entry->authors = g_ptr_array_new (); + } + g_ptr_array_add (entry->authors, author); } -AtomPerson * -atom_entry_author (AtomEntry *entry) +static void +atom_entry_authors_delete (AtomEntry *entry) { - return entry->author; + size_t len = entry->authors->len; + int i; + for (i = 0; i < len; i++) + atom_person_delete (g_ptr_array_index (entry->authors, i)); + g_ptr_array_free (entry->authors, TRUE); } void -atom_entry_author_set (AtomEntry *entry, AtomPerson *author) +atom_entry_categories (AtomEntry *entry, AtomCategory *** categories, + size_t *len) { - if (entry->author) - atom_person_delete (entry->author); - entry->author = author; + if (len) + *len = entry->categories->len; + if (categories) + *categories = entry->categories->pdata; +} + +void +atom_entry_category_add (AtomEntry *entry, AtomCategory *category) +{ + g_ptr_array_add (entry->categories, category); + if (entry->categories == NULL) + { + entry->categories = g_ptr_array_new (); + } + g_ptr_array_add (entry->categories, category); +} + +static void +atom_entry_categories_delete (AtomEntry *entry) +{ + size_t len = entry->categories->len; + int i; + for (i = 0; i < len; i++) + atom_category_delete (g_ptr_array_index (entry->categories, i)); + g_ptr_array_free (entry->categories, TRUE); } char * @@ -155,16 +265,97 @@ atom_entry_summary_set (AtomEntry *entry, char *summary) entry->summary = g_strdup (summary); } +AtomContent * +atom_entry_content (AtomEntry *entry) +{ + return entry->content; +} + +void +atom_entry_content_set (AtomEntry *entry, AtomContent *content) +{ + if (entry->content) + atom_content_delete (entry->content); + entry->content = content; +} + +static void +atom_entry_update_xmlnode (AtomEntry *entry) +{ + xmlNodePtr root; + xmlNodePtr id; + xmlNodePtr title; + xmlNodePtr updated; + xmlNodePtr summary; + xmlNodePtr author; + xmlNodePtr cat; + char *updatedstr; + int i; + if (entry->doc == NULL) + { + entry->doc = xmlNewDoc ("1.0"); + root = xmlNewNode (NULL, "entry"); + xmlNewNs (root, ATOM_NAMESPACE, NULL); + xmlDocSetRootElement (entry->doc, root); + } + else + { + xmlNodePtr child; + xmlNodePtr next; + root = xmlDocGetRootElement (entry->doc); + child = root->xmlChildrenNode; + while (child != NULL) + { + next = child->next; + if (!xmlStrcmp (child->name, "id") || + !xmlStrcmp (child->name, "title") || + !xmlStrcmp (child->name, "updated") || + !xmlStrcmp (child->name, "summary") || + !xmlStrcmp (child->name, "author") || + !xmlStrcmp (child->name, "category") || + !xmlStrcmp (child->name, "content")) + { + xmlUnlinkNode (child); + xmlFreeNode (child); + } + child = next; + } + } + id = xmlNewTextChild (root, NULL, "id", atom_id_string (entry->id)); + title = xmlNewTextChild (root, NULL, "title", entry->title); + updatedstr = atom_entry_updated_to_iso8601 (entry); + updated = xmlNewTextChild (root, NULL, "updated", updatedstr); + g_free (updatedstr); + if (entry->summary) + summary = xmlNewTextChild (root, NULL, "summary", entry->summary); + for (i = 0; i < entry->authors->len; i++) + { + AtomPerson *person; + person = g_ptr_array_index (entry->authors, i); + author = atom_person_to_xmlnode (person, "author"); + xmlAddChild (root, author); + } + for (i = 0; entry->categories && i < entry->categories->len; i++) + { + AtomCategory *category; + category = g_ptr_array_index (entry->categories, i); + cat = atom_category_to_xmlnode (category, "category"); + xmlAddChild (root, cat); + } + if (entry->content) + xmlAddChild (root, atom_content_to_xmlnode (entry->content)); +} + void atom_entry_string (AtomEntry *entry, char **buffer, size_t *len) { + atom_entry_update_xmlnode (entry); xmlDocDumpMemory (entry->doc, buffer, len); } xmlNodePtr atom_entry_to_xmlnode (AtomEntry *entry) { - if (entry->doc) - return xmlDocGetRootElement (entry->doc); - return NULL; + atom_entry_update_xmlnode (entry); + return xmlCopyNodeList (xmlDocGetRootElement (entry->doc)); }