1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
|
/*
* Copyright (C) 2009 Lincoln de Sousa <lincoln@minaslivre.org>
*
* This program 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 of the
* License, or (at your option) any later version.
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <taningia/atom.h>
#include <taningia/iri.h>
/* This example shows how our atom implementation works.
*
* == Basic usage of the API ==
*
* It is actually quite simple, the only thing we do is to provide an
* `object' for each piece of an atom document. For example, an atom
* person can be represented with a name, an email address and an uri,
* so to abstract this idea, the AtomPerson class was created and can
* be used like this:
*
* >>> ta_atom_person_t *person;
* >>> person = ta_atom_person_new ("lincoln", NULL, NULL);
*
* The only required argument in the above constructor is the
* `name'. Email and uri fields can be nullable.
*
* And now, to retrieve the value of these attributes you need to do:
*
* >>> const char *name;
* >>> name = ta_atom_person_get_name (person);
* >>> printf ("%s\n", name);
* lincoln
*
* To free the person object and all its attributes, use the
* destructor. That is a function named with the class full name,
* separated by underscores and with the `_free' sufix.
*
* >>> ta_object_unref (person);
*
* So, that's easy, all the rest of the API follows these
* standards. All of the available objects has a constructor with the
* `_new' sufix, getters and setters with the full class name, the
* attribute name and the `_get' or the `_set' sufix.
*
* The only current exception is in the list getters, that uses out
* parameters, like in `ta_atom_person_get_see' that returns a list of
* all simple extension elements. This is its prototype:
*
* >>> void
* >>> ta_atom_person_get_see (ta_atom_person_t *person,
* ... TAtomSimpleExtElement ***elements,
* ... int *len);
*
* Soon we'll implement a List type in our library and we'll change it
* to the above cited standard.
*
* == Uri/Iri consideratinos ==
*
* All fields that were designed to store uris, like Person.uri,
* Link.href, Content.src and others, are actually using iri's. This
* was done to follow recommendations in the RFC4287. So, to fill
* these attributes You'll need to use our iri implementation, like
* this:
*
* >>> TAtomLink *link;
* >>> iri_t *href;
* >>> href = iri_new ("http://gnu.org");
* >>> link = t_link_new (href);
*
* Remembering that when passing href parameter to the link
* constructor, you should not free href, since link is using the
* reference you just created. The `href' var will be freed by the
* `ta_atom_link_free' destructor. All setters of this lib follows this
* standard. Maybe in the future we should use reference count
* strategy. =P
*
*/
int
gen_feed (void)
{
ta_atom_feed_t *feed;
ta_atom_entry_t *entry;
ta_atom_content_t *content;
ta_atom_person_t *author;
ta_error_t *error;
ta_iri_t *feed_id, *entry_id;
char *feed_string;
/* This usually is the first step, create a feed instance: */
feed = ta_atom_feed_new ("My cool atom feed");
/* Creating a random id and setting it to our feed object */
feed_id = ta_iri_new ();
ta_iri_set_from_string (feed_id, "urn:uuid:981db243-7aca-4467-8e38-9641429eba37");
/* Since this iri is hardcoded we're sure that it will be parsed
* successfuly, but in a real example, you should validate it, like
* this: */
if ((error = ta_iri_get_error (feed_id)) != NULL)
{
/* This frees the already set attributes and the feed object
* itself. */
ta_object_unref (feed);
/* Giving some feedback to the user. */
fprintf (stderr, "Invalid uri: %s: %s\n", ta_error_get_name (error),
ta_error_get_message (error));
/* We had no time to set the iri in the feed object, so, we
* should free it manually. But only do it when done with the
* error object it will be freed here too. */
ta_object_unref (feed_id);
return 1;
}
ta_atom_feed_set_id (feed, feed_id);
/* Adding an author to the feed object. This can be done multiple
* times. */
author = ta_atom_person_new ("Lincoln", "lincoln@minaslivre.org", NULL);
ta_atom_feed_add_author (feed, author);
/* Now is the time to create an entry and set a random id to it */
entry = ta_atom_entry_new ("Blah!");
entry_id = ta_iri_new ();
ta_iri_set_from_string (entry_id, "urn:uuid:0a5866b1-1c53-4323-9370-1f7c6a0c3f66");
ta_atom_entry_set_id (entry, entry_id);
/* Setting the rights attribute of the entry */
ta_atom_entry_set_rights (entry, "GNU FDL... bleh bleh bleh...");
/* Adding a content to our entry, without it, it will not work. */
content = ta_atom_content_new ("text/plain");
ta_atom_content_set_content (content, "This is the entry content!", 26);
ta_atom_entry_set_content (entry, content);
/* Finally adding the entry to our feed object. */
ta_atom_feed_add_entry (feed, entry);
/* Generating the xml string of our feed object. Here you can use
* the `ta_atom_feed_to_file' to save it to a file instead of
* printing it. Or use the `ta_atom_feed_to_iks' to generate an iks
* instance and, maybe, send the entry in a pubsub message. */
feed_string = ta_atom_feed_to_string (feed);
printf ("%s\n", feed_string);
/* The only object that should be freed is the toplevel one. Don't
* worry about freeing iri's entries or content. */
ta_object_unref (feed);
free (feed_string);
return 0;
}
/* Simple extension of some atom objects.
*
* As said in the atom spec, it was designed to be extended easily
* when needed. There are three objects that accepts simple extension
* elements, they are: Person, Entry and Feed. And our library
* provides an API to do it. There are two kinds of extension
* elements: The simple and the structured elements. At this moment,
* our library only provides the first way.
*
* A `SimpleExtensionElement' is just a key/value structure that is
* added to an internal array of objects that suports this kind of
* extension. Its representation in an xml file is very simple, like
* this:
*
* >>> TAtomSimpleExtElement *ext_element;
* >>> ext_element = ta_atom_simple_ext_element_new ("key", "value");
* >>> printf ("%s\n", ta_atom_simple_ext_element_to_string (ext_element));
* <key>value</key>
*
* To use it in an object that supports it, you should use the
* `_add_see', `_del_see' and `_get_see' methods. Take a look at the
* function `simple_extension_example'. This example uses an atom
* person to demonstrate the extension, but you can do it with an atom
* entry or an atom feed too.
*/
void
simple_extension_example (void)
{
ta_atom_person_t *person;
ta_atom_simple_element_t *state, *city;
ta_iri_t *uri;
char *person_string;
/* Here we're creating a new person instance with name, email and
* uri fields filled. These are the only fields specified by the
* atom rfc. */
uri = ta_iri_new ();
ta_iri_set_from_string (uri, "http://lincoln.comum.org");
person = ta_atom_person_new ("Lincoln", "lincoln@minaslivre.org", uri);
/* Now, we're going to add simple extension objects to the person
* instance. */
state = ta_atom_simple_element_new ("state", "MG");
ta_atom_person_add_see (person, state);
city = ta_atom_simple_element_new ("city", "Belo Horizonte");
ta_atom_person_add_see (person, city);
/* When executing this example, you'll see all required fields
* (name, email and uri), but both the state and city fields were
* added too. */
person_string = ta_atom_person_to_string (person, "person");
printf ("%s\n", person_string);
free (person_string);
/* like in other places, freeing an instance that holds references
* for other objects is enough. You should not try to free state,
* city or uri vars */
ta_object_unref (person);
}
int
main (int argc, char **argv)
{
printf ("Generating an atom feed:\n");
gen_feed ();
printf ("\n");
printf ("Extending an atom element:\n");
simple_extension_example ();
return 0;
}
|